mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-07 16:13:49 +00:00
CpuProfiler add moduleName and modify napi get stack interval
issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I7K9YC Signed-off-by: Chongwei Su <suchongwei@huawei.com>
This commit is contained in:
parent
b0ba8a74b0
commit
6b2884fd80
@ -302,20 +302,27 @@ void CpuProfiler::GetStack(FrameIterator &it)
|
||||
generator_->PostFrame();
|
||||
}
|
||||
|
||||
void CpuProfiler::GetStackCallNapi(JSThread *thread, bool beforeCallNapi)
|
||||
bool CpuProfiler::GetStackBeforeCallNapi(JSThread *thread)
|
||||
{
|
||||
uint64_t tempTimeStamp = SamplingProcessor::GetMicrosecondsTimeStamp();
|
||||
if (beforeCallNapi) {
|
||||
if (tempTimeStamp - beforeCallNapiTimeStamp_ < INTERVAL_OF_ACTIVE_SAMPLING) {
|
||||
beforeCallNapiTimeStamp_ = tempTimeStamp;
|
||||
return;
|
||||
}
|
||||
beforeCallNapiTimeStamp_ = tempTimeStamp;
|
||||
} else {
|
||||
if (tempTimeStamp - beforeCallNapiTimeStamp_ < CPUPROFILER_DEFAULT_INTERVAL) {
|
||||
return;
|
||||
}
|
||||
if (tempTimeStamp - beforeCallNapiTimeStamp_ < interval_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (GetStackCallNapi(thread, true)) {
|
||||
beforeCallNapiTimeStamp_ = tempTimeStamp;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CpuProfiler::GetStackAfterCallNapi(JSThread *thread)
|
||||
{
|
||||
GetStackCallNapi(thread, false);
|
||||
}
|
||||
|
||||
bool CpuProfiler::GetStackCallNapi(JSThread *thread, bool beforeCallNapi)
|
||||
{
|
||||
[[maybe_unused]] CallNapiScope scope(this);
|
||||
const CMap<struct MethodKey, struct FrameInfo> &stackInfo = generator_->GetStackInfo();
|
||||
generator_->ClearNapiStack();
|
||||
@ -354,14 +361,15 @@ void CpuProfiler::GetStackCallNapi(JSThread *thread, bool beforeCallNapi)
|
||||
continue;
|
||||
}
|
||||
if (UNLIKELY(!generator_->PushNapiStackInfo(codeEntry))) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (UNLIKELY(!generator_->PushNapiFrameStack(methodKey))) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
generator_->PostNapiFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
void CpuProfiler::GetStackSignalHandler(int signal, [[maybe_unused]] siginfo_t *siginfo, void *context)
|
||||
|
@ -80,7 +80,9 @@ public:
|
||||
bool InHeaderOrTail(uint64_t pc, uint64_t entryBegin, uint64_t entryDuration, uint64_t headerSize,
|
||||
uint64_t tailSize) const;
|
||||
bool IsEntryFrameHeaderOrTail(JSThread *thread, uint64_t pc) const;
|
||||
void GetStackCallNapi(JSThread *thread, bool beforeCallNapi);
|
||||
bool GetStackBeforeCallNapi(JSThread *thread);
|
||||
void GetStackAfterCallNapi(JSThread *thread);
|
||||
bool GetStackCallNapi(JSThread *thread, bool beforeCallNapi);
|
||||
static void GetStackSignalHandler(int signal, siginfo_t *siginfo, void *context);
|
||||
|
||||
void StartCpuProfilerForInfo();
|
||||
|
@ -182,7 +182,8 @@ void SamplesRecord::StringifyNodes()
|
||||
replace(url.begin(), url.end(), '\\', '/');
|
||||
sampleData_ += "{\"id\":"
|
||||
+ std::to_string(node.id) + ",\"callFrame\":{\"functionName\":\""
|
||||
+ codeEntry.functionName + "\",\"scriptId\":\""
|
||||
+ codeEntry.functionName + "\",\"moduleName\":\""
|
||||
+ codeEntry.moduleName + "\",\"scriptId\":\""
|
||||
+ std::to_string(codeEntry.scriptId) + "\",\"url\":\""
|
||||
+ url + "\",\"lineNumber\":"
|
||||
+ std::to_string(codeEntry.lineNumber) + ",\"columnNumber\":"
|
||||
@ -658,6 +659,22 @@ bool SamplesRecord::PushNapiStackInfo(const FrameInfoTemp &frameInfoTemp)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string SamplesRecord::GetModuleName(char *recordName)
|
||||
{
|
||||
std::string recordNameStr = recordName;
|
||||
int atPos = recordNameStr.find("@");
|
||||
if (atPos == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
int slashPos = recordNameStr.rfind("/", atPos);
|
||||
if (slashPos == std::string::npos) {
|
||||
return "";
|
||||
}
|
||||
|
||||
return recordNameStr.substr(slashPos + 1, atPos - slashPos - 1);
|
||||
}
|
||||
|
||||
void SamplesRecord::FrameInfoTempToMap(FrameInfoTemp *frameInfoTemps, int frameInfoTempLength)
|
||||
{
|
||||
if (frameInfoTempLength == 0) {
|
||||
@ -676,6 +693,9 @@ void SamplesRecord::FrameInfoTempToMap(FrameInfoTemp *frameInfoTemps, int frameI
|
||||
frameInfo.functionName = AddRunningState(frameInfoTemps[i].functionName,
|
||||
frameInfoTemps[i].methodKey.state,
|
||||
frameInfoTemps[i].methodKey.deoptType);
|
||||
if (strlen(frameInfoTemps[i].recordName) != 0) {
|
||||
frameInfo.moduleName = GetModuleName(frameInfoTemps[i].recordName);
|
||||
}
|
||||
frameInfo.columnNumber = frameInfoTemps[i].columnNumber;
|
||||
frameInfo.lineNumber = frameInfoTemps[i].lineNumber;
|
||||
stackInfoMap_.emplace(frameInfoTemps[i].methodKey, frameInfo);
|
||||
@ -702,6 +722,9 @@ void SamplesRecord::NapiFrameInfoTempToMap()
|
||||
frameInfo.functionName = AddRunningState(napiFrameInfoTemps_[i].functionName,
|
||||
napiFrameInfoTemps_[i].methodKey.state,
|
||||
napiFrameInfoTemps_[i].methodKey.deoptType);
|
||||
if (strlen(napiFrameInfoTemps_[i].recordName) != 0) {
|
||||
frameInfo.moduleName = GetModuleName(napiFrameInfoTemps_[i].recordName);
|
||||
}
|
||||
frameInfo.columnNumber = napiFrameInfoTemps_[i].columnNumber;
|
||||
frameInfo.lineNumber = napiFrameInfoTemps_[i].lineNumber;
|
||||
stackInfoMap_.emplace(napiFrameInfoTemps_[i].methodKey, frameInfo);
|
||||
@ -759,6 +782,8 @@ void SamplesQueue::PostFrame(FrameInfoTemp *frameInfoTemps, MethodKey *frameStac
|
||||
for (int i = 0; i < frameInfoTempsLength; i++) {
|
||||
CheckAndCopy(frames_[rear_].frameInfoTemps[i].functionName,
|
||||
sizeof(frames_[rear_].frameInfoTemps[i].functionName), frameInfoTemps[i].functionName);
|
||||
CheckAndCopy(frames_[rear_].frameInfoTemps[i].recordName,
|
||||
sizeof(frames_[rear_].frameInfoTemps[i].recordName), frameInfoTemps[i].recordName);
|
||||
frames_[rear_].frameInfoTemps[i].columnNumber = frameInfoTemps[i].columnNumber;
|
||||
frames_[rear_].frameInfoTemps[i].lineNumber = frameInfoTemps[i].lineNumber;
|
||||
frames_[rear_].frameInfoTemps[i].scriptId = frameInfoTemps[i].scriptId;
|
||||
@ -794,6 +819,8 @@ void SamplesQueue::PostNapiFrame(CVector<FrameInfoTemp> &napiFrameInfoTemps,
|
||||
for (size_t i = 0; i < frameInfoTempsLength; i++) {
|
||||
CheckAndCopy(frames_[rear_].frameInfoTemps[i].functionName,
|
||||
sizeof(frames_[rear_].frameInfoTemps[i].functionName), napiFrameInfoTemps[i].functionName);
|
||||
CheckAndCopy(frames_[rear_].frameInfoTemps[i].recordName,
|
||||
sizeof(frames_[rear_].frameInfoTemps[i].recordName), napiFrameInfoTemps[i].recordName);
|
||||
frames_[rear_].frameInfoTemps[i].columnNumber = napiFrameInfoTemps[i].columnNumber;
|
||||
frames_[rear_].frameInfoTemps[i].lineNumber = napiFrameInfoTemps[i].lineNumber;
|
||||
frames_[rear_].frameInfoTemps[i].scriptId = napiFrameInfoTemps[i].scriptId;
|
||||
|
@ -38,11 +38,11 @@ const size_t NAPI_CALL_SETP = 2; // 2: step size of the variable napiCallIdx in
|
||||
const size_t PRE_IDX_RANGE = 5; // 5: length of variable preIdx looping backward
|
||||
|
||||
struct FrameInfo {
|
||||
std::string codeType = "";
|
||||
std::string functionName = "";
|
||||
int columnNumber = -1;
|
||||
int lineNumber = -1;
|
||||
int scriptId = 0;
|
||||
int lineNumber = -1;
|
||||
int columnNumber = -1;
|
||||
std::string functionName = "";
|
||||
std::string moduleName = "";
|
||||
std::string url = "";
|
||||
};
|
||||
|
||||
@ -121,6 +121,7 @@ public:
|
||||
int GetMethodNodeCount() const;
|
||||
int GetframeStackLength() const;
|
||||
std::string GetSampleData() const;
|
||||
std::string GetModuleName(char *recordName);
|
||||
void SetThreadStartTime(uint64_t threadStartTime);
|
||||
void SetThreadStopTime();
|
||||
void SetStartsampleData(std::string sampleData);
|
||||
|
@ -23,6 +23,7 @@ namespace panda::ecmascript {
|
||||
struct CallFrameInfo {
|
||||
std::string codeType_ = "";
|
||||
std::string functionName_ = "";
|
||||
std::string moduleName_ = "";
|
||||
int columnNumber_ = -1;
|
||||
int lineNumber_ = -1;
|
||||
int scriptId_ = 0;
|
||||
|
@ -64,35 +64,41 @@ bool JsStackGetter::ParseMethodInfo(struct MethodKey &methodKey,
|
||||
GetNativeStack(vm, it, codeEntry.functionName, sizeof(codeEntry.functionName), isCpuProfiler);
|
||||
} else {
|
||||
EntityId methodId = reinterpret_cast<MethodLiteral *>(methodKey.methodIdentifier)->GetMethodId();
|
||||
const char *tempVariable = MethodLiteral::GetMethodName(jsPandaFile, methodId);
|
||||
uint8_t length = strlen(tempVariable);
|
||||
if (length != 0 && tempVariable[0] == '#') {
|
||||
// function name
|
||||
const char *functionName = MethodLiteral::GetMethodName(jsPandaFile, methodId);
|
||||
uint8_t length = strlen(functionName);
|
||||
if (length != 0 && functionName[0] == '#') {
|
||||
uint8_t index = length - 1;
|
||||
while (tempVariable[index] != '#') {
|
||||
while (functionName[index] != '#') {
|
||||
index--;
|
||||
}
|
||||
tempVariable += (index + 1);
|
||||
functionName += (index + 1);
|
||||
}
|
||||
if (strlen(tempVariable) == 0) {
|
||||
tempVariable = "anonymous";
|
||||
if (strlen(functionName) == 0) {
|
||||
functionName = "anonymous";
|
||||
}
|
||||
if (!CheckAndCopy(codeEntry.functionName, sizeof(codeEntry.functionName), tempVariable)) {
|
||||
if (!CheckAndCopy(codeEntry.functionName, sizeof(codeEntry.functionName), functionName)) {
|
||||
return false;
|
||||
}
|
||||
// source file
|
||||
// record name
|
||||
CString recordNameStr = MethodLiteral::GetRecordName(jsPandaFile, methodId);
|
||||
if (!recordNameStr.empty()) {
|
||||
if (!CheckAndCopy(codeEntry.recordName, sizeof(codeEntry.recordName), recordNameStr.c_str())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
DebugInfoExtractor *debugExtractor =
|
||||
JSPandaFileManager::GetInstance()->GetJSPtExtractor(jsPandaFile);
|
||||
if (debugExtractor == nullptr) {
|
||||
return false;
|
||||
}
|
||||
// source file
|
||||
const std::string &sourceFile = debugExtractor->GetSourceFile(methodId);
|
||||
if (sourceFile.empty()) {
|
||||
tempVariable = "";
|
||||
} else {
|
||||
tempVariable = sourceFile.c_str();
|
||||
}
|
||||
if (!CheckAndCopy(codeEntry.url, sizeof(codeEntry.url), tempVariable)) {
|
||||
return false;
|
||||
if (!sourceFile.empty()) {
|
||||
if (!CheckAndCopy(codeEntry.url, sizeof(codeEntry.url), sourceFile.c_str())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// line number and clomn number
|
||||
codeEntry.lineNumber = debugExtractor->GetFristLine(methodId);
|
||||
|
@ -61,6 +61,7 @@ struct NodeKey {
|
||||
struct FrameInfoTemp {
|
||||
char codeType[20] = {0}; // 20:the maximum size of the codeType
|
||||
char functionName[100] = {0}; // 100:the maximum size of the functionName
|
||||
char recordName[100] = {0}; // 100:the maximum size of the recordName
|
||||
int columnNumber = -1;
|
||||
int lineNumber = -1;
|
||||
int scriptId = 0;
|
||||
|
@ -2741,14 +2741,15 @@ JSTaggedValue Callback::RegisterCallback(ecmascript::EcmaRuntimeCallInfo *ecmaRu
|
||||
|
||||
JsiRuntimeCallInfo jsiRuntimeCallInfo(ecmaRuntimeCallInfo, extraInfo->GetData());
|
||||
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
||||
bool getStackBeforeCallNapiSuccess = false;
|
||||
if (thread->GetIsProfiling() && function->IsCallNapi()) {
|
||||
thread->GetEcmaVM()->GetProfiler()->GetStackCallNapi(thread, true);
|
||||
getStackBeforeCallNapiSuccess = thread->GetEcmaVM()->GetProfiler()->GetStackBeforeCallNapi(thread);
|
||||
}
|
||||
#endif
|
||||
Local<JSValueRef> result = nativeFunc(&jsiRuntimeCallInfo);
|
||||
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
||||
if (thread->GetIsProfiling() && function->IsCallNapi()) {
|
||||
thread->GetEcmaVM()->GetProfiler()->GetStackCallNapi(thread, false);
|
||||
if (thread->GetIsProfiling() && function->IsCallNapi() && getStackBeforeCallNapiSuccess) {
|
||||
thread->GetEcmaVM()->GetProfiler()->GetStackAfterCallNapi(thread);
|
||||
}
|
||||
#endif
|
||||
return JSNApiHelper::ToJSHandle(result).GetTaggedValue();
|
||||
|
Loading…
Reference in New Issue
Block a user