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), ¤tIsHot, &exit); 2624514f5e3Sopenharmony_ci } 2634514f5e3Sopenharmony_ci Bind(¤tIsHot); 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), ¤tIsHot, &exit); 3714514f5e3Sopenharmony_ci Bind(¤tIsHot); 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, ¬Overflow); // hole -- slot is overflow 3864514f5e3Sopenharmony_ci Bind(¬Overflow); 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, ¬Int); 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(¬Int); 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, ¬ArrayProtoValues); 6844514f5e3Sopenharmony_ci Bind(&isArrayProtoValues); 6854514f5e3Sopenharmony_ci { 6864514f5e3Sopenharmony_ci functionId = Int32(PGO_BUILTINS_STUB_ID(ArrayProtoIterator)); 6874514f5e3Sopenharmony_ci Jump(&exit); 6884514f5e3Sopenharmony_ci } 6894514f5e3Sopenharmony_ci Bind(¬ArrayProtoValues); 6904514f5e3Sopenharmony_ci maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::SET_PROTO_VALUES_FUNCTION_INDEX); 6914514f5e3Sopenharmony_ci BRANCH(Int64Equal(iterator, *maybeFunc), &isSetProtoValues, ¬SetProtoValues); 6924514f5e3Sopenharmony_ci Bind(&isSetProtoValues); 6934514f5e3Sopenharmony_ci { 6944514f5e3Sopenharmony_ci functionId = Int32(PGO_BUILTINS_STUB_ID(SetProtoIterator)); 6954514f5e3Sopenharmony_ci Jump(&exit); 6964514f5e3Sopenharmony_ci } 6974514f5e3Sopenharmony_ci Bind(¬SetProtoValues); 6984514f5e3Sopenharmony_ci maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::MAP_PROTO_ENTRIES_FUNCTION_INDEX); 6994514f5e3Sopenharmony_ci BRANCH(Int64Equal(iterator, *maybeFunc), &isMapProtoEntries, ¬MapProtoEntries); 7004514f5e3Sopenharmony_ci Bind(&isMapProtoEntries); 7014514f5e3Sopenharmony_ci { 7024514f5e3Sopenharmony_ci functionId = Int32(PGO_BUILTINS_STUB_ID(MapProtoIterator)); 7034514f5e3Sopenharmony_ci Jump(&exit); 7044514f5e3Sopenharmony_ci } 7054514f5e3Sopenharmony_ci Bind(¬MapProtoEntries); 7064514f5e3Sopenharmony_ci maybeFunc = GetGlobalEnvValue(VariableType::JS_ANY(), glueGlobalEnv, GlobalEnv::STRING_PROTO_ITER_FUNCTION_INDEX); 7074514f5e3Sopenharmony_ci BRANCH(Int64Equal(iterator, *maybeFunc), &isStringProtoIter, ¬StringProtoIter); 7084514f5e3Sopenharmony_ci Bind(&isStringProtoIter); 7094514f5e3Sopenharmony_ci { 7104514f5e3Sopenharmony_ci functionId = Int32(PGO_BUILTINS_STUB_ID(StringProtoIterator)); 7114514f5e3Sopenharmony_ci Jump(&exit); 7124514f5e3Sopenharmony_ci } 7134514f5e3Sopenharmony_ci Bind(¬StringProtoIter); 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, ¬Overflow); // hole -- slot is overflow 7534514f5e3Sopenharmony_ci Bind(¬Overflow); 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, ¬EqualJitCallThreshold); 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(¬EqualJitCallThreshold); 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, ¬EqualJitThreshold); 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(¬EqualJitThreshold); 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, ¬EqualOsrThreshold); 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(¬EqualOsrThreshold); 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