14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
34514f5e3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
44514f5e3Sopenharmony_ci * you may not use this file except in compliance with the License.
54514f5e3Sopenharmony_ci * You may obtain a copy of the License at
64514f5e3Sopenharmony_ci *
74514f5e3Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
84514f5e3Sopenharmony_ci *
94514f5e3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
104514f5e3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
114514f5e3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
124514f5e3Sopenharmony_ci * See the License for the specific language governing permissions and
134514f5e3Sopenharmony_ci * limitations under the License.
144514f5e3Sopenharmony_ci */
154514f5e3Sopenharmony_ci
164514f5e3Sopenharmony_ci#include "ecmascript/jobs/hitrace_scope.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/jobs/pending_job.h"
194514f5e3Sopenharmony_ci#include "hitrace/trace.h"
204514f5e3Sopenharmony_ci#include "ecmascript/dfx/stackinfo/js_stackinfo.h"
214514f5e3Sopenharmony_ci
224514f5e3Sopenharmony_cinamespace panda::ecmascript::job {
234514f5e3Sopenharmony_ciEnqueueJobScope::EnqueueJobScope(const JSHandle<PendingJob> &pendingJob, QueueType queueType)
244514f5e3Sopenharmony_ci{
254514f5e3Sopenharmony_ci    HiTraceId id = HiTraceChain::GetId();
264514f5e3Sopenharmony_ci    if (id.IsValid() && id.IsFlagEnabled(HITRACE_FLAG_INCLUDE_ASYNC)) {
274514f5e3Sopenharmony_ci        HiTraceId childId = HiTraceChain::CreateSpan();
284514f5e3Sopenharmony_ci
294514f5e3Sopenharmony_ci        pendingJob->SetChainId(childId.GetChainId());
304514f5e3Sopenharmony_ci        pendingJob->SetSpanId(childId.GetSpanId());
314514f5e3Sopenharmony_ci        pendingJob->SetParentSpanId(childId.GetParentSpanId());
324514f5e3Sopenharmony_ci        pendingJob->SetFlags(childId.GetFlags());
334514f5e3Sopenharmony_ci
344514f5e3Sopenharmony_ci        if (id.IsFlagEnabled(HITRACE_FLAG_TP_INFO)) {
354514f5e3Sopenharmony_ci            if (queueType == QueueType::QUEUE_PROMISE) {
364514f5e3Sopenharmony_ci                HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS,
374514f5e3Sopenharmony_ci                    childId, "Queue type:%s", "Promise queue");
384514f5e3Sopenharmony_ci            } else if (queueType == QueueType::QUEUE_SCRIPT) {
394514f5e3Sopenharmony_ci                HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS,
404514f5e3Sopenharmony_ci                    childId, "Queue type:%s", "Script queue");
414514f5e3Sopenharmony_ci            } else {
424514f5e3Sopenharmony_ci                HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_CS,
434514f5e3Sopenharmony_ci                    childId, "Queue type:%s", "Other queue");
444514f5e3Sopenharmony_ci            }
454514f5e3Sopenharmony_ci        }
464514f5e3Sopenharmony_ci    }
474514f5e3Sopenharmony_ci}
484514f5e3Sopenharmony_ci
494514f5e3Sopenharmony_ciEnqueueJobScope::~EnqueueJobScope()
504514f5e3Sopenharmony_ci{
514514f5e3Sopenharmony_ci}
524514f5e3Sopenharmony_ci
534514f5e3Sopenharmony_ciExecuteJobScope::ExecuteJobScope(const JSHandle<PendingJob> &pendingJob)
544514f5e3Sopenharmony_ci{
554514f5e3Sopenharmony_ci    saveId_ = HiTraceChain::GetId();
564514f5e3Sopenharmony_ci    if (saveId_.IsValid()) {
574514f5e3Sopenharmony_ci        HiTraceChain::ClearId();
584514f5e3Sopenharmony_ci    }
594514f5e3Sopenharmony_ci    if (pendingJob->GetChainId() != 0) {
604514f5e3Sopenharmony_ci        hitraceId_.SetChainId(pendingJob->GetChainId());
614514f5e3Sopenharmony_ci        hitraceId_.SetSpanId(pendingJob->GetSpanId());
624514f5e3Sopenharmony_ci        hitraceId_.SetParentSpanId(pendingJob->GetParentSpanId());
634514f5e3Sopenharmony_ci        hitraceId_.SetFlags(pendingJob->GetFlags());
644514f5e3Sopenharmony_ci
654514f5e3Sopenharmony_ci        if (hitraceId_.IsValid()) {
664514f5e3Sopenharmony_ci            HiTraceChain::SetId(hitraceId_);
674514f5e3Sopenharmony_ci            if (hitraceId_.IsFlagEnabled(HITRACE_FLAG_TP_INFO)) {
684514f5e3Sopenharmony_ci                HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_SR,
694514f5e3Sopenharmony_ci                    hitraceId_, "Before %s pending job execute", "Promise");
704514f5e3Sopenharmony_ci            }
714514f5e3Sopenharmony_ci        }
724514f5e3Sopenharmony_ci    }
734514f5e3Sopenharmony_ci}
744514f5e3Sopenharmony_ci
754514f5e3Sopenharmony_ciExecuteJobScope::~ExecuteJobScope()
764514f5e3Sopenharmony_ci{
774514f5e3Sopenharmony_ci    if (hitraceId_.IsValid()) {
784514f5e3Sopenharmony_ci        if (hitraceId_.IsFlagEnabled(HITRACE_FLAG_TP_INFO)) {
794514f5e3Sopenharmony_ci            HiTraceChain::Tracepoint(HITRACE_CM_THREAD, HITRACE_TP_SS,
804514f5e3Sopenharmony_ci                hitraceId_, "After %s pending job execute", "Promise");
814514f5e3Sopenharmony_ci        }
824514f5e3Sopenharmony_ci        HiTraceChain::ClearId();
834514f5e3Sopenharmony_ci    }
844514f5e3Sopenharmony_ci    if (saveId_.IsValid()) {
854514f5e3Sopenharmony_ci        HiTraceChain::SetId(saveId_);
864514f5e3Sopenharmony_ci    }
874514f5e3Sopenharmony_ci}
884514f5e3Sopenharmony_ci
894514f5e3Sopenharmony_ciEnqueueJobTrace::EnqueueJobTrace(JSThread *thread, const JSHandle<PendingJob> &pendingJob)
904514f5e3Sopenharmony_ci{
914514f5e3Sopenharmony_ci    isMicroJobTraceEnable_ = thread->GetEcmaVM()->GetJSOptions().EnableMicroJobTrace();
924514f5e3Sopenharmony_ci    if (!isMicroJobTraceEnable_) {
934514f5e3Sopenharmony_ci        return;
944514f5e3Sopenharmony_ci    }
954514f5e3Sopenharmony_ci
964514f5e3Sopenharmony_ci    uint64_t jobId = thread->GetJobId();
974514f5e3Sopenharmony_ci    pendingJob->SetJobId(jobId);
984514f5e3Sopenharmony_ci    std::string strTrace = "MicroJobQueue::EnqueueJob: jobId: " + std::to_string(jobId);
994514f5e3Sopenharmony_ci    strTrace += ", threadId: " + std::to_string(thread->GetThreadId());
1004514f5e3Sopenharmony_ci
1014514f5e3Sopenharmony_ci    std::vector<JsFrameInfo> jsStackInfo = JsStackInfo::BuildJsStackInfo(thread, true);
1024514f5e3Sopenharmony_ci    if (jsStackInfo.empty()) {
1034514f5e3Sopenharmony_ci        ECMA_BYTRACE_START_TRACE(HITRACE_TAG_ARK, strTrace);
1044514f5e3Sopenharmony_ci        return;
1054514f5e3Sopenharmony_ci    }
1064514f5e3Sopenharmony_ci
1074514f5e3Sopenharmony_ci    JsFrameInfo jsFrameInfo = jsStackInfo.front();
1084514f5e3Sopenharmony_ci    size_t pos = jsFrameInfo.pos.find(':', 0);
1094514f5e3Sopenharmony_ci    if (pos != CString::npos) {
1104514f5e3Sopenharmony_ci        int lineNumber = std::stoi(jsFrameInfo.pos.substr(0, pos));
1114514f5e3Sopenharmony_ci        int columnNumber = std::stoi(jsFrameInfo.pos.substr(pos + 1));
1124514f5e3Sopenharmony_ci        auto sourceMapcb = thread->GetEcmaVM()->GetSourceMapTranslateCallback();
1134514f5e3Sopenharmony_ci        if (sourceMapcb != nullptr && !jsFrameInfo.fileName.empty()) {
1144514f5e3Sopenharmony_ci            sourceMapcb(jsFrameInfo.fileName, lineNumber, columnNumber);
1154514f5e3Sopenharmony_ci        }
1164514f5e3Sopenharmony_ci    }
1174514f5e3Sopenharmony_ci
1184514f5e3Sopenharmony_ci    strTrace += ", funcName: " + jsFrameInfo.functionName + ", url: " + jsFrameInfo.fileName + ":" + jsFrameInfo.pos;
1194514f5e3Sopenharmony_ci    ECMA_BYTRACE_START_TRACE(HITRACE_TAG_ARK, strTrace);
1204514f5e3Sopenharmony_ci}
1214514f5e3Sopenharmony_ci
1224514f5e3Sopenharmony_ciEnqueueJobTrace::~EnqueueJobTrace()
1234514f5e3Sopenharmony_ci{
1244514f5e3Sopenharmony_ci    if (isMicroJobTraceEnable_) {
1254514f5e3Sopenharmony_ci        ECMA_BYTRACE_FINISH_TRACE(HITRACE_TAG_ARK);
1264514f5e3Sopenharmony_ci    }
1274514f5e3Sopenharmony_ci}
1284514f5e3Sopenharmony_ci
1294514f5e3Sopenharmony_ciExecuteJobTrace::ExecuteJobTrace(JSThread *thread, const JSHandle<PendingJob> &pendingJob)
1304514f5e3Sopenharmony_ci{
1314514f5e3Sopenharmony_ci    isMicroJobTraceEnable_ = thread->GetEcmaVM()->GetJSOptions().EnableMicroJobTrace();
1324514f5e3Sopenharmony_ci    if (isMicroJobTraceEnable_) {
1334514f5e3Sopenharmony_ci        uint64_t jobId = pendingJob->GetJobId();
1344514f5e3Sopenharmony_ci        std::string strTrace = "PendingJob::ExecutePendingJob: jobId: " + std::to_string(jobId);
1354514f5e3Sopenharmony_ci        strTrace += ", threadId: " + std::to_string(thread->GetThreadId());
1364514f5e3Sopenharmony_ci        ECMA_BYTRACE_START_TRACE(HITRACE_TAG_ARK, strTrace);
1374514f5e3Sopenharmony_ci    }
1384514f5e3Sopenharmony_ci}
1394514f5e3Sopenharmony_ci
1404514f5e3Sopenharmony_ciExecuteJobTrace::~ExecuteJobTrace()
1414514f5e3Sopenharmony_ci{
1424514f5e3Sopenharmony_ci    if (isMicroJobTraceEnable_) {
1434514f5e3Sopenharmony_ci        ECMA_BYTRACE_FINISH_TRACE(HITRACE_TAG_ARK);
1444514f5e3Sopenharmony_ci    }
1454514f5e3Sopenharmony_ci}
1464514f5e3Sopenharmony_ci}  // namespace panda::ecmascript::job