1/* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecmascript/jobs/hitrace_scope.h" 17 18#include "ecmascript/jobs/pending_job.h" 19#include "hitrace/trace.h" 20#include "ecmascript/dfx/stackinfo/js_stackinfo.h" 21 22namespace panda::ecmascript::job { 23EnqueueJobScope::EnqueueJobScope(const JSHandle<PendingJob> &pendingJob, QueueType queueType) 24{ 25 HiTraceId id = HiTraceChain::GetId(); 26 if (id.IsValid() && id.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC)) { 27 HiTraceId childId = HiTraceChain::CreateSpan(); 28 29 pendingJob->SetChainId(childId.GetChainId()); 30 pendingJob->SetSpanId(childId.GetSpanId()); 31 pendingJob->SetParentSpanId(childId.GetParentSpanId()); 32 pendingJob->SetFlags(childId.GetFlags()); 33 34 if (id.IsFlagEnabled(HITRACE_FLAG_TP_INFO)) { 35 if (queueType == QueueType::QUEUE_PROMISE) { 36 HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS, 37 childId, "Queue type:%s", "Promise queue"); 38 } else if (queueType == QueueType::QUEUE_SCRIPT) { 39 HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS, 40 childId, "Queue type:%s", "Script queue"); 41 } else { 42 HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS, 43 childId, "Queue type:%s", "Other queue"); 44 } 45 } 46 } 47} 48 49EnqueueJobScope::~EnqueueJobScope() 50{ 51} 52 53ExecuteJobScope::ExecuteJobScope(const JSHandle<PendingJob> &pendingJob) 54{ 55 saveId_ = HiTraceChain::GetId(); 56 if (saveId_.IsValid()) { 57 HiTraceChain::ClearId(); 58 } 59 if (pendingJob->GetChainId() != 0) { 60 hitraceId_.SetChainId(pendingJob->GetChainId()); 61 hitraceId_.SetSpanId(pendingJob->GetSpanId()); 62 hitraceId_.SetParentSpanId(pendingJob->GetParentSpanId()); 63 hitraceId_.SetFlags(pendingJob->GetFlags()); 64 65 if (hitraceId_.IsValid()) { 66 HiTraceChain::SetId(hitraceId_); 67 if (hitraceId_.IsFlagEnabled(HITRACE_FLAG_TP_INFO)) { 68 HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_SR, 69 hitraceId_, "Before %s pending job execute", "Promise"); 70 } 71 } 72 } 73} 74 75ExecuteJobScope::~ExecuteJobScope() 76{ 77 if (hitraceId_.IsValid()) { 78 if (hitraceId_.IsFlagEnabled(HITRACE_FLAG_TP_INFO)) { 79 HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_SS, 80 hitraceId_, "After %s pending job execute", "Promise"); 81 } 82 HiTraceChain::ClearId(); 83 } 84 if (saveId_.IsValid()) { 85 HiTraceChain::SetId(saveId_); 86 } 87} 88 89EnqueueJobTrace::EnqueueJobTrace(JSThread *thread, const JSHandle<PendingJob> &pendingJob) 90{ 91 isMicroJobTraceEnable_ = thread->GetEcmaVM()->GetJSOptions().EnableMicroJobTrace(); 92 if (!isMicroJobTraceEnable_) { 93 return; 94 } 95 96 uint64_t jobId = thread->GetJobId(); 97 pendingJob->SetJobId(jobId); 98 std::string strTrace = "MicroJobQueue::EnqueueJob: jobId: " + std::to_string(jobId); 99 strTrace += ", threadId: " + std::to_string(thread->GetThreadId()); 100 101 std::vector<JsFrameInfo> jsStackInfo = JsStackInfo::BuildJsStackInfo(thread, true); 102 if (jsStackInfo.empty()) { 103 ECMA_BYTRACE_START_TRACE(HITRACE_TAG_ARK, strTrace); 104 return; 105 } 106 107 JsFrameInfo jsFrameInfo = jsStackInfo.front(); 108 size_t pos = jsFrameInfo.pos.find(':', 0); 109 if (pos != CString::npos) { 110 int lineNumber = std::stoi(jsFrameInfo.pos.substr(0, pos)); 111 int columnNumber = std::stoi(jsFrameInfo.pos.substr(pos + 1)); 112 auto sourceMapcb = thread->GetEcmaVM()->GetSourceMapTranslateCallback(); 113 if (sourceMapcb != nullptr && !jsFrameInfo.fileName.empty()) { 114 sourceMapcb(jsFrameInfo.fileName, lineNumber, columnNumber); 115 } 116 } 117 118 strTrace += ", funcName: " + jsFrameInfo.functionName + ", url: " + jsFrameInfo.fileName + ":" + jsFrameInfo.pos; 119 ECMA_BYTRACE_START_TRACE(HITRACE_TAG_ARK, strTrace); 120} 121 122EnqueueJobTrace::~EnqueueJobTrace() 123{ 124 if (isMicroJobTraceEnable_) { 125 ECMA_BYTRACE_FINISH_TRACE(HITRACE_TAG_ARK); 126 } 127} 128 129ExecuteJobTrace::ExecuteJobTrace(JSThread *thread, const JSHandle<PendingJob> &pendingJob) 130{ 131 isMicroJobTraceEnable_ = thread->GetEcmaVM()->GetJSOptions().EnableMicroJobTrace(); 132 if (isMicroJobTraceEnable_) { 133 uint64_t jobId = pendingJob->GetJobId(); 134 std::string strTrace = "PendingJob::ExecutePendingJob: jobId: " + std::to_string(jobId); 135 strTrace += ", threadId: " + std::to_string(thread->GetThreadId()); 136 ECMA_BYTRACE_START_TRACE(HITRACE_TAG_ARK, strTrace); 137 } 138} 139 140ExecuteJobTrace::~ExecuteJobTrace() 141{ 142 if (isMicroJobTraceEnable_) { 143 ECMA_BYTRACE_FINISH_TRACE(HITRACE_TAG_ARK); 144 } 145} 146} // namespace panda::ecmascript::job