// Copyright 2019 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "src/extensions/vtunedomain-support-extension.h" #include <string> #include <vector> namespace v8 { namespace internal { namespace libvtune { int startTask(const std::vector<std::string>& vparams); int endTask(const std::vector<std::string>& vparams); const auto& function_map = *new std::map<std::string, int (*)(const std::vector<std::string>&)>{ {"start", startTask}, {"end", endTask}}; void split(const std::string& str, char delimiter, std::vector<std::string>* vparams) { std::string::size_type baseindex = 0; std::string::size_type offindex = str.find(delimiter); while (offindex != std::string::npos) { (*vparams).push_back(str.substr(baseindex, offindex - baseindex)); baseindex = ++offindex; offindex = str.find(delimiter, offindex); if (offindex == std::string::npos) (*vparams).push_back(str.substr(baseindex, str.length())); } } int startTask(const std::vector<std::string>& vparams) { int errcode = 0; if (const char* domain_name = vparams[1].c_str()) { if (const char* task_name = vparams[2].c_str()) { if (std::shared_ptr<VTuneDomain> domainptr = VTuneDomain::createDomain(domain_name)) { if (!domainptr->beginTask(task_name)) { errcode += TASK_BEGIN_FAILED; } } else { errcode += CREATE_DOMAIN_FAILED; } } else { errcode += NO_TASK_NAME; } } else { errcode = NO_DOMAIN_NAME; } return errcode; } int endTask(const std::vector<std::string>& vparams) { int errcode = 0; if (const char* domain_name = vparams[1].c_str()) { if (std::shared_ptr<VTuneDomain> domainptr = VTuneDomain::createDomain(domain_name)) { domainptr->endTask(); } else { errcode += CREATE_DOMAIN_FAILED; } } else { errcode = NO_DOMAIN_NAME; } return errcode; } int invoke(const char* params) { int errcode = 0; std::vector<std::string> vparams; split(*(new std::string(params)), ' ', &vparams); auto it = function_map.find(vparams[0]); if (it != function_map.end()) { (it->second)(vparams); } else { errcode += UNKNOWN_PARAMS; } return errcode; } } // namespace libvtune v8::Local<v8::FunctionTemplate> VTuneDomainSupportExtension::GetNativeFunctionTemplate( v8::Isolate* isolate, v8::Local<v8::String> str) { return v8::FunctionTemplate::New(isolate, VTuneDomainSupportExtension::Mark); } // args should take three parameters // %0 : string, which is the domain name. Domain is used to tagging trace data // for different modules or libraryies in a program // %1 : string, which is the task name. Task is a logical unit of work performed // by a particular thread statement. Task can nest. // %2 : string, "start" / "end". Action to be taken on a task in a particular // domain void VTuneDomainSupportExtension::Mark( const v8::FunctionCallbackInfo<v8::Value>& args) { if (args.Length() != 3 || !args[0]->IsString() || !args[1]->IsString() || !args[2]->IsString()) { args.GetIsolate()->ThrowException(v8::String::NewFromUtf8Literal( args.GetIsolate(), "Parameter number should be exactly three, first domain name" "second task name, third start/end")); return; } v8::Isolate* isolate = args.GetIsolate(); v8::String::Utf8Value domainName(isolate, args[0]); v8::String::Utf8Value taskName(isolate, args[1]); v8::String::Utf8Value statName(isolate, args[2]); char* cdomainName = *domainName; char* ctaskName = *taskName; char* cstatName = *statName; std::stringstream params; params << cstatName << " " << cdomainName << " " << ctaskName; int r = 0; if ((r = libvtune::invoke(params.str().c_str())) != 0) { args.GetIsolate()->ThrowException( v8::String::NewFromUtf8(args.GetIsolate(), std::to_string(r).c_str()) .ToLocalChecked()); } } } // namespace internal } // namespace v8