1 // Copyright 2019 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "src/extensions/vtunedomain-support-extension.h"
6 #include <string>
7 #include <vector>
8
9 namespace v8 {
10 namespace internal {
11
12 namespace libvtune {
13
14 int startTask(const std::vector<std::string>& vparams);
15 int endTask(const std::vector<std::string>& vparams);
16
17 const auto& function_map =
18 *new std::map<std::string, int (*)(const std::vector<std::string>&)>{
19 {"start", startTask}, {"end", endTask}};
20
split(const std::string & str,char delimiter,std::vector<std::string> * vparams)21 void split(const std::string& str, char delimiter,
22 std::vector<std::string>* vparams) {
23 std::string::size_type baseindex = 0;
24 std::string::size_type offindex = str.find(delimiter);
25
26 while (offindex != std::string::npos) {
27 (*vparams).push_back(str.substr(baseindex, offindex - baseindex));
28 baseindex = ++offindex;
29 offindex = str.find(delimiter, offindex);
30
31 if (offindex == std::string::npos)
32 (*vparams).push_back(str.substr(baseindex, str.length()));
33 }
34 }
35
startTask(const std::vector<std::string> & vparams)36 int startTask(const std::vector<std::string>& vparams) {
37 int errcode = 0;
38
39 if (const char* domain_name = vparams[1].c_str()) {
40 if (const char* task_name = vparams[2].c_str()) {
41 if (std::shared_ptr<VTuneDomain> domainptr =
42 VTuneDomain::createDomain(domain_name)) {
43 if (!domainptr->beginTask(task_name)) {
44 errcode += TASK_BEGIN_FAILED;
45 }
46 } else {
47 errcode += CREATE_DOMAIN_FAILED;
48 }
49 } else {
50 errcode += NO_TASK_NAME;
51 }
52
53 } else {
54 errcode = NO_DOMAIN_NAME;
55 }
56
57 return errcode;
58 }
59
endTask(const std::vector<std::string> & vparams)60 int endTask(const std::vector<std::string>& vparams) {
61 int errcode = 0;
62
63 if (const char* domain_name = vparams[1].c_str()) {
64 if (std::shared_ptr<VTuneDomain> domainptr =
65 VTuneDomain::createDomain(domain_name)) {
66 domainptr->endTask();
67 } else {
68 errcode += CREATE_DOMAIN_FAILED;
69 }
70 } else {
71 errcode = NO_DOMAIN_NAME;
72 }
73
74 return errcode;
75 }
76
invoke(const char * params)77 int invoke(const char* params) {
78 int errcode = 0;
79 std::vector<std::string> vparams;
80
81 split(*(new std::string(params)), ' ', &vparams);
82
83 auto it = function_map.find(vparams[0]);
84 if (it != function_map.end()) {
85 (it->second)(vparams);
86 } else {
87 errcode += UNKNOWN_PARAMS;
88 }
89
90 return errcode;
91 }
92
93 } // namespace libvtune
94
95 v8::Local<v8::FunctionTemplate>
GetNativeFunctionTemplate(v8::Isolate * isolate,v8::Local<v8::String> str)96 VTuneDomainSupportExtension::GetNativeFunctionTemplate(
97 v8::Isolate* isolate, v8::Local<v8::String> str) {
98 return v8::FunctionTemplate::New(isolate, VTuneDomainSupportExtension::Mark);
99 }
100
101 // args should take three parameters
102 // %0 : string, which is the domain name. Domain is used to tagging trace data
103 // for different modules or libraryies in a program
104 // %1 : string, which is the task name. Task is a logical unit of work performed
105 // by a particular thread statement. Task can nest.
106 // %2 : string, "start" / "end". Action to be taken on a task in a particular
107 // domain
Mark(const v8::FunctionCallbackInfo<v8::Value> & args)108 void VTuneDomainSupportExtension::Mark(
109 const v8::FunctionCallbackInfo<v8::Value>& args) {
110 if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsString() ||
111 !args[2]->IsString()) {
112 args.GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal(
113 args.GetIsolate(),
114 "Parameter number should be exactly three, first domain name"
115 "second task name, third start/end"));
116 return;
117 }
118
119 v8::Isolate* isolate = args.GetIsolate();
120 v8::String::Utf8Value domainName(isolate, args[0]);
121 v8::String::Utf8Value taskName(isolate, args[1]);
122 v8::String::Utf8Value statName(isolate, args[2]);
123
124 char* cdomainName = *domainName;
125 char* ctaskName = *taskName;
126 char* cstatName = *statName;
127
128 std::stringstream params;
129 params << cstatName << " " << cdomainName << " " << ctaskName;
130
131 int r = 0;
132 if ((r = libvtune::invoke(params.str().c_str())) != 0) {
133 args.GetIsolate()->ThrowException(
134 v8::String::NewFromUtf8(args.GetIsolate(), std::to_string(r).c_str())
135 .ToLocalChecked());
136 }
137 }
138
139 } // namespace internal
140 } // namespace v8
141