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