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/compiler/profiler_stub_builder.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/base/number_helper.h"
194514f5e3Sopenharmony_ci#include "ecmascript/compiler/circuit_builder_helper.h"
204514f5e3Sopenharmony_ci#include "ecmascript/compiler/rt_call_signature.h"
214514f5e3Sopenharmony_ci#include "ecmascript/compiler/share_gate_meta_data.h"
224514f5e3Sopenharmony_ci#include "ecmascript/compiler/interpreter_stub-inl.h"
234514f5e3Sopenharmony_ci#include "ecmascript/compiler/stub_builder.h"
244514f5e3Sopenharmony_ci#include "ecmascript/compiler/stub_builder-inl.h"
254514f5e3Sopenharmony_ci#include "ecmascript/compiler/variable_type.h"
264514f5e3Sopenharmony_ci#include "ecmascript/ic/profile_type_info.h"
274514f5e3Sopenharmony_ci
284514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
294514f5e3Sopenharmony_civoid ProfilerStubBuilder::PGOProfiler(GateRef glue, GateRef pc, GateRef func, GateRef profileTypeInfo,
304514f5e3Sopenharmony_ci    const std::vector<GateRef> &values, SlotIDFormat format, OperationType type)
314514f5e3Sopenharmony_ci{
324514f5e3Sopenharmony_ci    if (type == OperationType::TRUE_BRANCH ||
334514f5e3Sopenharmony_ci        type == OperationType::FALSE_BRANCH ||
344514f5e3Sopenharmony_ci        type == OperationType::TRY_JIT) {
354514f5e3Sopenharmony_ci        SlotIDInfo slotIdInfo(pc, SlotIDInfo::SlotIDInfoType::PC);
364514f5e3Sopenharmony_ci        PGOProfiler(glue, func, profileTypeInfo, slotIdInfo, values, type);
374514f5e3Sopenharmony_ci    } else {
384514f5e3Sopenharmony_ci        SlotIDInfo slotIdInfo(pc, format);
394514f5e3Sopenharmony_ci        PGOProfiler(glue, func, profileTypeInfo, slotIdInfo, values, type);
404514f5e3Sopenharmony_ci    }
414514f5e3Sopenharmony_ci}
424514f5e3Sopenharmony_ci
434514f5e3Sopenharmony_civoid ProfilerStubBuilder::PGOProfiler(GateRef glue, GateRef func, GateRef profileTypeInfo,
444514f5e3Sopenharmony_ci    GateRef slotId, const std::vector<GateRef> &values, OperationType type)
454514f5e3Sopenharmony_ci{
464514f5e3Sopenharmony_ci    SlotIDInfo slotIdInfo(slotId, SlotIDInfo::SlotIDInfoType::SLOT_ID);
474514f5e3Sopenharmony_ci    PGOProfiler(glue, func, profileTypeInfo, slotIdInfo, values, type);
484514f5e3Sopenharmony_ci}
494514f5e3Sopenharmony_ci
504514f5e3Sopenharmony_civoid ProfilerStubBuilder::TryDump(GateRef glue, GateRef func, GateRef profileTypeInfo)
514514f5e3Sopenharmony_ci{
524514f5e3Sopenharmony_ci    auto env = GetEnvironment();
534514f5e3Sopenharmony_ci    Label subEntry(env);
544514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
554514f5e3Sopenharmony_ci
564514f5e3Sopenharmony_ci    Label updatePeriodCounter(env);
574514f5e3Sopenharmony_ci    Label exit(env);
584514f5e3Sopenharmony_ci    Label needDump(env);
594514f5e3Sopenharmony_ci
604514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoWithBigMethod(profileTypeInfo), &exit, &needDump);
614514f5e3Sopenharmony_ci    Bind(&needDump);
624514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoDumped(profileTypeInfo), &exit, &updatePeriodCounter);
634514f5e3Sopenharmony_ci    Bind(&updatePeriodCounter);
644514f5e3Sopenharmony_ci    {
654514f5e3Sopenharmony_ci        SetDumpPeriodIndex(glue, profileTypeInfo);
664514f5e3Sopenharmony_ci        CallRuntime(glue, RTSTUB_ID(PGODump), { func });
674514f5e3Sopenharmony_ci        Jump(&exit);
684514f5e3Sopenharmony_ci    }
694514f5e3Sopenharmony_ci    Bind(&exit);
704514f5e3Sopenharmony_ci    env->SubCfgExit();
714514f5e3Sopenharmony_ci}
724514f5e3Sopenharmony_ci
734514f5e3Sopenharmony_civoid ProfilerStubBuilder::TryPreDump(GateRef glue, GateRef func, GateRef profileTypeInfo)
744514f5e3Sopenharmony_ci{
754514f5e3Sopenharmony_ci    auto env = GetEnvironment();
764514f5e3Sopenharmony_ci    Label subEntry(env);
774514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
784514f5e3Sopenharmony_ci    Label exit(env);
794514f5e3Sopenharmony_ci    Label profiler(env);
804514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &profiler, &exit);
814514f5e3Sopenharmony_ci    Bind(&profiler);
824514f5e3Sopenharmony_ci    {
834514f5e3Sopenharmony_ci        TryPreDumpInner(glue, func, profileTypeInfo);
844514f5e3Sopenharmony_ci        Jump(&exit);
854514f5e3Sopenharmony_ci    }
864514f5e3Sopenharmony_ci    Bind(&exit);
874514f5e3Sopenharmony_ci    env->SubCfgExit();
884514f5e3Sopenharmony_ci}
894514f5e3Sopenharmony_ci
904514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileOpType(
914514f5e3Sopenharmony_ci    GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef profileTypeInfo, GateRef type)
924514f5e3Sopenharmony_ci{
934514f5e3Sopenharmony_ci    auto env = GetEnvironment();
944514f5e3Sopenharmony_ci    Label subEntry(env);
954514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
964514f5e3Sopenharmony_ci
974514f5e3Sopenharmony_ci    Label exit(env);
984514f5e3Sopenharmony_ci    Label profiler(env);
994514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &profiler, &exit);
1004514f5e3Sopenharmony_ci    Bind(&profiler);
1014514f5e3Sopenharmony_ci    {
1024514f5e3Sopenharmony_ci        Label icSlotValid(env);
1034514f5e3Sopenharmony_ci        Label uninitialized(env);
1044514f5e3Sopenharmony_ci        Label compareLabel(env);
1054514f5e3Sopenharmony_ci        Label updateSlot(env);
1064514f5e3Sopenharmony_ci
1074514f5e3Sopenharmony_ci        GateRef slotId = GetSlotID(slotInfo);
1084514f5e3Sopenharmony_ci        GateRef length = GetLengthOfTaggedArray(profileTypeInfo);
1094514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(slotId, length), &icSlotValid, &exit);
1104514f5e3Sopenharmony_ci        Bind(&icSlotValid);
1114514f5e3Sopenharmony_ci        GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId);
1124514f5e3Sopenharmony_ci        DEFVARIABLE(curTaggedSlotValue, VariableType::INT64(), type);
1134514f5e3Sopenharmony_ci        BRANCH(TaggedIsInt(slotValue), &compareLabel, &uninitialized);
1144514f5e3Sopenharmony_ci        Bind(&compareLabel);
1154514f5e3Sopenharmony_ci        {
1164514f5e3Sopenharmony_ci            GateRef oldTaggedSlotValue = ChangeTaggedPointerToInt64(slotValue);
1174514f5e3Sopenharmony_ci            curTaggedSlotValue = Int64Or(oldTaggedSlotValue, type);
1184514f5e3Sopenharmony_ci            BRANCH(Int64Equal(oldTaggedSlotValue, *curTaggedSlotValue), &exit, &updateSlot);
1194514f5e3Sopenharmony_ci        }
1204514f5e3Sopenharmony_ci        Bind(&uninitialized);
1214514f5e3Sopenharmony_ci        {
1224514f5e3Sopenharmony_ci            // Only when slot value is undefined, it means uninitialized, so we need to update the slot.
1234514f5e3Sopenharmony_ci            // When the slot value is hole, it means slot is overflow (0xff). Otherwise, do nothing.
1244514f5e3Sopenharmony_ci            BRANCH(TaggedIsUndefined(slotValue), &updateSlot, &exit);
1254514f5e3Sopenharmony_ci        }
1264514f5e3Sopenharmony_ci        Bind(&updateSlot);
1274514f5e3Sopenharmony_ci        {
1284514f5e3Sopenharmony_ci            SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, *curTaggedSlotValue);
1294514f5e3Sopenharmony_ci            TryPreDumpInner(glue, func, profileTypeInfo);
1304514f5e3Sopenharmony_ci            Jump(&exit);
1314514f5e3Sopenharmony_ci        }
1324514f5e3Sopenharmony_ci    }
1334514f5e3Sopenharmony_ci    Bind(&exit);
1344514f5e3Sopenharmony_ci    env->SubCfgExit();
1354514f5e3Sopenharmony_ci}
1364514f5e3Sopenharmony_ci
1374514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileDefineClass(
1384514f5e3Sopenharmony_ci    GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef constructor, GateRef profileTypeInfo)
1394514f5e3Sopenharmony_ci{
1404514f5e3Sopenharmony_ci    auto env = GetEnvironment();
1414514f5e3Sopenharmony_ci    Label subEntry(env);
1424514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
1434514f5e3Sopenharmony_ci
1444514f5e3Sopenharmony_ci    Label exit(env);
1454514f5e3Sopenharmony_ci    Label profiler(env);
1464514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &profiler, &exit);
1474514f5e3Sopenharmony_ci    Bind(&profiler);
1484514f5e3Sopenharmony_ci    {
1494514f5e3Sopenharmony_ci        Label icSlotValid(env);
1504514f5e3Sopenharmony_ci        Label updateSlot(env);
1514514f5e3Sopenharmony_ci        Label isHeapObject(env);
1524514f5e3Sopenharmony_ci        Label isProfileTypeInfoCell0(env);
1534514f5e3Sopenharmony_ci
1544514f5e3Sopenharmony_ci        GateRef slotId = GetSlotID(slotInfo);
1554514f5e3Sopenharmony_ci        GateRef length = GetLengthOfTaggedArray(profileTypeInfo);
1564514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(slotId, length), &icSlotValid, &exit);
1574514f5e3Sopenharmony_ci        Bind(&icSlotValid);
1584514f5e3Sopenharmony_ci        GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId);
1594514f5e3Sopenharmony_ci        Branch(TaggedIsHeapObject(slotValue), &isHeapObject, &exit);
1604514f5e3Sopenharmony_ci        Bind(&isHeapObject);
1614514f5e3Sopenharmony_ci        Branch(IsProfileTypeInfoCell0(slotValue), &isProfileTypeInfoCell0, &exit);
1624514f5e3Sopenharmony_ci        Bind(&isProfileTypeInfoCell0);
1634514f5e3Sopenharmony_ci        GateRef handleOffset = IntPtr(ProfileTypeInfoCell::HANDLE_OFFSET);
1644514f5e3Sopenharmony_ci        GateRef handle = Load(VariableType::JS_ANY(), slotValue, handleOffset);
1654514f5e3Sopenharmony_ci        BRANCH(TaggedIsUndefined(handle), &updateSlot, &exit);
1664514f5e3Sopenharmony_ci        Bind(&updateSlot);
1674514f5e3Sopenharmony_ci        auto weakCtor = env->GetBuilder()->CreateWeakRef(constructor);
1684514f5e3Sopenharmony_ci        Store(VariableType::JS_POINTER(), glue, slotValue, handleOffset, weakCtor);
1694514f5e3Sopenharmony_ci        TryPreDumpInner(glue, func, profileTypeInfo);
1704514f5e3Sopenharmony_ci        Jump(&exit);
1714514f5e3Sopenharmony_ci    }
1724514f5e3Sopenharmony_ci    Bind(&exit);
1734514f5e3Sopenharmony_ci    env->SubCfgExit();
1744514f5e3Sopenharmony_ci}
1754514f5e3Sopenharmony_ci
1764514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileCreateObject(
1774514f5e3Sopenharmony_ci    GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef newObj, GateRef profileTypeInfo)
1784514f5e3Sopenharmony_ci{
1794514f5e3Sopenharmony_ci    auto env = GetEnvironment();
1804514f5e3Sopenharmony_ci    Label subEntry(env);
1814514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
1824514f5e3Sopenharmony_ci    Label exit(env);
1834514f5e3Sopenharmony_ci
1844514f5e3Sopenharmony_ci    Label profiler(env);
1854514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &profiler, &exit);
1864514f5e3Sopenharmony_ci    Bind(&profiler);
1874514f5e3Sopenharmony_ci    {
1884514f5e3Sopenharmony_ci        Label icSlotValid(env);
1894514f5e3Sopenharmony_ci        Label isHeapObject(env);
1904514f5e3Sopenharmony_ci        Label isWeak(env);
1914514f5e3Sopenharmony_ci        Label uninitialized(env);
1924514f5e3Sopenharmony_ci        Label updateSlot(env);
1934514f5e3Sopenharmony_ci
1944514f5e3Sopenharmony_ci        GateRef slotId = GetSlotID(slotInfo);
1954514f5e3Sopenharmony_ci        GateRef length = GetLengthOfTaggedArray(profileTypeInfo);
1964514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(slotId, length), &icSlotValid, &exit);
1974514f5e3Sopenharmony_ci        Bind(&icSlotValid);
1984514f5e3Sopenharmony_ci        auto hclass = LoadHClass(newObj);
1994514f5e3Sopenharmony_ci        GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId);
2004514f5e3Sopenharmony_ci        BRANCH(TaggedIsHeapObject(slotValue), &isHeapObject, &uninitialized);
2014514f5e3Sopenharmony_ci        Bind(&isHeapObject);
2024514f5e3Sopenharmony_ci        {
2034514f5e3Sopenharmony_ci            BRANCH(TaggedIsWeak(slotValue), &isWeak, &updateSlot);
2044514f5e3Sopenharmony_ci        }
2054514f5e3Sopenharmony_ci        Bind(&isWeak);
2064514f5e3Sopenharmony_ci        {
2074514f5e3Sopenharmony_ci            auto cachedHClass = LoadObjectFromWeakRef(slotValue);
2084514f5e3Sopenharmony_ci            BRANCH(Equal(cachedHClass, hclass), &exit, &updateSlot);
2094514f5e3Sopenharmony_ci        }
2104514f5e3Sopenharmony_ci        Bind(&uninitialized);
2114514f5e3Sopenharmony_ci        {
2124514f5e3Sopenharmony_ci            // Only when slot value is undefined, it means uninitialized, so we need to update the slot.
2134514f5e3Sopenharmony_ci            // When the slot value is hole, it means slot is overflow (0xff). Otherwise, do nothing.
2144514f5e3Sopenharmony_ci            BRANCH(TaggedIsUndefined(slotValue), &updateSlot, &exit);
2154514f5e3Sopenharmony_ci        }
2164514f5e3Sopenharmony_ci        Bind(&updateSlot);
2174514f5e3Sopenharmony_ci        {
2184514f5e3Sopenharmony_ci            auto weakCtor = env->GetBuilder()->CreateWeakRef(hclass);
2194514f5e3Sopenharmony_ci            SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, weakCtor);
2204514f5e3Sopenharmony_ci            TryPreDumpInner(glue, func, profileTypeInfo);
2214514f5e3Sopenharmony_ci            Jump(&exit);
2224514f5e3Sopenharmony_ci        }
2234514f5e3Sopenharmony_ci    }
2244514f5e3Sopenharmony_ci    Bind(&exit);
2254514f5e3Sopenharmony_ci    env->SubCfgExit();
2264514f5e3Sopenharmony_ci}
2274514f5e3Sopenharmony_ci
2284514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileCall(
2294514f5e3Sopenharmony_ci    GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef target, GateRef profileTypeInfo)
2304514f5e3Sopenharmony_ci{
2314514f5e3Sopenharmony_ci    auto env = GetEnvironment();
2324514f5e3Sopenharmony_ci    Label subEntry(env);
2334514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
2344514f5e3Sopenharmony_ci
2354514f5e3Sopenharmony_ci    Label exit(env);
2364514f5e3Sopenharmony_ci    Label slowPath(env);
2374514f5e3Sopenharmony_ci    Label fastPath(env);
2384514f5e3Sopenharmony_ci    Label targetIsFunction(env);
2394514f5e3Sopenharmony_ci
2404514f5e3Sopenharmony_ci    BRANCH(IsJSFunction(target), &targetIsFunction, &exit);
2414514f5e3Sopenharmony_ci    Bind(&targetIsFunction);
2424514f5e3Sopenharmony_ci    {
2434514f5e3Sopenharmony_ci        GateRef targetProfileInfo = GetProfileTypeInfo(target);
2444514f5e3Sopenharmony_ci        Label targetIsNotHot(env);
2454514f5e3Sopenharmony_ci        Label targetIsHot(env);
2464514f5e3Sopenharmony_ci        Label currentIsHot(env);
2474514f5e3Sopenharmony_ci        Label updateTargetIC(env);
2484514f5e3Sopenharmony_ci
2494514f5e3Sopenharmony_ci        BRANCH(IsEnableForceIC(glue), &updateTargetIC, &targetIsHot);
2504514f5e3Sopenharmony_ci        Bind(&updateTargetIC);
2514514f5e3Sopenharmony_ci        {
2524514f5e3Sopenharmony_ci            BRANCH(IsProfileTypeInfoHotAndValid(targetProfileInfo), &targetIsHot, &targetIsNotHot);
2534514f5e3Sopenharmony_ci            Bind(&targetIsNotHot);
2544514f5e3Sopenharmony_ci            {
2554514f5e3Sopenharmony_ci                CallRuntime(glue, RTSTUB_ID(UpdateHotnessCounterWithProf), { target });
2564514f5e3Sopenharmony_ci                Jump(&targetIsHot);
2574514f5e3Sopenharmony_ci            }
2584514f5e3Sopenharmony_ci        }
2594514f5e3Sopenharmony_ci        Bind(&targetIsHot);
2604514f5e3Sopenharmony_ci        {
2614514f5e3Sopenharmony_ci            BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &currentIsHot, &exit);
2624514f5e3Sopenharmony_ci        }
2634514f5e3Sopenharmony_ci        Bind(&currentIsHot);
2644514f5e3Sopenharmony_ci        {
2654514f5e3Sopenharmony_ci            Label icSlotValid(env);
2664514f5e3Sopenharmony_ci            Label isHeapObject(env);
2674514f5e3Sopenharmony_ci            Label uninitialized(env);
2684514f5e3Sopenharmony_ci            Label updateSlot(env);
2694514f5e3Sopenharmony_ci
2704514f5e3Sopenharmony_ci            GateRef slotId = GetSlotID(slotInfo);
2714514f5e3Sopenharmony_ci            GateRef length = GetLengthOfTaggedArray(profileTypeInfo);
2724514f5e3Sopenharmony_ci            BRANCH(Int32LessThan(slotId, length), &icSlotValid, &exit);
2734514f5e3Sopenharmony_ci            Bind(&icSlotValid);
2744514f5e3Sopenharmony_ci            GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId);
2754514f5e3Sopenharmony_ci            BRANCH(TaggedIsHeapObject(slotValue), &isHeapObject, &uninitialized);
2764514f5e3Sopenharmony_ci            Bind(&isHeapObject);
2774514f5e3Sopenharmony_ci            {
2784514f5e3Sopenharmony_ci                Label change(env);
2794514f5e3Sopenharmony_ci                Label resetSlot(env);
2804514f5e3Sopenharmony_ci                BRANCH(Int64Equal(slotValue, target), &exit, &change);
2814514f5e3Sopenharmony_ci                Bind(&change);
2824514f5e3Sopenharmony_ci                {
2834514f5e3Sopenharmony_ci                    BRANCH(Int64Equal(ChangeTaggedPointerToInt64(slotValue), Int64(0)), &exit, &resetSlot);
2844514f5e3Sopenharmony_ci                }
2854514f5e3Sopenharmony_ci                Bind(&resetSlot);
2864514f5e3Sopenharmony_ci                {
2874514f5e3Sopenharmony_ci                    // NOTICE-PGO: lx about poly
2884514f5e3Sopenharmony_ci                    GateRef nonType = TaggedInt(0);
2894514f5e3Sopenharmony_ci                    SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, nonType);
2904514f5e3Sopenharmony_ci                    TryPreDumpInner(glue, func, profileTypeInfo);
2914514f5e3Sopenharmony_ci                    Jump(&exit);
2924514f5e3Sopenharmony_ci                }
2934514f5e3Sopenharmony_ci            }
2944514f5e3Sopenharmony_ci            Bind(&uninitialized);
2954514f5e3Sopenharmony_ci            {
2964514f5e3Sopenharmony_ci                // Only when slot value is undefined, it means uninitialized, so we need to update the slot.
2974514f5e3Sopenharmony_ci                // When the slot value is hole, it means slot is overflow (0xff). Otherwise, do nothing.
2984514f5e3Sopenharmony_ci                BRANCH(TaggedIsUndefined(slotValue), &updateSlot, &exit);
2994514f5e3Sopenharmony_ci            }
3004514f5e3Sopenharmony_ci            Bind(&updateSlot);
3014514f5e3Sopenharmony_ci            {
3024514f5e3Sopenharmony_ci                SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, target);
3034514f5e3Sopenharmony_ci                TryPreDumpInner(glue, func, profileTypeInfo);
3044514f5e3Sopenharmony_ci                Jump(&exit);
3054514f5e3Sopenharmony_ci            }
3064514f5e3Sopenharmony_ci        }
3074514f5e3Sopenharmony_ci    }
3084514f5e3Sopenharmony_ci    Bind(&exit);
3094514f5e3Sopenharmony_ci    env->SubCfgExit();
3104514f5e3Sopenharmony_ci}
3114514f5e3Sopenharmony_ci
3124514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileGetterSetterCall(GateRef glue, GateRef target)
3134514f5e3Sopenharmony_ci{
3144514f5e3Sopenharmony_ci    auto env = GetEnvironment();
3154514f5e3Sopenharmony_ci    Label subEntry(env);
3164514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
3174514f5e3Sopenharmony_ci
3184514f5e3Sopenharmony_ci    Label exit(env);
3194514f5e3Sopenharmony_ci
3204514f5e3Sopenharmony_ci    Label targetIsFunction(env);
3214514f5e3Sopenharmony_ci    BRANCH(IsJSFunction(target), &targetIsFunction, &exit);
3224514f5e3Sopenharmony_ci    Bind(&targetIsFunction);
3234514f5e3Sopenharmony_ci    {
3244514f5e3Sopenharmony_ci        GateRef targetProfileInfo = GetProfileTypeInfo(target);
3254514f5e3Sopenharmony_ci        Label targetNonHotness(env);
3264514f5e3Sopenharmony_ci        BRANCH(TaggedIsUndefined(targetProfileInfo), &targetNonHotness, &exit);
3274514f5e3Sopenharmony_ci        Bind(&targetNonHotness);
3284514f5e3Sopenharmony_ci        {
3294514f5e3Sopenharmony_ci            CallRuntime(glue, RTSTUB_ID(UpdateHotnessCounterWithProf), { target });
3304514f5e3Sopenharmony_ci            Jump(&exit);
3314514f5e3Sopenharmony_ci        }
3324514f5e3Sopenharmony_ci    }
3334514f5e3Sopenharmony_ci    Bind(&exit);
3344514f5e3Sopenharmony_ci    env->SubCfgExit();
3354514f5e3Sopenharmony_ci}
3364514f5e3Sopenharmony_ci
3374514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::TryGetBuiltinFunctionId(GateRef target)
3384514f5e3Sopenharmony_ci{
3394514f5e3Sopenharmony_ci    auto env = GetEnvironment();
3404514f5e3Sopenharmony_ci    Label subEntry(env);
3414514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
3424514f5e3Sopenharmony_ci    Label targetIsFunction(env);
3434514f5e3Sopenharmony_ci    Label exit(env);
3444514f5e3Sopenharmony_ci
3454514f5e3Sopenharmony_ci    DEFVARIABLE(functionId, VariableType::INT32(), Int32(PGO_BUILTINS_STUB_ID(NONE)));
3464514f5e3Sopenharmony_ci
3474514f5e3Sopenharmony_ci    BRANCH(IsJSFunction(target), &targetIsFunction, &exit);
3484514f5e3Sopenharmony_ci    Bind(&targetIsFunction);
3494514f5e3Sopenharmony_ci    {
3504514f5e3Sopenharmony_ci        auto builtinsId = env->GetBuilder()->GetBuiltinsId(target);
3514514f5e3Sopenharmony_ci        functionId = Int32Mul(TruncInt64ToInt32(builtinsId), Int32(-1));
3524514f5e3Sopenharmony_ci        Jump(&exit);
3534514f5e3Sopenharmony_ci    }
3544514f5e3Sopenharmony_ci    Bind(&exit);
3554514f5e3Sopenharmony_ci    auto ret = *functionId;
3564514f5e3Sopenharmony_ci    env->SubCfgExit();
3574514f5e3Sopenharmony_ci    return ret;
3584514f5e3Sopenharmony_ci}
3594514f5e3Sopenharmony_ci
3604514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileNativeCall(
3614514f5e3Sopenharmony_ci    GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef target, GateRef profileTypeInfo)
3624514f5e3Sopenharmony_ci{
3634514f5e3Sopenharmony_ci    auto env = GetEnvironment();
3644514f5e3Sopenharmony_ci    Label subEntry(env);
3654514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
3664514f5e3Sopenharmony_ci
3674514f5e3Sopenharmony_ci    Label exit(env);
3684514f5e3Sopenharmony_ci    Label currentIsHot(env);
3694514f5e3Sopenharmony_ci
3704514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &currentIsHot, &exit);
3714514f5e3Sopenharmony_ci    Bind(&currentIsHot);
3724514f5e3Sopenharmony_ci    {
3734514f5e3Sopenharmony_ci        Label icSlotValid(env);
3744514f5e3Sopenharmony_ci        Label updateSlot(env);
3754514f5e3Sopenharmony_ci        Label initSlot(env);
3764514f5e3Sopenharmony_ci        Label sameValueCheck(env);
3774514f5e3Sopenharmony_ci        Label invalidate(env);
3784514f5e3Sopenharmony_ci        Label notOverflow(env);
3794514f5e3Sopenharmony_ci
3804514f5e3Sopenharmony_ci        GateRef slotId = GetSlotID(slotInfo);
3814514f5e3Sopenharmony_ci        GateRef length = GetLengthOfTaggedArray(profileTypeInfo);
3824514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(slotId, length), &icSlotValid, &exit);
3834514f5e3Sopenharmony_ci        Bind(&icSlotValid);
3844514f5e3Sopenharmony_ci        GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId);
3854514f5e3Sopenharmony_ci        BRANCH(TaggedIsHole(slotValue), &exit, &notOverflow); // hole -- slot is overflow
3864514f5e3Sopenharmony_ci        Bind(&notOverflow);
3874514f5e3Sopenharmony_ci        BRANCH(TaggedIsInt(slotValue), &updateSlot, &initSlot);
3884514f5e3Sopenharmony_ci        Bind(&updateSlot);
3894514f5e3Sopenharmony_ci        GateRef oldId = TaggedGetInt(slotValue);
3904514f5e3Sopenharmony_ci        BRANCH(Int32Equal(oldId, Int32(PGO_BUILTINS_STUB_ID(NONE))), &exit, &sameValueCheck);
3914514f5e3Sopenharmony_ci        Bind(&sameValueCheck);
3924514f5e3Sopenharmony_ci        {
3934514f5e3Sopenharmony_ci            GateRef newId = TryGetBuiltinFunctionId(target);
3944514f5e3Sopenharmony_ci            BRANCH(Int32Equal(oldId, newId), &exit, &invalidate);
3954514f5e3Sopenharmony_ci        }
3964514f5e3Sopenharmony_ci        Bind(&invalidate);
3974514f5e3Sopenharmony_ci        {
3984514f5e3Sopenharmony_ci            GateRef invalidId = Int32(PGO_BUILTINS_STUB_ID(NONE));
3994514f5e3Sopenharmony_ci            SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, IntToTaggedInt(invalidId));
4004514f5e3Sopenharmony_ci            TryPreDumpInner(glue, func, profileTypeInfo);
4014514f5e3Sopenharmony_ci            Jump(&exit);
4024514f5e3Sopenharmony_ci        }
4034514f5e3Sopenharmony_ci        Bind(&initSlot);
4044514f5e3Sopenharmony_ci        {
4054514f5e3Sopenharmony_ci            GateRef newId = TryGetBuiltinFunctionId(target);
4064514f5e3Sopenharmony_ci            SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, IntToTaggedInt(newId));
4074514f5e3Sopenharmony_ci            TryPreDumpInner(glue, func, profileTypeInfo);
4084514f5e3Sopenharmony_ci            Jump(&exit);
4094514f5e3Sopenharmony_ci        }
4104514f5e3Sopenharmony_ci    }
4114514f5e3Sopenharmony_ci    Bind(&exit);
4124514f5e3Sopenharmony_ci    env->SubCfgExit();
4134514f5e3Sopenharmony_ci}
4144514f5e3Sopenharmony_ci
4154514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsProfileTypeInfoDumped(GateRef profileTypeInfo, ProfileOperation callback)
4164514f5e3Sopenharmony_ci{
4174514f5e3Sopenharmony_ci    if (callback.IsEmpty()) {
4184514f5e3Sopenharmony_ci        return Boolean(true);
4194514f5e3Sopenharmony_ci    }
4204514f5e3Sopenharmony_ci    return IsProfileTypeInfoDumped(profileTypeInfo);
4214514f5e3Sopenharmony_ci}
4224514f5e3Sopenharmony_ci
4234514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::UpdateTrackTypeInPropAttr(GateRef attr, GateRef value, ProfileOperation callback)
4244514f5e3Sopenharmony_ci{
4254514f5e3Sopenharmony_ci    if (callback.IsEmpty()) {
4264514f5e3Sopenharmony_ci        return attr;
4274514f5e3Sopenharmony_ci    }
4284514f5e3Sopenharmony_ci    auto env = GetEnvironment();
4294514f5e3Sopenharmony_ci    Label entry(env);
4304514f5e3Sopenharmony_ci    env->SubCfgEntry(&entry);
4314514f5e3Sopenharmony_ci
4324514f5e3Sopenharmony_ci    GateRef oldTrackType = GetTrackTypeInPropAttr(attr);
4334514f5e3Sopenharmony_ci    DEFVARIABLE(newTrackType, VariableType::INT32(), Int32(static_cast<int32_t>(TrackType::TAGGED)));
4344514f5e3Sopenharmony_ci    DEFVARIABLE(result, VariableType::INT64(), attr);
4354514f5e3Sopenharmony_ci
4364514f5e3Sopenharmony_ci    Label exit(env);
4374514f5e3Sopenharmony_ci    Label judgeValue(env);
4384514f5e3Sopenharmony_ci    BRANCH(Equal(oldTrackType, Int32(static_cast<int32_t>(TrackType::TAGGED))), &exit, &judgeValue);
4394514f5e3Sopenharmony_ci    Bind(&judgeValue);
4404514f5e3Sopenharmony_ci    {
4414514f5e3Sopenharmony_ci        newTrackType = TaggedToTrackType(value);
4424514f5e3Sopenharmony_ci        Label update(env);
4434514f5e3Sopenharmony_ci        Label merge(env);
4444514f5e3Sopenharmony_ci        BRANCH(Int32Equal(*newTrackType, Int32(static_cast<int32_t>(TrackType::TAGGED))), &update, &merge);
4454514f5e3Sopenharmony_ci        Bind(&merge);
4464514f5e3Sopenharmony_ci        {
4474514f5e3Sopenharmony_ci            newTrackType = Int32Or(oldTrackType, *newTrackType);
4484514f5e3Sopenharmony_ci            BRANCH(Int32Equal(oldTrackType, *newTrackType), &exit, &update);
4494514f5e3Sopenharmony_ci        }
4504514f5e3Sopenharmony_ci        Bind(&update);
4514514f5e3Sopenharmony_ci        {
4524514f5e3Sopenharmony_ci            result = SetTrackTypeInPropAttr(attr, *newTrackType);
4534514f5e3Sopenharmony_ci            Jump(&exit);
4544514f5e3Sopenharmony_ci        }
4554514f5e3Sopenharmony_ci    }
4564514f5e3Sopenharmony_ci    Bind(&exit);
4574514f5e3Sopenharmony_ci    auto ret = *result;
4584514f5e3Sopenharmony_ci    env->SubCfgExit();
4594514f5e3Sopenharmony_ci    return ret;
4604514f5e3Sopenharmony_ci}
4614514f5e3Sopenharmony_ci
4624514f5e3Sopenharmony_civoid ProfilerStubBuilder::UpdatePropAttrIC(
4634514f5e3Sopenharmony_ci    GateRef glue, GateRef receiver, GateRef value, GateRef handler, ProfileOperation callback)
4644514f5e3Sopenharmony_ci{
4654514f5e3Sopenharmony_ci    if (callback.IsEmpty()) {
4664514f5e3Sopenharmony_ci        return;
4674514f5e3Sopenharmony_ci    }
4684514f5e3Sopenharmony_ci    auto env = GetEnvironment();
4694514f5e3Sopenharmony_ci    Label entry(env);
4704514f5e3Sopenharmony_ci    env->SubCfgEntry(&entry);
4714514f5e3Sopenharmony_ci    Label exit(env);
4724514f5e3Sopenharmony_ci    Label handleUnShared(env);
4734514f5e3Sopenharmony_ci    Label updateLayout(env);
4744514f5e3Sopenharmony_ci
4754514f5e3Sopenharmony_ci    GateRef attrIndex = HandlerBaseGetAttrIndex(handler);
4764514f5e3Sopenharmony_ci    GateRef hclass = LoadHClass(receiver);
4774514f5e3Sopenharmony_ci    GateRef layout = GetLayoutFromHClass(hclass);
4784514f5e3Sopenharmony_ci    GateRef attr = GetPropAttrFromLayoutInfo(layout, attrIndex);
4794514f5e3Sopenharmony_ci    GateRef newAttr = UpdateTrackTypeInPropAttr(attr, value, callback);
4804514f5e3Sopenharmony_ci    BRANCH(IsJSShared(receiver), &exit, &handleUnShared);
4814514f5e3Sopenharmony_ci    Bind(&handleUnShared);
4824514f5e3Sopenharmony_ci    {
4834514f5e3Sopenharmony_ci        BRANCH(Equal(attr, newAttr), &exit, &updateLayout);
4844514f5e3Sopenharmony_ci        Bind(&updateLayout);
4854514f5e3Sopenharmony_ci        {
4864514f5e3Sopenharmony_ci            UpdateFieldType(glue, LoadHClass(receiver), newAttr);
4874514f5e3Sopenharmony_ci            callback.TryPreDump();
4884514f5e3Sopenharmony_ci            Jump(&exit);
4894514f5e3Sopenharmony_ci        }
4904514f5e3Sopenharmony_ci    }
4914514f5e3Sopenharmony_ci    Bind(&exit);
4924514f5e3Sopenharmony_ci    env->SubCfgExit();
4934514f5e3Sopenharmony_ci}
4944514f5e3Sopenharmony_ci
4954514f5e3Sopenharmony_civoid ProfilerStubBuilder::UpdatePropAttrWithValue(GateRef glue, GateRef receiver, GateRef attr,
4964514f5e3Sopenharmony_ci                                                  GateRef value, ProfileOperation callback)
4974514f5e3Sopenharmony_ci{
4984514f5e3Sopenharmony_ci    if (callback.IsEmpty()) {
4994514f5e3Sopenharmony_ci        return;
5004514f5e3Sopenharmony_ci    }
5014514f5e3Sopenharmony_ci    auto env = GetEnvironment();
5024514f5e3Sopenharmony_ci    Label entry(env);
5034514f5e3Sopenharmony_ci    env->SubCfgEntry(&entry);
5044514f5e3Sopenharmony_ci    Label exit(env);
5054514f5e3Sopenharmony_ci    Label updateLayout(env);
5064514f5e3Sopenharmony_ci    Label isNotJSShared(env);
5074514f5e3Sopenharmony_ci    BRANCH(IsJSShared(receiver), &exit, &isNotJSShared);
5084514f5e3Sopenharmony_ci    Bind(&isNotJSShared);
5094514f5e3Sopenharmony_ci    GateRef newAttr = UpdateTrackTypeInPropAttr(attr, value, callback);
5104514f5e3Sopenharmony_ci    BRANCH(Equal(attr, newAttr), &exit, &updateLayout);
5114514f5e3Sopenharmony_ci    Bind(&updateLayout);
5124514f5e3Sopenharmony_ci    {
5134514f5e3Sopenharmony_ci        UpdateFieldType(glue, LoadHClass(receiver), newAttr);
5144514f5e3Sopenharmony_ci        Jump(&exit);
5154514f5e3Sopenharmony_ci    }
5164514f5e3Sopenharmony_ci    Bind(&exit);
5174514f5e3Sopenharmony_ci    env->SubCfgExit();
5184514f5e3Sopenharmony_ci}
5194514f5e3Sopenharmony_ci
5204514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::TaggedToTrackType(GateRef value)
5214514f5e3Sopenharmony_ci{
5224514f5e3Sopenharmony_ci    auto env = GetEnvironment();
5234514f5e3Sopenharmony_ci    Label entry(env);
5244514f5e3Sopenharmony_ci    env->SubCfgEntry(&entry);
5254514f5e3Sopenharmony_ci
5264514f5e3Sopenharmony_ci    DEFVARIABLE(newTrackType, VariableType::INT32(), Int32(static_cast<int32_t>(TrackType::TAGGED)));
5274514f5e3Sopenharmony_ci    Label exit(env);
5284514f5e3Sopenharmony_ci    Label isInt(env);
5294514f5e3Sopenharmony_ci    Label notInt(env);
5304514f5e3Sopenharmony_ci    BRANCH(TaggedIsInt(value), &isInt, &notInt);
5314514f5e3Sopenharmony_ci    Bind(&isInt);
5324514f5e3Sopenharmony_ci    {
5334514f5e3Sopenharmony_ci        newTrackType = Int32(static_cast<int32_t>(TrackType::INT));
5344514f5e3Sopenharmony_ci        Jump(&exit);
5354514f5e3Sopenharmony_ci    }
5364514f5e3Sopenharmony_ci    Bind(&notInt);
5374514f5e3Sopenharmony_ci    {
5384514f5e3Sopenharmony_ci        Label isObject(env);
5394514f5e3Sopenharmony_ci        Label isDouble(env);
5404514f5e3Sopenharmony_ci        BRANCH(TaggedIsObject(value), &isObject, &isDouble);
5414514f5e3Sopenharmony_ci        Bind(&isObject);
5424514f5e3Sopenharmony_ci        {
5434514f5e3Sopenharmony_ci            newTrackType = Int32(static_cast<int32_t>(TrackType::TAGGED));
5444514f5e3Sopenharmony_ci            Jump(&exit);
5454514f5e3Sopenharmony_ci        }
5464514f5e3Sopenharmony_ci        Bind(&isDouble);
5474514f5e3Sopenharmony_ci        {
5484514f5e3Sopenharmony_ci            newTrackType = Int32(static_cast<int32_t>(TrackType::DOUBLE));
5494514f5e3Sopenharmony_ci            Jump(&exit);
5504514f5e3Sopenharmony_ci        }
5514514f5e3Sopenharmony_ci    }
5524514f5e3Sopenharmony_ci    Bind(&exit);
5534514f5e3Sopenharmony_ci    auto ret = *newTrackType;
5544514f5e3Sopenharmony_ci    env->SubCfgExit();
5554514f5e3Sopenharmony_ci    return ret;
5564514f5e3Sopenharmony_ci}
5574514f5e3Sopenharmony_ci
5584514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileBranch(
5594514f5e3Sopenharmony_ci    GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef profileTypeInfo, bool isTrue)
5604514f5e3Sopenharmony_ci{
5614514f5e3Sopenharmony_ci    auto env = GetEnvironment();
5624514f5e3Sopenharmony_ci    Label subEntry(env);
5634514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
5644514f5e3Sopenharmony_ci    Label profiler(env);
5654514f5e3Sopenharmony_ci    Label icSlotValid(env);
5664514f5e3Sopenharmony_ci    Label hasSlot(env);
5674514f5e3Sopenharmony_ci    Label currentIsTrue(env);
5684514f5e3Sopenharmony_ci    Label currentIsFalse(env);
5694514f5e3Sopenharmony_ci    Label genCurrentWeight(env);
5704514f5e3Sopenharmony_ci    Label compareLabel(env);
5714514f5e3Sopenharmony_ci    Label updateSlot(env);
5724514f5e3Sopenharmony_ci    Label preProfile(env);
5734514f5e3Sopenharmony_ci    Label needUpdate(env);
5744514f5e3Sopenharmony_ci    Label exit(env);
5754514f5e3Sopenharmony_ci    DEFVARIABLE(oldPrama, VariableType::INT32(), Int32(PGOSampleType::None()));
5764514f5e3Sopenharmony_ci    DEFVARIABLE(newTrue, VariableType::INT32(), isTrue ? Int32(1) : Int32(0));
5774514f5e3Sopenharmony_ci    DEFVARIABLE(newFalse, VariableType::INT32(), isTrue ? Int32(0) : Int32(1));
5784514f5e3Sopenharmony_ci
5794514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &profiler, &exit);
5804514f5e3Sopenharmony_ci    Bind(&profiler);
5814514f5e3Sopenharmony_ci    {
5824514f5e3Sopenharmony_ci        GateRef slotId = GetSlotID(slotInfo);
5834514f5e3Sopenharmony_ci        GateRef length = GetLengthOfTaggedArray(profileTypeInfo);
5844514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(slotId, length), &icSlotValid, &exit);
5854514f5e3Sopenharmony_ci        Bind(&icSlotValid);
5864514f5e3Sopenharmony_ci        GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId);
5874514f5e3Sopenharmony_ci        BRANCH(TaggedIsHole(slotValue), &exit, &hasSlot); // ishole -- isundefined
5884514f5e3Sopenharmony_ci        Bind(&hasSlot);
5894514f5e3Sopenharmony_ci        {
5904514f5e3Sopenharmony_ci            Label uninitialized(env);
5914514f5e3Sopenharmony_ci            BRANCH(TaggedIsInt(slotValue), &compareLabel, &uninitialized);
5924514f5e3Sopenharmony_ci            Bind(&compareLabel);
5934514f5e3Sopenharmony_ci            {
5944514f5e3Sopenharmony_ci                GateRef oldSlotValue = TaggedGetInt(slotValue);
5954514f5e3Sopenharmony_ci                GateRef oldTrue = Int32LSR(oldSlotValue, Int32(PGOSampleType::WEIGHT_TRUE_START_BIT));
5964514f5e3Sopenharmony_ci                GateRef oldFalse = Int32LSR(oldSlotValue, Int32(PGOSampleType::WEIGHT_START_BIT));
5974514f5e3Sopenharmony_ci                oldFalse = Int32And(oldFalse, Int32(PGOSampleType::WEIGHT_MASK));
5984514f5e3Sopenharmony_ci                oldPrama = Int32And(oldSlotValue, Int32(PGOSampleType::AnyType()));
5994514f5e3Sopenharmony_ci                auto condition = BitAnd(Int32LessThan(oldTrue, Int32(PGOSampleType::WEIGHT_THRESHOLD)),
6004514f5e3Sopenharmony_ci                                        Int32LessThan(oldFalse, Int32(PGOSampleType::WEIGHT_THRESHOLD)));
6014514f5e3Sopenharmony_ci                BRANCH(condition, &needUpdate, &exit); // WEIGHT_THRESHOLD: 2047 limit
6024514f5e3Sopenharmony_ci                Bind(&needUpdate);
6034514f5e3Sopenharmony_ci                {
6044514f5e3Sopenharmony_ci                    newTrue = Int32Add(*newTrue, oldTrue);
6054514f5e3Sopenharmony_ci                    newFalse = Int32Add(*newFalse, oldFalse);
6064514f5e3Sopenharmony_ci                    Jump(&updateSlot);
6074514f5e3Sopenharmony_ci                }
6084514f5e3Sopenharmony_ci            }
6094514f5e3Sopenharmony_ci            Bind(&uninitialized);
6104514f5e3Sopenharmony_ci            {
6114514f5e3Sopenharmony_ci                // Only when slot value is undefined, it means uninitialized, so we need to update the slot.
6124514f5e3Sopenharmony_ci                // When the slot value is hole, it means slot is overflow (0xff). Otherwise, do nothing.
6134514f5e3Sopenharmony_ci                BRANCH(TaggedIsUndefined(slotValue), &updateSlot, &exit);
6144514f5e3Sopenharmony_ci            }
6154514f5e3Sopenharmony_ci            Bind(&updateSlot);
6164514f5e3Sopenharmony_ci            {
6174514f5e3Sopenharmony_ci                GateRef newSlotValue =
6184514f5e3Sopenharmony_ci                    Int32Or(*oldPrama, Int32LSL(*newTrue, Int32(PGOSampleType::WEIGHT_TRUE_START_BIT)));
6194514f5e3Sopenharmony_ci                newSlotValue = Int32Or(newSlotValue, Int32LSL(*newFalse, Int32(PGOSampleType::WEIGHT_START_BIT)));
6204514f5e3Sopenharmony_ci                SetValueToTaggedArray(
6214514f5e3Sopenharmony_ci                    VariableType::JS_ANY(), glue, profileTypeInfo, slotId, IntToTaggedInt(newSlotValue));
6224514f5e3Sopenharmony_ci                auto isFinal = BitOr(Int32Equal(*newTrue, Int32(PGOSampleType::WEIGHT_THRESHOLD)),
6234514f5e3Sopenharmony_ci                                     Int32Equal(*newFalse, Int32(PGOSampleType::WEIGHT_THRESHOLD)));
6244514f5e3Sopenharmony_ci                BRANCH(isFinal, &preProfile, &exit);
6254514f5e3Sopenharmony_ci            }
6264514f5e3Sopenharmony_ci            Bind(&preProfile);
6274514f5e3Sopenharmony_ci            {
6284514f5e3Sopenharmony_ci                TryPreDumpInner(glue, func, profileTypeInfo);
6294514f5e3Sopenharmony_ci                Jump(&exit);
6304514f5e3Sopenharmony_ci            }
6314514f5e3Sopenharmony_ci        }
6324514f5e3Sopenharmony_ci    }
6334514f5e3Sopenharmony_ci    Bind(&exit);
6344514f5e3Sopenharmony_ci    env->SubCfgExit();
6354514f5e3Sopenharmony_ci}
6364514f5e3Sopenharmony_ci
6374514f5e3Sopenharmony_civoid ProfilerStubBuilder::TryPreDumpInner(GateRef glue, GateRef func, GateRef profileTypeInfo)
6384514f5e3Sopenharmony_ci{
6394514f5e3Sopenharmony_ci    auto env = GetEnvironment();
6404514f5e3Sopenharmony_ci    Label subEntry(env);
6414514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
6424514f5e3Sopenharmony_ci    Label setPreDumpPeriodIndex(env);
6434514f5e3Sopenharmony_ci    Label isInPredumpWorkList(env);
6444514f5e3Sopenharmony_ci    Label addPredumpWorkList(env);
6454514f5e3Sopenharmony_ci    Label exit(env);
6464514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoPreDumped(profileTypeInfo), &exit, &setPreDumpPeriodIndex);
6474514f5e3Sopenharmony_ci    Bind(&setPreDumpPeriodIndex);
6484514f5e3Sopenharmony_ci    {
6494514f5e3Sopenharmony_ci        SetPreDumpPeriodIndex(glue, profileTypeInfo);
6504514f5e3Sopenharmony_ci        Jump(&addPredumpWorkList);
6514514f5e3Sopenharmony_ci    }
6524514f5e3Sopenharmony_ci    Bind(&addPredumpWorkList);
6534514f5e3Sopenharmony_ci    {
6544514f5e3Sopenharmony_ci        CallRuntime(glue, RTSTUB_ID(PGOPreDump), { func });
6554514f5e3Sopenharmony_ci        Jump(&exit);
6564514f5e3Sopenharmony_ci    }
6574514f5e3Sopenharmony_ci    Bind(&exit);
6584514f5e3Sopenharmony_ci    env->SubCfgExit();
6594514f5e3Sopenharmony_ci}
6604514f5e3Sopenharmony_ci
6614514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetIterationFunctionId(GateRef glue, GateRef iterator)
6624514f5e3Sopenharmony_ci{
6634514f5e3Sopenharmony_ci    auto env = GetEnvironment();
6644514f5e3Sopenharmony_ci    Label subEntry(env);
6654514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
6664514f5e3Sopenharmony_ci    Label exit(env);
6674514f5e3Sopenharmony_ci
6684514f5e3Sopenharmony_ci    DEFVARIABLE(functionId, VariableType::INT32(), Int32(PGO_BUILTINS_STUB_ID(NONE)));
6694514f5e3Sopenharmony_ci    DEFVARIABLE(maybeFunc, VariableType::JS_ANY(), Undefined());
6704514f5e3Sopenharmony_ci    Label isArrayProtoValues(env);
6714514f5e3Sopenharmony_ci    Label notArrayProtoValues(env);
6724514f5e3Sopenharmony_ci    Label isSetProtoValues(env);
6734514f5e3Sopenharmony_ci    Label notSetProtoValues(env);
6744514f5e3Sopenharmony_ci    Label isMapProtoEntries(env);
6754514f5e3Sopenharmony_ci    Label notMapProtoEntries(env);
6764514f5e3Sopenharmony_ci    Label isStringProtoIter(env);
6774514f5e3Sopenharmony_ci    Label notStringProtoIter(env);
6784514f5e3Sopenharmony_ci    Label isTypedArrayProtoValues(env);
6794514f5e3Sopenharmony_ci
6804514f5e3Sopenharmony_ci    GateRef glueGlobalEnvOffset = IntPtr(JSThread::GlueData::GetGlueGlobalEnvOffset(env->Is32Bit()));
6814514f5e3Sopenharmony_ci    GateRef glueGlobalEnv = Load(VariableType::NATIVE_POINTER(), glue, glueGlobalEnvOffset);
6824514f5e3Sopenharmony_ci    maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::ARRAY_PROTO_VALUES_FUNCTION_INDEX);
6834514f5e3Sopenharmony_ci    BRANCH(Int64Equal(iterator, *maybeFunc), &isArrayProtoValues, &notArrayProtoValues);
6844514f5e3Sopenharmony_ci    Bind(&isArrayProtoValues);
6854514f5e3Sopenharmony_ci    {
6864514f5e3Sopenharmony_ci        functionId = Int32(PGO_BUILTINS_STUB_ID(ArrayProtoIterator));
6874514f5e3Sopenharmony_ci        Jump(&exit);
6884514f5e3Sopenharmony_ci    }
6894514f5e3Sopenharmony_ci    Bind(&notArrayProtoValues);
6904514f5e3Sopenharmony_ci    maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::SET_PROTO_VALUES_FUNCTION_INDEX);
6914514f5e3Sopenharmony_ci    BRANCH(Int64Equal(iterator, *maybeFunc), &isSetProtoValues, &notSetProtoValues);
6924514f5e3Sopenharmony_ci    Bind(&isSetProtoValues);
6934514f5e3Sopenharmony_ci    {
6944514f5e3Sopenharmony_ci        functionId = Int32(PGO_BUILTINS_STUB_ID(SetProtoIterator));
6954514f5e3Sopenharmony_ci        Jump(&exit);
6964514f5e3Sopenharmony_ci    }
6974514f5e3Sopenharmony_ci    Bind(&notSetProtoValues);
6984514f5e3Sopenharmony_ci    maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::MAP_PROTO_ENTRIES_FUNCTION_INDEX);
6994514f5e3Sopenharmony_ci    BRANCH(Int64Equal(iterator, *maybeFunc), &isMapProtoEntries, &notMapProtoEntries);
7004514f5e3Sopenharmony_ci    Bind(&isMapProtoEntries);
7014514f5e3Sopenharmony_ci    {
7024514f5e3Sopenharmony_ci        functionId = Int32(PGO_BUILTINS_STUB_ID(MapProtoIterator));
7034514f5e3Sopenharmony_ci        Jump(&exit);
7044514f5e3Sopenharmony_ci    }
7054514f5e3Sopenharmony_ci    Bind(&notMapProtoEntries);
7064514f5e3Sopenharmony_ci    maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::STRING_PROTO_ITER_FUNCTION_INDEX);
7074514f5e3Sopenharmony_ci    BRANCH(Int64Equal(iterator, *maybeFunc), &isStringProtoIter, &notStringProtoIter);
7084514f5e3Sopenharmony_ci    Bind(&isStringProtoIter);
7094514f5e3Sopenharmony_ci    {
7104514f5e3Sopenharmony_ci        functionId = Int32(PGO_BUILTINS_STUB_ID(StringProtoIterator));
7114514f5e3Sopenharmony_ci        Jump(&exit);
7124514f5e3Sopenharmony_ci    }
7134514f5e3Sopenharmony_ci    Bind(&notStringProtoIter);
7144514f5e3Sopenharmony_ci    maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv,
7154514f5e3Sopenharmony_ci                                  GlobalEnv::TYPED_ARRAY_PROTO_VALUES_FUNCTION_INDEX);
7164514f5e3Sopenharmony_ci    BRANCH(Int64Equal(iterator, *maybeFunc), &isTypedArrayProtoValues, &exit);
7174514f5e3Sopenharmony_ci    Bind(&isTypedArrayProtoValues);
7184514f5e3Sopenharmony_ci    {
7194514f5e3Sopenharmony_ci        functionId = Int32(PGO_BUILTINS_STUB_ID(TypeArrayProtoIterator));
7204514f5e3Sopenharmony_ci        Jump(&exit);
7214514f5e3Sopenharmony_ci    }
7224514f5e3Sopenharmony_ci    Bind(&exit);
7234514f5e3Sopenharmony_ci    auto ret = *functionId;
7244514f5e3Sopenharmony_ci    env->SubCfgExit();
7254514f5e3Sopenharmony_ci    return ret;
7264514f5e3Sopenharmony_ci}
7274514f5e3Sopenharmony_ci
7284514f5e3Sopenharmony_civoid ProfilerStubBuilder::ProfileGetIterator(
7294514f5e3Sopenharmony_ci    GateRef glue, SlotIDInfo slotInfo, GateRef func, GateRef iterator, GateRef profileTypeInfo)
7304514f5e3Sopenharmony_ci{
7314514f5e3Sopenharmony_ci    auto env = GetEnvironment();
7324514f5e3Sopenharmony_ci    Label subEntry(env);
7334514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
7344514f5e3Sopenharmony_ci
7354514f5e3Sopenharmony_ci    Label exit(env);
7364514f5e3Sopenharmony_ci    Label profiler(env);
7374514f5e3Sopenharmony_ci    BRANCH(IsProfileTypeInfoHotAndValid(profileTypeInfo), &profiler, &exit);
7384514f5e3Sopenharmony_ci    Bind(&profiler);
7394514f5e3Sopenharmony_ci    {
7404514f5e3Sopenharmony_ci        Label icSlotValid(env);
7414514f5e3Sopenharmony_ci        Label updateSlot(env);
7424514f5e3Sopenharmony_ci        Label initSlot(env);
7434514f5e3Sopenharmony_ci        Label sameValueCheck(env);
7444514f5e3Sopenharmony_ci        Label invalidate(env);
7454514f5e3Sopenharmony_ci        Label notOverflow(env);
7464514f5e3Sopenharmony_ci
7474514f5e3Sopenharmony_ci        GateRef slotId = GetSlotID(slotInfo);
7484514f5e3Sopenharmony_ci        GateRef length = GetLengthOfTaggedArray(profileTypeInfo);
7494514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(slotId, length), &icSlotValid, &exit);
7504514f5e3Sopenharmony_ci        Bind(&icSlotValid);
7514514f5e3Sopenharmony_ci        GateRef slotValue = GetValueFromTaggedArray(profileTypeInfo, slotId);
7524514f5e3Sopenharmony_ci        BRANCH(TaggedIsHole(slotValue), &exit, &notOverflow); // hole -- slot is overflow
7534514f5e3Sopenharmony_ci        Bind(&notOverflow);
7544514f5e3Sopenharmony_ci        BRANCH(TaggedIsInt(slotValue), &updateSlot, &initSlot);
7554514f5e3Sopenharmony_ci        Bind(&updateSlot);
7564514f5e3Sopenharmony_ci        GateRef oldIterKind = TaggedGetInt(slotValue);
7574514f5e3Sopenharmony_ci        BRANCH(Int32Equal(oldIterKind, Int32(PGO_BUILTINS_STUB_ID(NONE))),
7584514f5e3Sopenharmony_ci            &exit, &sameValueCheck);
7594514f5e3Sopenharmony_ci        Bind(&sameValueCheck);
7604514f5e3Sopenharmony_ci        {
7614514f5e3Sopenharmony_ci            GateRef newIterKind = GetIterationFunctionId(glue, iterator);
7624514f5e3Sopenharmony_ci            BRANCH(Int32Equal(oldIterKind, newIterKind), &exit, &invalidate);
7634514f5e3Sopenharmony_ci        }
7644514f5e3Sopenharmony_ci        Bind(&invalidate);
7654514f5e3Sopenharmony_ci        {
7664514f5e3Sopenharmony_ci            GateRef invalidKind = Int32(PGO_BUILTINS_STUB_ID(NONE));
7674514f5e3Sopenharmony_ci            SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, IntToTaggedInt(invalidKind));
7684514f5e3Sopenharmony_ci            TryPreDumpInner(glue, func, profileTypeInfo);
7694514f5e3Sopenharmony_ci            Jump(&exit);
7704514f5e3Sopenharmony_ci        }
7714514f5e3Sopenharmony_ci        Bind(&initSlot);
7724514f5e3Sopenharmony_ci        {
7734514f5e3Sopenharmony_ci            GateRef newIterKind = GetIterationFunctionId(glue, iterator);
7744514f5e3Sopenharmony_ci            SetValueToTaggedArray(VariableType::JS_ANY(), glue, profileTypeInfo, slotId, IntToTaggedInt(newIterKind));
7754514f5e3Sopenharmony_ci            TryPreDumpInner(glue, func, profileTypeInfo);
7764514f5e3Sopenharmony_ci            Jump(&exit);
7774514f5e3Sopenharmony_ci        }
7784514f5e3Sopenharmony_ci    }
7794514f5e3Sopenharmony_ci    Bind(&exit);
7804514f5e3Sopenharmony_ci    env->SubCfgExit();
7814514f5e3Sopenharmony_ci}
7824514f5e3Sopenharmony_ci
7834514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetSlotID(const SlotIDInfo &slotInfo)
7844514f5e3Sopenharmony_ci{
7854514f5e3Sopenharmony_ci    auto slotType = slotInfo.GetSlotType();
7864514f5e3Sopenharmony_ci    if (slotType == SlotIDInfo::SlotIDInfoType::SLOT_ID) {
7874514f5e3Sopenharmony_ci        return slotInfo.GetSlotID();
7884514f5e3Sopenharmony_ci    }
7894514f5e3Sopenharmony_ci    if (slotType == SlotIDInfo::SlotIDInfoType::PC) {
7904514f5e3Sopenharmony_ci        // for PROFILE_BRANCH
7914514f5e3Sopenharmony_ci        return ZExtInt8ToInt32(Load(VariableType::INT8(), slotInfo.GetPC(), IntPtr(1)));
7924514f5e3Sopenharmony_ci    }
7934514f5e3Sopenharmony_ci    ASSERT(slotType == SlotIDInfo::SlotIDInfoType::PC_FORMAT);
7944514f5e3Sopenharmony_ci    auto format = slotInfo.GetFormat();
7954514f5e3Sopenharmony_ci    auto pc = slotInfo.GetPC();
7964514f5e3Sopenharmony_ci    if (format == SlotIDFormat::IMM16) {
7974514f5e3Sopenharmony_ci        auto hight = Load(VariableType::INT8(), pc, IntPtr(2)); // 2 : skip 1 byte of bytecode
7984514f5e3Sopenharmony_ci        hight = Int16LSL(ZExtInt8ToInt16(hight), Int16(8)); // 8 : set as high 8 bits
7994514f5e3Sopenharmony_ci        auto low = Load(VariableType::INT8(), pc, IntPtr(1));
8004514f5e3Sopenharmony_ci        auto result = Int16Add(hight, ZExtInt8ToInt16(low));
8014514f5e3Sopenharmony_ci        return ZExtInt16ToInt32(result);
8024514f5e3Sopenharmony_ci    } else if (format == SlotIDFormat::PREF_IMM8) {
8034514f5e3Sopenharmony_ci        return ZExtInt8ToInt32(Load(VariableType::INT8(), pc, IntPtr(2)));
8044514f5e3Sopenharmony_ci    }
8054514f5e3Sopenharmony_ci    return ZExtInt8ToInt32(Load(VariableType::INT8(), pc, IntPtr(1)));
8064514f5e3Sopenharmony_ci}
8074514f5e3Sopenharmony_ci
8084514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetBitFieldOffsetFromProfileTypeInfo(GateRef profileTypeInfo)
8094514f5e3Sopenharmony_ci{
8104514f5e3Sopenharmony_ci    auto length = GetLengthOfTaggedArray(profileTypeInfo);
8114514f5e3Sopenharmony_ci    auto index = Int32Sub(length, Int32(ProfileTypeInfo::BIT_FIELD_INDEX));
8124514f5e3Sopenharmony_ci    auto indexOffset = PtrMul(ZExtInt32ToPtr(index), IntPtr(JSTaggedValue::TaggedTypeSize()));
8134514f5e3Sopenharmony_ci    return PtrAdd(indexOffset, IntPtr(TaggedArray::DATA_OFFSET));
8144514f5e3Sopenharmony_ci}
8154514f5e3Sopenharmony_ci
8164514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsProfileTypeInfoDumped(GateRef profileTypeInfo)
8174514f5e3Sopenharmony_ci{
8184514f5e3Sopenharmony_ci    GateRef periodCounterOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
8194514f5e3Sopenharmony_ci    GateRef count = Load(VariableType::INT32(), profileTypeInfo, periodCounterOffset);
8204514f5e3Sopenharmony_ci    return Int32Equal(count, Int32(ProfileTypeInfo::DUMP_PERIOD_INDEX));
8214514f5e3Sopenharmony_ci}
8224514f5e3Sopenharmony_ci
8234514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsProfileTypeInfoPreDumped(GateRef profileTypeInfo)
8244514f5e3Sopenharmony_ci{
8254514f5e3Sopenharmony_ci    GateRef periodCounterOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
8264514f5e3Sopenharmony_ci    GateRef count = Load(VariableType::INT32(), profileTypeInfo, periodCounterOffset);
8274514f5e3Sopenharmony_ci    return Int32Equal(count, Int32(ProfileTypeInfo::PRE_DUMP_PERIOD_INDEX));
8284514f5e3Sopenharmony_ci}
8294514f5e3Sopenharmony_ci
8304514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsProfileTypeInfoWithBigMethod(GateRef profileTypeInfo)
8314514f5e3Sopenharmony_ci{
8324514f5e3Sopenharmony_ci    GateRef periodCounterOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
8334514f5e3Sopenharmony_ci    GateRef count = Load(VariableType::INT32(), profileTypeInfo, periodCounterOffset);
8344514f5e3Sopenharmony_ci    return Int32Equal(count, Int32(ProfileTypeInfo::BIG_METHOD_PERIOD_INDEX));
8354514f5e3Sopenharmony_ci}
8364514f5e3Sopenharmony_ci
8374514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsProfileTypeInfoHotAndValid(GateRef profileTypeInfo)
8384514f5e3Sopenharmony_ci{
8394514f5e3Sopenharmony_ci    auto env = GetEnvironment();
8404514f5e3Sopenharmony_ci    Label subEntry(env);
8414514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
8424514f5e3Sopenharmony_ci    Label exit(env);
8434514f5e3Sopenharmony_ci    Label isHot(env);
8444514f5e3Sopenharmony_ci    Label hotAndValid(env);
8454514f5e3Sopenharmony_ci    DEFVARIABLE(res, VariableType::BOOL(), Boolean(false));
8464514f5e3Sopenharmony_ci    BRANCH(TaggedIsUndefined(profileTypeInfo), &exit, &isHot);
8474514f5e3Sopenharmony_ci    Bind(&isHot);
8484514f5e3Sopenharmony_ci    {
8494514f5e3Sopenharmony_ci        res = BoolNot(IsProfileTypeInfoWithBigMethod(profileTypeInfo));
8504514f5e3Sopenharmony_ci        Jump(&exit);
8514514f5e3Sopenharmony_ci    }
8524514f5e3Sopenharmony_ci    Bind(&exit);
8534514f5e3Sopenharmony_ci    auto ret = *res;
8544514f5e3Sopenharmony_ci    env->SubCfgExit();
8554514f5e3Sopenharmony_ci    return ret;
8564514f5e3Sopenharmony_ci}
8574514f5e3Sopenharmony_ci
8584514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsEnableForceIC(GateRef glue)
8594514f5e3Sopenharmony_ci{
8604514f5e3Sopenharmony_ci    auto env = GetEnvironment();
8614514f5e3Sopenharmony_ci    GateRef offset = IntPtr(JSThread::GlueData::GetIsEnableForceICOffSet(env->Is32Bit()));
8624514f5e3Sopenharmony_ci    return Load(VariableType::BOOL(), glue, offset);
8634514f5e3Sopenharmony_ci}
8644514f5e3Sopenharmony_ci
8654514f5e3Sopenharmony_civoid ProfilerStubBuilder::SetDumpPeriodIndex(GateRef glue, GateRef profileTypeInfo)
8664514f5e3Sopenharmony_ci{
8674514f5e3Sopenharmony_ci    GateRef periodCounterOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
8684514f5e3Sopenharmony_ci    GateRef newCount = Int32(ProfileTypeInfo::DUMP_PERIOD_INDEX);
8694514f5e3Sopenharmony_ci    Store(VariableType::INT32(), glue, profileTypeInfo, periodCounterOffset, newCount);
8704514f5e3Sopenharmony_ci}
8714514f5e3Sopenharmony_ci
8724514f5e3Sopenharmony_civoid ProfilerStubBuilder::SetPreDumpPeriodIndex(GateRef glue, GateRef profileTypeInfo)
8734514f5e3Sopenharmony_ci{
8744514f5e3Sopenharmony_ci    GateRef periodCounterOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
8754514f5e3Sopenharmony_ci    GateRef newCount = Int32(ProfileTypeInfo::PRE_DUMP_PERIOD_INDEX);
8764514f5e3Sopenharmony_ci    Store(VariableType::INT32(), glue, profileTypeInfo, periodCounterOffset, newCount);
8774514f5e3Sopenharmony_ci}
8784514f5e3Sopenharmony_ci
8794514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsCompiledOrTryCompile(GateRef glue, GateRef func, GateRef profileTypeInfo,
8804514f5e3Sopenharmony_ci                                                    ProfileOperation callback)
8814514f5e3Sopenharmony_ci{
8824514f5e3Sopenharmony_ci    if (callback.IsEmpty() && callback.IsJitEmpty()) {
8834514f5e3Sopenharmony_ci        return Boolean(true);
8844514f5e3Sopenharmony_ci    }
8854514f5e3Sopenharmony_ci    return IsCompiledOrTryCompile(glue, func, profileTypeInfo);
8864514f5e3Sopenharmony_ci}
8874514f5e3Sopenharmony_ci
8884514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitHotnessThresholdOffset(GateRef profileTypeInfo)
8894514f5e3Sopenharmony_ci{
8904514f5e3Sopenharmony_ci    GateRef bitFieldOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
8914514f5e3Sopenharmony_ci    return PtrAdd(bitFieldOffset,
8924514f5e3Sopenharmony_ci        IntPtr(ProfileTypeInfo::JIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD));
8934514f5e3Sopenharmony_ci}
8944514f5e3Sopenharmony_ci
8954514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitHotnessCntOffset(GateRef profileTypeInfo)
8964514f5e3Sopenharmony_ci{
8974514f5e3Sopenharmony_ci    GateRef thresholdOffset = GetJitHotnessThresholdOffset(profileTypeInfo);
8984514f5e3Sopenharmony_ci    return PtrAdd(thresholdOffset, IntPtr(ProfileTypeInfo::JIT_CNT_OFFSET_FROM_THRESHOLD));
8994514f5e3Sopenharmony_ci}
9004514f5e3Sopenharmony_ci
9014514f5e3Sopenharmony_civoid ProfilerStubBuilder::SetJitHotnessCnt(GateRef glue, GateRef profileTypeInfo, GateRef hotnessCnt)
9024514f5e3Sopenharmony_ci{
9034514f5e3Sopenharmony_ci    GateRef hotnessCntOffset = GetJitHotnessCntOffset(profileTypeInfo);
9044514f5e3Sopenharmony_ci    Store(VariableType::INT16(), glue, profileTypeInfo, hotnessCntOffset, hotnessCnt);
9054514f5e3Sopenharmony_ci}
9064514f5e3Sopenharmony_ci
9074514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitHotnessCnt(GateRef profileTypeInfo)
9084514f5e3Sopenharmony_ci{
9094514f5e3Sopenharmony_ci    GateRef hotnessCntOffset = GetJitHotnessCntOffset(profileTypeInfo);
9104514f5e3Sopenharmony_ci    GateRef hotnessCnt = Load(VariableType::INT16(), profileTypeInfo, hotnessCntOffset);
9114514f5e3Sopenharmony_ci    return ZExtInt16ToInt32(hotnessCnt);
9124514f5e3Sopenharmony_ci}
9134514f5e3Sopenharmony_ci
9144514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitHotnessThreshold(GateRef profileTypeInfo)
9154514f5e3Sopenharmony_ci{
9164514f5e3Sopenharmony_ci    GateRef hotnessThresholdOffset = GetJitHotnessThresholdOffset(profileTypeInfo);
9174514f5e3Sopenharmony_ci    GateRef hotnessThreshold = Load(VariableType::INT16(), profileTypeInfo, hotnessThresholdOffset);
9184514f5e3Sopenharmony_ci    return ZExtInt16ToInt32(hotnessThreshold);
9194514f5e3Sopenharmony_ci}
9204514f5e3Sopenharmony_ci
9214514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitCallThresholdOffset(GateRef profileTypeInfo)
9224514f5e3Sopenharmony_ci{
9234514f5e3Sopenharmony_ci    GateRef bitFieldOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
9244514f5e3Sopenharmony_ci    return PtrAdd(bitFieldOffset,
9254514f5e3Sopenharmony_ci                  IntPtr(ProfileTypeInfo::JIT_CALL_THRESHOLD_OFFSET_FROM_BITFIELD));
9264514f5e3Sopenharmony_ci}
9274514f5e3Sopenharmony_ci
9284514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitCallThreshold(GateRef profileTypeInfo)
9294514f5e3Sopenharmony_ci{
9304514f5e3Sopenharmony_ci    GateRef jitCallThresholdOffset = GetJitCallThresholdOffset(profileTypeInfo);
9314514f5e3Sopenharmony_ci    GateRef jitCallThreshold = Load(VariableType::INT8(), profileTypeInfo, jitCallThresholdOffset);
9324514f5e3Sopenharmony_ci    return ZExtInt8ToInt32(jitCallThreshold);
9334514f5e3Sopenharmony_ci}
9344514f5e3Sopenharmony_ci
9354514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitCallCntOffset(GateRef profileTypeInfo)
9364514f5e3Sopenharmony_ci{
9374514f5e3Sopenharmony_ci    GateRef jitCallThresholdOffset = GetJitCallThresholdOffset(profileTypeInfo);
9384514f5e3Sopenharmony_ci    return PtrAdd(jitCallThresholdOffset, IntPtr(ProfileTypeInfo::JIT_CALL_CNT_OFFSET_FROM_JIT_CALL_THRESHOLD));
9394514f5e3Sopenharmony_ci}
9404514f5e3Sopenharmony_ci
9414514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetJitCallCnt(GateRef profileTypeInfo)
9424514f5e3Sopenharmony_ci{
9434514f5e3Sopenharmony_ci    GateRef jitCallCntOffset = GetJitCallCntOffset(profileTypeInfo);
9444514f5e3Sopenharmony_ci    GateRef jitCallCnt = Load(VariableType::INT8(), profileTypeInfo, jitCallCntOffset);
9454514f5e3Sopenharmony_ci    return ZExtInt8ToInt32(jitCallCnt);
9464514f5e3Sopenharmony_ci}
9474514f5e3Sopenharmony_ci
9484514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetOsrHotnessThresholdOffset(GateRef profileTypeInfo)
9494514f5e3Sopenharmony_ci{
9504514f5e3Sopenharmony_ci    GateRef bitFieldOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
9514514f5e3Sopenharmony_ci    return PtrAdd(bitFieldOffset,
9524514f5e3Sopenharmony_ci                  IntPtr(ProfileTypeInfo::OSR_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD));
9534514f5e3Sopenharmony_ci}
9544514f5e3Sopenharmony_ci
9554514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetOsrHotnessThreshold(GateRef profileTypeInfo)
9564514f5e3Sopenharmony_ci{
9574514f5e3Sopenharmony_ci    GateRef hotnessThresholdOffset = GetOsrHotnessThresholdOffset(profileTypeInfo);
9584514f5e3Sopenharmony_ci    GateRef hotnessThreshold = Load(VariableType::INT16(), profileTypeInfo, hotnessThresholdOffset);
9594514f5e3Sopenharmony_ci    return ZExtInt16ToInt32(hotnessThreshold);
9604514f5e3Sopenharmony_ci}
9614514f5e3Sopenharmony_ci
9624514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetBaselineJitHotnessThresholdOffset(GateRef profileTypeInfo)
9634514f5e3Sopenharmony_ci{
9644514f5e3Sopenharmony_ci    GateRef bitFieldOffset = GetBitFieldOffsetFromProfileTypeInfo(profileTypeInfo);
9654514f5e3Sopenharmony_ci    return PtrAdd(bitFieldOffset,
9664514f5e3Sopenharmony_ci                  IntPtr(ProfileTypeInfo::BASELINEJIT_HOTNESS_THRESHOLD_OFFSET_FROM_BITFIELD));
9674514f5e3Sopenharmony_ci}
9684514f5e3Sopenharmony_ci
9694514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetBaselineJitHotnessThreshold(GateRef profileTypeInfo)
9704514f5e3Sopenharmony_ci{
9714514f5e3Sopenharmony_ci    GateRef hotnessThresholdOffset = GetBaselineJitHotnessThresholdOffset(profileTypeInfo);
9724514f5e3Sopenharmony_ci    GateRef hotnessThreshold = Load(VariableType::INT16(), profileTypeInfo, hotnessThresholdOffset);
9734514f5e3Sopenharmony_ci    return ZExtInt16ToInt32(hotnessThreshold);
9744514f5e3Sopenharmony_ci}
9754514f5e3Sopenharmony_ci
9764514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetOsrHotnessCntOffset(GateRef profileTypeInfo)
9774514f5e3Sopenharmony_ci{
9784514f5e3Sopenharmony_ci    GateRef thresholdOffset = GetOsrHotnessThresholdOffset(profileTypeInfo);
9794514f5e3Sopenharmony_ci    return PtrAdd(thresholdOffset, IntPtr(ProfileTypeInfo::OSR_CNT_OFFSET_FROM_OSR_THRESHOLD));
9804514f5e3Sopenharmony_ci}
9814514f5e3Sopenharmony_ci
9824514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::GetOsrHotnessCnt(GateRef profileTypeInfo)
9834514f5e3Sopenharmony_ci{
9844514f5e3Sopenharmony_ci    GateRef hotnessCntOffset = GetOsrHotnessCntOffset(profileTypeInfo);
9854514f5e3Sopenharmony_ci    GateRef hotnessCnt = Load(VariableType::INT16(), profileTypeInfo, hotnessCntOffset);
9864514f5e3Sopenharmony_ci    return ZExtInt16ToInt32(hotnessCnt);
9874514f5e3Sopenharmony_ci}
9884514f5e3Sopenharmony_ci
9894514f5e3Sopenharmony_ciGateRef ProfilerStubBuilder::IsCompiledOrTryCompile(GateRef glue, GateRef func, GateRef profileTypeInfo)
9904514f5e3Sopenharmony_ci{
9914514f5e3Sopenharmony_ci    auto env = GetEnvironment();
9924514f5e3Sopenharmony_ci    Label subEntry(env);
9934514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
9944514f5e3Sopenharmony_ci
9954514f5e3Sopenharmony_ci    DEFVARIABLE(result, VariableType::BOOL(), False());
9964514f5e3Sopenharmony_ci
9974514f5e3Sopenharmony_ci    GateRef hotnessThreshold = GetJitHotnessThreshold(profileTypeInfo);
9984514f5e3Sopenharmony_ci    GateRef hotnessCnt = GetJitHotnessCnt(profileTypeInfo);
9994514f5e3Sopenharmony_ci    GateRef jitCallThreshold = GetJitCallThreshold(profileTypeInfo);
10004514f5e3Sopenharmony_ci    GateRef jitCallCnt = GetJitCallCnt(profileTypeInfo);
10014514f5e3Sopenharmony_ci
10024514f5e3Sopenharmony_ci    Label cmpJitHotnessCnt(env);
10034514f5e3Sopenharmony_ci    Label checkJitCallThreshold(env);
10044514f5e3Sopenharmony_ci    Label cmpJitCallThreshold(env);
10054514f5e3Sopenharmony_ci    Label equalJitCallThreshold(env);
10064514f5e3Sopenharmony_ci    Label notEqualJitCallThreshold(env);
10074514f5e3Sopenharmony_ci    Label incJitCallCnt(env);
10084514f5e3Sopenharmony_ci    Label setResultAsTrue(env);
10094514f5e3Sopenharmony_ci    Label exit(env);
10104514f5e3Sopenharmony_ci
10114514f5e3Sopenharmony_ci    Branch(Int32Equal(hotnessThreshold, Int32(ProfileTypeInfo::JIT_DISABLE_FLAG)), &setResultAsTrue, &cmpJitHotnessCnt);
10124514f5e3Sopenharmony_ci    Bind(&cmpJitHotnessCnt);
10134514f5e3Sopenharmony_ci    BRANCH(Int32GreaterThan(hotnessCnt, hotnessThreshold), &setResultAsTrue, &checkJitCallThreshold);
10144514f5e3Sopenharmony_ci    Bind(&checkJitCallThreshold);
10154514f5e3Sopenharmony_ci    BRANCH(Int32Equal(jitCallThreshold, Int32(ProfileTypeInfo::INITIAL_JIT_CALL_THRESHOLD)),
10164514f5e3Sopenharmony_ci           &exit, &cmpJitCallThreshold);
10174514f5e3Sopenharmony_ci    Bind(&cmpJitCallThreshold);
10184514f5e3Sopenharmony_ci    BRANCH(Int32Equal(jitCallCnt, jitCallThreshold), &equalJitCallThreshold, &notEqualJitCallThreshold);
10194514f5e3Sopenharmony_ci    Bind(&equalJitCallThreshold);
10204514f5e3Sopenharmony_ci    {
10214514f5e3Sopenharmony_ci        DEFVARIABLE(invalidOsrOffset, VariableType::INT32(), Int32(MachineCode::INVALID_OSR_OFFSET));
10224514f5e3Sopenharmony_ci        CallRuntime(glue, RTSTUB_ID(JitCompile), { func, IntToTaggedInt(*invalidOsrOffset) });
10234514f5e3Sopenharmony_ci        GateRef newJitCallCnt = Int32Add(jitCallCnt, Int32(1));
10244514f5e3Sopenharmony_ci        GateRef jitCallCntOffset = GetJitCallCntOffset(profileTypeInfo);
10254514f5e3Sopenharmony_ci        Store(VariableType::INT8(), glue, profileTypeInfo, jitCallCntOffset, TruncInt32ToInt8(newJitCallCnt));
10264514f5e3Sopenharmony_ci        Jump(&setResultAsTrue);
10274514f5e3Sopenharmony_ci    }
10284514f5e3Sopenharmony_ci    Bind(&notEqualJitCallThreshold);
10294514f5e3Sopenharmony_ci    BRANCH(Int32LessThan(jitCallCnt, jitCallThreshold), &incJitCallCnt, &setResultAsTrue);
10304514f5e3Sopenharmony_ci    Bind(&incJitCallCnt);
10314514f5e3Sopenharmony_ci    {
10324514f5e3Sopenharmony_ci        GateRef newJitCallCnt = Int32Add(jitCallCnt, Int32(1));
10334514f5e3Sopenharmony_ci        GateRef jitCallCntOffset = GetJitCallCntOffset(profileTypeInfo);
10344514f5e3Sopenharmony_ci        Store(VariableType::INT8(), glue, profileTypeInfo, jitCallCntOffset, TruncInt32ToInt8(newJitCallCnt));
10354514f5e3Sopenharmony_ci        Jump(&exit);
10364514f5e3Sopenharmony_ci    }
10374514f5e3Sopenharmony_ci    Bind(&setResultAsTrue);
10384514f5e3Sopenharmony_ci    result = True();
10394514f5e3Sopenharmony_ci    Jump(&exit);
10404514f5e3Sopenharmony_ci    Bind(&exit);
10414514f5e3Sopenharmony_ci    GateRef ret = *result;
10424514f5e3Sopenharmony_ci    env->SubCfgExit();
10434514f5e3Sopenharmony_ci    return ret;
10444514f5e3Sopenharmony_ci}
10454514f5e3Sopenharmony_ci
10464514f5e3Sopenharmony_civoid ProfilerStubBuilder::TryJitCompile(GateRef glue, OffsetInfo offsetInfo,
10474514f5e3Sopenharmony_ci                                        GateRef func, GateRef profileTypeInfo)
10484514f5e3Sopenharmony_ci{
10494514f5e3Sopenharmony_ci    auto env = GetEnvironment();
10504514f5e3Sopenharmony_ci    Label subEntry(env);
10514514f5e3Sopenharmony_ci    env->SubCfgEntry(&subEntry);
10524514f5e3Sopenharmony_ci    Label equalJitThreshold(env);
10534514f5e3Sopenharmony_ci    Label equalBaselineJitThreshold(env);
10544514f5e3Sopenharmony_ci    Label notEqualJitThreshold(env);
10554514f5e3Sopenharmony_ci    Label checkEqualJitThreshold(env);
10564514f5e3Sopenharmony_ci    Label incJitHotnessCntAndCmpOpcode(env);
10574514f5e3Sopenharmony_ci    Label incJitHotnessCntAndExit(env);
10584514f5e3Sopenharmony_ci    Label cmpOpcode(env);
10594514f5e3Sopenharmony_ci    Label cmpOsrThreshold(env);
10604514f5e3Sopenharmony_ci    Label equalOsrThreshold(env);
10614514f5e3Sopenharmony_ci    Label notEqualOsrThreshold(env);
10624514f5e3Sopenharmony_ci    Label incOsrHotnessCnt(env);
10634514f5e3Sopenharmony_ci    Label checkFastJit(env);
10644514f5e3Sopenharmony_ci    Label checkBaselineJit(env);
10654514f5e3Sopenharmony_ci    Label exit(env);
10664514f5e3Sopenharmony_ci    Label checkNeedIncHotnessCnt(env);
10674514f5e3Sopenharmony_ci
10684514f5e3Sopenharmony_ci    GateRef jitHotnessThreshold = GetJitHotnessThreshold(profileTypeInfo);
10694514f5e3Sopenharmony_ci    GateRef jitHotnessCnt = GetJitHotnessCnt(profileTypeInfo);
10704514f5e3Sopenharmony_ci    GateRef osrHotnessThreshold = GetOsrHotnessThreshold(profileTypeInfo);
10714514f5e3Sopenharmony_ci    GateRef osrHotnessCnt = GetOsrHotnessCnt(profileTypeInfo);
10724514f5e3Sopenharmony_ci    GateRef baselineJitHotnessThreshold = GetBaselineJitHotnessThreshold(profileTypeInfo);
10734514f5e3Sopenharmony_ci    Branch(Int32Equal(baselineJitHotnessThreshold, Int32(ProfileTypeInfo::JIT_DISABLE_FLAG)),
10744514f5e3Sopenharmony_ci        &checkFastJit, &checkBaselineJit);
10754514f5e3Sopenharmony_ci
10764514f5e3Sopenharmony_ci    Bind(&checkBaselineJit);
10774514f5e3Sopenharmony_ci    BRANCH(Int32Equal(jitHotnessCnt, baselineJitHotnessThreshold),
10784514f5e3Sopenharmony_ci        &equalBaselineJitThreshold, &checkFastJit);
10794514f5e3Sopenharmony_ci    Bind(&equalBaselineJitThreshold);
10804514f5e3Sopenharmony_ci    {
10814514f5e3Sopenharmony_ci        CallRuntime(glue, RTSTUB_ID(BaselineJitCompile), { func });
10824514f5e3Sopenharmony_ci        Jump(&checkFastJit);
10834514f5e3Sopenharmony_ci    }
10844514f5e3Sopenharmony_ci
10854514f5e3Sopenharmony_ci    Bind(&checkFastJit);
10864514f5e3Sopenharmony_ci    Branch(Int32Equal(jitHotnessThreshold, Int32(ProfileTypeInfo::JIT_DISABLE_FLAG)),
10874514f5e3Sopenharmony_ci        &checkNeedIncHotnessCnt, &checkEqualJitThreshold);
10884514f5e3Sopenharmony_ci    Bind(&checkNeedIncHotnessCnt);
10894514f5e3Sopenharmony_ci    Branch(Int32Equal(baselineJitHotnessThreshold, Int32(ProfileTypeInfo::JIT_DISABLE_FLAG)),
10904514f5e3Sopenharmony_ci        &exit, &incJitHotnessCntAndExit);
10914514f5e3Sopenharmony_ci
10924514f5e3Sopenharmony_ci    Bind(&checkEqualJitThreshold);
10934514f5e3Sopenharmony_ci    BRANCH(Int32Equal(jitHotnessCnt, jitHotnessThreshold), &equalJitThreshold, &notEqualJitThreshold);
10944514f5e3Sopenharmony_ci    Bind(&equalJitThreshold);
10954514f5e3Sopenharmony_ci    {
10964514f5e3Sopenharmony_ci        DEFVARIABLE(varOffset, VariableType::INT32(), Int32(MachineCode::INVALID_OSR_OFFSET));
10974514f5e3Sopenharmony_ci        CallRuntime(glue, RTSTUB_ID(JitCompile), { func, IntToTaggedInt(*varOffset) });
10984514f5e3Sopenharmony_ci        Jump(&incJitHotnessCntAndExit);
10994514f5e3Sopenharmony_ci    }
11004514f5e3Sopenharmony_ci    Bind(&notEqualJitThreshold);
11014514f5e3Sopenharmony_ci    {
11024514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(jitHotnessCnt, jitHotnessThreshold), &incJitHotnessCntAndCmpOpcode, &exit);
11034514f5e3Sopenharmony_ci    }
11044514f5e3Sopenharmony_ci    Bind(&incJitHotnessCntAndCmpOpcode);
11054514f5e3Sopenharmony_ci    {
11064514f5e3Sopenharmony_ci#if ECMASCRIPT_ENABLE_JIT_WARMUP_PROFILER
11074514f5e3Sopenharmony_ci        CallRuntime(glue, RTSTUB_ID(CountInterpExecFuncs), { func });
11084514f5e3Sopenharmony_ci#endif
11094514f5e3Sopenharmony_ci        GateRef newJitHotnessCnt = Int16Add(jitHotnessCnt, Int16(1));
11104514f5e3Sopenharmony_ci        GateRef jitHotnessCntOffset = GetJitHotnessCntOffset(profileTypeInfo);
11114514f5e3Sopenharmony_ci        Store(VariableType::INT16(), glue, profileTypeInfo, jitHotnessCntOffset, newJitHotnessCnt);
11124514f5e3Sopenharmony_ci        Jump(&cmpOpcode);
11134514f5e3Sopenharmony_ci    }
11144514f5e3Sopenharmony_ci    Bind(&incJitHotnessCntAndExit);
11154514f5e3Sopenharmony_ci    {
11164514f5e3Sopenharmony_ci        GateRef newJitHotnessCnt = Int16Add(jitHotnessCnt, Int16(1));
11174514f5e3Sopenharmony_ci        GateRef jitHotnessCntOffset = GetJitHotnessCntOffset(profileTypeInfo);
11184514f5e3Sopenharmony_ci        Store(VariableType::INT16(), glue, profileTypeInfo, jitHotnessCntOffset, newJitHotnessCnt);
11194514f5e3Sopenharmony_ci        Jump(&exit);
11204514f5e3Sopenharmony_ci    }
11214514f5e3Sopenharmony_ci    Bind(&cmpOpcode);
11224514f5e3Sopenharmony_ci    {
11234514f5e3Sopenharmony_ci        GateRef isJmp = 0;
11244514f5e3Sopenharmony_ci        if (offsetInfo.isPc) {
11254514f5e3Sopenharmony_ci            GateRef opcode = Load(VariableType::INT8(), offsetInfo.pc);
11264514f5e3Sopenharmony_ci            GateRef jmpImm8 = Int8(static_cast<uint8_t>(EcmaOpcode::JMP_IMM8));
11274514f5e3Sopenharmony_ci            GateRef jmpImm16 = Int8(static_cast<uint8_t>(EcmaOpcode::JMP_IMM16));
11284514f5e3Sopenharmony_ci            GateRef jmpImm32 = Int8(static_cast<uint8_t>(EcmaOpcode::JMP_IMM32));
11294514f5e3Sopenharmony_ci            isJmp = BitOr(Int8Equal(opcode, jmpImm8), Int8Equal(opcode, jmpImm16));
11304514f5e3Sopenharmony_ci            isJmp = BitOr(isJmp, Int8Equal(opcode, jmpImm32));
11314514f5e3Sopenharmony_ci        } else {
11324514f5e3Sopenharmony_ci            isJmp = Boolean(offsetInfo.offset == 0);
11334514f5e3Sopenharmony_ci        }
11344514f5e3Sopenharmony_ci        BRANCH(isJmp, &cmpOsrThreshold, &exit);
11354514f5e3Sopenharmony_ci    }
11364514f5e3Sopenharmony_ci    Bind(&cmpOsrThreshold);
11374514f5e3Sopenharmony_ci    {
11384514f5e3Sopenharmony_ci        BRANCH(Int32Equal(osrHotnessCnt, osrHotnessThreshold), &equalOsrThreshold, &notEqualOsrThreshold);
11394514f5e3Sopenharmony_ci    }
11404514f5e3Sopenharmony_ci    Bind(&equalOsrThreshold);
11414514f5e3Sopenharmony_ci    {
11424514f5e3Sopenharmony_ci        GateRef method = GetMethodFromJSFunctionOrProxy(func);
11434514f5e3Sopenharmony_ci        GateRef firstPC = Load(VariableType::NATIVE_POINTER(), method,
11444514f5e3Sopenharmony_ci                               IntPtr(Method::NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET));
11454514f5e3Sopenharmony_ci        GateRef offset = offsetInfo.isPc ? TaggedPtrToTaggedIntPtr(PtrSub(offsetInfo.pc, firstPC))
11464514f5e3Sopenharmony_ci                                         : offsetInfo.offset;
11474514f5e3Sopenharmony_ci        CallRuntime(glue, RTSTUB_ID(JitCompile), { func, offset });
11484514f5e3Sopenharmony_ci        GateRef osrHotnessCntOffset = GetOsrHotnessCntOffset(profileTypeInfo);
11494514f5e3Sopenharmony_ci        Store(VariableType::INT16(), glue, profileTypeInfo, osrHotnessCntOffset, Int16(0));
11504514f5e3Sopenharmony_ci        Jump(&exit);
11514514f5e3Sopenharmony_ci    }
11524514f5e3Sopenharmony_ci    Bind(&notEqualOsrThreshold);
11534514f5e3Sopenharmony_ci    {
11544514f5e3Sopenharmony_ci        BRANCH(Int32LessThan(osrHotnessCnt, osrHotnessThreshold), &incOsrHotnessCnt, &exit);
11554514f5e3Sopenharmony_ci    }
11564514f5e3Sopenharmony_ci    Bind(&incOsrHotnessCnt);
11574514f5e3Sopenharmony_ci    {
11584514f5e3Sopenharmony_ci        GateRef newOsrHotnessCnt = Int16Add(osrHotnessCnt, Int16(1));
11594514f5e3Sopenharmony_ci        GateRef osrHotnessCntOffset = GetOsrHotnessCntOffset(profileTypeInfo);
11604514f5e3Sopenharmony_ci        Store(VariableType::INT16(), glue, profileTypeInfo, osrHotnessCntOffset, newOsrHotnessCnt);
11614514f5e3Sopenharmony_ci        Jump(&exit);
11624514f5e3Sopenharmony_ci    }
11634514f5e3Sopenharmony_ci    Bind(&exit);
11644514f5e3Sopenharmony_ci    env->SubCfgExit();
11654514f5e3Sopenharmony_ci}
11664514f5e3Sopenharmony_ci
11674514f5e3Sopenharmony_civoid ProfilerStubBuilder::PGOProfiler(GateRef glue, GateRef func, GateRef profileTypeInfo,
11684514f5e3Sopenharmony_ci    SlotIDInfo slotIdInfo, const std::vector<GateRef> &values, OperationType type)
11694514f5e3Sopenharmony_ci{
11704514f5e3Sopenharmony_ci    switch (type) {
11714514f5e3Sopenharmony_ci        case OperationType::CALL:
11724514f5e3Sopenharmony_ci            ProfileCall(glue, slotIdInfo, func, values[0], profileTypeInfo);
11734514f5e3Sopenharmony_ci            break;
11744514f5e3Sopenharmony_ci        case OperationType::NATIVE_CALL:
11754514f5e3Sopenharmony_ci            ProfileNativeCall(glue, slotIdInfo, func, values[0], profileTypeInfo);
11764514f5e3Sopenharmony_ci            break;
11774514f5e3Sopenharmony_ci        case OperationType::GETTER_SETTER_CALL:
11784514f5e3Sopenharmony_ci            ProfileGetterSetterCall(glue, values[0]);
11794514f5e3Sopenharmony_ci            break;
11804514f5e3Sopenharmony_ci        case OperationType::OPERATION_TYPE:
11814514f5e3Sopenharmony_ci            ProfileOpType(glue, slotIdInfo, func, profileTypeInfo, values[0]);
11824514f5e3Sopenharmony_ci            break;
11834514f5e3Sopenharmony_ci        case OperationType::DEFINE_CLASS:
11844514f5e3Sopenharmony_ci            ProfileDefineClass(glue, slotIdInfo, func, values[0], profileTypeInfo);
11854514f5e3Sopenharmony_ci            break;
11864514f5e3Sopenharmony_ci        case OperationType::CREATE_OBJECT:
11874514f5e3Sopenharmony_ci            ProfileCreateObject(glue, slotIdInfo, func, values[0], profileTypeInfo);
11884514f5e3Sopenharmony_ci            break;
11894514f5e3Sopenharmony_ci        case OperationType::TRY_DUMP:
11904514f5e3Sopenharmony_ci            TryDump(glue, func, profileTypeInfo);
11914514f5e3Sopenharmony_ci            break;
11924514f5e3Sopenharmony_ci        case OperationType::TRY_PREDUMP:
11934514f5e3Sopenharmony_ci            TryPreDump(glue, func, profileTypeInfo);
11944514f5e3Sopenharmony_ci            break;
11954514f5e3Sopenharmony_ci        case OperationType::TRUE_BRANCH:
11964514f5e3Sopenharmony_ci            ProfileBranch(glue, slotIdInfo, func, profileTypeInfo, true);
11974514f5e3Sopenharmony_ci            break;
11984514f5e3Sopenharmony_ci        case OperationType::FALSE_BRANCH:
11994514f5e3Sopenharmony_ci            ProfileBranch(glue, slotIdInfo, func, profileTypeInfo, false);
12004514f5e3Sopenharmony_ci            break;
12014514f5e3Sopenharmony_ci        case OperationType::ITERATOR_FUNC_KIND:
12024514f5e3Sopenharmony_ci            ProfileGetIterator(glue, slotIdInfo, func, values[0], profileTypeInfo);
12034514f5e3Sopenharmony_ci            break;
12044514f5e3Sopenharmony_ci        case OperationType::TRY_JIT:
12054514f5e3Sopenharmony_ci            TryJitCompile(glue, { 0, slotIdInfo.GetPC(), true }, func, profileTypeInfo);
12064514f5e3Sopenharmony_ci            break;
12074514f5e3Sopenharmony_ci        default:
12084514f5e3Sopenharmony_ci            break;
12094514f5e3Sopenharmony_ci    }
12104514f5e3Sopenharmony_ci}
12114514f5e3Sopenharmony_ci} // namespace panda::ecmascript::kungfu
1212