14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023 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/pgo_profiler/pgo_profiler.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include <chrono>
194514f5e3Sopenharmony_ci#include <memory>
204514f5e3Sopenharmony_ci
214514f5e3Sopenharmony_ci#include "ecmascript/enum_conversion.h"
224514f5e3Sopenharmony_ci#include "ecmascript/interpreter/interpreter-inl.h"
234514f5e3Sopenharmony_ci#include "ecmascript/jit/jit_profiler.h"
244514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_info.h"
254514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_trace.h"
264514f5e3Sopenharmony_ci
274514f5e3Sopenharmony_cinamespace panda::ecmascript::pgo {
284514f5e3Sopenharmony_civoid PGOProfiler::RecordProfileType(JSHClass *hclass, JSPandaFile *pandaFile, int32_t traceId)
294514f5e3Sopenharmony_ci{
304514f5e3Sopenharmony_ci    if (!isEnable_) {
314514f5e3Sopenharmony_ci        return;
324514f5e3Sopenharmony_ci    }
334514f5e3Sopenharmony_ci    ProfileType traceType = GetProfileType(hclass);
344514f5e3Sopenharmony_ci    if (traceType.IsNone()) {
354514f5e3Sopenharmony_ci        pgo::ApEntityId abcId(0);
364514f5e3Sopenharmony_ci        pgo::PGOProfilerManager::GetInstance()->GetPandaFileId(pandaFile->GetJSPandaFileDesc(), abcId);
374514f5e3Sopenharmony_ci        SetRootProfileType(hclass, abcId, traceId, ProfileType::Kind::ObjectLiteralId);
384514f5e3Sopenharmony_ci    }
394514f5e3Sopenharmony_ci}
404514f5e3Sopenharmony_ci
414514f5e3Sopenharmony_civoid PGOProfiler::ProfileDefineClass(JSTaggedType ctor)
424514f5e3Sopenharmony_ci{
434514f5e3Sopenharmony_ci    if (!isEnable_) {
444514f5e3Sopenharmony_ci        return;
454514f5e3Sopenharmony_ci    }
464514f5e3Sopenharmony_ci    auto ctorValue = JSTaggedValue(ctor);
474514f5e3Sopenharmony_ci    if (!ctorValue.IsJSFunction()) {
484514f5e3Sopenharmony_ci        return;
494514f5e3Sopenharmony_ci    }
504514f5e3Sopenharmony_ci    auto ctorFunc = JSFunction::Cast(ctorValue.GetTaggedObject());
514514f5e3Sopenharmony_ci    auto ctorMethodValue = ctorFunc->GetMethod();
524514f5e3Sopenharmony_ci    if (!ctorMethodValue.IsMethod()) {
534514f5e3Sopenharmony_ci        return;
544514f5e3Sopenharmony_ci    }
554514f5e3Sopenharmony_ci    auto ctorMethod = Method::Cast(ctorMethodValue);
564514f5e3Sopenharmony_ci    auto entityId = ctorMethod->GetMethodId().GetOffset();
574514f5e3Sopenharmony_ci    if (!InsertDefinedCtor(entityId)) {
584514f5e3Sopenharmony_ci        InsertSkipCtorMethodIdSafe(ctorMethod->GetMethodId());
594514f5e3Sopenharmony_ci        return;
604514f5e3Sopenharmony_ci    }
614514f5e3Sopenharmony_ci
624514f5e3Sopenharmony_ci    auto abcId = GetMethodAbcId(ctorFunc);
634514f5e3Sopenharmony_ci    auto chc = ctorFunc->GetClass();
644514f5e3Sopenharmony_ci    SetRootProfileType(chc, abcId, entityId, ProfileType::Kind::ConstructorId);
654514f5e3Sopenharmony_ci
664514f5e3Sopenharmony_ci    auto protoOrHClass = ctorFunc->GetProtoOrHClass();
674514f5e3Sopenharmony_ci    if (protoOrHClass.IsJSHClass()) {
684514f5e3Sopenharmony_ci        auto ihc = JSHClass::Cast(protoOrHClass.GetTaggedObject());
694514f5e3Sopenharmony_ci        SetRootProfileType(ihc, abcId, entityId, ProfileType::Kind::ClassId);
704514f5e3Sopenharmony_ci        protoOrHClass = ihc->GetProto();
714514f5e3Sopenharmony_ci    }
724514f5e3Sopenharmony_ci    if (protoOrHClass.IsJSObject()) {
734514f5e3Sopenharmony_ci        auto phc = protoOrHClass.GetTaggedObject()->GetClass();
744514f5e3Sopenharmony_ci        SetRootProfileType(phc, abcId, entityId, ProfileType::Kind::PrototypeId);
754514f5e3Sopenharmony_ci    }
764514f5e3Sopenharmony_ci}
774514f5e3Sopenharmony_ci
784514f5e3Sopenharmony_civoid PGOProfiler::ProfileClassRootHClass(JSTaggedType ctor, JSTaggedType rootHcValue, ProfileType::Kind kind)
794514f5e3Sopenharmony_ci{
804514f5e3Sopenharmony_ci    if (!isEnable_) {
814514f5e3Sopenharmony_ci        return;
824514f5e3Sopenharmony_ci    }
834514f5e3Sopenharmony_ci
844514f5e3Sopenharmony_ci    auto ctorValue = JSTaggedValue(ctor);
854514f5e3Sopenharmony_ci    if (!ctorValue.IsJSFunction()) {
864514f5e3Sopenharmony_ci        return;
874514f5e3Sopenharmony_ci    }
884514f5e3Sopenharmony_ci    auto ctorFunc = JSFunction::Cast(ctorValue.GetTaggedObject());
894514f5e3Sopenharmony_ci    if (!FunctionKindVerify(ctorFunc)) {
904514f5e3Sopenharmony_ci        return;
914514f5e3Sopenharmony_ci    }
924514f5e3Sopenharmony_ci    auto ctorMethodValue = ctorFunc->GetMethod();
934514f5e3Sopenharmony_ci    if (!ctorMethodValue.IsMethod()) {
944514f5e3Sopenharmony_ci        return;
954514f5e3Sopenharmony_ci    }
964514f5e3Sopenharmony_ci    auto ctorMethod = Method::Cast(ctorMethodValue);
974514f5e3Sopenharmony_ci    auto entityId = ctorMethod->GetMethodId().GetOffset();
984514f5e3Sopenharmony_ci    if (IsSkippableCtor(entityId)) {
994514f5e3Sopenharmony_ci        return;
1004514f5e3Sopenharmony_ci    }
1014514f5e3Sopenharmony_ci
1024514f5e3Sopenharmony_ci    auto rootHc = JSHClass::Cast(JSTaggedValue(rootHcValue).GetTaggedObject());
1034514f5e3Sopenharmony_ci    auto abcId = GetMethodAbcId(ctorFunc);
1044514f5e3Sopenharmony_ci    SetRootProfileType(rootHc, abcId, entityId, kind);
1054514f5e3Sopenharmony_ci}
1064514f5e3Sopenharmony_ci
1074514f5e3Sopenharmony_civoid PGOProfiler::ProfileProtoTransitionClass(JSHandle<JSFunction> func,
1084514f5e3Sopenharmony_ci                                              JSHandle<JSHClass> hclass,
1094514f5e3Sopenharmony_ci                                              JSHandle<JSTaggedValue> proto)
1104514f5e3Sopenharmony_ci{
1114514f5e3Sopenharmony_ci    if (!isEnable_) {
1124514f5e3Sopenharmony_ci        return;
1134514f5e3Sopenharmony_ci    }
1144514f5e3Sopenharmony_ci    auto thread = vm_->GetJSThread();
1154514f5e3Sopenharmony_ci    JSHClass *phc = proto->GetTaggedObject()->GetClass();
1164514f5e3Sopenharmony_ci    JSHClass *phcRoot = JSHClass::FindRootHClass(phc);
1174514f5e3Sopenharmony_ci    auto *transitionTable = thread->GetCurrentEcmaContext()->GetFunctionProtoTransitionTable();
1184514f5e3Sopenharmony_ci    JSTaggedType baseIhc = transitionTable->GetFakeParent(JSTaggedType(phcRoot));
1194514f5e3Sopenharmony_ci    if (baseIhc == 0) {
1204514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "fake parent not found!";
1214514f5e3Sopenharmony_ci        ProfileClassRootHClass(func.GetTaggedType(), hclass.GetTaggedType());
1224514f5e3Sopenharmony_ci        return;
1234514f5e3Sopenharmony_ci    }
1244514f5e3Sopenharmony_ci    JSTaggedType ihc = func->GetProtoTransRootHClass().GetRawData();
1254514f5e3Sopenharmony_ci    if (JSTaggedValue(ihc).IsUndefined()) {
1264514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "maybe the prototype of the current function is just the initial prototype!";
1274514f5e3Sopenharmony_ci        ProfileClassRootHClass(func.GetTaggedType(), hclass.GetTaggedType());
1284514f5e3Sopenharmony_ci        return;
1294514f5e3Sopenharmony_ci    }
1304514f5e3Sopenharmony_ci    [[maybe_unused]] bool success = transitionTable->TryInsertFakeParentItem(hclass.GetTaggedType(), ihc);
1314514f5e3Sopenharmony_ci    ASSERT(success == true);  // ihc wont conflict
1324514f5e3Sopenharmony_ci    // record original ihc type
1334514f5e3Sopenharmony_ci    ProfileClassRootHClass(func.GetTaggedType(), ihc, ProfileType::Kind::ClassId);
1344514f5e3Sopenharmony_ci    // record transition ihc type
1354514f5e3Sopenharmony_ci    ProfileClassRootHClass(func.GetTaggedType(), hclass.GetTaggedType(), ProfileType::Kind::TransitionClassId);
1364514f5e3Sopenharmony_ci}
1374514f5e3Sopenharmony_ci
1384514f5e3Sopenharmony_civoid PGOProfiler::ProfileProtoTransitionPrototype(JSHandle<JSFunction> func,
1394514f5e3Sopenharmony_ci                                                  JSHandle<JSTaggedValue> prototype,
1404514f5e3Sopenharmony_ci                                                  JSHandle<JSTaggedValue> oldPrototype,
1414514f5e3Sopenharmony_ci                                                  JSHandle<JSTaggedValue> baseIhc)
1424514f5e3Sopenharmony_ci{
1434514f5e3Sopenharmony_ci    if (!isEnable_) {
1444514f5e3Sopenharmony_ci        return;
1454514f5e3Sopenharmony_ci    }
1464514f5e3Sopenharmony_ci
1474514f5e3Sopenharmony_ci    // fuzz test modifies prototype explicitly, add check protection
1484514f5e3Sopenharmony_ci    if (!oldPrototype->IsECMAObject()) {
1494514f5e3Sopenharmony_ci        return;
1504514f5e3Sopenharmony_ci    }
1514514f5e3Sopenharmony_ci
1524514f5e3Sopenharmony_ci    auto method = func->GetMethod();
1534514f5e3Sopenharmony_ci    if (Method::Cast(method)->IsNativeWithCallField()) {
1544514f5e3Sopenharmony_ci        return;
1554514f5e3Sopenharmony_ci    }
1564514f5e3Sopenharmony_ci    // set prototype once, and just skip this time
1574514f5e3Sopenharmony_ci    if (!func->GetProtoTransRootHClass().IsUndefined()) {
1584514f5e3Sopenharmony_ci        return;
1594514f5e3Sopenharmony_ci    }
1604514f5e3Sopenharmony_ci    auto thread = vm_->GetJSThread();
1614514f5e3Sopenharmony_ci    // insert transition item
1624514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> transIhc(thread, JSTaggedValue::Undefined());
1634514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> transPhc(thread, prototype->GetTaggedObject()->GetClass());
1644514f5e3Sopenharmony_ci    if (JSHandle<JSHClass>(baseIhc)->IsDictionaryMode() || JSHandle<JSHClass>(transPhc)->IsDictionaryMode()) {
1654514f5e3Sopenharmony_ci        return;
1664514f5e3Sopenharmony_ci    }
1674514f5e3Sopenharmony_ci    auto *transitionTable = thread->GetCurrentEcmaContext()->GetFunctionProtoTransitionTable();
1684514f5e3Sopenharmony_ci    bool success = transitionTable->TryInsertFakeParentItem(transPhc.GetTaggedType(), baseIhc.GetTaggedType());
1694514f5e3Sopenharmony_ci    if (!success) {
1704514f5e3Sopenharmony_ci        return;
1714514f5e3Sopenharmony_ci    }
1724514f5e3Sopenharmony_ci    // Do not generate ihc lazily, beacause it's used for the key of hash table
1734514f5e3Sopenharmony_ci    ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
1744514f5e3Sopenharmony_ci    JSHandle<JSHClass> ihc = factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT, oldPrototype);
1754514f5e3Sopenharmony_ci    func->SetProtoTransRootHClass(thread, JSHandle<JSTaggedValue>(ihc));
1764514f5e3Sopenharmony_ci
1774514f5e3Sopenharmony_ci    // record phc type
1784514f5e3Sopenharmony_ci    JSHClass *phc0Root = JSHClass::FindRootHClass(oldPrototype->GetTaggedObject()->GetClass());
1794514f5e3Sopenharmony_ci    ProfileClassRootHClass(func.GetTaggedType(), JSTaggedType(phc0Root), ProfileType::Kind::PrototypeId);
1804514f5e3Sopenharmony_ci    ProfileClassRootHClass(func.GetTaggedType(), transPhc.GetTaggedType(), ProfileType::Kind::TransitionPrototypeId);
1814514f5e3Sopenharmony_ci}
1824514f5e3Sopenharmony_ci
1834514f5e3Sopenharmony_civoid PGOProfiler::ProfileDefineGetterSetter(JSHClass* receiverHClass,
1844514f5e3Sopenharmony_ci                                            JSHClass* holderHClass,
1854514f5e3Sopenharmony_ci                                            const JSHandle<JSTaggedValue>& func,
1864514f5e3Sopenharmony_ci                                            int32_t pcOffset)
1874514f5e3Sopenharmony_ci{
1884514f5e3Sopenharmony_ci    if (!isEnable_) {
1894514f5e3Sopenharmony_ci        return;
1904514f5e3Sopenharmony_ci    }
1914514f5e3Sopenharmony_ci    JSTaggedValue funcValue = JSTaggedValue(func.GetTaggedValue());
1924514f5e3Sopenharmony_ci    if (!funcValue.IsJSFunction()) {
1934514f5e3Sopenharmony_ci        return;
1944514f5e3Sopenharmony_ci    }
1954514f5e3Sopenharmony_ci    auto methodValue = JSFunction::Cast(funcValue)->GetMethod();
1964514f5e3Sopenharmony_ci    if (!methodValue.IsMethod()) {
1974514f5e3Sopenharmony_ci        return;
1984514f5e3Sopenharmony_ci    }
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ci    JSHandle<JSFunction> function(func);
2014514f5e3Sopenharmony_ci
2024514f5e3Sopenharmony_ci    WorkNode* workNode = reinterpret_cast<WorkNode*>(function->GetWorkNodePointer());
2034514f5e3Sopenharmony_ci    if (workNode != nullptr) {
2044514f5e3Sopenharmony_ci        workNode->SetValue(JSTaggedType(JSFunction::Cast(funcValue)));
2054514f5e3Sopenharmony_ci    }
2064514f5e3Sopenharmony_ci
2074514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> key(vm_->GetJSThread(), JSTaggedValue(pcOffset));
2084514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> receiverHClassHandle(vm_->GetJSThread(), receiverHClass);
2094514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> holderHClassHandle(vm_->GetJSThread(), holderHClass);
2104514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> profileTypeInfoValue(vm_->GetJSThread(), function->GetRawProfileTypeInfo());
2114514f5e3Sopenharmony_ci    JSHandle<ProfileTypeInfoCell> profileTypeInfoCell(profileTypeInfoValue);
2124514f5e3Sopenharmony_ci
2134514f5e3Sopenharmony_ci    if (function->HasProfileTypeInfo(vm_->GetJSThread())) {
2144514f5e3Sopenharmony_ci        JSHandle<ProfileTypeInfo> profileTypeInfo(vm_->GetJSThread(), profileTypeInfoCell->GetValue());
2154514f5e3Sopenharmony_ci        JSHandle<NumberDictionary> dictJShandle = ProfileTypeInfo::CreateOrGetExtraInfoMap(vm_->GetJSThread(),
2164514f5e3Sopenharmony_ci                                                                                           profileTypeInfo);
2174514f5e3Sopenharmony_ci        int entry = dictJShandle->FindEntry(key.GetTaggedValue());
2184514f5e3Sopenharmony_ci        if (entry == -1) {
2194514f5e3Sopenharmony_ci            ProfileTypeInfo::UpdateExtraInfoMap(vm_->GetJSThread(), dictJShandle, key, receiverHClassHandle,
2204514f5e3Sopenharmony_ci                                                holderHClassHandle, profileTypeInfo);
2214514f5e3Sopenharmony_ci            return;
2224514f5e3Sopenharmony_ci        }
2234514f5e3Sopenharmony_ci        ExtraProfileTypeInfo *mapInfoObj = ExtraProfileTypeInfo::Cast(dictJShandle->GetValue(entry).GetTaggedObject());
2244514f5e3Sopenharmony_ci        if (mapInfoObj->GetReceiver() == receiverHClassHandle.GetTaggedValue().CreateAndGetWeakRef() &&
2254514f5e3Sopenharmony_ci            mapInfoObj->GetHolder() == holderHClassHandle.GetTaggedValue()) {
2264514f5e3Sopenharmony_ci            return;
2274514f5e3Sopenharmony_ci        }
2284514f5e3Sopenharmony_ci
2294514f5e3Sopenharmony_ci        ExtraProfileTypeInfo::Cast(dictJShandle->GetValue(entry).GetTaggedObject())->Clear(vm_->GetJSThread());
2304514f5e3Sopenharmony_ci    }
2314514f5e3Sopenharmony_ci}
2324514f5e3Sopenharmony_ci
2334514f5e3Sopenharmony_civoid PGOProfiler::UpdateRootProfileTypeSafe(JSHClass* oldHClass, JSHClass* newHClass)
2344514f5e3Sopenharmony_ci{
2354514f5e3Sopenharmony_ci    if (!isEnable_) {
2364514f5e3Sopenharmony_ci        return;
2374514f5e3Sopenharmony_ci    }
2384514f5e3Sopenharmony_ci    ProfileType oldPt = GetProfileType(oldHClass);
2394514f5e3Sopenharmony_ci    if (oldPt.IsRootType()) {
2404514f5e3Sopenharmony_ci        newHClass->SetProfileType(oldPt.GetRaw());
2414514f5e3Sopenharmony_ci        oldHClass->SetProfileType(0);
2424514f5e3Sopenharmony_ci    }
2434514f5e3Sopenharmony_ci}
2444514f5e3Sopenharmony_ci
2454514f5e3Sopenharmony_civoid PGOProfiler::UpdateTrackElementsKind(JSTaggedValue trackInfoVal, ElementsKind newKind)
2464514f5e3Sopenharmony_ci{
2474514f5e3Sopenharmony_ci    if (trackInfoVal.IsHeapObject() && trackInfoVal.IsWeak()) {
2484514f5e3Sopenharmony_ci        auto trackInfo = TrackInfo::Cast(trackInfoVal.GetWeakReferentUnChecked());
2494514f5e3Sopenharmony_ci        auto oldKind = trackInfo->GetElementsKind();
2504514f5e3Sopenharmony_ci        if (Elements::IsGeneric(oldKind) || oldKind == newKind) {
2514514f5e3Sopenharmony_ci            return;
2524514f5e3Sopenharmony_ci        }
2534514f5e3Sopenharmony_ci        auto mixKind = Elements::MergeElementsKind(oldKind, newKind);
2544514f5e3Sopenharmony_ci        if (mixKind == oldKind) {
2554514f5e3Sopenharmony_ci            return;
2564514f5e3Sopenharmony_ci        }
2574514f5e3Sopenharmony_ci        trackInfo->SetElementsKind(mixKind);
2584514f5e3Sopenharmony_ci        auto thread = vm_->GetJSThread();
2594514f5e3Sopenharmony_ci        auto globalConst = thread->GlobalConstants();
2604514f5e3Sopenharmony_ci        // Since trackinfo is only used at define point,
2614514f5e3Sopenharmony_ci        // we update cachedHClass with initial array hclass which does not have IsPrototype set.
2624514f5e3Sopenharmony_ci        auto constantId = thread->GetArrayHClassIndexMap().at(mixKind).first;
2634514f5e3Sopenharmony_ci        auto hclass = globalConst->GetGlobalConstantObject(static_cast<size_t>(constantId));
2644514f5e3Sopenharmony_ci        trackInfo->SetCachedHClass(vm_->GetJSThread(), hclass);
2654514f5e3Sopenharmony_ci        UpdateTrackInfo(JSTaggedValue(trackInfo));
2664514f5e3Sopenharmony_ci    }
2674514f5e3Sopenharmony_ci}
2684514f5e3Sopenharmony_ci
2694514f5e3Sopenharmony_civoid PGOProfiler::UpdateTrackArrayLength(JSTaggedValue trackInfoVal, uint32_t newSize)
2704514f5e3Sopenharmony_ci{
2714514f5e3Sopenharmony_ci    if (trackInfoVal.IsHeapObject() && trackInfoVal.IsWeak()) {
2724514f5e3Sopenharmony_ci        auto trackInfo = TrackInfo::Cast(trackInfoVal.GetWeakReferentUnChecked());
2734514f5e3Sopenharmony_ci        uint32_t oldSize = trackInfo->GetArrayLength();
2744514f5e3Sopenharmony_ci        if (oldSize >= newSize) {
2754514f5e3Sopenharmony_ci            return;
2764514f5e3Sopenharmony_ci        }
2774514f5e3Sopenharmony_ci        trackInfo->SetArrayLength(newSize);
2784514f5e3Sopenharmony_ci        UpdateTrackInfo(JSTaggedValue(trackInfo));
2794514f5e3Sopenharmony_ci    }
2804514f5e3Sopenharmony_ci}
2814514f5e3Sopenharmony_ci
2824514f5e3Sopenharmony_civoid PGOProfiler::UpdateTrackSpaceFlag(TaggedObject *object, RegionSpaceFlag spaceFlag)
2834514f5e3Sopenharmony_ci{
2844514f5e3Sopenharmony_ci    if (!object->GetClass()->IsTrackInfoObject()) {
2854514f5e3Sopenharmony_ci        return;
2864514f5e3Sopenharmony_ci    }
2874514f5e3Sopenharmony_ci    auto trackInfo = TrackInfo::Cast(object);
2884514f5e3Sopenharmony_ci    RegionSpaceFlag oldFlag = trackInfo->GetSpaceFlag();
2894514f5e3Sopenharmony_ci    if (oldFlag == RegionSpaceFlag::IN_YOUNG_SPACE) {
2904514f5e3Sopenharmony_ci        trackInfo->SetSpaceFlag(spaceFlag);
2914514f5e3Sopenharmony_ci        UpdateTrackInfo(JSTaggedValue(trackInfo));
2924514f5e3Sopenharmony_ci    }
2934514f5e3Sopenharmony_ci}
2944514f5e3Sopenharmony_ci
2954514f5e3Sopenharmony_civoid PGOProfiler::UpdateTrackInfo(JSTaggedValue trackInfoVal)
2964514f5e3Sopenharmony_ci{
2974514f5e3Sopenharmony_ci    if (trackInfoVal.IsHeapObject()) {
2984514f5e3Sopenharmony_ci        auto trackInfo = TrackInfo::Cast(trackInfoVal.GetTaggedObject());
2994514f5e3Sopenharmony_ci        auto func = trackInfo->GetCachedFunc();
3004514f5e3Sopenharmony_ci        auto thread = vm_->GetJSThread();
3014514f5e3Sopenharmony_ci        if (!func.IsWeak()) {
3024514f5e3Sopenharmony_ci            return;
3034514f5e3Sopenharmony_ci        }
3044514f5e3Sopenharmony_ci        TaggedObject *object = func.GetWeakReferentUnChecked();
3054514f5e3Sopenharmony_ci        if (!object->GetClass()->IsJSFunction()) {
3064514f5e3Sopenharmony_ci            return;
3074514f5e3Sopenharmony_ci        }
3084514f5e3Sopenharmony_ci        JSFunction* function = JSFunction::Cast(object);
3094514f5e3Sopenharmony_ci        if (!function->HasProfileTypeInfo(thread)) {
3104514f5e3Sopenharmony_ci            return;
3114514f5e3Sopenharmony_ci        }
3124514f5e3Sopenharmony_ci        auto profileTypeInfoVal = function->GetProfileTypeInfo();
3134514f5e3Sopenharmony_ci        if (profileTypeInfoVal.IsUndefined() || !profileTypeInfoVal.IsTaggedArray()) {
3144514f5e3Sopenharmony_ci            return;
3154514f5e3Sopenharmony_ci        }
3164514f5e3Sopenharmony_ci        auto profileTypeInfo = ProfileTypeInfo::Cast(profileTypeInfoVal.GetTaggedObject());
3174514f5e3Sopenharmony_ci        if (profileTypeInfo->IsProfileTypeInfoWithBigMethod()) {
3184514f5e3Sopenharmony_ci            return;
3194514f5e3Sopenharmony_ci        }
3204514f5e3Sopenharmony_ci        if (!profileTypeInfo->IsProfileTypeInfoPreDumped()) {
3214514f5e3Sopenharmony_ci            profileTypeInfo->SetPreDumpPeriodIndex();
3224514f5e3Sopenharmony_ci            PGOPreDump(JSTaggedType(object));
3234514f5e3Sopenharmony_ci        }
3244514f5e3Sopenharmony_ci    }
3254514f5e3Sopenharmony_ci}
3264514f5e3Sopenharmony_ci
3274514f5e3Sopenharmony_civoid PGOProfiler::PGODump(JSTaggedType func)
3284514f5e3Sopenharmony_ci{
3294514f5e3Sopenharmony_ci    if (!isEnable_ || !vm_->GetJSOptions().IsEnableProfileDump()) {
3304514f5e3Sopenharmony_ci        return;
3314514f5e3Sopenharmony_ci    }
3324514f5e3Sopenharmony_ci
3334514f5e3Sopenharmony_ci    auto funcValue = JSTaggedValue(func);
3344514f5e3Sopenharmony_ci    if (!funcValue.IsJSFunction()) {
3354514f5e3Sopenharmony_ci        return;
3364514f5e3Sopenharmony_ci    }
3374514f5e3Sopenharmony_ci    auto methodValue = JSFunction::Cast(funcValue)->GetMethod();
3384514f5e3Sopenharmony_ci    if (!methodValue.IsMethod()) {
3394514f5e3Sopenharmony_ci        return;
3404514f5e3Sopenharmony_ci    }
3414514f5e3Sopenharmony_ci    auto function = JSFunction::Cast(funcValue);
3424514f5e3Sopenharmony_ci    auto workNode = reinterpret_cast<WorkNode *>(function->GetWorkNodePointer());
3434514f5e3Sopenharmony_ci    if (workNode == nullptr) {
3444514f5e3Sopenharmony_ci        workNode = nativeAreaAllocator_->New<WorkNode>(JSTaggedType(function));
3454514f5e3Sopenharmony_ci        function->SetWorkNodePointer(reinterpret_cast<uintptr_t>(workNode));
3464514f5e3Sopenharmony_ci        LockHolder lock(mutex_);
3474514f5e3Sopenharmony_ci        dumpWorkList_.PushBack(workNode);
3484514f5e3Sopenharmony_ci    } else {
3494514f5e3Sopenharmony_ci        workNode->SetValue(JSTaggedType(function));
3504514f5e3Sopenharmony_ci        auto workList = workNode->GetWorkList();
3514514f5e3Sopenharmony_ci        LockHolder lock(mutex_);
3524514f5e3Sopenharmony_ci        if (workList == &preDumpWorkList_) {
3534514f5e3Sopenharmony_ci            preDumpWorkList_.Remove(workNode);
3544514f5e3Sopenharmony_ci        }
3554514f5e3Sopenharmony_ci        if (workList != &dumpWorkList_) {
3564514f5e3Sopenharmony_ci            dumpWorkList_.PushBack(workNode);
3574514f5e3Sopenharmony_ci        }
3584514f5e3Sopenharmony_ci    }
3594514f5e3Sopenharmony_ci    StartPGODump();
3604514f5e3Sopenharmony_ci}
3614514f5e3Sopenharmony_ci
3624514f5e3Sopenharmony_civoid PGOProfiler::SuspendByGC()
3634514f5e3Sopenharmony_ci{
3644514f5e3Sopenharmony_ci    if (!isEnable_) {
3654514f5e3Sopenharmony_ci        return;
3664514f5e3Sopenharmony_ci    }
3674514f5e3Sopenharmony_ci    LockHolder lock(mutex_);
3684514f5e3Sopenharmony_ci    if (GetState() == State::START) {
3694514f5e3Sopenharmony_ci        SetState(State::PAUSE);
3704514f5e3Sopenharmony_ci        WaitingPGODump();
3714514f5e3Sopenharmony_ci    } else if (GetState() == State::FORCE_SAVE) {
3724514f5e3Sopenharmony_ci        SetState(State::FORCE_SAVE_PAUSE);
3734514f5e3Sopenharmony_ci        WaitingPGODump();
3744514f5e3Sopenharmony_ci    }
3754514f5e3Sopenharmony_ci}
3764514f5e3Sopenharmony_ci
3774514f5e3Sopenharmony_civoid PGOProfiler::ResumeByGC()
3784514f5e3Sopenharmony_ci{
3794514f5e3Sopenharmony_ci    if (!isEnable_) {
3804514f5e3Sopenharmony_ci        return;
3814514f5e3Sopenharmony_ci    }
3824514f5e3Sopenharmony_ci    LockHolder lock(mutex_);
3834514f5e3Sopenharmony_ci    if (GetState() == State::PAUSE) {
3844514f5e3Sopenharmony_ci        SetState(State::START);
3854514f5e3Sopenharmony_ci        DispatchPGODumpTask();
3864514f5e3Sopenharmony_ci    } else if (GetState() == State::FORCE_SAVE_PAUSE) {
3874514f5e3Sopenharmony_ci        SetState(State::FORCE_SAVE);
3884514f5e3Sopenharmony_ci        DispatchPGODumpTask();
3894514f5e3Sopenharmony_ci    }
3904514f5e3Sopenharmony_ci}
3914514f5e3Sopenharmony_ci
3924514f5e3Sopenharmony_civoid PGOProfiler::StopPGODump()
3934514f5e3Sopenharmony_ci{
3944514f5e3Sopenharmony_ci    LockHolder lock(mutex_);
3954514f5e3Sopenharmony_ci    if (IsGCWaiting()) {
3964514f5e3Sopenharmony_ci        NotifyGC("[StopPGODump::PAUSE]");
3974514f5e3Sopenharmony_ci        return;
3984514f5e3Sopenharmony_ci    }
3994514f5e3Sopenharmony_ci    SetState(State::STOP);
4004514f5e3Sopenharmony_ci    NotifyAll("[StopPGODump::STOP]");
4014514f5e3Sopenharmony_ci}
4024514f5e3Sopenharmony_ci
4034514f5e3Sopenharmony_civoid PGOProfiler::StartPGODump()
4044514f5e3Sopenharmony_ci{
4054514f5e3Sopenharmony_ci    if (GetState() == State::STOP) {
4064514f5e3Sopenharmony_ci        SetState(State::START);
4074514f5e3Sopenharmony_ci        DispatchPGODumpTask();
4084514f5e3Sopenharmony_ci    }
4094514f5e3Sopenharmony_ci}
4104514f5e3Sopenharmony_ci
4114514f5e3Sopenharmony_civoid PGOProfiler::DispatchPGODumpTask()
4124514f5e3Sopenharmony_ci{
4134514f5e3Sopenharmony_ci    Taskpool::GetCurrentTaskpool()->PostTask(
4144514f5e3Sopenharmony_ci        std::make_unique<PGOProfilerTask>(this, vm_->GetJSThread()->GetThreadId()));
4154514f5e3Sopenharmony_ci}
4164514f5e3Sopenharmony_ci
4174514f5e3Sopenharmony_ciPGOProfiler::State PGOProfiler::GetState()
4184514f5e3Sopenharmony_ci{
4194514f5e3Sopenharmony_ci    return state_.load(std::memory_order_acquire);
4204514f5e3Sopenharmony_ci}
4214514f5e3Sopenharmony_ci
4224514f5e3Sopenharmony_civoid PGOProfiler::SetState(State state)
4234514f5e3Sopenharmony_ci{
4244514f5e3Sopenharmony_ci    v_.AddLogWithDebugLog("[PGODumpStateChange] " + StateToString(GetState()) + " -> " + StateToString(state));
4254514f5e3Sopenharmony_ci    state_.store(state, std::memory_order_release);
4264514f5e3Sopenharmony_ci}
4274514f5e3Sopenharmony_ci
4284514f5e3Sopenharmony_civoid PGOProfiler::NotifyGC(std::string tag)
4294514f5e3Sopenharmony_ci{
4304514f5e3Sopenharmony_ci    v_.AddLogWithDebugLog(tag + " notify GC");
4314514f5e3Sopenharmony_ci    condition_.SignalAll();
4324514f5e3Sopenharmony_ci}
4334514f5e3Sopenharmony_ci
4344514f5e3Sopenharmony_civoid PGOProfiler::NotifyAll(std::string tag)
4354514f5e3Sopenharmony_ci{
4364514f5e3Sopenharmony_ci    v_.AddLogWithDebugLog(tag + " notify all");
4374514f5e3Sopenharmony_ci    condition_.SignalAll();
4384514f5e3Sopenharmony_ci}
4394514f5e3Sopenharmony_ci
4404514f5e3Sopenharmony_civoid PGOProfiler::WaitingPGODump()
4414514f5e3Sopenharmony_ci{
4424514f5e3Sopenharmony_ci    condition_.Wait(&mutex_);
4434514f5e3Sopenharmony_ci}
4444514f5e3Sopenharmony_ci
4454514f5e3Sopenharmony_civoid PGOProfiler::WaitPGODumpFinish()
4464514f5e3Sopenharmony_ci{
4474514f5e3Sopenharmony_ci    if (!isEnable_) {
4484514f5e3Sopenharmony_ci        return;
4494514f5e3Sopenharmony_ci    }
4504514f5e3Sopenharmony_ci    LockHolder lock(mutex_);
4514514f5e3Sopenharmony_ci    while (GetState() == State::START) {
4524514f5e3Sopenharmony_ci        WaitingPGODump();
4534514f5e3Sopenharmony_ci    }
4544514f5e3Sopenharmony_ci}
4554514f5e3Sopenharmony_ci
4564514f5e3Sopenharmony_civoid PGOProfiler::DumpByForce()
4574514f5e3Sopenharmony_ci{
4584514f5e3Sopenharmony_ci    isForce_ = true;
4594514f5e3Sopenharmony_ci    LockHolder lock(mutex_);
4604514f5e3Sopenharmony_ci    if (GetState() == State::START) {
4614514f5e3Sopenharmony_ci        SetState(State::FORCE_SAVE);
4624514f5e3Sopenharmony_ci        WaitingPGODump();
4634514f5e3Sopenharmony_ci    } else if (GetState() == State::STOP && !dumpWorkList_.IsEmpty()) {
4644514f5e3Sopenharmony_ci        SetState(State::FORCE_SAVE);
4654514f5e3Sopenharmony_ci        WaitingPGODump();
4664514f5e3Sopenharmony_ci        DispatchPGODumpTask();
4674514f5e3Sopenharmony_ci    } else if (GetState() == State::PAUSE) {
4684514f5e3Sopenharmony_ci        SetState(State::FORCE_SAVE_PAUSE);
4694514f5e3Sopenharmony_ci        WaitingPGODump();
4704514f5e3Sopenharmony_ci    }
4714514f5e3Sopenharmony_ci}
4724514f5e3Sopenharmony_ci
4734514f5e3Sopenharmony_cibool PGOProfiler::IsGCWaitingWithLock()
4744514f5e3Sopenharmony_ci{
4754514f5e3Sopenharmony_ci    if (GetState() == State::PAUSE) {
4764514f5e3Sopenharmony_ci        LockHolder lock(mutex_);
4774514f5e3Sopenharmony_ci        if (GetState() == State::PAUSE) {
4784514f5e3Sopenharmony_ci            return true;
4794514f5e3Sopenharmony_ci        }
4804514f5e3Sopenharmony_ci    }
4814514f5e3Sopenharmony_ci    return false;
4824514f5e3Sopenharmony_ci}
4834514f5e3Sopenharmony_ci
4844514f5e3Sopenharmony_cibool PGOProfiler::IsGCWaiting()
4854514f5e3Sopenharmony_ci{
4864514f5e3Sopenharmony_ci    if (GetState() == State::PAUSE) {
4874514f5e3Sopenharmony_ci        return true;
4884514f5e3Sopenharmony_ci    }
4894514f5e3Sopenharmony_ci    return false;
4904514f5e3Sopenharmony_ci}
4914514f5e3Sopenharmony_ci
4924514f5e3Sopenharmony_civoid PGOProfiler::PGOPreDump(JSTaggedType func)
4934514f5e3Sopenharmony_ci{
4944514f5e3Sopenharmony_ci    if (!isEnable_ || !vm_->GetJSOptions().IsEnableProfileDump()) {
4954514f5e3Sopenharmony_ci        return;
4964514f5e3Sopenharmony_ci    }
4974514f5e3Sopenharmony_ci
4984514f5e3Sopenharmony_ci    auto funcValue = JSTaggedValue(func);
4994514f5e3Sopenharmony_ci    if (!funcValue.IsJSFunction()) {
5004514f5e3Sopenharmony_ci        return;
5014514f5e3Sopenharmony_ci    }
5024514f5e3Sopenharmony_ci    auto methodValue = JSFunction::Cast(funcValue)->GetMethod();
5034514f5e3Sopenharmony_ci    if (!methodValue.IsMethod()) {
5044514f5e3Sopenharmony_ci        return;
5054514f5e3Sopenharmony_ci    }
5064514f5e3Sopenharmony_ci    auto function = JSFunction::Cast(funcValue);
5074514f5e3Sopenharmony_ci    auto workNode = reinterpret_cast<WorkNode *>(function->GetWorkNodePointer());
5084514f5e3Sopenharmony_ci    if (workNode == nullptr) {
5094514f5e3Sopenharmony_ci        workNode = nativeAreaAllocator_->New<WorkNode>(JSTaggedType(function));
5104514f5e3Sopenharmony_ci        function->SetWorkNodePointer(reinterpret_cast<uintptr_t>(workNode));
5114514f5e3Sopenharmony_ci        LockHolder lock(mutex_);
5124514f5e3Sopenharmony_ci        preDumpWorkList_.PushBack(workNode);
5134514f5e3Sopenharmony_ci    } else {
5144514f5e3Sopenharmony_ci        workNode->SetValue(JSTaggedType(function));
5154514f5e3Sopenharmony_ci        auto workList = workNode->GetWorkList();
5164514f5e3Sopenharmony_ci        LockHolder lock(mutex_);
5174514f5e3Sopenharmony_ci        if (workList == &dumpWorkList_) {
5184514f5e3Sopenharmony_ci            workList->Remove(workNode);
5194514f5e3Sopenharmony_ci        }
5204514f5e3Sopenharmony_ci        if (workList != &preDumpWorkList_) {
5214514f5e3Sopenharmony_ci            preDumpWorkList_.PushBack(workNode);
5224514f5e3Sopenharmony_ci        }
5234514f5e3Sopenharmony_ci    }
5244514f5e3Sopenharmony_ci}
5254514f5e3Sopenharmony_ci
5264514f5e3Sopenharmony_civoid PGOProfiler::UpdateExtraProfileTypeInfo(ApEntityId abcId,
5274514f5e3Sopenharmony_ci                                             const CString& recordName,
5284514f5e3Sopenharmony_ci                                             EntityId methodId,
5294514f5e3Sopenharmony_ci                                             WorkNode* current)
5304514f5e3Sopenharmony_ci{
5314514f5e3Sopenharmony_ci    JSTaggedValue funcValue = JSTaggedValue(current->GetValue());
5324514f5e3Sopenharmony_ci    if (!funcValue.IsJSFunction()) {
5334514f5e3Sopenharmony_ci        return;
5344514f5e3Sopenharmony_ci    }
5354514f5e3Sopenharmony_ci    auto func = JSFunction::Cast(funcValue);
5364514f5e3Sopenharmony_ci    if (!func->HasProfileTypeInfo(vm_->GetJSThread())) {
5374514f5e3Sopenharmony_ci        return;
5384514f5e3Sopenharmony_ci    }
5394514f5e3Sopenharmony_ci    ProfileTypeInfoCell *cell = ProfileTypeInfoCell::Cast(func->GetRawProfileTypeInfo());
5404514f5e3Sopenharmony_ci    ProfileTypeInfo *info = ProfileTypeInfo::Cast((cell->GetValue()).GetTaggedObject());
5414514f5e3Sopenharmony_ci    if ((info->GetExtraInfoMap()).IsHole() || (info->GetExtraInfoMap()).IsUndefined()) {
5424514f5e3Sopenharmony_ci        return;
5434514f5e3Sopenharmony_ci    }
5444514f5e3Sopenharmony_ci    NumberDictionary *dict = NumberDictionary::Cast(info->GetExtraInfoMap().GetTaggedObject());
5454514f5e3Sopenharmony_ci    int size = dict->Size();
5464514f5e3Sopenharmony_ci    for (int hashIndex = 0; hashIndex < size; hashIndex++) {
5474514f5e3Sopenharmony_ci        JSTaggedValue key(dict->GetKey(hashIndex));
5484514f5e3Sopenharmony_ci        if (!key.IsUndefined() && !key.IsHole()) {
5494514f5e3Sopenharmony_ci            JSTaggedValue val(dict->GetValue(hashIndex));
5504514f5e3Sopenharmony_ci            ExtraProfileTypeInfo *extraInfo = ExtraProfileTypeInfo::Cast(val.GetTaggedObject());
5514514f5e3Sopenharmony_ci            if (!extraInfo->IsValid()) {
5524514f5e3Sopenharmony_ci                continue;
5534514f5e3Sopenharmony_ci            }
5544514f5e3Sopenharmony_ci            AddObjectInfo(abcId,
5554514f5e3Sopenharmony_ci                          recordName,
5564514f5e3Sopenharmony_ci                          methodId,
5574514f5e3Sopenharmony_ci                          key.GetInt(),
5584514f5e3Sopenharmony_ci                          extraInfo->GetReceiverHClass(),
5594514f5e3Sopenharmony_ci                          extraInfo->GetReceiverHClass(),
5604514f5e3Sopenharmony_ci                          extraInfo->GetHolderHClass());
5614514f5e3Sopenharmony_ci        }
5624514f5e3Sopenharmony_ci    }
5634514f5e3Sopenharmony_ci}
5644514f5e3Sopenharmony_ci
5654514f5e3Sopenharmony_cibool PGOProfiler::HasValidExtraProfileTypeInfo(JSFunction *func)
5664514f5e3Sopenharmony_ci{
5674514f5e3Sopenharmony_ci    if (!func->HasProfileTypeInfo(vm_->GetJSThread())) {
5684514f5e3Sopenharmony_ci        return false;
5694514f5e3Sopenharmony_ci    }
5704514f5e3Sopenharmony_ci    ProfileTypeInfoCell *profileCell = ProfileTypeInfoCell::Cast(func->GetRawProfileTypeInfo());
5714514f5e3Sopenharmony_ci    ProfileTypeInfo *profileInfo = ProfileTypeInfo::Cast((profileCell->GetValue()).GetTaggedObject());
5724514f5e3Sopenharmony_ci    JSTaggedValue map = profileInfo->GetExtraInfoMap();
5734514f5e3Sopenharmony_ci    if (map.IsHole() || map.IsUndefined()) {
5744514f5e3Sopenharmony_ci        return false;
5754514f5e3Sopenharmony_ci    }
5764514f5e3Sopenharmony_ci    NumberDictionary *numberDict = NumberDictionary::Cast(map.GetTaggedObject());
5774514f5e3Sopenharmony_ci    return numberDict->GetEntrySize() > 0;
5784514f5e3Sopenharmony_ci}
5794514f5e3Sopenharmony_ci
5804514f5e3Sopenharmony_civoid PGOProfiler::ProcessExtraProfileTypeInfo(JSFunction *func, ApEntityId abcId, const CString &recordName,
5814514f5e3Sopenharmony_ci                                              JSTaggedValue methodValue, WorkNode *current)
5824514f5e3Sopenharmony_ci{
5834514f5e3Sopenharmony_ci    if (!HasValidExtraProfileTypeInfo(func)) {
5844514f5e3Sopenharmony_ci        return;
5854514f5e3Sopenharmony_ci    }
5864514f5e3Sopenharmony_ci    Method* method = Method::Cast(methodValue.GetTaggedObject());
5874514f5e3Sopenharmony_ci    EntityId methodId = method->GetMethodId();
5884514f5e3Sopenharmony_ci    UpdateExtraProfileTypeInfo(abcId, recordName, methodId, current);
5894514f5e3Sopenharmony_ci}
5904514f5e3Sopenharmony_ci
5914514f5e3Sopenharmony_civoid PGOProfiler::HandlePGOPreDump()
5924514f5e3Sopenharmony_ci{
5934514f5e3Sopenharmony_ci    LockHolder lock(recordInfoMutex_);
5944514f5e3Sopenharmony_ci    if (!isEnable_ || !vm_->GetJSOptions().IsEnableProfileDump()) {
5954514f5e3Sopenharmony_ci        return;
5964514f5e3Sopenharmony_ci    }
5974514f5e3Sopenharmony_ci    DISALLOW_GARBAGE_COLLECTION;
5984514f5e3Sopenharmony_ci    preDumpWorkList_.Iterate([this](WorkNode* current) {
5994514f5e3Sopenharmony_ci        JSTaggedValue funcValue = JSTaggedValue(current->GetValue());
6004514f5e3Sopenharmony_ci        if (!funcValue.IsJSFunction()) {
6014514f5e3Sopenharmony_ci            return;
6024514f5e3Sopenharmony_ci        }
6034514f5e3Sopenharmony_ci        auto func = JSFunction::Cast(funcValue);
6044514f5e3Sopenharmony_ci        if (func->IsSendableOrConcurrentFunction()) {
6054514f5e3Sopenharmony_ci            return;
6064514f5e3Sopenharmony_ci        }
6074514f5e3Sopenharmony_ci        JSTaggedValue methodValue = func->GetMethod();
6084514f5e3Sopenharmony_ci        if (!methodValue.IsMethod()) {
6094514f5e3Sopenharmony_ci            return;
6104514f5e3Sopenharmony_ci        }
6114514f5e3Sopenharmony_ci        CString recordName = func->GetRecordName();
6124514f5e3Sopenharmony_ci        if (recordName.empty()) {
6134514f5e3Sopenharmony_ci            return;
6144514f5e3Sopenharmony_ci        }
6154514f5e3Sopenharmony_ci        auto abcId = GetMethodAbcId(func);
6164514f5e3Sopenharmony_ci
6174514f5e3Sopenharmony_ci        ProcessExtraProfileTypeInfo(func, abcId, recordName, methodValue, current);
6184514f5e3Sopenharmony_ci        ProfileType recordType = GetRecordProfileType(abcId, recordName);
6194514f5e3Sopenharmony_ci        recordInfos_->AddMethod(recordType, Method::Cast(methodValue), SampleMode::HOTNESS_MODE);
6204514f5e3Sopenharmony_ci        ProfileBytecode(abcId, recordName, funcValue);
6214514f5e3Sopenharmony_ci        if (PGOTrace::GetInstance()->IsEnable()) {
6224514f5e3Sopenharmony_ci            PGOTrace::GetInstance()->TryGetMethodData(methodValue, false);
6234514f5e3Sopenharmony_ci        }
6244514f5e3Sopenharmony_ci    });
6254514f5e3Sopenharmony_ci}
6264514f5e3Sopenharmony_ci
6274514f5e3Sopenharmony_civoid PGOProfiler::HandlePGODumpByDumpThread(bool force)
6284514f5e3Sopenharmony_ci{
6294514f5e3Sopenharmony_ci    ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PGOProfiler::HandlePGODumpByDumpThread");
6304514f5e3Sopenharmony_ci    LockHolder lock(recordInfoMutex_);
6314514f5e3Sopenharmony_ci    if (!isEnable_ || !vm_->GetJSOptions().IsEnableProfileDump()) {
6324514f5e3Sopenharmony_ci        return;
6334514f5e3Sopenharmony_ci    }
6344514f5e3Sopenharmony_ci    DISALLOW_GARBAGE_COLLECTION;
6354514f5e3Sopenharmony_ci    auto current = PopFromProfileQueue();
6364514f5e3Sopenharmony_ci    while (current != nullptr) {
6374514f5e3Sopenharmony_ci        JSTaggedValue value = JSTaggedValue(current->GetValue());
6384514f5e3Sopenharmony_ci        if (value.IsUndefined()) {
6394514f5e3Sopenharmony_ci            current = PopFromProfileQueue();
6404514f5e3Sopenharmony_ci            continue;
6414514f5e3Sopenharmony_ci        }
6424514f5e3Sopenharmony_ci        if (!value.IsJSFunction()) {
6434514f5e3Sopenharmony_ci            current = PopFromProfileQueue();
6444514f5e3Sopenharmony_ci            continue;
6454514f5e3Sopenharmony_ci        }
6464514f5e3Sopenharmony_ci        auto func = JSFunction::Cast(value);
6474514f5e3Sopenharmony_ci        if (func->IsSendableOrConcurrentFunction()) {
6484514f5e3Sopenharmony_ci            current = PopFromProfileQueue();
6494514f5e3Sopenharmony_ci            continue;
6504514f5e3Sopenharmony_ci        }
6514514f5e3Sopenharmony_ci        JSTaggedValue methodValue = func->GetMethod();
6524514f5e3Sopenharmony_ci        if (!methodValue.IsMethod()) {
6534514f5e3Sopenharmony_ci            current = PopFromProfileQueue();
6544514f5e3Sopenharmony_ci            continue;
6554514f5e3Sopenharmony_ci        }
6564514f5e3Sopenharmony_ci        CString recordName = func->GetRecordName();
6574514f5e3Sopenharmony_ci        if (recordName.empty()) {
6584514f5e3Sopenharmony_ci            current = PopFromProfileQueue();
6594514f5e3Sopenharmony_ci            continue;
6604514f5e3Sopenharmony_ci        }
6614514f5e3Sopenharmony_ci        auto abcId = GetMethodAbcId(func);
6624514f5e3Sopenharmony_ci
6634514f5e3Sopenharmony_ci        ProcessExtraProfileTypeInfo(func, abcId, recordName, methodValue, current);
6644514f5e3Sopenharmony_ci
6654514f5e3Sopenharmony_ci        ProfileType recordType = GetRecordProfileType(abcId, recordName);
6664514f5e3Sopenharmony_ci        if (recordInfos_->AddMethod(recordType, Method::Cast(methodValue), SampleMode::HOTNESS_MODE)) {
6674514f5e3Sopenharmony_ci            methodCount_++;
6684514f5e3Sopenharmony_ci        }
6694514f5e3Sopenharmony_ci        ProfileBytecode(abcId, recordName, value);
6704514f5e3Sopenharmony_ci        current = PopFromProfileQueue();
6714514f5e3Sopenharmony_ci        if (PGOTrace::GetInstance()->IsEnable()) {
6724514f5e3Sopenharmony_ci            PGOTrace::GetInstance()->TryGetMethodData(methodValue, true);
6734514f5e3Sopenharmony_ci        }
6744514f5e3Sopenharmony_ci    }
6754514f5e3Sopenharmony_ci    ASSERT(GetState() != State::STOP);
6764514f5e3Sopenharmony_ci    if (IsGCWaitingWithLock()) {
6774514f5e3Sopenharmony_ci        return;
6784514f5e3Sopenharmony_ci    }
6794514f5e3Sopenharmony_ci    MergeProfilerAndDispatchAsyncSaveTask(force);
6804514f5e3Sopenharmony_ci}
6814514f5e3Sopenharmony_ci
6824514f5e3Sopenharmony_civoid PGOProfiler::MergeProfilerAndDispatchAsyncSaveTask(bool force)
6834514f5e3Sopenharmony_ci{
6844514f5e3Sopenharmony_ci    ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PGOProfiler::MergeProfilerAndDispatchAsyncSaveTask");
6854514f5e3Sopenharmony_ci    // Merged every 50 methods and merge interval greater than minimal interval
6864514f5e3Sopenharmony_ci    auto interval = std::chrono::system_clock::now() - saveTimestamp_;
6874514f5e3Sopenharmony_ci    auto minIntervalOption = vm_->GetJSOptions().GetPGOSaveMinInterval();
6884514f5e3Sopenharmony_ci    auto mergeMinInterval = std::chrono::milliseconds(minIntervalOption * MS_PRE_SECOND);
6894514f5e3Sopenharmony_ci    if ((methodCount_ >= MERGED_EVERY_COUNT && interval > mergeMinInterval) || (force && methodCount_ > 0)) {
6904514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "Sample: post task to save profiler";
6914514f5e3Sopenharmony_ci        {
6924514f5e3Sopenharmony_ci            ClockScope start;
6934514f5e3Sopenharmony_ci            PGOProfilerManager::GetInstance()->Merge(this);
6944514f5e3Sopenharmony_ci            if (PGOTrace::GetInstance()->IsEnable()) {
6954514f5e3Sopenharmony_ci                PGOTrace::GetInstance()->SetMergeTime(start.TotalSpentTime());
6964514f5e3Sopenharmony_ci            }
6974514f5e3Sopenharmony_ci        }
6984514f5e3Sopenharmony_ci        if (!force) {
6994514f5e3Sopenharmony_ci            PGOProfilerManager::GetInstance()->AsyncSave();
7004514f5e3Sopenharmony_ci        }
7014514f5e3Sopenharmony_ci        SetSaveTimestamp(std::chrono::system_clock::now());
7024514f5e3Sopenharmony_ci        methodCount_ = 0;
7034514f5e3Sopenharmony_ci    }
7044514f5e3Sopenharmony_ci}
7054514f5e3Sopenharmony_ci
7064514f5e3Sopenharmony_ciPGOProfiler::WorkNode* PGOProfiler::PopFromProfileQueue()
7074514f5e3Sopenharmony_ci{
7084514f5e3Sopenharmony_ci    LockHolder lock(mutex_);
7094514f5e3Sopenharmony_ci    WorkNode* node = nullptr;
7104514f5e3Sopenharmony_ci    while (node == nullptr) {
7114514f5e3Sopenharmony_ci        if (IsGCWaiting()) {
7124514f5e3Sopenharmony_ci            break;
7134514f5e3Sopenharmony_ci        }
7144514f5e3Sopenharmony_ci        if (dumpWorkList_.IsEmpty()) {
7154514f5e3Sopenharmony_ci            break;
7164514f5e3Sopenharmony_ci        }
7174514f5e3Sopenharmony_ci        node = dumpWorkList_.PopFront();
7184514f5e3Sopenharmony_ci    }
7194514f5e3Sopenharmony_ci    return node;
7204514f5e3Sopenharmony_ci}
7214514f5e3Sopenharmony_ci
7224514f5e3Sopenharmony_civoid PGOProfiler::ProfileBytecode(ApEntityId abcId, const CString &recordName, JSTaggedValue funcValue)
7234514f5e3Sopenharmony_ci{
7244514f5e3Sopenharmony_ci    ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "PGOProfiler::ProfileBytecode");
7254514f5e3Sopenharmony_ci    ClockScope start;
7264514f5e3Sopenharmony_ci    JSFunction *function = JSFunction::Cast(funcValue);
7274514f5e3Sopenharmony_ci    if (function->IsSendableOrConcurrentFunction()) {
7284514f5e3Sopenharmony_ci        return;
7294514f5e3Sopenharmony_ci    }
7304514f5e3Sopenharmony_ci    Method *method = Method::Cast(function->GetMethod());
7314514f5e3Sopenharmony_ci    JSTaggedValue profileTypeInfoVal = function->GetProfileTypeInfo();
7324514f5e3Sopenharmony_ci    ASSERT(!profileTypeInfoVal.IsUndefined());
7334514f5e3Sopenharmony_ci    auto profileTypeInfo = ProfileTypeInfo::Cast(profileTypeInfoVal.GetTaggedObject());
7344514f5e3Sopenharmony_ci    auto methodId = method->GetMethodId();
7354514f5e3Sopenharmony_ci    auto pcStart = method->GetBytecodeArray();
7364514f5e3Sopenharmony_ci    auto codeSize = method->GetCodeSize();
7374514f5e3Sopenharmony_ci    BytecodeInstruction bcIns(pcStart);
7384514f5e3Sopenharmony_ci    auto bcInsLast = bcIns.JumpTo(codeSize);
7394514f5e3Sopenharmony_ci    bool isForceDump = vm_->GetJSOptions().IsPgoForceDump();
7404514f5e3Sopenharmony_ci
7414514f5e3Sopenharmony_ci    while (bcIns.GetAddress() != bcInsLast.GetAddress()) {
7424514f5e3Sopenharmony_ci        if (!isForceDump) {
7434514f5e3Sopenharmony_ci            if (IsGCWaitingWithLock()) {
7444514f5e3Sopenharmony_ci                break;
7454514f5e3Sopenharmony_ci            }
7464514f5e3Sopenharmony_ci        }
7474514f5e3Sopenharmony_ci        auto opcode = bcIns.GetOpcode();
7484514f5e3Sopenharmony_ci        auto bcOffset = bcIns.GetAddress() - pcStart;
7494514f5e3Sopenharmony_ci        auto pc = bcIns.GetAddress();
7504514f5e3Sopenharmony_ci        switch (opcode) {
7514514f5e3Sopenharmony_ci            case EcmaOpcode::LDTHISBYNAME_IMM8_ID16:
7524514f5e3Sopenharmony_ci            case EcmaOpcode::LDOBJBYNAME_IMM8_ID16:
7534514f5e3Sopenharmony_ci            case EcmaOpcode::LDPRIVATEPROPERTY_IMM8_IMM16_IMM16: {
7544514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
7554514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
7564514f5e3Sopenharmony_ci                DumpICByName(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::LOAD);
7574514f5e3Sopenharmony_ci                break;
7584514f5e3Sopenharmony_ci            }
7594514f5e3Sopenharmony_ci            case EcmaOpcode::LDTHISBYNAME_IMM16_ID16:
7604514f5e3Sopenharmony_ci            case EcmaOpcode::LDOBJBYNAME_IMM16_ID16: {
7614514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
7624514f5e3Sopenharmony_ci                DumpICByName(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::LOAD);
7634514f5e3Sopenharmony_ci                break;
7644514f5e3Sopenharmony_ci            }
7654514f5e3Sopenharmony_ci            case EcmaOpcode::LDOBJBYVALUE_IMM8_V8:
7664514f5e3Sopenharmony_ci            case EcmaOpcode::LDTHISBYVALUE_IMM8: {
7674514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
7684514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
7694514f5e3Sopenharmony_ci                DumpICByValue(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::LOAD);
7704514f5e3Sopenharmony_ci                break;
7714514f5e3Sopenharmony_ci            }
7724514f5e3Sopenharmony_ci            case EcmaOpcode::LDOBJBYVALUE_IMM16_V8:
7734514f5e3Sopenharmony_ci            case EcmaOpcode::LDTHISBYVALUE_IMM16: {
7744514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
7754514f5e3Sopenharmony_ci                DumpICByValue(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::LOAD);
7764514f5e3Sopenharmony_ci                break;
7774514f5e3Sopenharmony_ci            }
7784514f5e3Sopenharmony_ci            case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8:
7794514f5e3Sopenharmony_ci            case EcmaOpcode::STTHISBYNAME_IMM8_ID16:
7804514f5e3Sopenharmony_ci            case EcmaOpcode::DEFINEPROPERTYBYNAME_IMM8_ID16_V8:
7814514f5e3Sopenharmony_ci            case EcmaOpcode::STPRIVATEPROPERTY_IMM8_IMM16_IMM16_V8: {
7824514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
7834514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
7844514f5e3Sopenharmony_ci                DumpICByName(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::STORE);
7854514f5e3Sopenharmony_ci                break;
7864514f5e3Sopenharmony_ci            }
7874514f5e3Sopenharmony_ci            case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8:
7884514f5e3Sopenharmony_ci            case EcmaOpcode::STTHISBYNAME_IMM16_ID16: {
7894514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
7904514f5e3Sopenharmony_ci                DumpICByName(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::STORE);
7914514f5e3Sopenharmony_ci                break;
7924514f5e3Sopenharmony_ci            }
7934514f5e3Sopenharmony_ci            case EcmaOpcode::STOBJBYVALUE_IMM8_V8_V8:
7944514f5e3Sopenharmony_ci            case EcmaOpcode::STOWNBYINDEX_IMM8_V8_IMM16:
7954514f5e3Sopenharmony_ci            case EcmaOpcode::STTHISBYVALUE_IMM8_V8: {
7964514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
7974514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
7984514f5e3Sopenharmony_ci                DumpICByValue(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::STORE);
7994514f5e3Sopenharmony_ci                break;
8004514f5e3Sopenharmony_ci            }
8014514f5e3Sopenharmony_ci            case EcmaOpcode::STOBJBYVALUE_IMM16_V8_V8:
8024514f5e3Sopenharmony_ci            case EcmaOpcode::STOWNBYINDEX_IMM16_V8_IMM16:
8034514f5e3Sopenharmony_ci            case EcmaOpcode::STTHISBYVALUE_IMM16_V8: {
8044514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
8054514f5e3Sopenharmony_ci                DumpICByValue(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, BCType::STORE);
8064514f5e3Sopenharmony_ci                break;
8074514f5e3Sopenharmony_ci            }
8084514f5e3Sopenharmony_ci            // Op
8094514f5e3Sopenharmony_ci            case EcmaOpcode::ADD2_IMM8_V8:
8104514f5e3Sopenharmony_ci            case EcmaOpcode::SUB2_IMM8_V8:
8114514f5e3Sopenharmony_ci            case EcmaOpcode::MUL2_IMM8_V8:
8124514f5e3Sopenharmony_ci            case EcmaOpcode::DIV2_IMM8_V8:
8134514f5e3Sopenharmony_ci            case EcmaOpcode::MOD2_IMM8_V8:
8144514f5e3Sopenharmony_ci            case EcmaOpcode::SHL2_IMM8_V8:
8154514f5e3Sopenharmony_ci            case EcmaOpcode::SHR2_IMM8_V8:
8164514f5e3Sopenharmony_ci            case EcmaOpcode::AND2_IMM8_V8:
8174514f5e3Sopenharmony_ci            case EcmaOpcode::OR2_IMM8_V8:
8184514f5e3Sopenharmony_ci            case EcmaOpcode::XOR2_IMM8_V8:
8194514f5e3Sopenharmony_ci            case EcmaOpcode::ASHR2_IMM8_V8:
8204514f5e3Sopenharmony_ci            case EcmaOpcode::EXP_IMM8_V8:
8214514f5e3Sopenharmony_ci            case EcmaOpcode::NEG_IMM8:
8224514f5e3Sopenharmony_ci            case EcmaOpcode::NOT_IMM8:
8234514f5e3Sopenharmony_ci            case EcmaOpcode::INC_IMM8:
8244514f5e3Sopenharmony_ci            case EcmaOpcode::DEC_IMM8:
8254514f5e3Sopenharmony_ci            case EcmaOpcode::EQ_IMM8_V8:
8264514f5e3Sopenharmony_ci            case EcmaOpcode::NOTEQ_IMM8_V8:
8274514f5e3Sopenharmony_ci            case EcmaOpcode::LESS_IMM8_V8:
8284514f5e3Sopenharmony_ci            case EcmaOpcode::LESSEQ_IMM8_V8:
8294514f5e3Sopenharmony_ci            case EcmaOpcode::GREATER_IMM8_V8:
8304514f5e3Sopenharmony_ci            case EcmaOpcode::GREATEREQ_IMM8_V8:
8314514f5e3Sopenharmony_ci            case EcmaOpcode::STRICTNOTEQ_IMM8_V8:
8324514f5e3Sopenharmony_ci            case EcmaOpcode::STRICTEQ_IMM8_V8:
8334514f5e3Sopenharmony_ci            case EcmaOpcode::TONUMERIC_IMM8: {
8344514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
8354514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
8364514f5e3Sopenharmony_ci                DumpOpType(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8374514f5e3Sopenharmony_ci                break;
8384514f5e3Sopenharmony_ci            }
8394514f5e3Sopenharmony_ci            case EcmaOpcode::CALLRUNTIME_ISTRUE_PREF_IMM8:
8404514f5e3Sopenharmony_ci            case EcmaOpcode::CALLRUNTIME_ISFALSE_PREF_IMM8: {
8414514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_1();
8424514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
8434514f5e3Sopenharmony_ci                DumpOpType(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8444514f5e3Sopenharmony_ci                break;
8454514f5e3Sopenharmony_ci            }
8464514f5e3Sopenharmony_ci            // Call
8474514f5e3Sopenharmony_ci            case EcmaOpcode::CALLARG0_IMM8:
8484514f5e3Sopenharmony_ci            case EcmaOpcode::CALLARG1_IMM8_V8:
8494514f5e3Sopenharmony_ci            case EcmaOpcode::CALLARGS2_IMM8_V8_V8:
8504514f5e3Sopenharmony_ci            case EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8:
8514514f5e3Sopenharmony_ci            case EcmaOpcode::CALLRANGE_IMM8_IMM8_V8:
8524514f5e3Sopenharmony_ci            case EcmaOpcode::CALLTHIS0_IMM8_V8:
8534514f5e3Sopenharmony_ci            case EcmaOpcode::CALLTHIS1_IMM8_V8_V8:
8544514f5e3Sopenharmony_ci            case EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8:
8554514f5e3Sopenharmony_ci            case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8:
8564514f5e3Sopenharmony_ci            case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8: {
8574514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
8584514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
8594514f5e3Sopenharmony_ci                DumpCall(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8604514f5e3Sopenharmony_ci                break;
8614514f5e3Sopenharmony_ci            }
8624514f5e3Sopenharmony_ci            case EcmaOpcode::CALLRUNTIME_CALLINIT_PREF_IMM8_V8: {
8634514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_1();
8644514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
8654514f5e3Sopenharmony_ci                DumpCall(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8664514f5e3Sopenharmony_ci                break;
8674514f5e3Sopenharmony_ci            }
8684514f5e3Sopenharmony_ci            case EcmaOpcode::WIDE_CALLRANGE_PREF_IMM16_V8:
8694514f5e3Sopenharmony_ci            case EcmaOpcode::WIDE_CALLTHISRANGE_PREF_IMM16_V8: {
8704514f5e3Sopenharmony_ci                // no ic slot
8714514f5e3Sopenharmony_ci                break;
8724514f5e3Sopenharmony_ci            }
8734514f5e3Sopenharmony_ci            case EcmaOpcode::NEWOBJRANGE_IMM8_IMM8_V8: {
8744514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
8754514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
8764514f5e3Sopenharmony_ci                DumpNewObjRange(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8774514f5e3Sopenharmony_ci                break;
8784514f5e3Sopenharmony_ci            }
8794514f5e3Sopenharmony_ci            case EcmaOpcode::NEWOBJRANGE_IMM16_IMM8_V8: {
8804514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
8814514f5e3Sopenharmony_ci                DumpNewObjRange(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8824514f5e3Sopenharmony_ci                break;
8834514f5e3Sopenharmony_ci            }
8844514f5e3Sopenharmony_ci            case EcmaOpcode::WIDE_NEWOBJRANGE_PREF_IMM16_V8: {
8854514f5e3Sopenharmony_ci                break;
8864514f5e3Sopenharmony_ci            }
8874514f5e3Sopenharmony_ci            // Create object
8884514f5e3Sopenharmony_ci            case EcmaOpcode::DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8: {
8894514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
8904514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
8914514f5e3Sopenharmony_ci                DumpDefineClass(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8924514f5e3Sopenharmony_ci                break;
8934514f5e3Sopenharmony_ci            }
8944514f5e3Sopenharmony_ci            case EcmaOpcode::DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8: {
8954514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
8964514f5e3Sopenharmony_ci                DumpDefineClass(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
8974514f5e3Sopenharmony_ci                break;
8984514f5e3Sopenharmony_ci            }
8994514f5e3Sopenharmony_ci            case EcmaOpcode::DEFINEFUNC_IMM8_ID16_IMM8: {
9004514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
9014514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
9024514f5e3Sopenharmony_ci                DumpDefineClass(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
9034514f5e3Sopenharmony_ci                break;
9044514f5e3Sopenharmony_ci            }
9054514f5e3Sopenharmony_ci            case EcmaOpcode::DEFINEFUNC_IMM16_ID16_IMM8: {
9064514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
9074514f5e3Sopenharmony_ci                DumpDefineClass(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
9084514f5e3Sopenharmony_ci                break;
9094514f5e3Sopenharmony_ci            }
9104514f5e3Sopenharmony_ci            case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM8_ID16:
9114514f5e3Sopenharmony_ci            case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
9124514f5e3Sopenharmony_ci            case EcmaOpcode::CREATEEMPTYARRAY_IMM8: {
9134514f5e3Sopenharmony_ci                if (method->GetJSPandaFile() == nullptr) {
9144514f5e3Sopenharmony_ci                    break;
9154514f5e3Sopenharmony_ci                }
9164514f5e3Sopenharmony_ci                auto header = method->GetJSPandaFile()->GetPandaFile()->GetHeader();
9174514f5e3Sopenharmony_ci                auto traceId =
9184514f5e3Sopenharmony_ci                    static_cast<int32_t>(reinterpret_cast<uintptr_t>(pc) - reinterpret_cast<uintptr_t>(header));
9194514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
9204514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
9214514f5e3Sopenharmony_ci                DumpCreateObject(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, traceId);
9224514f5e3Sopenharmony_ci                break;
9234514f5e3Sopenharmony_ci            }
9244514f5e3Sopenharmony_ci            case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM16_ID16:
9254514f5e3Sopenharmony_ci            case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16:
9264514f5e3Sopenharmony_ci            case EcmaOpcode::CREATEEMPTYARRAY_IMM16: {
9274514f5e3Sopenharmony_ci                if (method->GetJSPandaFile() == nullptr) {
9284514f5e3Sopenharmony_ci                    break;
9294514f5e3Sopenharmony_ci                }
9304514f5e3Sopenharmony_ci                auto header = method->GetJSPandaFile()->GetPandaFile()->GetHeader();
9314514f5e3Sopenharmony_ci                auto traceId =
9324514f5e3Sopenharmony_ci                    static_cast<int32_t>(reinterpret_cast<uintptr_t>(pc) - reinterpret_cast<uintptr_t>(header));
9334514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
9344514f5e3Sopenharmony_ci                DumpCreateObject(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo, traceId);
9354514f5e3Sopenharmony_ci                break;
9364514f5e3Sopenharmony_ci            }
9374514f5e3Sopenharmony_ci            case EcmaOpcode::GETITERATOR_IMM8: {
9384514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
9394514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
9404514f5e3Sopenharmony_ci                DumpGetIterator(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
9414514f5e3Sopenharmony_ci                break;
9424514f5e3Sopenharmony_ci            }
9434514f5e3Sopenharmony_ci            case EcmaOpcode::GETITERATOR_IMM16: {
9444514f5e3Sopenharmony_ci                uint16_t slotId = READ_INST_16_0();
9454514f5e3Sopenharmony_ci                DumpGetIterator(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
9464514f5e3Sopenharmony_ci                break;
9474514f5e3Sopenharmony_ci            }
9484514f5e3Sopenharmony_ci            // Others
9494514f5e3Sopenharmony_ci            case EcmaOpcode::INSTANCEOF_IMM8_V8: {
9504514f5e3Sopenharmony_ci                uint8_t slotId = READ_INST_8_0();
9514514f5e3Sopenharmony_ci                CHECK_SLOTID_BREAK(slotId);
9524514f5e3Sopenharmony_ci                DumpInstanceof(abcId, recordName, methodId, bcOffset, slotId, profileTypeInfo);
9534514f5e3Sopenharmony_ci                break;
9544514f5e3Sopenharmony_ci            }
9554514f5e3Sopenharmony_ci            case EcmaOpcode::DEFINEGETTERSETTERBYVALUE_V8_V8_V8_V8:
9564514f5e3Sopenharmony_ci            default:
9574514f5e3Sopenharmony_ci                break;
9584514f5e3Sopenharmony_ci        }
9594514f5e3Sopenharmony_ci        bcIns = bcIns.GetNext();
9604514f5e3Sopenharmony_ci    }
9614514f5e3Sopenharmony_ci    if (PGOTrace::GetInstance()->IsEnable()) {
9624514f5e3Sopenharmony_ci        auto methodData = PGOTrace::GetInstance()->TryGetMethodData(function->GetMethod());
9634514f5e3Sopenharmony_ci        methodData->SetProfileBytecodeTime(start.TotalSpentTime());
9644514f5e3Sopenharmony_ci    }
9654514f5e3Sopenharmony_ci}
9664514f5e3Sopenharmony_ci
9674514f5e3Sopenharmony_civoid PGOProfiler::DumpICByName(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
9684514f5e3Sopenharmony_ci                               uint32_t slotId, ProfileTypeInfo *profileTypeInfo, BCType type)
9694514f5e3Sopenharmony_ci{
9704514f5e3Sopenharmony_ci    JSTaggedValue firstValue = profileTypeInfo->Get(slotId);
9714514f5e3Sopenharmony_ci    if (!firstValue.IsHeapObject()) {
9724514f5e3Sopenharmony_ci        if (firstValue.IsHole()) {
9734514f5e3Sopenharmony_ci            // Mega state
9744514f5e3Sopenharmony_ci            AddObjectInfoWithMega(abcId, recordName, methodId, bcOffset);
9754514f5e3Sopenharmony_ci        }
9764514f5e3Sopenharmony_ci        return;
9774514f5e3Sopenharmony_ci    }
9784514f5e3Sopenharmony_ci    if (firstValue.IsWeak()) {
9794514f5e3Sopenharmony_ci        TaggedObject *object = firstValue.GetWeakReferentUnChecked();
9804514f5e3Sopenharmony_ci        if (object->GetClass()->IsHClass()) {
9814514f5e3Sopenharmony_ci            JSTaggedValue secondValue = profileTypeInfo->Get(slotId + 1);
9824514f5e3Sopenharmony_ci            JSHClass *hclass = JSHClass::Cast(object);
9834514f5e3Sopenharmony_ci            DumpICByNameWithHandler(abcId, recordName, methodId, bcOffset, hclass, secondValue, type);
9844514f5e3Sopenharmony_ci        }
9854514f5e3Sopenharmony_ci        return;
9864514f5e3Sopenharmony_ci    }
9874514f5e3Sopenharmony_ci    DumpICByNameWithPoly(abcId, recordName, methodId, bcOffset, firstValue, type);
9884514f5e3Sopenharmony_ci}
9894514f5e3Sopenharmony_ci
9904514f5e3Sopenharmony_civoid PGOProfiler::DumpICByValue(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
9914514f5e3Sopenharmony_ci                                uint32_t slotId, ProfileTypeInfo *profileTypeInfo, BCType type)
9924514f5e3Sopenharmony_ci{
9934514f5e3Sopenharmony_ci    JSTaggedValue firstValue = profileTypeInfo->Get(slotId);
9944514f5e3Sopenharmony_ci    if (!firstValue.IsHeapObject()) {
9954514f5e3Sopenharmony_ci        if (firstValue.IsHole()) {
9964514f5e3Sopenharmony_ci            // Mega state
9974514f5e3Sopenharmony_ci            AddObjectInfoWithMega(abcId, recordName, methodId, bcOffset);
9984514f5e3Sopenharmony_ci        }
9994514f5e3Sopenharmony_ci        return;
10004514f5e3Sopenharmony_ci    }
10014514f5e3Sopenharmony_ci    if (firstValue.IsWeak()) {
10024514f5e3Sopenharmony_ci        TaggedObject *object = firstValue.GetWeakReferentUnChecked();
10034514f5e3Sopenharmony_ci        if (object->GetClass()->IsHClass()) {
10044514f5e3Sopenharmony_ci            JSTaggedValue secondValue = profileTypeInfo->Get(slotId + 1);
10054514f5e3Sopenharmony_ci            JSHClass *hclass = JSHClass::Cast(object);
10064514f5e3Sopenharmony_ci            DumpICByValueWithHandler(abcId, recordName, methodId, bcOffset, hclass, secondValue, type);
10074514f5e3Sopenharmony_ci        }
10084514f5e3Sopenharmony_ci        return;
10094514f5e3Sopenharmony_ci    }
10104514f5e3Sopenharmony_ci    // Check key
10114514f5e3Sopenharmony_ci    if ((firstValue.IsString() || firstValue.IsSymbol())) {
10124514f5e3Sopenharmony_ci        return;
10134514f5e3Sopenharmony_ci    }
10144514f5e3Sopenharmony_ci    // Check without key
10154514f5e3Sopenharmony_ci    DumpICByValueWithPoly(abcId, recordName, methodId, bcOffset, firstValue, type);
10164514f5e3Sopenharmony_ci}
10174514f5e3Sopenharmony_ci
10184514f5e3Sopenharmony_civoid PGOProfiler::DumpICByNameWithPoly(ApEntityId abcId,
10194514f5e3Sopenharmony_ci    const CString &recordName, EntityId methodId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type)
10204514f5e3Sopenharmony_ci{
10214514f5e3Sopenharmony_ci    if (cacheValue.IsWeak()) {
10224514f5e3Sopenharmony_ci        return;
10234514f5e3Sopenharmony_ci    }
10244514f5e3Sopenharmony_ci    ASSERT(cacheValue.IsTaggedArray());
10254514f5e3Sopenharmony_ci    auto array = TaggedArray::Cast(cacheValue);
10264514f5e3Sopenharmony_ci    uint32_t length = array->GetLength();
10274514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < length; i += 2) { // 2 means one ic, two slot
10284514f5e3Sopenharmony_ci        auto result = array->Get(i);
10294514f5e3Sopenharmony_ci        auto handler = array->Get(i + 1);
10304514f5e3Sopenharmony_ci        if (!result.IsHeapObject() || !result.IsWeak()) {
10314514f5e3Sopenharmony_ci            continue;
10324514f5e3Sopenharmony_ci        }
10334514f5e3Sopenharmony_ci        TaggedObject *object = result.GetWeakReferentUnChecked();
10344514f5e3Sopenharmony_ci        if (!object->GetClass()->IsHClass()) {
10354514f5e3Sopenharmony_ci            continue;
10364514f5e3Sopenharmony_ci        }
10374514f5e3Sopenharmony_ci        JSHClass *hclass = JSHClass::Cast(object);
10384514f5e3Sopenharmony_ci        if (!DumpICByNameWithHandler(abcId, recordName, methodId, bcOffset, hclass, handler, type)) {
10394514f5e3Sopenharmony_ci            AddObjectInfoWithMega(abcId, recordName, methodId, bcOffset);
10404514f5e3Sopenharmony_ci            break;
10414514f5e3Sopenharmony_ci        }
10424514f5e3Sopenharmony_ci    }
10434514f5e3Sopenharmony_ci}
10444514f5e3Sopenharmony_ci
10454514f5e3Sopenharmony_civoid PGOProfiler::DumpICByValueWithPoly(ApEntityId abcId,
10464514f5e3Sopenharmony_ci    const CString &recordName, EntityId methodId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type)
10474514f5e3Sopenharmony_ci{
10484514f5e3Sopenharmony_ci    if (cacheValue.IsWeak()) {
10494514f5e3Sopenharmony_ci        return;
10504514f5e3Sopenharmony_ci    }
10514514f5e3Sopenharmony_ci    ASSERT(cacheValue.IsTaggedArray());
10524514f5e3Sopenharmony_ci    auto array = TaggedArray::Cast(cacheValue);
10534514f5e3Sopenharmony_ci    uint32_t length = array->GetLength();
10544514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < length; i += 2) { // 2 means one ic, two slot
10554514f5e3Sopenharmony_ci        auto result = array->Get(i);
10564514f5e3Sopenharmony_ci        auto handler = array->Get(i + 1);
10574514f5e3Sopenharmony_ci        if (!result.IsHeapObject() || !result.IsWeak()) {
10584514f5e3Sopenharmony_ci            continue;
10594514f5e3Sopenharmony_ci        }
10604514f5e3Sopenharmony_ci        TaggedObject *object = result.GetWeakReferentUnChecked();
10614514f5e3Sopenharmony_ci        if (!object->GetClass()->IsHClass()) {
10624514f5e3Sopenharmony_ci            continue;
10634514f5e3Sopenharmony_ci        }
10644514f5e3Sopenharmony_ci        JSHClass *hclass = JSHClass::Cast(object);
10654514f5e3Sopenharmony_ci        DumpICByValueWithHandler(abcId, recordName, methodId, bcOffset, hclass, handler, type);
10664514f5e3Sopenharmony_ci    }
10674514f5e3Sopenharmony_ci}
10684514f5e3Sopenharmony_ci
10694514f5e3Sopenharmony_cibool PGOProfiler::DumpICByNameWithHandler(ApEntityId abcId, const CString &recordName, EntityId methodId,
10704514f5e3Sopenharmony_ci                                          int32_t bcOffset, JSHClass *hclass, JSTaggedValue secondValue, BCType type)
10714514f5e3Sopenharmony_ci{
10724514f5e3Sopenharmony_ci    TryDumpProtoTransitionType(hclass);
10734514f5e3Sopenharmony_ci    if (type == BCType::LOAD) {
10744514f5e3Sopenharmony_ci        return DumpICLoadByNameWithHandler(abcId, recordName, methodId, bcOffset, hclass, secondValue);
10754514f5e3Sopenharmony_ci    }
10764514f5e3Sopenharmony_ci
10774514f5e3Sopenharmony_ci    if (secondValue.IsInt()) {
10784514f5e3Sopenharmony_ci        return AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, hclass);
10794514f5e3Sopenharmony_ci    } else if (secondValue.IsTransitionHandler()) {
10804514f5e3Sopenharmony_ci        auto transitionHandler = TransitionHandler::Cast(secondValue.GetTaggedObject());
10814514f5e3Sopenharmony_ci        auto transitionHClassVal = transitionHandler->GetTransitionHClass();
10824514f5e3Sopenharmony_ci        if (transitionHClassVal.IsJSHClass()) {
10834514f5e3Sopenharmony_ci            auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject());
10844514f5e3Sopenharmony_ci            return AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, transitionHClass);
10854514f5e3Sopenharmony_ci        }
10864514f5e3Sopenharmony_ci    } else if (secondValue.IsTransWithProtoHandler()) {
10874514f5e3Sopenharmony_ci        auto transWithProtoHandler = TransWithProtoHandler::Cast(secondValue.GetTaggedObject());
10884514f5e3Sopenharmony_ci        auto cellValue = transWithProtoHandler->GetProtoCell();
10894514f5e3Sopenharmony_ci        if (CheckProtoChangeMarker(cellValue)) {
10904514f5e3Sopenharmony_ci            return false;
10914514f5e3Sopenharmony_ci        }
10924514f5e3Sopenharmony_ci        auto transitionHClassVal = transWithProtoHandler->GetTransitionHClass();
10934514f5e3Sopenharmony_ci        if (transitionHClassVal.IsJSHClass()) {
10944514f5e3Sopenharmony_ci            auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject());
10954514f5e3Sopenharmony_ci            return AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, transitionHClass);
10964514f5e3Sopenharmony_ci        }
10974514f5e3Sopenharmony_ci    } else if (secondValue.IsPrototypeHandler()) {
10984514f5e3Sopenharmony_ci        auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject());
10994514f5e3Sopenharmony_ci        auto cellValue = prototypeHandler->GetProtoCell();
11004514f5e3Sopenharmony_ci        if (CheckProtoChangeMarker(cellValue)) {
11014514f5e3Sopenharmony_ci            return false;
11024514f5e3Sopenharmony_ci        }
11034514f5e3Sopenharmony_ci        auto holder = prototypeHandler->GetHolder();
11044514f5e3Sopenharmony_ci        auto holderHClass = holder.GetTaggedObject()->GetClass();
11054514f5e3Sopenharmony_ci        auto accessorMethodId = prototypeHandler->GetAccessorMethodId();
11064514f5e3Sopenharmony_ci        return AddObjectInfo(
11074514f5e3Sopenharmony_ci            abcId, recordName, methodId, bcOffset, hclass, holderHClass, holderHClass, accessorMethodId);
11084514f5e3Sopenharmony_ci    } else if (secondValue.IsStoreTSHandler()) {
11094514f5e3Sopenharmony_ci        StoreTSHandler *storeTSHandler = StoreTSHandler::Cast(secondValue.GetTaggedObject());
11104514f5e3Sopenharmony_ci        auto cellValue = storeTSHandler->GetProtoCell();
11114514f5e3Sopenharmony_ci        if (CheckProtoChangeMarker(cellValue)) {
11124514f5e3Sopenharmony_ci            return false;
11134514f5e3Sopenharmony_ci        }
11144514f5e3Sopenharmony_ci        auto holder = storeTSHandler->GetHolder();
11154514f5e3Sopenharmony_ci        auto holderHClass = holder.GetTaggedObject()->GetClass();
11164514f5e3Sopenharmony_ci        return AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, holderHClass, holderHClass);
11174514f5e3Sopenharmony_ci    }
11184514f5e3Sopenharmony_ci    // StoreGlobal
11194514f5e3Sopenharmony_ci    return false;
11204514f5e3Sopenharmony_ci}
11214514f5e3Sopenharmony_ci
11224514f5e3Sopenharmony_cibool PGOProfiler::DumpICLoadByNameWithHandler(ApEntityId abcId, const CString &recordName, EntityId methodId,
11234514f5e3Sopenharmony_ci                                              int32_t bcOffset, JSHClass *hclass, JSTaggedValue secondValue)
11244514f5e3Sopenharmony_ci{
11254514f5e3Sopenharmony_ci    bool ret = false;
11264514f5e3Sopenharmony_ci    if (secondValue.IsInt()) {
11274514f5e3Sopenharmony_ci        auto handlerInfo = static_cast<uint32_t>(secondValue.GetInt());
11284514f5e3Sopenharmony_ci        if (HandlerBase::IsNonExist(handlerInfo)) {
11294514f5e3Sopenharmony_ci            return ret;
11304514f5e3Sopenharmony_ci        }
11314514f5e3Sopenharmony_ci        if (HandlerBase::IsField(handlerInfo) || HandlerBase::IsAccessor(handlerInfo)) {
11324514f5e3Sopenharmony_ci            if (AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, hclass)) {
11334514f5e3Sopenharmony_ci                return true;
11344514f5e3Sopenharmony_ci            }
11354514f5e3Sopenharmony_ci        }
11364514f5e3Sopenharmony_ci        return AddBuiltinsInfoByNameInInstance(abcId, recordName, methodId, bcOffset, hclass);
11374514f5e3Sopenharmony_ci    } else if (secondValue.IsPrototypeHandler()) {
11384514f5e3Sopenharmony_ci        auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject());
11394514f5e3Sopenharmony_ci        auto cellValue = prototypeHandler->GetProtoCell();
11404514f5e3Sopenharmony_ci        if (CheckProtoChangeMarker(cellValue)) {
11414514f5e3Sopenharmony_ci            return ret;
11424514f5e3Sopenharmony_ci        }
11434514f5e3Sopenharmony_ci        auto holder = prototypeHandler->GetHolder();
11444514f5e3Sopenharmony_ci        auto holderHClass = holder.GetTaggedObject()->GetClass();
11454514f5e3Sopenharmony_ci        JSTaggedValue handlerInfoVal = prototypeHandler->GetHandlerInfo();
11464514f5e3Sopenharmony_ci        if (!handlerInfoVal.IsInt()) {
11474514f5e3Sopenharmony_ci            return ret;
11484514f5e3Sopenharmony_ci        }
11494514f5e3Sopenharmony_ci        auto handlerInfo = static_cast<uint32_t>(handlerInfoVal.GetInt());
11504514f5e3Sopenharmony_ci        if (HandlerBase::IsNonExist(handlerInfo)) {
11514514f5e3Sopenharmony_ci            return ret;
11524514f5e3Sopenharmony_ci        }
11534514f5e3Sopenharmony_ci        auto accessorMethodId = prototypeHandler->GetAccessorMethodId();
11544514f5e3Sopenharmony_ci        if (!AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, holderHClass,
11554514f5e3Sopenharmony_ci                           holderHClass, accessorMethodId)) {
11564514f5e3Sopenharmony_ci            return AddBuiltinsInfoByNameInProt(abcId, recordName, methodId, bcOffset, hclass, holderHClass);
11574514f5e3Sopenharmony_ci        }
11584514f5e3Sopenharmony_ci        return true;
11594514f5e3Sopenharmony_ci    }
11604514f5e3Sopenharmony_ci    // LoadGlobal
11614514f5e3Sopenharmony_ci    return false;
11624514f5e3Sopenharmony_ci}
11634514f5e3Sopenharmony_ci
11644514f5e3Sopenharmony_civoid PGOProfiler::DumpICByValueWithHandler(ApEntityId abcId, const CString &recordName, EntityId methodId,
11654514f5e3Sopenharmony_ci                                           int32_t bcOffset, JSHClass *hclass, JSTaggedValue secondValue, BCType type)
11664514f5e3Sopenharmony_ci{
11674514f5e3Sopenharmony_ci    TryDumpProtoTransitionType(hclass);
11684514f5e3Sopenharmony_ci    if (type == BCType::LOAD) {
11694514f5e3Sopenharmony_ci        if (secondValue.IsInt()) {
11704514f5e3Sopenharmony_ci            auto handlerInfo = static_cast<uint32_t>(secondValue.GetInt());
11714514f5e3Sopenharmony_ci            if (HandlerBase::IsNormalElement(handlerInfo) || HandlerBase::IsStringElement(handlerInfo)) {
11724514f5e3Sopenharmony_ci                if (HandlerBase::NeedSkipInPGODump(handlerInfo)) {
11734514f5e3Sopenharmony_ci                    return;
11744514f5e3Sopenharmony_ci                }
11754514f5e3Sopenharmony_ci                AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, hclass, hclass);
11764514f5e3Sopenharmony_ci                return;
11774514f5e3Sopenharmony_ci            }
11784514f5e3Sopenharmony_ci
11794514f5e3Sopenharmony_ci            if (HandlerBase::IsTypedArrayElement(handlerInfo)) {
11804514f5e3Sopenharmony_ci                OnHeapMode onHeap =  HandlerBase::IsOnHeap(handlerInfo) ? OnHeapMode::ON_HEAP : OnHeapMode::NOT_ON_HEAP;
11814514f5e3Sopenharmony_ci                AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, onHeap);
11824514f5e3Sopenharmony_ci                return;
11834514f5e3Sopenharmony_ci            }
11844514f5e3Sopenharmony_ci
11854514f5e3Sopenharmony_ci            AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, hclass);
11864514f5e3Sopenharmony_ci        }
11874514f5e3Sopenharmony_ci        return;
11884514f5e3Sopenharmony_ci    }
11894514f5e3Sopenharmony_ci    if (secondValue.IsInt()) {
11904514f5e3Sopenharmony_ci        auto handlerInfo = static_cast<uint32_t>(secondValue.GetInt());
11914514f5e3Sopenharmony_ci        if (HandlerBase::IsNormalElement(handlerInfo) || HandlerBase::IsStringElement(handlerInfo)) {
11924514f5e3Sopenharmony_ci            AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, hclass, hclass,
11934514f5e3Sopenharmony_ci                            OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo));
11944514f5e3Sopenharmony_ci            return;
11954514f5e3Sopenharmony_ci        }
11964514f5e3Sopenharmony_ci
11974514f5e3Sopenharmony_ci        if (HandlerBase::IsTypedArrayElement(handlerInfo)) {
11984514f5e3Sopenharmony_ci            OnHeapMode onHeap = HandlerBase::IsOnHeap(handlerInfo) ? OnHeapMode::ON_HEAP : OnHeapMode::NOT_ON_HEAP;
11994514f5e3Sopenharmony_ci            AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, onHeap,
12004514f5e3Sopenharmony_ci                            HandlerBase::IsStoreOutOfBounds(handlerInfo));
12014514f5e3Sopenharmony_ci            return;
12024514f5e3Sopenharmony_ci        }
12034514f5e3Sopenharmony_ci
12044514f5e3Sopenharmony_ci        AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, hclass);
12054514f5e3Sopenharmony_ci    } else if (secondValue.IsTransitionHandler()) {
12064514f5e3Sopenharmony_ci        auto transitionHandler = TransitionHandler::Cast(secondValue.GetTaggedObject());
12074514f5e3Sopenharmony_ci        auto transitionHClassVal = transitionHandler->GetTransitionHClass();
12084514f5e3Sopenharmony_ci
12094514f5e3Sopenharmony_ci        auto handlerInfoValue = transitionHandler->GetHandlerInfo();
12104514f5e3Sopenharmony_ci        ASSERT(handlerInfoValue.IsInt());
12114514f5e3Sopenharmony_ci        auto handlerInfo = static_cast<uint32_t>(handlerInfoValue.GetInt());
12124514f5e3Sopenharmony_ci        if (transitionHClassVal.IsJSHClass()) {
12134514f5e3Sopenharmony_ci            auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject());
12144514f5e3Sopenharmony_ci            if (HandlerBase::IsElement(handlerInfo)) {
12154514f5e3Sopenharmony_ci                AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, hclass, transitionHClass,
12164514f5e3Sopenharmony_ci                                OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo));
12174514f5e3Sopenharmony_ci                return;
12184514f5e3Sopenharmony_ci            }
12194514f5e3Sopenharmony_ci            AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, transitionHClass);
12204514f5e3Sopenharmony_ci        }
12214514f5e3Sopenharmony_ci    } else if (secondValue.IsTransWithProtoHandler()) {
12224514f5e3Sopenharmony_ci        auto transWithProtoHandler = TransWithProtoHandler::Cast(secondValue.GetTaggedObject());
12234514f5e3Sopenharmony_ci        auto transitionHClassVal = transWithProtoHandler->GetTransitionHClass();
12244514f5e3Sopenharmony_ci
12254514f5e3Sopenharmony_ci        auto handlerInfoValue = transWithProtoHandler->GetHandlerInfo();
12264514f5e3Sopenharmony_ci        ASSERT(handlerInfoValue.IsInt());
12274514f5e3Sopenharmony_ci        auto handlerInfo = static_cast<uint32_t>(handlerInfoValue.GetInt());
12284514f5e3Sopenharmony_ci        if (transitionHClassVal.IsJSHClass()) {
12294514f5e3Sopenharmony_ci            auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject());
12304514f5e3Sopenharmony_ci            if (HandlerBase::IsElement(handlerInfo)) {
12314514f5e3Sopenharmony_ci                AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, hclass, transitionHClass,
12324514f5e3Sopenharmony_ci                                OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo));
12334514f5e3Sopenharmony_ci                return;
12344514f5e3Sopenharmony_ci            }
12354514f5e3Sopenharmony_ci            AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, transitionHClass);
12364514f5e3Sopenharmony_ci        }
12374514f5e3Sopenharmony_ci    } else if (secondValue.IsPrototypeHandler()) {
12384514f5e3Sopenharmony_ci        PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject());
12394514f5e3Sopenharmony_ci        auto cellValue = prototypeHandler->GetProtoCell();
12404514f5e3Sopenharmony_ci        if (!cellValue.IsProtoChangeMarker()) {
12414514f5e3Sopenharmony_ci            return;
12424514f5e3Sopenharmony_ci        }
12434514f5e3Sopenharmony_ci        ASSERT(cellValue.IsProtoChangeMarker());
12444514f5e3Sopenharmony_ci        ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject());
12454514f5e3Sopenharmony_ci        if (cell->GetHasChanged()) {
12464514f5e3Sopenharmony_ci            return;
12474514f5e3Sopenharmony_ci        }
12484514f5e3Sopenharmony_ci        JSTaggedValue handlerInfoValue = prototypeHandler->GetHandlerInfo();
12494514f5e3Sopenharmony_ci        ASSERT(handlerInfoValue.IsInt());
12504514f5e3Sopenharmony_ci        auto handlerInfo = static_cast<uint32_t>(handlerInfoValue.GetInt());
12514514f5e3Sopenharmony_ci        if (HandlerBase::IsElement(handlerInfo)) {
12524514f5e3Sopenharmony_ci            AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, hclass, hclass,
12534514f5e3Sopenharmony_ci                            OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo));
12544514f5e3Sopenharmony_ci            return;
12554514f5e3Sopenharmony_ci        }
12564514f5e3Sopenharmony_ci        auto holder = prototypeHandler->GetHolder();
12574514f5e3Sopenharmony_ci        auto holderHClass = holder.GetTaggedObject()->GetClass();
12584514f5e3Sopenharmony_ci        AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, holderHClass, holderHClass);
12594514f5e3Sopenharmony_ci    }
12604514f5e3Sopenharmony_ci}
12614514f5e3Sopenharmony_ci
12624514f5e3Sopenharmony_civoid PGOProfiler::TryDumpProtoTransitionType(JSHClass *hclass)
12634514f5e3Sopenharmony_ci{
12644514f5e3Sopenharmony_ci    JSHClass *ihc1 = JSHClass::FindRootHClass(hclass);
12654514f5e3Sopenharmony_ci    auto transitionType = GetProfileType(ihc1, true);
12664514f5e3Sopenharmony_ci    if (!transitionType.IsRootType() || !transitionType.IsTransitionClassType()) {
12674514f5e3Sopenharmony_ci        return;
12684514f5e3Sopenharmony_ci    }
12694514f5e3Sopenharmony_ci    JSTaggedValue phc1Root = JSHClass::FindProtoRootHClass(ihc1);
12704514f5e3Sopenharmony_ci    auto transitionProtoType = GetProfileType(JSHClass::Cast(phc1Root.GetTaggedObject()), true);
12714514f5e3Sopenharmony_ci    if (!transitionProtoType.IsRootType()) {
12724514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "Set as the prototype of a function again after transition happened for this prototype!";
12734514f5e3Sopenharmony_ci        return;
12744514f5e3Sopenharmony_ci    }
12754514f5e3Sopenharmony_ci
12764514f5e3Sopenharmony_ci    auto thread = vm_->GetJSThread();
12774514f5e3Sopenharmony_ci    auto *transitionTable = thread->GetCurrentEcmaContext()->GetFunctionProtoTransitionTable();
12784514f5e3Sopenharmony_ci    JSTaggedType ihc0 = transitionTable->GetFakeParent(JSTaggedType(ihc1));
12794514f5e3Sopenharmony_ci    JSTaggedType baseIhc = transitionTable->GetFakeParent(phc1Root.GetRawData());
12804514f5e3Sopenharmony_ci    if ((ihc0 == 0) || (baseIhc == 0)) {
12814514f5e3Sopenharmony_ci        return;
12824514f5e3Sopenharmony_ci    }
12834514f5e3Sopenharmony_ci
12844514f5e3Sopenharmony_ci    auto ihc0Obj = JSHClass::Cast(JSTaggedValue(ihc0).GetTaggedObject());
12854514f5e3Sopenharmony_ci    auto baseIhcObj = JSHClass::Cast(JSTaggedValue(baseIhc).GetTaggedObject());
12864514f5e3Sopenharmony_ci    UpdateLayout(ihc0Obj);
12874514f5e3Sopenharmony_ci    UpdateLayout(ihc1);
12884514f5e3Sopenharmony_ci    UpdateLayout(baseIhcObj);
12894514f5e3Sopenharmony_ci
12904514f5e3Sopenharmony_ci    auto ihc0RootType = GetProfileType(ihc0Obj);
12914514f5e3Sopenharmony_ci    ASSERT(ihc0RootType.IsRootType());
12924514f5e3Sopenharmony_ci    auto baseRootHClass = JSHClass::FindRootHClass(baseIhcObj);
12934514f5e3Sopenharmony_ci    auto baseRootType = GetProfileType(baseRootHClass, true);
12944514f5e3Sopenharmony_ci    if (!baseRootType.IsRootType()) {
12954514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "Unsupported prototypes which cannot be recorded!";
12964514f5e3Sopenharmony_ci        return;
12974514f5e3Sopenharmony_ci    }
12984514f5e3Sopenharmony_ci    auto baseType = GetProfileType(baseIhcObj);
12994514f5e3Sopenharmony_ci    ASSERT(!baseType.IsNone());
13004514f5e3Sopenharmony_ci    PGOProtoTransitionType protoTransitionType(ihc0RootType);
13014514f5e3Sopenharmony_ci    protoTransitionType.SetBaseType(baseRootType, baseType);
13024514f5e3Sopenharmony_ci    protoTransitionType.SetTransitionType(transitionType);
13034514f5e3Sopenharmony_ci    protoTransitionType.SetTransitionProtoPt(transitionProtoType);
13044514f5e3Sopenharmony_ci
13054514f5e3Sopenharmony_ci    recordInfos_->GetProtoTransitionPool()->Add(protoTransitionType);
13064514f5e3Sopenharmony_ci}
13074514f5e3Sopenharmony_ci
13084514f5e3Sopenharmony_civoid PGOProfiler::DumpOpType(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
13094514f5e3Sopenharmony_ci                             uint32_t slotId, ProfileTypeInfo *profileTypeInfo)
13104514f5e3Sopenharmony_ci{
13114514f5e3Sopenharmony_ci    JSTaggedValue slotValue = profileTypeInfo->Get(slotId);
13124514f5e3Sopenharmony_ci    if (slotValue.IsInt()) {
13134514f5e3Sopenharmony_ci        auto type = slotValue.GetInt();
13144514f5e3Sopenharmony_ci        ProfileType recordType = GetRecordProfileType(abcId, recordName);
13154514f5e3Sopenharmony_ci        recordInfos_->AddType(recordType, methodId, bcOffset, PGOSampleType(type));
13164514f5e3Sopenharmony_ci    }
13174514f5e3Sopenharmony_ci}
13184514f5e3Sopenharmony_ci
13194514f5e3Sopenharmony_cibool PGOProfiler::FunctionKindVerify(const JSFunction *ctorFunction)
13204514f5e3Sopenharmony_ci{
13214514f5e3Sopenharmony_ci    FunctionKind kind = Method::Cast(ctorFunction->GetMethod())->GetFunctionKind();
13224514f5e3Sopenharmony_ci    return kind == FunctionKind::BASE_CONSTRUCTOR ||
13234514f5e3Sopenharmony_ci           kind == FunctionKind::CLASS_CONSTRUCTOR ||
13244514f5e3Sopenharmony_ci           kind == FunctionKind::DERIVED_CONSTRUCTOR;
13254514f5e3Sopenharmony_ci}
13264514f5e3Sopenharmony_ci
13274514f5e3Sopenharmony_civoid PGOProfiler::DumpDefineClass(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
13284514f5e3Sopenharmony_ci                                  uint32_t slotId, ProfileTypeInfo *profileTypeInfo)
13294514f5e3Sopenharmony_ci{
13304514f5e3Sopenharmony_ci    JSTaggedValue slotValue = profileTypeInfo->Get(slotId);
13314514f5e3Sopenharmony_ci    if (!slotValue.IsProfileTypeInfoCell0()) {
13324514f5e3Sopenharmony_ci        return;
13334514f5e3Sopenharmony_ci    }
13344514f5e3Sopenharmony_ci    JSTaggedValue handle = ProfileTypeInfoCell::Cast(slotValue)->GetHandle();
13354514f5e3Sopenharmony_ci    if (!handle.IsHeapObject() || !handle.IsWeak()) {
13364514f5e3Sopenharmony_ci        return;
13374514f5e3Sopenharmony_ci    }
13384514f5e3Sopenharmony_ci    auto object = handle.GetWeakReferentUnChecked();
13394514f5e3Sopenharmony_ci    if (object->GetClass()->IsJSFunction()) {
13404514f5e3Sopenharmony_ci        JSFunction *ctorFunction = JSFunction::Cast(object);
13414514f5e3Sopenharmony_ci        auto ctorMethod = ctorFunction->GetMethod();
13424514f5e3Sopenharmony_ci        if (!ctorMethod.IsMethod() || !FunctionKindVerify(ctorFunction)) {
13434514f5e3Sopenharmony_ci            return;
13444514f5e3Sopenharmony_ci        }
13454514f5e3Sopenharmony_ci        ApEntityId ctorAbcId = GetMethodAbcId(ctorFunction);
13464514f5e3Sopenharmony_ci        auto ctorJSMethod = Method::Cast(ctorMethod);
13474514f5e3Sopenharmony_ci        auto ctorMethodId = ctorJSMethod->GetMethodId().GetOffset();
13484514f5e3Sopenharmony_ci
13494514f5e3Sopenharmony_ci        auto localType = ProfileType(ctorAbcId, ctorMethodId, ProfileType::Kind::ClassId, true);
13504514f5e3Sopenharmony_ci        if (IsSkippableObjectTypeSafe(localType)) {
13514514f5e3Sopenharmony_ci            return;
13524514f5e3Sopenharmony_ci        }
13534514f5e3Sopenharmony_ci        PGODefineOpType objDefType(localType);
13544514f5e3Sopenharmony_ci        auto protoOrHClass = ctorFunction->GetProtoOrHClass();
13554514f5e3Sopenharmony_ci        if (protoOrHClass.IsJSHClass()) {
13564514f5e3Sopenharmony_ci            auto ihc = JSHClass::Cast(protoOrHClass.GetTaggedObject());
13574514f5e3Sopenharmony_ci            SetRootProfileType(ihc, ctorAbcId, ctorMethodId, ProfileType::Kind::ClassId);
13584514f5e3Sopenharmony_ci            recordInfos_->AddRootLayout(JSTaggedType(ihc), localType);
13594514f5e3Sopenharmony_ci            protoOrHClass = ihc->GetProto();
13604514f5e3Sopenharmony_ci        }
13614514f5e3Sopenharmony_ci
13624514f5e3Sopenharmony_ci        auto ctorRootHClass = JSHClass::FindRootHClass(ctorFunction->GetJSHClass());
13634514f5e3Sopenharmony_ci        auto ctorType = GetProfileType(ctorRootHClass);
13644514f5e3Sopenharmony_ci        if (!ctorType.IsRootType()) {
13654514f5e3Sopenharmony_ci            LOG_ECMA(DEBUG) << "The profileType of constructor root hclass was not found.";
13664514f5e3Sopenharmony_ci        } else {
13674514f5e3Sopenharmony_ci            objDefType.SetCtorPt(ctorType);
13684514f5e3Sopenharmony_ci            recordInfos_->AddRootLayout(JSTaggedType(ctorRootHClass), ctorType);
13694514f5e3Sopenharmony_ci        }
13704514f5e3Sopenharmony_ci
13714514f5e3Sopenharmony_ci        if (protoOrHClass.IsJSObject()) {
13724514f5e3Sopenharmony_ci            auto prototypeHClass = JSObject::Cast(protoOrHClass)->GetClass();
13734514f5e3Sopenharmony_ci            auto prototypeRootHClass = JSHClass::FindRootHClass(prototypeHClass);
13744514f5e3Sopenharmony_ci            ProfileType prototypeType = GetProfileType(prototypeRootHClass);
13754514f5e3Sopenharmony_ci            if (!prototypeType.IsRootType()) {
13764514f5e3Sopenharmony_ci                LOG_ECMA(DEBUG) << "The profileType of prototype root hclass was not found.";
13774514f5e3Sopenharmony_ci            } else {
13784514f5e3Sopenharmony_ci                objDefType.SetProtoTypePt(prototypeType);
13794514f5e3Sopenharmony_ci                recordInfos_->AddRootLayout(JSTaggedType(prototypeRootHClass), prototypeType);
13804514f5e3Sopenharmony_ci            }
13814514f5e3Sopenharmony_ci        }
13824514f5e3Sopenharmony_ci
13834514f5e3Sopenharmony_ci        ProfileType recordType = GetRecordProfileType(abcId, recordName);
13844514f5e3Sopenharmony_ci        recordInfos_->AddDefine(recordType, methodId, bcOffset, objDefType);
13854514f5e3Sopenharmony_ci    }
13864514f5e3Sopenharmony_ci}
13874514f5e3Sopenharmony_ci
13884514f5e3Sopenharmony_civoid PGOProfiler::DumpCreateObject(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
13894514f5e3Sopenharmony_ci                                   uint32_t slotId, ProfileTypeInfo *profileTypeInfo, int32_t traceId)
13904514f5e3Sopenharmony_ci{
13914514f5e3Sopenharmony_ci    JSTaggedValue slotValue = profileTypeInfo->Get(slotId);
13924514f5e3Sopenharmony_ci    if (!slotValue.IsHeapObject()) {
13934514f5e3Sopenharmony_ci        return;
13944514f5e3Sopenharmony_ci    }
13954514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
13964514f5e3Sopenharmony_ci    if (slotValue.IsWeak()) {
13974514f5e3Sopenharmony_ci        auto object = slotValue.GetWeakReferentUnChecked();
13984514f5e3Sopenharmony_ci        if (object->GetClass()->IsHClass()) {
13994514f5e3Sopenharmony_ci            auto newHClass = JSHClass::Cast(object);
14004514f5e3Sopenharmony_ci            auto rootHClass = JSHClass::FindRootHClass(newHClass);
14014514f5e3Sopenharmony_ci            ProfileType profileType = GetProfileType(rootHClass);
14024514f5e3Sopenharmony_ci            if (!profileType.IsRootType()) {
14034514f5e3Sopenharmony_ci                return;
14044514f5e3Sopenharmony_ci            }
14054514f5e3Sopenharmony_ci            ASSERT(profileType.GetKind() == ProfileType::Kind::ObjectLiteralId);
14064514f5e3Sopenharmony_ci            PGOSampleType currentType(profileType);
14074514f5e3Sopenharmony_ci            PGODefineOpType objDefType(profileType);
14084514f5e3Sopenharmony_ci            recordInfos_->AddDefine(recordType, methodId, bcOffset, objDefType);
14094514f5e3Sopenharmony_ci            recordInfos_->AddRootLayout(JSTaggedType(rootHClass), profileType);
14104514f5e3Sopenharmony_ci        }
14114514f5e3Sopenharmony_ci    } else if (slotValue.IsTrackInfoObject()) {
14124514f5e3Sopenharmony_ci        auto currentType = PGOSampleType::CreateProfileType(abcId, traceId, ProfileType::Kind::ArrayLiteralId, true);
14134514f5e3Sopenharmony_ci        auto profileType = currentType.GetProfileType();
14144514f5e3Sopenharmony_ci        PGODefineOpType objDefType(profileType);
14154514f5e3Sopenharmony_ci        TrackInfo *trackInfo = TrackInfo::Cast(slotValue.GetTaggedObject());
14164514f5e3Sopenharmony_ci        auto elementsKind = trackInfo->GetElementsKind();
14174514f5e3Sopenharmony_ci        objDefType.SetElementsKind(elementsKind);
14184514f5e3Sopenharmony_ci        objDefType.SetElementsLength(trackInfo->GetArrayLength());
14194514f5e3Sopenharmony_ci        objDefType.SetSpaceFlag(trackInfo->GetSpaceFlag());
14204514f5e3Sopenharmony_ci        recordInfos_->AddDefine(recordType, methodId, bcOffset, objDefType);
14214514f5e3Sopenharmony_ci        auto cachedHClass = trackInfo->GetCachedHClass();
14224514f5e3Sopenharmony_ci        if (cachedHClass.IsJSHClass()) {
14234514f5e3Sopenharmony_ci            auto hclass = JSHClass::Cast(cachedHClass.GetTaggedObject());
14244514f5e3Sopenharmony_ci            recordInfos_->AddRootLayout(JSTaggedType(hclass), profileType);
14254514f5e3Sopenharmony_ci        }
14264514f5e3Sopenharmony_ci    }
14274514f5e3Sopenharmony_ci}
14284514f5e3Sopenharmony_ci
14294514f5e3Sopenharmony_civoid PGOProfiler::DumpCall(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
14304514f5e3Sopenharmony_ci                           uint32_t slotId, ProfileTypeInfo *profileTypeInfo)
14314514f5e3Sopenharmony_ci{
14324514f5e3Sopenharmony_ci    JSTaggedValue slotValue = profileTypeInfo->Get(slotId);
14334514f5e3Sopenharmony_ci    ProfileType::Kind kind;
14344514f5e3Sopenharmony_ci    int calleeMethodId = 0;
14354514f5e3Sopenharmony_ci    ApEntityId calleeAbcId = 0;
14364514f5e3Sopenharmony_ci    if (slotValue.IsInt()) {
14374514f5e3Sopenharmony_ci        calleeMethodId = slotValue.GetInt();
14384514f5e3Sopenharmony_ci        calleeAbcId = abcId;
14394514f5e3Sopenharmony_ci        ASSERT(calleeMethodId <= 0);
14404514f5e3Sopenharmony_ci        if (calleeMethodId == 0) {
14414514f5e3Sopenharmony_ci            kind = ProfileType::Kind::MethodId;
14424514f5e3Sopenharmony_ci        } else {
14434514f5e3Sopenharmony_ci            kind = ProfileType::Kind::BuiltinFunctionId;
14444514f5e3Sopenharmony_ci        }
14454514f5e3Sopenharmony_ci    } else if (slotValue.IsJSFunction()) {
14464514f5e3Sopenharmony_ci        JSFunction *callee = JSFunction::Cast(slotValue);
14474514f5e3Sopenharmony_ci        Method *calleeMethod = Method::Cast(callee->GetMethod());
14484514f5e3Sopenharmony_ci        calleeMethodId = static_cast<int>(calleeMethod->GetMethodId().GetOffset());
14494514f5e3Sopenharmony_ci        calleeAbcId = GetMethodAbcId(callee->GetMethod());
14504514f5e3Sopenharmony_ci        kind = ProfileType::Kind::MethodId;
14514514f5e3Sopenharmony_ci    } else {
14524514f5e3Sopenharmony_ci        return;
14534514f5e3Sopenharmony_ci    }
14544514f5e3Sopenharmony_ci    PGOSampleType type = PGOSampleType::CreateProfileType(calleeAbcId, std::abs(calleeMethodId), kind);
14554514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
14564514f5e3Sopenharmony_ci    recordInfos_->AddCallTargetType(recordType, methodId, bcOffset, type);
14574514f5e3Sopenharmony_ci}
14584514f5e3Sopenharmony_ci
14594514f5e3Sopenharmony_civoid PGOProfiler::DumpGetIterator(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
14604514f5e3Sopenharmony_ci                                  uint32_t slotId, ProfileTypeInfo *profileTypeInfo)
14614514f5e3Sopenharmony_ci{
14624514f5e3Sopenharmony_ci    if (vm_->GetJSThread()->GetEnableLazyBuiltins()) {
14634514f5e3Sopenharmony_ci        return;
14644514f5e3Sopenharmony_ci    }
14654514f5e3Sopenharmony_ci    JSTaggedValue value = profileTypeInfo->Get(slotId);
14664514f5e3Sopenharmony_ci    if (!value.IsInt()) {
14674514f5e3Sopenharmony_ci        return;
14684514f5e3Sopenharmony_ci    }
14694514f5e3Sopenharmony_ci    int iterKind = value.GetInt();
14704514f5e3Sopenharmony_ci    ASSERT(iterKind <= 0);
14714514f5e3Sopenharmony_ci    ProfileType::Kind pgoKind = ProfileType::Kind::BuiltinFunctionId;
14724514f5e3Sopenharmony_ci    PGOSampleType type = PGOSampleType::CreateProfileType(abcId, std::abs(iterKind), pgoKind);
14734514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
14744514f5e3Sopenharmony_ci    recordInfos_->AddCallTargetType(recordType, methodId, bcOffset, type);
14754514f5e3Sopenharmony_ci}
14764514f5e3Sopenharmony_ci
14774514f5e3Sopenharmony_civoid PGOProfiler::DumpNewObjRange(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
14784514f5e3Sopenharmony_ci                                  uint32_t slotId, ProfileTypeInfo *profileTypeInfo)
14794514f5e3Sopenharmony_ci{
14804514f5e3Sopenharmony_ci    JSTaggedValue slotValue = profileTypeInfo->Get(slotId);
14814514f5e3Sopenharmony_ci    int ctorMethodId = 0;
14824514f5e3Sopenharmony_ci    if (slotValue.IsInt()) {
14834514f5e3Sopenharmony_ci        ctorMethodId = slotValue.GetInt();
14844514f5e3Sopenharmony_ci    } else if (slotValue.IsJSFunction()) {
14854514f5e3Sopenharmony_ci        JSFunction *callee = JSFunction::Cast(slotValue);
14864514f5e3Sopenharmony_ci        Method *calleeMethod = Method::Cast(callee->GetMethod());
14874514f5e3Sopenharmony_ci        ctorMethodId = static_cast<int>(calleeMethod->GetMethodId().GetOffset());
14884514f5e3Sopenharmony_ci    } else {
14894514f5e3Sopenharmony_ci        return;
14904514f5e3Sopenharmony_ci    }
14914514f5e3Sopenharmony_ci    PGOSampleType type;
14924514f5e3Sopenharmony_ci    if (ctorMethodId > 0) {
14934514f5e3Sopenharmony_ci        type = PGOSampleType::CreateProfileType(abcId, ctorMethodId, ProfileType::Kind::ClassId, true);
14944514f5e3Sopenharmony_ci    } else {
14954514f5e3Sopenharmony_ci        auto kind = ProfileType::Kind::BuiltinFunctionId;
14964514f5e3Sopenharmony_ci        type = PGOSampleType::CreateProfileType(abcId, std::abs(ctorMethodId), kind);
14974514f5e3Sopenharmony_ci    }
14984514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
14994514f5e3Sopenharmony_ci    recordInfos_->AddCallTargetType(recordType, methodId, bcOffset, type);
15004514f5e3Sopenharmony_ci}
15014514f5e3Sopenharmony_ci
15024514f5e3Sopenharmony_civoid PGOProfiler::DumpInstanceof(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
15034514f5e3Sopenharmony_ci                                 uint32_t slotId, ProfileTypeInfo *profileTypeInfo)
15044514f5e3Sopenharmony_ci{
15054514f5e3Sopenharmony_ci    JSTaggedValue firstValue = profileTypeInfo->Get(slotId);
15064514f5e3Sopenharmony_ci    if (!firstValue.IsHeapObject()) {
15074514f5e3Sopenharmony_ci        if (firstValue.IsHole()) {
15084514f5e3Sopenharmony_ci            // Mega state
15094514f5e3Sopenharmony_ci            AddObjectInfoWithMega(abcId, recordName, methodId, bcOffset);
15104514f5e3Sopenharmony_ci        }
15114514f5e3Sopenharmony_ci        return;
15124514f5e3Sopenharmony_ci    }
15134514f5e3Sopenharmony_ci    if (firstValue.IsWeak()) {
15144514f5e3Sopenharmony_ci        TaggedObject *object = firstValue.GetWeakReferentUnChecked();
15154514f5e3Sopenharmony_ci        if (object->GetClass()->IsHClass()) {
15164514f5e3Sopenharmony_ci            JSHClass *hclass = JSHClass::Cast(object);
15174514f5e3Sopenharmony_ci            // Since pgo does not support symbol, we choose to return if hclass having @@hasInstance
15184514f5e3Sopenharmony_ci            JSHandle<GlobalEnv> env = vm_->GetGlobalEnv();
15194514f5e3Sopenharmony_ci            JSTaggedValue key = env->GetHasInstanceSymbol().GetTaggedValue();
15204514f5e3Sopenharmony_ci            JSHClass *functionPrototypeHC = JSObject::Cast(env->GetFunctionPrototype().GetTaggedValue())->GetClass();
15214514f5e3Sopenharmony_ci            JSTaggedValue foundHClass = TryFindKeyInPrototypeChain(object, hclass, key);
15224514f5e3Sopenharmony_ci            if (!foundHClass.IsUndefined() && JSHClass::Cast(foundHClass.GetTaggedObject()) != functionPrototypeHC) {
15234514f5e3Sopenharmony_ci                return;
15244514f5e3Sopenharmony_ci            }
15254514f5e3Sopenharmony_ci            AddObjectInfo(abcId, recordName, methodId, bcOffset, hclass, hclass, hclass);
15264514f5e3Sopenharmony_ci        }
15274514f5e3Sopenharmony_ci        return;
15284514f5e3Sopenharmony_ci    }
15294514f5e3Sopenharmony_ci    // Poly Not Consider now
15304514f5e3Sopenharmony_ci    return;
15314514f5e3Sopenharmony_ci}
15324514f5e3Sopenharmony_ci
15334514f5e3Sopenharmony_civoid PGOProfiler::UpdateLayout(JSHClass *hclass)
15344514f5e3Sopenharmony_ci{
15354514f5e3Sopenharmony_ci    auto parentHClass = hclass->GetParent();
15364514f5e3Sopenharmony_ci    if (!GetProfileType(hclass).IsRootType() && parentHClass.IsJSHClass()) {
15374514f5e3Sopenharmony_ci        UpdateTransitionLayout(JSHClass::Cast(parentHClass.GetTaggedObject()), hclass);
15384514f5e3Sopenharmony_ci    } else {
15394514f5e3Sopenharmony_ci        auto rootHClass = JSHClass::FindRootHClass(hclass);
15404514f5e3Sopenharmony_ci        ProfileType rootType = GetProfileType(rootHClass, true);
15414514f5e3Sopenharmony_ci        if (!rootType.IsRootType()) {
15424514f5e3Sopenharmony_ci            return;
15434514f5e3Sopenharmony_ci        }
15444514f5e3Sopenharmony_ci
15454514f5e3Sopenharmony_ci        auto prototypeHClass = JSHClass::FindProtoRootHClass(rootHClass);
15464514f5e3Sopenharmony_ci        if (prototypeHClass.IsJSHClass()) {
15474514f5e3Sopenharmony_ci            auto prototypeObject = JSHClass::Cast(prototypeHClass.GetTaggedObject());
15484514f5e3Sopenharmony_ci            ProfileType prototypeType = GetProfileType(prototypeObject, true);
15494514f5e3Sopenharmony_ci            if (prototypeType.IsRootType()) {
15504514f5e3Sopenharmony_ci                recordInfos_->AddRootPtType(rootType, prototypeType);
15514514f5e3Sopenharmony_ci                UpdateLayout(JSHClass::Cast(prototypeHClass.GetTaggedObject()));
15524514f5e3Sopenharmony_ci            }
15534514f5e3Sopenharmony_ci        }
15544514f5e3Sopenharmony_ci
15554514f5e3Sopenharmony_ci        auto curType = GetOrInsertProfileType(hclass, rootType);
15564514f5e3Sopenharmony_ci        recordInfos_->UpdateLayout(rootType, JSTaggedType(hclass), curType);
15574514f5e3Sopenharmony_ci    }
15584514f5e3Sopenharmony_ci}
15594514f5e3Sopenharmony_ci
15604514f5e3Sopenharmony_civoid PGOProfiler::UpdateTransitionLayout(JSHClass* parent, JSHClass* child)
15614514f5e3Sopenharmony_ci{
15624514f5e3Sopenharmony_ci    auto rootHClass = JSHClass::FindRootHClass(parent);
15634514f5e3Sopenharmony_ci    auto rootType = GetProfileType(rootHClass, true);
15644514f5e3Sopenharmony_ci    if (!rootType.IsRootType()) {
15654514f5e3Sopenharmony_ci        return;
15664514f5e3Sopenharmony_ci    }
15674514f5e3Sopenharmony_ci    // If the child hclass is set as a prototype, it will become the root hclass. Need to give up.
15684514f5e3Sopenharmony_ci    if (GetProfileType(child).IsRootType()) {
15694514f5e3Sopenharmony_ci        return;
15704514f5e3Sopenharmony_ci    }
15714514f5e3Sopenharmony_ci    CStack<JSHClass *> hclassVec;
15724514f5e3Sopenharmony_ci    hclassVec.emplace(child);
15734514f5e3Sopenharmony_ci    hclassVec.emplace(parent);
15744514f5e3Sopenharmony_ci
15754514f5e3Sopenharmony_ci    while (!GetProfileType(parent).IsRootType()) {
15764514f5e3Sopenharmony_ci        auto parentHCValue = parent->GetParent();
15774514f5e3Sopenharmony_ci        if (!parentHCValue.IsJSHClass()) {
15784514f5e3Sopenharmony_ci            break;
15794514f5e3Sopenharmony_ci        }
15804514f5e3Sopenharmony_ci        parent = JSHClass::Cast(parentHCValue.GetTaggedObject());
15814514f5e3Sopenharmony_ci        hclassVec.emplace(parent);
15824514f5e3Sopenharmony_ci    }
15834514f5e3Sopenharmony_ci
15844514f5e3Sopenharmony_ci    auto prototypeRootHClassVal = JSHClass::FindProtoRootHClass(rootHClass);
15854514f5e3Sopenharmony_ci    if (prototypeRootHClassVal.IsJSHClass()) {
15864514f5e3Sopenharmony_ci        auto prototypeRootHClass = JSHClass::Cast(prototypeRootHClassVal.GetTaggedObject());
15874514f5e3Sopenharmony_ci        auto prototypeType = GetProfileType(prototypeRootHClass);
15884514f5e3Sopenharmony_ci        if (prototypeType.IsRootType()) {
15894514f5e3Sopenharmony_ci            recordInfos_->AddRootPtType(rootType, prototypeType);
15904514f5e3Sopenharmony_ci            UpdateLayout(prototypeRootHClass);
15914514f5e3Sopenharmony_ci        }
15924514f5e3Sopenharmony_ci    }
15934514f5e3Sopenharmony_ci
15944514f5e3Sopenharmony_ci    parent = hclassVec.top();
15954514f5e3Sopenharmony_ci    hclassVec.pop();
15964514f5e3Sopenharmony_ci    auto parentType = GetProfileType(parent);
15974514f5e3Sopenharmony_ci    while (!hclassVec.empty()) {
15984514f5e3Sopenharmony_ci        child = hclassVec.top();
15994514f5e3Sopenharmony_ci        hclassVec.pop();
16004514f5e3Sopenharmony_ci        auto childType = GetOrInsertProfileType(child, rootType);
16014514f5e3Sopenharmony_ci        recordInfos_->UpdateTransitionLayout(
16024514f5e3Sopenharmony_ci            rootType, JSTaggedType(parent), parentType, JSTaggedType(child), childType);
16034514f5e3Sopenharmony_ci        parentType = childType;
16044514f5e3Sopenharmony_ci        parent = child;
16054514f5e3Sopenharmony_ci    }
16064514f5e3Sopenharmony_ci}
16074514f5e3Sopenharmony_ci
16084514f5e3Sopenharmony_cibool PGOProfiler::AddTransitionObjectInfo(ProfileType recordType,
16094514f5e3Sopenharmony_ci                                          EntityId methodId,
16104514f5e3Sopenharmony_ci                                          int32_t bcOffset,
16114514f5e3Sopenharmony_ci                                          JSHClass* receiver,
16124514f5e3Sopenharmony_ci                                          JSHClass* hold,
16134514f5e3Sopenharmony_ci                                          JSHClass* holdTra,
16144514f5e3Sopenharmony_ci                                          PGOSampleType accessorMethod)
16154514f5e3Sopenharmony_ci{
16164514f5e3Sopenharmony_ci    auto receiverRootType = FindRootProfileType(receiver);
16174514f5e3Sopenharmony_ci    if (!receiverRootType.IsRootType()) {
16184514f5e3Sopenharmony_ci        return false;
16194514f5e3Sopenharmony_ci    }
16204514f5e3Sopenharmony_ci
16214514f5e3Sopenharmony_ci    auto holdRootType = FindRootProfileType(hold);
16224514f5e3Sopenharmony_ci    if (!holdRootType.IsRootType()) {
16234514f5e3Sopenharmony_ci        return true;
16244514f5e3Sopenharmony_ci    }
16254514f5e3Sopenharmony_ci
16264514f5e3Sopenharmony_ci    auto receiverType = GetOrInsertProfileType(receiver, receiverRootType);
16274514f5e3Sopenharmony_ci    auto holdType = GetOrInsertProfileType(hold, holdRootType);
16284514f5e3Sopenharmony_ci    auto holdTraType = GetOrInsertProfileType(holdTra, holdRootType);
16294514f5e3Sopenharmony_ci
16304514f5e3Sopenharmony_ci    if (receiver != hold) {
16314514f5e3Sopenharmony_ci        UpdateLayout(receiver);
16324514f5e3Sopenharmony_ci    }
16334514f5e3Sopenharmony_ci
16344514f5e3Sopenharmony_ci    if (holdType == holdTraType) {
16354514f5e3Sopenharmony_ci        UpdateLayout(hold);
16364514f5e3Sopenharmony_ci    } else {
16374514f5e3Sopenharmony_ci        UpdateTransitionLayout(hold, holdTra);
16384514f5e3Sopenharmony_ci    }
16394514f5e3Sopenharmony_ci
16404514f5e3Sopenharmony_ci    PGOObjectInfo info(receiverRootType, receiverType, holdRootType, holdType, holdRootType, holdTraType,
16414514f5e3Sopenharmony_ci                       accessorMethod);
16424514f5e3Sopenharmony_ci    UpdatePrototypeChainInfo(receiver, hold, info);
16434514f5e3Sopenharmony_ci    recordInfos_->AddObjectInfo(recordType, methodId, bcOffset, info);
16444514f5e3Sopenharmony_ci    return true;
16454514f5e3Sopenharmony_ci}
16464514f5e3Sopenharmony_ci
16474514f5e3Sopenharmony_cibool PGOProfiler::AddObjectInfo(ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset,
16484514f5e3Sopenharmony_ci                                JSHClass *receiver, JSHClass *hold, JSHClass *holdTra, uint32_t accessorMethodId)
16494514f5e3Sopenharmony_ci{
16504514f5e3Sopenharmony_ci    PGOSampleType accessor = PGOSampleType::CreateProfileType(abcId, accessorMethodId, ProfileType::Kind::MethodId);
16514514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
16524514f5e3Sopenharmony_ci    return AddTransitionObjectInfo(recordType, methodId, bcOffset, receiver, hold, holdTra, accessor);
16534514f5e3Sopenharmony_ci}
16544514f5e3Sopenharmony_ci
16554514f5e3Sopenharmony_civoid PGOProfiler::UpdatePrototypeChainInfo(JSHClass *receiver, JSHClass *holder, PGOObjectInfo &info)
16564514f5e3Sopenharmony_ci{
16574514f5e3Sopenharmony_ci    if (receiver == holder) {
16584514f5e3Sopenharmony_ci        return;
16594514f5e3Sopenharmony_ci    }
16604514f5e3Sopenharmony_ci
16614514f5e3Sopenharmony_ci    std::vector<std::pair<ProfileType, ProfileType>> protoChain;
16624514f5e3Sopenharmony_ci    JSTaggedValue proto = JSHClass::FindProtoHClass(receiver);
16634514f5e3Sopenharmony_ci    while (proto.IsJSHClass()) {
16644514f5e3Sopenharmony_ci        auto protoHClass = JSHClass::Cast(proto.GetTaggedObject());
16654514f5e3Sopenharmony_ci        if (protoHClass == holder) {
16664514f5e3Sopenharmony_ci            break;
16674514f5e3Sopenharmony_ci        }
16684514f5e3Sopenharmony_ci        auto protoRootType = FindRootProfileType(protoHClass);
16694514f5e3Sopenharmony_ci        if (!protoRootType.IsRootType()) {
16704514f5e3Sopenharmony_ci            break;
16714514f5e3Sopenharmony_ci        }
16724514f5e3Sopenharmony_ci        auto protoType = GetOrInsertProfileType(protoHClass, protoRootType);
16734514f5e3Sopenharmony_ci        protoChain.emplace_back(protoRootType, protoType);
16744514f5e3Sopenharmony_ci        proto = JSHClass::FindProtoHClass(protoHClass);
16754514f5e3Sopenharmony_ci    }
16764514f5e3Sopenharmony_ci    if (!protoChain.empty()) {
16774514f5e3Sopenharmony_ci        info.AddPrototypePt(protoChain);
16784514f5e3Sopenharmony_ci    }
16794514f5e3Sopenharmony_ci}
16804514f5e3Sopenharmony_ci
16814514f5e3Sopenharmony_civoid PGOProfiler::AddObjectInfoWithMega(
16824514f5e3Sopenharmony_ci    ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset)
16834514f5e3Sopenharmony_ci{
16844514f5e3Sopenharmony_ci    auto megaType = ProfileType::CreateMegaType();
16854514f5e3Sopenharmony_ci    PGOObjectInfo info(megaType, megaType, megaType, megaType, megaType, megaType, PGOSampleType());
16864514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
16874514f5e3Sopenharmony_ci    recordInfos_->AddObjectInfo(recordType, methodId, bcOffset, info);
16884514f5e3Sopenharmony_ci}
16894514f5e3Sopenharmony_ci
16904514f5e3Sopenharmony_cibool PGOProfiler::AddBuiltinsInfoByNameInInstance(ApEntityId abcId, const CString &recordName, EntityId methodId,
16914514f5e3Sopenharmony_ci    int32_t bcOffset, JSHClass *receiver)
16924514f5e3Sopenharmony_ci{
16934514f5e3Sopenharmony_ci    auto thread = vm_->GetJSThread();
16944514f5e3Sopenharmony_ci    auto type = receiver->GetObjectType();
16954514f5e3Sopenharmony_ci    const auto &ctorEntries = thread->GetCtorHclassEntries();
16964514f5e3Sopenharmony_ci    auto entry = ctorEntries.find(receiver);
16974514f5e3Sopenharmony_ci    if (entry != ctorEntries.end()) {
16984514f5e3Sopenharmony_ci        AddBuiltinsGlobalInfo(abcId, recordName, methodId, bcOffset, entry->second);
16994514f5e3Sopenharmony_ci        return true;
17004514f5e3Sopenharmony_ci    }
17014514f5e3Sopenharmony_ci
17024514f5e3Sopenharmony_ci    auto builtinsId = ToBuiltinsTypeId(type);
17034514f5e3Sopenharmony_ci    if (!builtinsId.has_value()) {
17044514f5e3Sopenharmony_ci        return false;
17054514f5e3Sopenharmony_ci    }
17064514f5e3Sopenharmony_ci    JSHClass *exceptRecvHClass = nullptr;
17074514f5e3Sopenharmony_ci    if (builtinsId == BuiltinTypeId::ARRAY) {
17084514f5e3Sopenharmony_ci        bool receiverIsPrototype = receiver->IsPrototype();
17094514f5e3Sopenharmony_ci        exceptRecvHClass = thread->GetArrayInstanceHClass(receiver->GetElementsKind(), receiverIsPrototype);
17104514f5e3Sopenharmony_ci    } else if (builtinsId == BuiltinTypeId::STRING) {
17114514f5e3Sopenharmony_ci        exceptRecvHClass = receiver;
17124514f5e3Sopenharmony_ci    } else {
17134514f5e3Sopenharmony_ci        exceptRecvHClass = thread->GetBuiltinInstanceHClass(builtinsId.value());
17144514f5e3Sopenharmony_ci    }
17154514f5e3Sopenharmony_ci
17164514f5e3Sopenharmony_ci    if (exceptRecvHClass != receiver) {
17174514f5e3Sopenharmony_ci        // When JSType cannot uniquely identify builtins object, it is necessary to
17184514f5e3Sopenharmony_ci        // query the receiver on the global constants.
17194514f5e3Sopenharmony_ci        if (builtinsId == BuiltinTypeId::OBJECT) {
17204514f5e3Sopenharmony_ci            exceptRecvHClass = JSHClass::Cast(thread->GlobalConstants()->GetIteratorResultClass().GetTaggedObject());
17214514f5e3Sopenharmony_ci            if (exceptRecvHClass == receiver) {
17224514f5e3Sopenharmony_ci                GlobalIndex globalsId;
17234514f5e3Sopenharmony_ci                globalsId.UpdateGlobalConstId(static_cast<size_t>(ConstantIndex::ITERATOR_RESULT_CLASS));
17244514f5e3Sopenharmony_ci                AddBuiltinsGlobalInfo(abcId, recordName, methodId, bcOffset, globalsId);
17254514f5e3Sopenharmony_ci                return true;
17264514f5e3Sopenharmony_ci            }
17274514f5e3Sopenharmony_ci        }
17284514f5e3Sopenharmony_ci        return false;
17294514f5e3Sopenharmony_ci    }
17304514f5e3Sopenharmony_ci
17314514f5e3Sopenharmony_ci    return AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, receiver, receiver);
17324514f5e3Sopenharmony_ci}
17334514f5e3Sopenharmony_ci
17344514f5e3Sopenharmony_cibool PGOProfiler::AddBuiltinsInfoByNameInProt(ApEntityId abcId, const CString &recordName, EntityId methodId,
17354514f5e3Sopenharmony_ci    int32_t bcOffset, JSHClass *receiver, JSHClass *hold)
17364514f5e3Sopenharmony_ci{
17374514f5e3Sopenharmony_ci    auto type = receiver->GetObjectType();
17384514f5e3Sopenharmony_ci    auto builtinsId = ToBuiltinsTypeId(type);
17394514f5e3Sopenharmony_ci    if (!builtinsId.has_value()) {
17404514f5e3Sopenharmony_ci        return false;
17414514f5e3Sopenharmony_ci    }
17424514f5e3Sopenharmony_ci    auto thread = vm_->GetJSThread();
17434514f5e3Sopenharmony_ci    JSHClass *exceptRecvHClass = nullptr;
17444514f5e3Sopenharmony_ci    if (builtinsId == BuiltinTypeId::ARRAY) {
17454514f5e3Sopenharmony_ci        bool receiverIsPrototype = receiver->IsPrototype();
17464514f5e3Sopenharmony_ci        exceptRecvHClass = thread->GetArrayInstanceHClass(receiver->GetElementsKind(), receiverIsPrototype);
17474514f5e3Sopenharmony_ci    } else if (builtinsId == BuiltinTypeId::STRING) {
17484514f5e3Sopenharmony_ci        exceptRecvHClass = receiver;
17494514f5e3Sopenharmony_ci    } else {
17504514f5e3Sopenharmony_ci        exceptRecvHClass = thread->GetBuiltinInstanceHClass(builtinsId.value());
17514514f5e3Sopenharmony_ci    }
17524514f5e3Sopenharmony_ci
17534514f5e3Sopenharmony_ci    auto exceptHoldHClass = thread->GetBuiltinPrototypeHClass(builtinsId.value());
17544514f5e3Sopenharmony_ci    auto exceptPrototypeOfPrototypeHClass =
17554514f5e3Sopenharmony_ci        thread->GetBuiltinPrototypeOfPrototypeHClass(builtinsId.value());
17564514f5e3Sopenharmony_ci    // iterator needs to find two layers of prototype
17574514f5e3Sopenharmony_ci    if (builtinsId == BuiltinTypeId::ARRAY_ITERATOR) {
17584514f5e3Sopenharmony_ci        if ((exceptRecvHClass != receiver) ||
17594514f5e3Sopenharmony_ci            (exceptHoldHClass != hold && exceptPrototypeOfPrototypeHClass != hold)) {
17604514f5e3Sopenharmony_ci            return false;
17614514f5e3Sopenharmony_ci        }
17624514f5e3Sopenharmony_ci    } else if (IsTypedArrayType(builtinsId.value())) {
17634514f5e3Sopenharmony_ci        auto exceptRecvHClassOnHeap = thread->GetBuiltinExtraHClass(builtinsId.value());
17644514f5e3Sopenharmony_ci        ASSERT_PRINT(exceptRecvHClassOnHeap == nullptr || exceptRecvHClassOnHeap->IsOnHeapFromBitField(),
17654514f5e3Sopenharmony_ci                     "must be on heap");
17664514f5e3Sopenharmony_ci        if (IsJSHClassNotEqual(receiver, hold, exceptRecvHClass, exceptRecvHClassOnHeap,
17674514f5e3Sopenharmony_ci                               exceptHoldHClass, exceptPrototypeOfPrototypeHClass)) {
17684514f5e3Sopenharmony_ci            return false;
17694514f5e3Sopenharmony_ci        }
17704514f5e3Sopenharmony_ci    } else if (exceptRecvHClass != receiver || exceptHoldHClass != hold) {
17714514f5e3Sopenharmony_ci        return false;
17724514f5e3Sopenharmony_ci    }
17734514f5e3Sopenharmony_ci
17744514f5e3Sopenharmony_ci    return AddBuiltinsInfo(abcId, recordName, methodId, bcOffset, receiver, receiver);
17754514f5e3Sopenharmony_ci}
17764514f5e3Sopenharmony_ci
17774514f5e3Sopenharmony_cibool PGOProfiler::IsJSHClassNotEqual(JSHClass *receiver, JSHClass *hold, JSHClass *exceptRecvHClass,
17784514f5e3Sopenharmony_ci                                     JSHClass *exceptRecvHClassOnHeap, JSHClass *exceptHoldHClass,
17794514f5e3Sopenharmony_ci                                     JSHClass *exceptPrototypeOfPrototypeHClass)
17804514f5e3Sopenharmony_ci{
17814514f5e3Sopenharmony_ci    //exceptRecvHClass = IHC, exceptRecvHClassOnHeap = IHC OnHeap
17824514f5e3Sopenharmony_ci    //exceptHoldHClass = PHC, exceptPrototypeOfPrototypeHClass = HClass of X.prototype.prototype
17834514f5e3Sopenharmony_ci    return ((exceptRecvHClass != receiver && exceptRecvHClassOnHeap != receiver) ||
17844514f5e3Sopenharmony_ci            (exceptHoldHClass != hold && exceptPrototypeOfPrototypeHClass != hold));
17854514f5e3Sopenharmony_ci}
17864514f5e3Sopenharmony_ci
17874514f5e3Sopenharmony_cibool PGOProfiler::CheckProtoChangeMarker(JSTaggedValue cellValue) const
17884514f5e3Sopenharmony_ci{
17894514f5e3Sopenharmony_ci    if (!cellValue.IsProtoChangeMarker()) {
17904514f5e3Sopenharmony_ci        return true;
17914514f5e3Sopenharmony_ci    }
17924514f5e3Sopenharmony_ci    ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject());
17934514f5e3Sopenharmony_ci    return cell->GetHasChanged();
17944514f5e3Sopenharmony_ci}
17954514f5e3Sopenharmony_ci
17964514f5e3Sopenharmony_civoid PGOProfiler::AddBuiltinsGlobalInfo(ApEntityId abcId, const CString &recordName, EntityId methodId,
17974514f5e3Sopenharmony_ci                                        int32_t bcOffset, GlobalIndex globalsId)
17984514f5e3Sopenharmony_ci{
17994514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
18004514f5e3Sopenharmony_ci    PGOObjectInfo info(ProfileType::CreateGlobals(abcId, globalsId));
18014514f5e3Sopenharmony_ci    recordInfos_->AddObjectInfo(recordType, methodId, bcOffset, info);
18024514f5e3Sopenharmony_ci}
18034514f5e3Sopenharmony_ci
18044514f5e3Sopenharmony_cibool PGOProfiler::AddBuiltinsInfo(
18054514f5e3Sopenharmony_ci    ApEntityId abcId, const CString &recordName, EntityId methodId, int32_t bcOffset, JSHClass *receiver,
18064514f5e3Sopenharmony_ci    JSHClass *transitionHClass, OnHeapMode onHeap, bool everOutOfBounds)
18074514f5e3Sopenharmony_ci{
18084514f5e3Sopenharmony_ci    ProfileType recordType = GetRecordProfileType(abcId, recordName);
18094514f5e3Sopenharmony_ci    if (receiver->IsJSArray()) {
18104514f5e3Sopenharmony_ci        auto type = receiver->GetObjectType();
18114514f5e3Sopenharmony_ci        auto elementsKind = receiver->GetElementsKind();
18124514f5e3Sopenharmony_ci        auto transitionElementsKind = transitionHClass->GetElementsKind();
18134514f5e3Sopenharmony_ci        auto profileType = ProfileType::CreateBuiltinsArray(abcId, type, elementsKind, transitionElementsKind,
18144514f5e3Sopenharmony_ci                                                            everOutOfBounds);
18154514f5e3Sopenharmony_ci        PGOObjectInfo info(profileType);
18164514f5e3Sopenharmony_ci        recordInfos_->AddObjectInfo(recordType, methodId, bcOffset, info);
18174514f5e3Sopenharmony_ci    } else if (receiver->IsTypedArray()) {
18184514f5e3Sopenharmony_ci        JSType jsType = receiver->GetObjectType();
18194514f5e3Sopenharmony_ci        auto profileType = ProfileType::CreateBuiltinsTypedArray(abcId, jsType, onHeap, everOutOfBounds);
18204514f5e3Sopenharmony_ci        PGOObjectInfo info(profileType);
18214514f5e3Sopenharmony_ci        recordInfos_->AddObjectInfo(recordType, methodId, bcOffset, info);
18224514f5e3Sopenharmony_ci    } else {
18234514f5e3Sopenharmony_ci        auto type = receiver->GetObjectType();
18244514f5e3Sopenharmony_ci        PGOObjectInfo info(ProfileType::CreateBuiltins(abcId, type));
18254514f5e3Sopenharmony_ci        recordInfos_->AddObjectInfo(recordType, methodId, bcOffset, info);
18264514f5e3Sopenharmony_ci    }
18274514f5e3Sopenharmony_ci    return true;
18284514f5e3Sopenharmony_ci}
18294514f5e3Sopenharmony_ci
18304514f5e3Sopenharmony_cibool PGOProfiler::IsRecoredTransRootType(ProfileType type)
18314514f5e3Sopenharmony_ci{
18324514f5e3Sopenharmony_ci    if (!type.IsRootType() || !type.IsTransitionType()) {
18334514f5e3Sopenharmony_ci        return false;
18344514f5e3Sopenharmony_ci    }
18354514f5e3Sopenharmony_ci    if (std::find(recordedTransRootType_.begin(), recordedTransRootType_.end(), type) != recordedTransRootType_.end()) {
18364514f5e3Sopenharmony_ci        LOG_ECMA(DEBUG) << "forbide to add more than 1 hclass for a root type!";
18374514f5e3Sopenharmony_ci        return true;
18384514f5e3Sopenharmony_ci    }
18394514f5e3Sopenharmony_ci    recordedTransRootType_.emplace_back(type);
18404514f5e3Sopenharmony_ci    return false;
18414514f5e3Sopenharmony_ci}
18424514f5e3Sopenharmony_ci
18434514f5e3Sopenharmony_civoid PGOProfiler::SetRootProfileType(JSHClass *root, ApEntityId abcId, uint32_t type, ProfileType::Kind kind)
18444514f5e3Sopenharmony_ci{
18454514f5e3Sopenharmony_ci    ProfileType traceType(root->GetProfileType());
18464514f5e3Sopenharmony_ci    if (traceType.IsNone()) {
18474514f5e3Sopenharmony_ci        traceType = ProfileType(abcId, type, kind, true);
18484514f5e3Sopenharmony_ci        if (IsRecoredTransRootType(traceType)) {
18494514f5e3Sopenharmony_ci            return;
18504514f5e3Sopenharmony_ci        }
18514514f5e3Sopenharmony_ci        root->SetProfileType(traceType.GetRaw());
18524514f5e3Sopenharmony_ci    }
18534514f5e3Sopenharmony_ci}
18544514f5e3Sopenharmony_ci
18554514f5e3Sopenharmony_ciProfileType PGOProfiler::FindRootProfileType(JSHClass *hclass)
18564514f5e3Sopenharmony_ci{
18574514f5e3Sopenharmony_ci    auto rootHClass = JSHClass::FindRootHClass(hclass);
18584514f5e3Sopenharmony_ci    return GetProfileType(rootHClass, true);
18594514f5e3Sopenharmony_ci}
18604514f5e3Sopenharmony_ci
18614514f5e3Sopenharmony_ciProfileType PGOProfiler::GetOrInsertProfileType(JSHClass *child, ProfileType rootType)
18624514f5e3Sopenharmony_ci{
18634514f5e3Sopenharmony_ci    ProfileType childType = GetProfileType(child);
18644514f5e3Sopenharmony_ci    if (childType.IsNone()) {
18654514f5e3Sopenharmony_ci        ASSERT(rootType.IsRootType());
18664514f5e3Sopenharmony_ci        childType = PGOTypeGenerator::GenerateProfileType(JSTaggedType(child), rootType);
18674514f5e3Sopenharmony_ci        child->SetProfileType(childType.GetRaw());
18684514f5e3Sopenharmony_ci    }
18694514f5e3Sopenharmony_ci    return childType;
18704514f5e3Sopenharmony_ci}
18714514f5e3Sopenharmony_ci
18724514f5e3Sopenharmony_ciProfileType PGOProfiler::GetProfileType(JSHClass *hclass, bool check)
18734514f5e3Sopenharmony_ci{
18744514f5e3Sopenharmony_ci    auto result = ProfileType(hclass->GetProfileType());
18754514f5e3Sopenharmony_ci    if (check) {
18764514f5e3Sopenharmony_ci        if (IsSkippableObjectTypeSafe(result)) {
18774514f5e3Sopenharmony_ci            result = ProfileType::PROFILE_TYPE_NONE;
18784514f5e3Sopenharmony_ci        }
18794514f5e3Sopenharmony_ci    }
18804514f5e3Sopenharmony_ci    return result;
18814514f5e3Sopenharmony_ci}
18824514f5e3Sopenharmony_ci
18834514f5e3Sopenharmony_civoid PGOProfiler::ProcessReferences(const WeakRootVisitor &visitor)
18844514f5e3Sopenharmony_ci{
18854514f5e3Sopenharmony_ci    if (!isEnable_) {
18864514f5e3Sopenharmony_ci        return;
18874514f5e3Sopenharmony_ci    }
18884514f5e3Sopenharmony_ci    preDumpWorkList_.Iterate([this, &visitor](WorkNode *node) {
18894514f5e3Sopenharmony_ci        auto object = reinterpret_cast<TaggedObject *>(node->GetValue());
18904514f5e3Sopenharmony_ci        auto fwd = visitor(object);
18914514f5e3Sopenharmony_ci        if (fwd == nullptr) {
18924514f5e3Sopenharmony_ci            preDumpWorkList_.Remove(node);
18934514f5e3Sopenharmony_ci            nativeAreaAllocator_->Delete(node);
18944514f5e3Sopenharmony_ci            return;
18954514f5e3Sopenharmony_ci        }
18964514f5e3Sopenharmony_ci        if (fwd != object) {
18974514f5e3Sopenharmony_ci            node->SetValue(JSTaggedType(fwd));
18984514f5e3Sopenharmony_ci        }
18994514f5e3Sopenharmony_ci    });
19004514f5e3Sopenharmony_ci}
19014514f5e3Sopenharmony_ci
19024514f5e3Sopenharmony_civoid PGOProfiler::Iterate(const RootVisitor &visitor)
19034514f5e3Sopenharmony_ci{
19044514f5e3Sopenharmony_ci    if (!isEnable_) {
19054514f5e3Sopenharmony_ci        return;
19064514f5e3Sopenharmony_ci    }
19074514f5e3Sopenharmony_ci    // If the IC of the method is stable, the current design forces the dump data.
19084514f5e3Sopenharmony_ci    // Must pause dump during GC.
19094514f5e3Sopenharmony_ci    dumpWorkList_.Iterate([&visitor](WorkNode* node) {
19104514f5e3Sopenharmony_ci        visitor(Root::ROOT_VM, ObjectSlot(node->GetValueAddr()));
19114514f5e3Sopenharmony_ci    });
19124514f5e3Sopenharmony_ci}
19134514f5e3Sopenharmony_ci
19144514f5e3Sopenharmony_ciPGOProfiler::PGOProfiler(EcmaVM* vm, bool isEnable)
19154514f5e3Sopenharmony_ci    : nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()), vm_(vm), isEnable_(isEnable)
19164514f5e3Sopenharmony_ci{
19174514f5e3Sopenharmony_ci    if (isEnable_) {
19184514f5e3Sopenharmony_ci        recordInfos_ = std::make_unique<PGORecordDetailInfos>(0);
19194514f5e3Sopenharmony_ci    }
19204514f5e3Sopenharmony_ci};
19214514f5e3Sopenharmony_ci
19224514f5e3Sopenharmony_ciPGOProfiler::~PGOProfiler()
19234514f5e3Sopenharmony_ci{
19244514f5e3Sopenharmony_ci    Reset(false);
19254514f5e3Sopenharmony_ci}
19264514f5e3Sopenharmony_ci
19274514f5e3Sopenharmony_civoid PGOProfiler::Reset(bool isEnable)
19284514f5e3Sopenharmony_ci{
19294514f5e3Sopenharmony_ci    LockHolder lock(recordInfoMutex_);
19304514f5e3Sopenharmony_ci    isEnable_ = isEnable;
19314514f5e3Sopenharmony_ci    methodCount_ = 0;
19324514f5e3Sopenharmony_ci    if (recordInfos_) {
19334514f5e3Sopenharmony_ci        recordInfos_->Clear();
19344514f5e3Sopenharmony_ci    } else {
19354514f5e3Sopenharmony_ci        if (isEnable_) {
19364514f5e3Sopenharmony_ci            recordInfos_ = std::make_unique<PGORecordDetailInfos>(0);
19374514f5e3Sopenharmony_ci        }
19384514f5e3Sopenharmony_ci    }
19394514f5e3Sopenharmony_ci}
19404514f5e3Sopenharmony_ci
19414514f5e3Sopenharmony_ciApEntityId PGOProfiler::GetMethodAbcId(JSTaggedValue jsMethod)
19424514f5e3Sopenharmony_ci{
19434514f5e3Sopenharmony_ci    ASSERT(jsMethod.IsMethod());
19444514f5e3Sopenharmony_ci    CString pfName;
19454514f5e3Sopenharmony_ci
19464514f5e3Sopenharmony_ci    const auto *pf = Method::Cast(jsMethod)->GetJSPandaFile();
19474514f5e3Sopenharmony_ci    if (pf != nullptr) {
19484514f5e3Sopenharmony_ci        pfName = pf->GetJSPandaFileDesc();
19494514f5e3Sopenharmony_ci    }
19504514f5e3Sopenharmony_ci    ApEntityId abcId(0);
19514514f5e3Sopenharmony_ci    if (!PGOProfilerManager::GetInstance()->GetPandaFileId(pfName, abcId) && !pfName.empty()) {
19524514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "Get method abc id failed. abcName: " << pfName;
19534514f5e3Sopenharmony_ci    }
19544514f5e3Sopenharmony_ci    return abcId;
19554514f5e3Sopenharmony_ci}
19564514f5e3Sopenharmony_ciApEntityId PGOProfiler::GetMethodAbcId(JSFunction *jsFunction)
19574514f5e3Sopenharmony_ci{
19584514f5e3Sopenharmony_ci    CString pfName;
19594514f5e3Sopenharmony_ci    auto jsMethod = jsFunction->GetMethod();
19604514f5e3Sopenharmony_ci    if (jsMethod.IsMethod()) {
19614514f5e3Sopenharmony_ci        return GetMethodAbcId(jsMethod);
19624514f5e3Sopenharmony_ci    }
19634514f5e3Sopenharmony_ci    LOG_ECMA(ERROR) << "Get method abc id failed. Not a method.";
19644514f5e3Sopenharmony_ci    UNREACHABLE();
19654514f5e3Sopenharmony_ci}
19664514f5e3Sopenharmony_ci
19674514f5e3Sopenharmony_ciProfileType PGOProfiler::GetRecordProfileType(JSFunction *jsFunction, const CString &recordName)
19684514f5e3Sopenharmony_ci{
19694514f5e3Sopenharmony_ci    CString pfName;
19704514f5e3Sopenharmony_ci    auto jsMethod = jsFunction->GetMethod();
19714514f5e3Sopenharmony_ci    if (jsMethod.IsMethod()) {
19724514f5e3Sopenharmony_ci        const auto *pf = Method::Cast(jsMethod)->GetJSPandaFile();
19734514f5e3Sopenharmony_ci        if (pf != nullptr) {
19744514f5e3Sopenharmony_ci            pfName = pf->GetJSPandaFileDesc();
19754514f5e3Sopenharmony_ci        }
19764514f5e3Sopenharmony_ci    }
19774514f5e3Sopenharmony_ci    const auto &pf = JSPandaFileManager::GetInstance()->FindJSPandaFile(pfName);
19784514f5e3Sopenharmony_ci    if (pf == nullptr) {
19794514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "Get record profile type failed. pf is null, pfName: " << pfName
19804514f5e3Sopenharmony_ci                        << ", recordName: " << recordName;
19814514f5e3Sopenharmony_ci        return ProfileType::PROFILE_TYPE_NONE;
19824514f5e3Sopenharmony_ci    }
19834514f5e3Sopenharmony_ci    return GetRecordProfileType(pf, GetMethodAbcId(jsFunction), recordName);
19844514f5e3Sopenharmony_ci}
19854514f5e3Sopenharmony_ci
19864514f5e3Sopenharmony_ciProfileType PGOProfiler::GetRecordProfileType(ApEntityId abcId, const CString &recordName)
19874514f5e3Sopenharmony_ci{
19884514f5e3Sopenharmony_ci    CString pfDesc;
19894514f5e3Sopenharmony_ci    PGOProfilerManager::GetInstance()->GetPandaFileDesc(abcId, pfDesc);
19904514f5e3Sopenharmony_ci    const auto &pf = JSPandaFileManager::GetInstance()->FindJSPandaFile(pfDesc);
19914514f5e3Sopenharmony_ci    if (pf == nullptr) {
19924514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "Get record profile type failed. pf is null, pfDesc: " << pfDesc
19934514f5e3Sopenharmony_ci                        << ", recordName: " << recordName;
19944514f5e3Sopenharmony_ci        return ProfileType::PROFILE_TYPE_NONE;
19954514f5e3Sopenharmony_ci    }
19964514f5e3Sopenharmony_ci    return GetRecordProfileType(pf, abcId, recordName);
19974514f5e3Sopenharmony_ci}
19984514f5e3Sopenharmony_ci
19994514f5e3Sopenharmony_ciProfileType PGOProfiler::GetRecordProfileType(const std::shared_ptr<JSPandaFile> &pf, ApEntityId abcId,
20004514f5e3Sopenharmony_ci                                              const CString &recordName)
20014514f5e3Sopenharmony_ci{
20024514f5e3Sopenharmony_ci    ASSERT(pf != nullptr);
20034514f5e3Sopenharmony_ci    JSRecordInfo *recordInfo = nullptr;
20044514f5e3Sopenharmony_ci    bool hasRecord = pf->CheckAndGetRecordInfo(recordName, &recordInfo);
20054514f5e3Sopenharmony_ci    if (!hasRecord) {
20064514f5e3Sopenharmony_ci        LOG_ECMA(ERROR) << "Get recordInfo failed. recordName: " << recordName;
20074514f5e3Sopenharmony_ci        return ProfileType::PROFILE_TYPE_NONE;
20084514f5e3Sopenharmony_ci    }
20094514f5e3Sopenharmony_ci    ProfileType recordType {0};
20104514f5e3Sopenharmony_ci    if (pf->IsBundlePack()) {
20114514f5e3Sopenharmony_ci        recordType = CreateRecordProfileType(abcId, ProfileType::RECORD_ID_FOR_BUNDLE);
20124514f5e3Sopenharmony_ci        recordInfos_->GetRecordPool()->Add(recordType, recordName);
20134514f5e3Sopenharmony_ci        return recordType;
20144514f5e3Sopenharmony_ci    }
20154514f5e3Sopenharmony_ci    if (recordInfo->classId != JSPandaFile::CLASSID_OFFSET_NOT_FOUND) {
20164514f5e3Sopenharmony_ci        recordType = CreateRecordProfileType(abcId, recordInfo->classId);
20174514f5e3Sopenharmony_ci        recordInfos_->GetRecordPool()->Add(recordType, recordName);
20184514f5e3Sopenharmony_ci        return recordType;
20194514f5e3Sopenharmony_ci    }
20204514f5e3Sopenharmony_ci    LOG_ECMA(ERROR) << "Invalid classId, skip it. recordName: " << recordName << ", isCjs: " << recordInfo->isCjs
20214514f5e3Sopenharmony_ci                    << ", isJson: " << recordInfo->isJson;
20224514f5e3Sopenharmony_ci    return ProfileType::PROFILE_TYPE_NONE;
20234514f5e3Sopenharmony_ci}
20244514f5e3Sopenharmony_ci
20254514f5e3Sopenharmony_civoid PGOProfiler::WorkList::PushBack(WorkNode *node)
20264514f5e3Sopenharmony_ci{
20274514f5e3Sopenharmony_ci    if (node == nullptr) {
20284514f5e3Sopenharmony_ci        LOG_ECMA(FATAL) << "PGOProfiler::WorkList::PushBack:node is nullptr";
20294514f5e3Sopenharmony_ci        UNREACHABLE();
20304514f5e3Sopenharmony_ci    }
20314514f5e3Sopenharmony_ci    if (last_ == nullptr) {
20324514f5e3Sopenharmony_ci        first_ = node;
20334514f5e3Sopenharmony_ci        last_ = node;
20344514f5e3Sopenharmony_ci    } else {
20354514f5e3Sopenharmony_ci        last_->SetNext(node);
20364514f5e3Sopenharmony_ci        node->SetPrev(last_);
20374514f5e3Sopenharmony_ci        last_ = node;
20384514f5e3Sopenharmony_ci    }
20394514f5e3Sopenharmony_ci    node->SetWorkList(this);
20404514f5e3Sopenharmony_ci}
20414514f5e3Sopenharmony_ci
20424514f5e3Sopenharmony_ciPGOProfiler::WorkNode *PGOProfiler::WorkList::PopFront()
20434514f5e3Sopenharmony_ci{
20444514f5e3Sopenharmony_ci    WorkNode *result = nullptr;
20454514f5e3Sopenharmony_ci    if (first_ != nullptr) {
20464514f5e3Sopenharmony_ci        result = first_;
20474514f5e3Sopenharmony_ci        if (first_->GetNext() != nullptr) {
20484514f5e3Sopenharmony_ci            first_ = first_->GetNext();
20494514f5e3Sopenharmony_ci            first_->SetPrev(nullptr);
20504514f5e3Sopenharmony_ci        } else {
20514514f5e3Sopenharmony_ci            first_ = nullptr;
20524514f5e3Sopenharmony_ci            last_ = nullptr;
20534514f5e3Sopenharmony_ci        }
20544514f5e3Sopenharmony_ci        result->SetNext(nullptr);
20554514f5e3Sopenharmony_ci        result->SetWorkList(nullptr);
20564514f5e3Sopenharmony_ci    }
20574514f5e3Sopenharmony_ci    return result;
20584514f5e3Sopenharmony_ci}
20594514f5e3Sopenharmony_ci
20604514f5e3Sopenharmony_civoid PGOProfiler::WorkList::Remove(WorkNode *node)
20614514f5e3Sopenharmony_ci{
20624514f5e3Sopenharmony_ci    if (node->GetPrev() != nullptr) {
20634514f5e3Sopenharmony_ci        node->GetPrev()->SetNext(node->GetNext());
20644514f5e3Sopenharmony_ci    }
20654514f5e3Sopenharmony_ci    if (node->GetNext() != nullptr) {
20664514f5e3Sopenharmony_ci        node->GetNext()->SetPrev(node->GetPrev());
20674514f5e3Sopenharmony_ci    }
20684514f5e3Sopenharmony_ci    if (node == first_) {
20694514f5e3Sopenharmony_ci        first_ = node->GetNext();
20704514f5e3Sopenharmony_ci    }
20714514f5e3Sopenharmony_ci    if (node == last_) {
20724514f5e3Sopenharmony_ci        last_ = node->GetPrev();
20734514f5e3Sopenharmony_ci    }
20744514f5e3Sopenharmony_ci    node->SetPrev(nullptr);
20754514f5e3Sopenharmony_ci    node->SetNext(nullptr);
20764514f5e3Sopenharmony_ci    node->SetWorkList(nullptr);
20774514f5e3Sopenharmony_ci}
20784514f5e3Sopenharmony_ci
20794514f5e3Sopenharmony_civoid PGOProfiler::WorkList::Iterate(Callback callback) const
20804514f5e3Sopenharmony_ci{
20814514f5e3Sopenharmony_ci    auto current = first_;
20824514f5e3Sopenharmony_ci    while (current != nullptr) {
20834514f5e3Sopenharmony_ci        auto next = current->GetNext();
20844514f5e3Sopenharmony_ci        callback(current);
20854514f5e3Sopenharmony_ci        current = next;
20864514f5e3Sopenharmony_ci    }
20874514f5e3Sopenharmony_ci}
20884514f5e3Sopenharmony_ci
20894514f5e3Sopenharmony_ciProfileType PGOProfiler::CreateRecordProfileType(ApEntityId abcId, ApEntityId classId)
20904514f5e3Sopenharmony_ci{
20914514f5e3Sopenharmony_ci    return {abcId, classId, ProfileType::Kind::RecordClassId};
20924514f5e3Sopenharmony_ci}
20934514f5e3Sopenharmony_ci
20944514f5e3Sopenharmony_ciJSTaggedValue PGOProfiler::TryFindKeyInPrototypeChain(TaggedObject *currObj, JSHClass *currHC, JSTaggedValue key)
20954514f5e3Sopenharmony_ci{
20964514f5e3Sopenharmony_ci    // This is a temporary solution for Instanceof Only!
20974514f5e3Sopenharmony_ci    // Do NOT use this function for other purpose.
20984514f5e3Sopenharmony_ci    if (currHC->IsDictionaryMode()) {
20994514f5e3Sopenharmony_ci        return JSTaggedValue(currHC);
21004514f5e3Sopenharmony_ci    }
21014514f5e3Sopenharmony_ci    while (!JSTaggedValue(currHC).IsUndefinedOrNull()) {
21024514f5e3Sopenharmony_ci        if (LIKELY(!currHC->IsDictionaryMode())) {
21034514f5e3Sopenharmony_ci            int entry = JSHClass::FindPropertyEntry(vm_->GetJSThread(), currHC, key);
21044514f5e3Sopenharmony_ci            if (entry != -1) {
21054514f5e3Sopenharmony_ci                return JSTaggedValue(currHC);
21064514f5e3Sopenharmony_ci            }
21074514f5e3Sopenharmony_ci        } else {
21084514f5e3Sopenharmony_ci            TaggedArray *array = TaggedArray::Cast(JSObject::Cast(currObj)->GetProperties().GetTaggedObject());
21094514f5e3Sopenharmony_ci            ASSERT(array->IsDictionaryMode());
21104514f5e3Sopenharmony_ci            NameDictionary *dict = NameDictionary::Cast(array);
21114514f5e3Sopenharmony_ci            int entry = dict->FindEntry(key);
21124514f5e3Sopenharmony_ci            if (entry != -1) {
21134514f5e3Sopenharmony_ci                return JSTaggedValue(currHC);
21144514f5e3Sopenharmony_ci            }
21154514f5e3Sopenharmony_ci        }
21164514f5e3Sopenharmony_ci        currObj = currHC->GetProto().GetTaggedObject();
21174514f5e3Sopenharmony_ci        if (JSTaggedValue(currObj).IsUndefinedOrNull()) {
21184514f5e3Sopenharmony_ci            break;
21194514f5e3Sopenharmony_ci        }
21204514f5e3Sopenharmony_ci        currHC = currObj->GetClass();
21214514f5e3Sopenharmony_ci    }
21224514f5e3Sopenharmony_ci    return JSTaggedValue::Undefined();
21234514f5e3Sopenharmony_ci}
21244514f5e3Sopenharmony_civoid PGOProfiler::InitJITProfiler()
21254514f5e3Sopenharmony_ci{
21264514f5e3Sopenharmony_ci    jitProfiler_ = new JITProfiler(vm_);
21274514f5e3Sopenharmony_ci    jitProfiler_->InitJITProfiler();
21284514f5e3Sopenharmony_ci}
21294514f5e3Sopenharmony_ci
21304514f5e3Sopenharmony_ci} // namespace panda::ecmascript::pgo
2131