14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2024 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#include "ecmascript/jit/jit_profiler.h" 164514f5e3Sopenharmony_ci 174514f5e3Sopenharmony_ci#include <chrono> 184514f5e3Sopenharmony_ci#include <cstdint> 194514f5e3Sopenharmony_ci#include <memory> 204514f5e3Sopenharmony_ci 214514f5e3Sopenharmony_ci#include "ecmascript/compiler/jit_compilation_env.h" 224514f5e3Sopenharmony_ci#include "ecmascript/compiler/pgo_type/pgo_type_manager.h" 234514f5e3Sopenharmony_ci#include "ecmascript/enum_conversion.h" 244514f5e3Sopenharmony_ci#include "ecmascript/interpreter/interpreter-inl.h" 254514f5e3Sopenharmony_ci 264514f5e3Sopenharmony_cinamespace panda::ecmascript { 274514f5e3Sopenharmony_ciusing namespace pgo; 284514f5e3Sopenharmony_ciJITProfiler::JITProfiler(EcmaVM *vm) : vm_(vm) 294514f5e3Sopenharmony_ci{ 304514f5e3Sopenharmony_ci} 314514f5e3Sopenharmony_ci 324514f5e3Sopenharmony_civoid JITProfiler::ProfileBytecode(JSThread *thread, const JSHandle<ProfileTypeInfo> &profileTypeInfo, 334514f5e3Sopenharmony_ci ProfileTypeInfo *rawProfileTypeInfo, 344514f5e3Sopenharmony_ci EntityId methodId, ApEntityId abcId, const uint8_t *pcStart, uint32_t codeSize, 354514f5e3Sopenharmony_ci [[maybe_unused]]const panda_file::File::Header *header, bool useRawProfileTypeInfo) 364514f5e3Sopenharmony_ci{ 374514f5e3Sopenharmony_ci Clear(); 384514f5e3Sopenharmony_ci if (useRawProfileTypeInfo) { 394514f5e3Sopenharmony_ci profileTypeInfo_ = rawProfileTypeInfo; 404514f5e3Sopenharmony_ci } 414514f5e3Sopenharmony_ci abcId_ = abcId; 424514f5e3Sopenharmony_ci methodId_ = methodId; 434514f5e3Sopenharmony_ci BytecodeInstruction bcIns(pcStart); 444514f5e3Sopenharmony_ci auto bcInsLast = bcIns.JumpTo(codeSize); 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_ci while (bcIns.GetAddress() != bcInsLast.GetAddress()) { 474514f5e3Sopenharmony_ci auto opcode = bcIns.GetOpcode(); 484514f5e3Sopenharmony_ci auto bcOffset = bcIns.GetAddress() - pcStart; 494514f5e3Sopenharmony_ci auto pc = bcIns.GetAddress(); 504514f5e3Sopenharmony_ci switch (opcode) { 514514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYNAME_IMM8_ID16: 524514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYNAME_IMM8_ID16: { 534514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 544514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 554514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 564514f5e3Sopenharmony_ci } 574514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 584514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 594514f5e3Sopenharmony_ci ConvertICByName(bcOffset, slotId, BCType::LOAD); 604514f5e3Sopenharmony_ci break; 614514f5e3Sopenharmony_ci } 624514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYNAME_IMM16_ID16: 634514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYNAME_IMM16_ID16: { 644514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 654514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 664514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 674514f5e3Sopenharmony_ci } 684514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 694514f5e3Sopenharmony_ci ConvertICByName(bcOffset, slotId, BCType::LOAD); 704514f5e3Sopenharmony_ci break; 714514f5e3Sopenharmony_ci } 724514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYVALUE_IMM8_V8: 734514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYVALUE_IMM8: { 744514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 754514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 764514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 774514f5e3Sopenharmony_ci } 784514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 794514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 804514f5e3Sopenharmony_ci ConvertICByValue(bcOffset, slotId, BCType::LOAD); 814514f5e3Sopenharmony_ci break; 824514f5e3Sopenharmony_ci } 834514f5e3Sopenharmony_ci case EcmaOpcode::LDOBJBYVALUE_IMM16_V8: 844514f5e3Sopenharmony_ci case EcmaOpcode::LDTHISBYVALUE_IMM16: { 854514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 864514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 874514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 884514f5e3Sopenharmony_ci } 894514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 904514f5e3Sopenharmony_ci ConvertICByValue(bcOffset, slotId, BCType::LOAD); 914514f5e3Sopenharmony_ci break; 924514f5e3Sopenharmony_ci } 934514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYNAME_IMM8_ID16_V8: 944514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYNAME_IMM8_ID16: 954514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEPROPERTYBYNAME_IMM8_ID16_V8: 964514f5e3Sopenharmony_ci case EcmaOpcode::STPRIVATEPROPERTY_IMM8_IMM16_IMM16_V8: { 974514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 984514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 994514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 1004514f5e3Sopenharmony_ci } 1014514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 1024514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 1034514f5e3Sopenharmony_ci ConvertICByName(bcOffset, slotId, BCType::STORE); 1044514f5e3Sopenharmony_ci break; 1054514f5e3Sopenharmony_ci } 1064514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYNAME_IMM16_ID16_V8: 1074514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYNAME_IMM16_ID16: { 1084514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 1094514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 1104514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 1114514f5e3Sopenharmony_ci } 1124514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 1134514f5e3Sopenharmony_ci ConvertICByName(bcOffset, slotId, BCType::STORE); 1144514f5e3Sopenharmony_ci break; 1154514f5e3Sopenharmony_ci } 1164514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYVALUE_IMM8_V8_V8: 1174514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYINDEX_IMM8_V8_IMM16: 1184514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYVALUE_IMM8_V8: { 1194514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 1204514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 1214514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 1224514f5e3Sopenharmony_ci } 1234514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 1244514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 1254514f5e3Sopenharmony_ci ConvertICByValue(bcOffset, slotId, BCType::STORE); 1264514f5e3Sopenharmony_ci break; 1274514f5e3Sopenharmony_ci } 1284514f5e3Sopenharmony_ci case EcmaOpcode::STOBJBYVALUE_IMM16_V8_V8: 1294514f5e3Sopenharmony_ci case EcmaOpcode::STOWNBYINDEX_IMM16_V8_IMM16: 1304514f5e3Sopenharmony_ci case EcmaOpcode::STTHISBYVALUE_IMM16_V8: { 1314514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 1324514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 1334514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 1344514f5e3Sopenharmony_ci } 1354514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 1364514f5e3Sopenharmony_ci ConvertICByValue(bcOffset, slotId, BCType::STORE); 1374514f5e3Sopenharmony_ci break; 1384514f5e3Sopenharmony_ci } 1394514f5e3Sopenharmony_ci // Op 1404514f5e3Sopenharmony_ci case EcmaOpcode::ADD2_IMM8_V8: 1414514f5e3Sopenharmony_ci case EcmaOpcode::SUB2_IMM8_V8: 1424514f5e3Sopenharmony_ci case EcmaOpcode::MUL2_IMM8_V8: 1434514f5e3Sopenharmony_ci case EcmaOpcode::DIV2_IMM8_V8: 1444514f5e3Sopenharmony_ci case EcmaOpcode::MOD2_IMM8_V8: 1454514f5e3Sopenharmony_ci case EcmaOpcode::SHL2_IMM8_V8: 1464514f5e3Sopenharmony_ci case EcmaOpcode::SHR2_IMM8_V8: 1474514f5e3Sopenharmony_ci case EcmaOpcode::AND2_IMM8_V8: 1484514f5e3Sopenharmony_ci case EcmaOpcode::OR2_IMM8_V8: 1494514f5e3Sopenharmony_ci case EcmaOpcode::XOR2_IMM8_V8: 1504514f5e3Sopenharmony_ci case EcmaOpcode::ASHR2_IMM8_V8: 1514514f5e3Sopenharmony_ci case EcmaOpcode::EXP_IMM8_V8: 1524514f5e3Sopenharmony_ci case EcmaOpcode::NEG_IMM8: 1534514f5e3Sopenharmony_ci case EcmaOpcode::NOT_IMM8: 1544514f5e3Sopenharmony_ci case EcmaOpcode::INC_IMM8: 1554514f5e3Sopenharmony_ci case EcmaOpcode::DEC_IMM8: 1564514f5e3Sopenharmony_ci case EcmaOpcode::EQ_IMM8_V8: 1574514f5e3Sopenharmony_ci case EcmaOpcode::NOTEQ_IMM8_V8: 1584514f5e3Sopenharmony_ci case EcmaOpcode::LESS_IMM8_V8: 1594514f5e3Sopenharmony_ci case EcmaOpcode::LESSEQ_IMM8_V8: 1604514f5e3Sopenharmony_ci case EcmaOpcode::GREATER_IMM8_V8: 1614514f5e3Sopenharmony_ci case EcmaOpcode::GREATEREQ_IMM8_V8: 1624514f5e3Sopenharmony_ci case EcmaOpcode::STRICTNOTEQ_IMM8_V8: 1634514f5e3Sopenharmony_ci case EcmaOpcode::STRICTEQ_IMM8_V8: 1644514f5e3Sopenharmony_ci case EcmaOpcode::TONUMERIC_IMM8: { 1654514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 1664514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 1674514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 1684514f5e3Sopenharmony_ci } 1694514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 1704514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 1714514f5e3Sopenharmony_ci ConvertOpType(slotId, bcOffset); 1724514f5e3Sopenharmony_ci break; 1734514f5e3Sopenharmony_ci } 1744514f5e3Sopenharmony_ci // Call 1754514f5e3Sopenharmony_ci case EcmaOpcode::CALLARG0_IMM8: 1764514f5e3Sopenharmony_ci case EcmaOpcode::CALLARG1_IMM8_V8: 1774514f5e3Sopenharmony_ci case EcmaOpcode::CALLARGS2_IMM8_V8_V8: 1784514f5e3Sopenharmony_ci case EcmaOpcode::CALLARGS3_IMM8_V8_V8_V8: 1794514f5e3Sopenharmony_ci case EcmaOpcode::CALLRANGE_IMM8_IMM8_V8: 1804514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS0_IMM8_V8: 1814514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS1_IMM8_V8_V8: 1824514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS2_IMM8_V8_V8_V8: 1834514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHIS3_IMM8_V8_V8_V8_V8: 1844514f5e3Sopenharmony_ci case EcmaOpcode::CALLTHISRANGE_IMM8_IMM8_V8: { 1854514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 1864514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 1874514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 1884514f5e3Sopenharmony_ci } 1894514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 1904514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 1914514f5e3Sopenharmony_ci ConvertCall(slotId, bcOffset); 1924514f5e3Sopenharmony_ci break; 1934514f5e3Sopenharmony_ci } 1944514f5e3Sopenharmony_ci case EcmaOpcode::CALLRUNTIME_CALLINIT_PREF_IMM8_V8: { 1954514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 1964514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 1974514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 1984514f5e3Sopenharmony_ci } 1994514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_1(); 2004514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 2014514f5e3Sopenharmony_ci ConvertCall(slotId, bcOffset); 2024514f5e3Sopenharmony_ci break; 2034514f5e3Sopenharmony_ci } 2044514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_CALLRANGE_PREF_IMM16_V8: 2054514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_CALLTHISRANGE_PREF_IMM16_V8: { 2064514f5e3Sopenharmony_ci // no ic slot 2074514f5e3Sopenharmony_ci break; 2084514f5e3Sopenharmony_ci } 2094514f5e3Sopenharmony_ci case EcmaOpcode::NEWOBJRANGE_IMM8_IMM8_V8: { 2104514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 2114514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 2124514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 2134514f5e3Sopenharmony_ci } 2144514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 2154514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 2164514f5e3Sopenharmony_ci ConvertNewObjRange(slotId, bcOffset); 2174514f5e3Sopenharmony_ci break; 2184514f5e3Sopenharmony_ci } 2194514f5e3Sopenharmony_ci case EcmaOpcode::NEWOBJRANGE_IMM16_IMM8_V8: { 2204514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 2214514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 2224514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 2234514f5e3Sopenharmony_ci } 2244514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 2254514f5e3Sopenharmony_ci ConvertNewObjRange(slotId, bcOffset); 2264514f5e3Sopenharmony_ci break; 2274514f5e3Sopenharmony_ci } 2284514f5e3Sopenharmony_ci case EcmaOpcode::WIDE_NEWOBJRANGE_PREF_IMM16_V8: { 2294514f5e3Sopenharmony_ci break; 2304514f5e3Sopenharmony_ci } 2314514f5e3Sopenharmony_ci // Create object 2324514f5e3Sopenharmony_ci case EcmaOpcode::DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8: { 2334514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 2344514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 2354514f5e3Sopenharmony_ci (void) slotId; 2364514f5e3Sopenharmony_ci break; 2374514f5e3Sopenharmony_ci } 2384514f5e3Sopenharmony_ci case EcmaOpcode::DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8: { 2394514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 2404514f5e3Sopenharmony_ci (void) slotId; 2414514f5e3Sopenharmony_ci break; 2424514f5e3Sopenharmony_ci } 2434514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEFUNC_IMM8_ID16_IMM8: { 2444514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 2454514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 2464514f5e3Sopenharmony_ci break; 2474514f5e3Sopenharmony_ci } 2484514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEFUNC_IMM16_ID16_IMM8: { 2494514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 2504514f5e3Sopenharmony_ci (void) slotId; 2514514f5e3Sopenharmony_ci break; 2524514f5e3Sopenharmony_ci } 2534514f5e3Sopenharmony_ci case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM8_ID16: 2544514f5e3Sopenharmony_ci case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM8_ID16: 2554514f5e3Sopenharmony_ci case EcmaOpcode::CREATEEMPTYARRAY_IMM8: { 2564514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 2574514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 2584514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 2594514f5e3Sopenharmony_ci } 2604514f5e3Sopenharmony_ci auto traceId = 2614514f5e3Sopenharmony_ci static_cast<int32_t>(reinterpret_cast<uintptr_t>(pc) - reinterpret_cast<uintptr_t>(header)); 2624514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 2634514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 2644514f5e3Sopenharmony_ci ConvertCreateObject(slotId, bcOffset, traceId); 2654514f5e3Sopenharmony_ci break; 2664514f5e3Sopenharmony_ci } 2674514f5e3Sopenharmony_ci case EcmaOpcode::CREATEOBJECTWITHBUFFER_IMM16_ID16: 2684514f5e3Sopenharmony_ci case EcmaOpcode::CREATEARRAYWITHBUFFER_IMM16_ID16: 2694514f5e3Sopenharmony_ci case EcmaOpcode::CREATEEMPTYARRAY_IMM16: { 2704514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 2714514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 2724514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 2734514f5e3Sopenharmony_ci } 2744514f5e3Sopenharmony_ci auto traceId = 2754514f5e3Sopenharmony_ci static_cast<int32_t>(reinterpret_cast<uintptr_t>(pc) - reinterpret_cast<uintptr_t>(header)); 2764514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 2774514f5e3Sopenharmony_ci ConvertCreateObject(slotId, bcOffset, traceId); 2784514f5e3Sopenharmony_ci break; 2794514f5e3Sopenharmony_ci } 2804514f5e3Sopenharmony_ci case EcmaOpcode::GETITERATOR_IMM8: { 2814514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 2824514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 2834514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 2844514f5e3Sopenharmony_ci } 2854514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 2864514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 2874514f5e3Sopenharmony_ci ConvertGetIterator(slotId, bcOffset); 2884514f5e3Sopenharmony_ci break; 2894514f5e3Sopenharmony_ci } 2904514f5e3Sopenharmony_ci case EcmaOpcode::GETITERATOR_IMM16: { 2914514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 2924514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 2934514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 2944514f5e3Sopenharmony_ci } 2954514f5e3Sopenharmony_ci uint16_t slotId = READ_INST_16_0(); 2964514f5e3Sopenharmony_ci ConvertGetIterator(slotId, bcOffset); 2974514f5e3Sopenharmony_ci break; 2984514f5e3Sopenharmony_ci } 2994514f5e3Sopenharmony_ci // Others 3004514f5e3Sopenharmony_ci case EcmaOpcode::INSTANCEOF_IMM8_V8: { 3014514f5e3Sopenharmony_ci Jit::JitLockHolder lock(thread); 3024514f5e3Sopenharmony_ci if (!useRawProfileTypeInfo) { 3034514f5e3Sopenharmony_ci profileTypeInfo_ = *profileTypeInfo; 3044514f5e3Sopenharmony_ci } 3054514f5e3Sopenharmony_ci uint8_t slotId = READ_INST_8_0(); 3064514f5e3Sopenharmony_ci CHECK_SLOTID_BREAK(slotId); 3074514f5e3Sopenharmony_ci ConvertInstanceof(bcOffset, slotId); 3084514f5e3Sopenharmony_ci break; 3094514f5e3Sopenharmony_ci } 3104514f5e3Sopenharmony_ci case EcmaOpcode::DEFINEGETTERSETTERBYVALUE_V8_V8_V8_V8: 3114514f5e3Sopenharmony_ci default: 3124514f5e3Sopenharmony_ci break; 3134514f5e3Sopenharmony_ci } 3144514f5e3Sopenharmony_ci bcIns = bcIns.GetNext(); 3154514f5e3Sopenharmony_ci } 3164514f5e3Sopenharmony_ci} 3174514f5e3Sopenharmony_ci 3184514f5e3Sopenharmony_ci// PGOSampleType 3194514f5e3Sopenharmony_civoid JITProfiler::ConvertOpType(uint32_t slotId, long bcOffset) 3204514f5e3Sopenharmony_ci{ 3214514f5e3Sopenharmony_ci JSTaggedValue slotValue = profileTypeInfo_->Get(slotId); 3224514f5e3Sopenharmony_ci if (slotValue.IsInt()) { 3234514f5e3Sopenharmony_ci auto type = slotValue.GetInt(); 3244514f5e3Sopenharmony_ci UpdatePGOType(bcOffset, chunk_->New<PGOSampleType>(type)); 3254514f5e3Sopenharmony_ci } 3264514f5e3Sopenharmony_ci} 3274514f5e3Sopenharmony_ci 3284514f5e3Sopenharmony_civoid JITProfiler::ConvertCall(uint32_t slotId, long bcOffset) 3294514f5e3Sopenharmony_ci{ 3304514f5e3Sopenharmony_ci JSTaggedValue slotValue = profileTypeInfo_->Get(slotId); 3314514f5e3Sopenharmony_ci ProfileType::Kind kind; 3324514f5e3Sopenharmony_ci int calleeMethodId = 0; 3334514f5e3Sopenharmony_ci ApEntityId calleeAbcId = 0; 3344514f5e3Sopenharmony_ci if (slotValue.IsInt()) { 3354514f5e3Sopenharmony_ci calleeMethodId = slotValue.GetInt(); 3364514f5e3Sopenharmony_ci if (calleeMethodId == 0) { 3374514f5e3Sopenharmony_ci return; 3384514f5e3Sopenharmony_ci } 3394514f5e3Sopenharmony_ci calleeAbcId = abcId_; 3404514f5e3Sopenharmony_ci ASSERT(calleeMethodId <= 0); 3414514f5e3Sopenharmony_ci kind = ProfileType::Kind::BuiltinFunctionId; 3424514f5e3Sopenharmony_ci } else if (slotValue.IsJSFunction()) { 3434514f5e3Sopenharmony_ci JSFunction *callee = JSFunction::Cast(slotValue); 3444514f5e3Sopenharmony_ci Method *calleeMethod = Method::Cast(callee->GetMethod()); 3454514f5e3Sopenharmony_ci calleeMethodId = static_cast<int>(calleeMethod->GetMethodId().GetOffset()); 3464514f5e3Sopenharmony_ci calleeAbcId = PGOProfiler::GetMethodAbcId(callee); 3474514f5e3Sopenharmony_ci static_cast<JitCompilationEnv *>(compilationEnv_) 3484514f5e3Sopenharmony_ci ->UpdateFuncSlotIdMap(calleeMethodId, methodId_.GetOffset(), slotId); 3494514f5e3Sopenharmony_ci kind = ProfileType::Kind::MethodId; 3504514f5e3Sopenharmony_ci } else { 3514514f5e3Sopenharmony_ci return; 3524514f5e3Sopenharmony_ci } 3534514f5e3Sopenharmony_ci PGOSampleType* type = chunk_->New<PGOSampleType>(ProfileType(abcId_, std::abs(calleeMethodId), kind)); 3544514f5e3Sopenharmony_ci UpdatePGOType(bcOffset, type); 3554514f5e3Sopenharmony_ci} 3564514f5e3Sopenharmony_ci 3574514f5e3Sopenharmony_civoid JITProfiler::ConvertNewObjRange(uint32_t slotId, long bcOffset) 3584514f5e3Sopenharmony_ci{ 3594514f5e3Sopenharmony_ci JSTaggedValue slotValue = profileTypeInfo_->Get(slotId); 3604514f5e3Sopenharmony_ci int ctorMethodId = 0; 3614514f5e3Sopenharmony_ci JSHClass* hclass = nullptr; 3624514f5e3Sopenharmony_ci if (slotValue.IsInt()) { 3634514f5e3Sopenharmony_ci ctorMethodId = slotValue.GetInt(); 3644514f5e3Sopenharmony_ci // JIT cannot optimize this scenario because it doesn't know the hclass 3654514f5e3Sopenharmony_ci if (ctorMethodId > 0) { 3664514f5e3Sopenharmony_ci return; 3674514f5e3Sopenharmony_ci } 3684514f5e3Sopenharmony_ci } else if (slotValue.IsJSFunction()) { 3694514f5e3Sopenharmony_ci JSFunction *callee = JSFunction::Cast(slotValue); 3704514f5e3Sopenharmony_ci Method *calleeMethod = Method::Cast(callee->GetMethod()); 3714514f5e3Sopenharmony_ci ctorMethodId = static_cast<int>(calleeMethod->GetMethodId().GetOffset()); 3724514f5e3Sopenharmony_ci JSTaggedValue protoOrHClass = callee->GetProtoOrHClass(); 3734514f5e3Sopenharmony_ci if (protoOrHClass.IsJSHClass()) { 3744514f5e3Sopenharmony_ci hclass = JSHClass::Cast(protoOrHClass.GetTaggedObject()); 3754514f5e3Sopenharmony_ci } else { 3764514f5e3Sopenharmony_ci return; 3774514f5e3Sopenharmony_ci } 3784514f5e3Sopenharmony_ci } else { 3794514f5e3Sopenharmony_ci return; 3804514f5e3Sopenharmony_ci } 3814514f5e3Sopenharmony_ci if (ctorMethodId > 0) { 3824514f5e3Sopenharmony_ci ptManager_->RecordAndGetHclassIndexForJIT(hclass); 3834514f5e3Sopenharmony_ci auto pt = ProfileType(abcId_, std::abs(ctorMethodId), ProfileType::Kind::JITClassId, true); 3844514f5e3Sopenharmony_ci PGODefineOpType* type = chunk_->New<PGODefineOpType>(pt, hclass); 3854514f5e3Sopenharmony_ci UpdatePGOType(bcOffset, type); 3864514f5e3Sopenharmony_ci } else { 3874514f5e3Sopenharmony_ci auto kind = ProfileType::Kind::BuiltinFunctionId; 3884514f5e3Sopenharmony_ci auto type = chunk_->New<PGOSampleType>(ProfileType(abcId_, std::abs(ctorMethodId), kind)); 3894514f5e3Sopenharmony_ci UpdatePGOType(bcOffset, type); 3904514f5e3Sopenharmony_ci } 3914514f5e3Sopenharmony_ci} 3924514f5e3Sopenharmony_ci 3934514f5e3Sopenharmony_civoid JITProfiler::ConvertGetIterator(uint32_t slotId, long bcOffset) 3944514f5e3Sopenharmony_ci{ 3954514f5e3Sopenharmony_ci if (vm_->GetJSThread()->GetEnableLazyBuiltins()) { 3964514f5e3Sopenharmony_ci return; 3974514f5e3Sopenharmony_ci } 3984514f5e3Sopenharmony_ci JSTaggedValue value = profileTypeInfo_->Get(slotId); 3994514f5e3Sopenharmony_ci if (!value.IsInt()) { 4004514f5e3Sopenharmony_ci return; 4014514f5e3Sopenharmony_ci } 4024514f5e3Sopenharmony_ci int iterKind = value.GetInt(); 4034514f5e3Sopenharmony_ci ASSERT(iterKind <= 0); 4044514f5e3Sopenharmony_ci ProfileType::Kind pgoKind = ProfileType::Kind::BuiltinFunctionId; 4054514f5e3Sopenharmony_ci auto type = chunk_->New<PGOSampleType>(ProfileType(abcId_, std::abs(iterKind), pgoKind)); 4064514f5e3Sopenharmony_ci UpdatePGOType(bcOffset, type); 4074514f5e3Sopenharmony_ci} 4084514f5e3Sopenharmony_ci 4094514f5e3Sopenharmony_civoid JITProfiler::ConvertCreateObject(uint32_t slotId, long bcOffset, [[maybe_unused]]int32_t traceId) 4104514f5e3Sopenharmony_ci{ 4114514f5e3Sopenharmony_ci JSTaggedValue slotValue = profileTypeInfo_->Get(slotId); 4124514f5e3Sopenharmony_ci if (!slotValue.IsHeapObject()) { 4134514f5e3Sopenharmony_ci return; 4144514f5e3Sopenharmony_ci } 4154514f5e3Sopenharmony_ci if (slotValue.IsWeak()) { 4164514f5e3Sopenharmony_ci auto object = slotValue.GetWeakReferentUnChecked(); 4174514f5e3Sopenharmony_ci if (object->GetClass()->IsHClass()) { 4184514f5e3Sopenharmony_ci auto newHClass = JSHClass::Cast(object); 4194514f5e3Sopenharmony_ci PGODefineOpType* objDefType = chunk_->New<PGODefineOpType>(ProfileType::CreateJITType(), newHClass); 4204514f5e3Sopenharmony_ci ptManager_->RecordAndGetHclassIndexForJIT(newHClass); 4214514f5e3Sopenharmony_ci UpdatePGOType(bcOffset, objDefType); 4224514f5e3Sopenharmony_ci } 4234514f5e3Sopenharmony_ci } else if (slotValue.IsTrackInfoObject()) { 4244514f5e3Sopenharmony_ci TrackInfo *trackInfo = TrackInfo::Cast(slotValue.GetTaggedObject()); 4254514f5e3Sopenharmony_ci auto hclass = JSHClass::Cast(trackInfo->GetCachedHClass().GetTaggedObject()); 4264514f5e3Sopenharmony_ci PGODefineOpType* objDefType = chunk_->New<PGODefineOpType>(ProfileType::CreateJITType(), hclass); 4274514f5e3Sopenharmony_ci ptManager_->RecordAndGetHclassIndexForJIT(hclass); 4284514f5e3Sopenharmony_ci auto elementsKind = trackInfo->GetElementsKind(); 4294514f5e3Sopenharmony_ci objDefType->SetElementsKind(elementsKind); 4304514f5e3Sopenharmony_ci objDefType->SetElementsLength(trackInfo->GetArrayLength()); 4314514f5e3Sopenharmony_ci objDefType->SetSpaceFlag(trackInfo->GetSpaceFlag()); 4324514f5e3Sopenharmony_ci UpdatePGOType(bcOffset, objDefType); 4334514f5e3Sopenharmony_ci } 4344514f5e3Sopenharmony_ci} 4354514f5e3Sopenharmony_ci 4364514f5e3Sopenharmony_civoid JITProfiler::ConvertICByName(int32_t bcOffset, uint32_t slotId, BCType type) 4374514f5e3Sopenharmony_ci{ 4384514f5e3Sopenharmony_ci ProfileTypeAccessorLockScope accessorLockScope(vm_->GetJSThreadNoCheck()); 4394514f5e3Sopenharmony_ci JSTaggedValue firstValue = profileTypeInfo_->Get(slotId); 4404514f5e3Sopenharmony_ci if (!firstValue.IsHeapObject()) { 4414514f5e3Sopenharmony_ci if (firstValue.IsHole()) { 4424514f5e3Sopenharmony_ci // Mega state 4434514f5e3Sopenharmony_ci AddObjectInfoWithMega(bcOffset); 4444514f5e3Sopenharmony_ci } 4454514f5e3Sopenharmony_ci return; 4464514f5e3Sopenharmony_ci } 4474514f5e3Sopenharmony_ci if (firstValue.IsWeak()) { 4484514f5e3Sopenharmony_ci TaggedObject *object = firstValue.GetWeakReferentUnChecked(); 4494514f5e3Sopenharmony_ci if (object->GetClass()->IsHClass()) { 4504514f5e3Sopenharmony_ci JSTaggedValue secondValue = profileTypeInfo_->Get(slotId + 1); 4514514f5e3Sopenharmony_ci JSHClass *hclass = JSHClass::Cast(object); 4524514f5e3Sopenharmony_ci ConvertICByNameWithHandler(abcId_, bcOffset, hclass, secondValue, type, slotId + 1); 4534514f5e3Sopenharmony_ci } 4544514f5e3Sopenharmony_ci return; 4554514f5e3Sopenharmony_ci } 4564514f5e3Sopenharmony_ci ConvertICByNameWithPoly(abcId_, bcOffset, firstValue, type, slotId); 4574514f5e3Sopenharmony_ci} 4584514f5e3Sopenharmony_ci 4594514f5e3Sopenharmony_civoid JITProfiler::ConvertICByNameWithHandler(ApEntityId abcId, int32_t bcOffset, 4604514f5e3Sopenharmony_ci JSHClass *hclass, 4614514f5e3Sopenharmony_ci JSTaggedValue secondValue, BCType type, uint32_t slotId) 4624514f5e3Sopenharmony_ci{ 4634514f5e3Sopenharmony_ci if (type == BCType::LOAD) { 4644514f5e3Sopenharmony_ci HandleLoadType(abcId, bcOffset, hclass, secondValue, slotId); 4654514f5e3Sopenharmony_ci // LoadGlobal 4664514f5e3Sopenharmony_ci return; 4674514f5e3Sopenharmony_ci } 4684514f5e3Sopenharmony_ci HandleOtherTypes(abcId, bcOffset, hclass, secondValue, slotId); 4694514f5e3Sopenharmony_ci} 4704514f5e3Sopenharmony_ci 4714514f5e3Sopenharmony_civoid JITProfiler::HandleLoadType(ApEntityId &abcId, int32_t &bcOffset, 4724514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId) 4734514f5e3Sopenharmony_ci{ 4744514f5e3Sopenharmony_ci if (secondValue.IsInt()) { 4754514f5e3Sopenharmony_ci HandleLoadTypeInt(abcId, bcOffset, hclass, secondValue); 4764514f5e3Sopenharmony_ci } else if (secondValue.IsPrototypeHandler()) { 4774514f5e3Sopenharmony_ci HandleLoadTypePrototypeHandler(abcId, bcOffset, hclass, secondValue, slotId); 4784514f5e3Sopenharmony_ci } 4794514f5e3Sopenharmony_ci} 4804514f5e3Sopenharmony_ci 4814514f5e3Sopenharmony_civoid JITProfiler::HandleLoadTypeInt(ApEntityId &abcId, int32_t &bcOffset, 4824514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 4834514f5e3Sopenharmony_ci{ 4844514f5e3Sopenharmony_ci auto handlerInfo = static_cast<uint32_t>(secondValue.GetInt()); 4854514f5e3Sopenharmony_ci if (HandlerBase::IsNonExist(handlerInfo)) { 4864514f5e3Sopenharmony_ci return; 4874514f5e3Sopenharmony_ci } 4884514f5e3Sopenharmony_ci if (AddBuiltinsInfoByNameInInstance(abcId, bcOffset, hclass)) { 4894514f5e3Sopenharmony_ci return; 4904514f5e3Sopenharmony_ci } 4914514f5e3Sopenharmony_ci if (HandlerBase::IsField(handlerInfo) || HandlerBase::IsAccessor(handlerInfo)) { 4924514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, hclass); 4934514f5e3Sopenharmony_ci } 4944514f5e3Sopenharmony_ci} 4954514f5e3Sopenharmony_ci 4964514f5e3Sopenharmony_civoid JITProfiler::HandleLoadTypePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 4974514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId) 4984514f5e3Sopenharmony_ci{ 4994514f5e3Sopenharmony_ci auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject()); 5004514f5e3Sopenharmony_ci auto cellValue = prototypeHandler->GetProtoCell(); 5014514f5e3Sopenharmony_ci if (cellValue.IsUndefined()) { 5024514f5e3Sopenharmony_ci return; 5034514f5e3Sopenharmony_ci } 5044514f5e3Sopenharmony_ci ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); 5054514f5e3Sopenharmony_ci if (cell->GetHasChanged()) { 5064514f5e3Sopenharmony_ci return; 5074514f5e3Sopenharmony_ci } 5084514f5e3Sopenharmony_ci auto holder = prototypeHandler->GetHolder(); 5094514f5e3Sopenharmony_ci auto holderHClass = holder.GetTaggedObject()->GetClass(); 5104514f5e3Sopenharmony_ci JSTaggedValue handlerInfoVal = prototypeHandler->GetHandlerInfo(); 5114514f5e3Sopenharmony_ci if (!handlerInfoVal.IsInt()) { 5124514f5e3Sopenharmony_ci return; 5134514f5e3Sopenharmony_ci } 5144514f5e3Sopenharmony_ci auto handlerInfo = static_cast<uint32_t>(handlerInfoVal.GetInt()); 5154514f5e3Sopenharmony_ci if (HandlerBase::IsNonExist(handlerInfo)) { 5164514f5e3Sopenharmony_ci return; 5174514f5e3Sopenharmony_ci } 5184514f5e3Sopenharmony_ci auto accessorMethodId = prototypeHandler->GetAccessorMethodId(); 5194514f5e3Sopenharmony_ci auto accessor = prototypeHandler->GetAccessorJSFunction(); 5204514f5e3Sopenharmony_ci if (accessor.IsJSFunction()) { 5214514f5e3Sopenharmony_ci auto accessorFunction = JSFunction::Cast(accessor); 5224514f5e3Sopenharmony_ci auto methodId = Method::Cast(accessorFunction->GetMethod())->GetMethodId().GetOffset(); 5234514f5e3Sopenharmony_ci ASSERT(accessorMethodId == methodId); 5244514f5e3Sopenharmony_ci accessorMethodId = methodId; 5254514f5e3Sopenharmony_ci static_cast<JitCompilationEnv *>(compilationEnv_) 5264514f5e3Sopenharmony_ci ->UpdateFuncSlotIdMap(accessorMethodId, methodId_.GetOffset(), slotId); 5274514f5e3Sopenharmony_ci } 5284514f5e3Sopenharmony_ci if (AddBuiltinsInfoByNameInProt(abcId, bcOffset, hclass, holderHClass)) { 5294514f5e3Sopenharmony_ci return ; 5304514f5e3Sopenharmony_ci } 5314514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass, accessorMethodId); 5324514f5e3Sopenharmony_ci} 5334514f5e3Sopenharmony_ci 5344514f5e3Sopenharmony_civoid JITProfiler::HandleOtherTypes(ApEntityId &abcId, int32_t &bcOffset, 5354514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId) 5364514f5e3Sopenharmony_ci{ 5374514f5e3Sopenharmony_ci if (secondValue.IsInt()) { 5384514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, hclass); 5394514f5e3Sopenharmony_ci } else if (secondValue.IsTransitionHandler()) { 5404514f5e3Sopenharmony_ci HandleTransitionHandler(abcId, bcOffset, hclass, secondValue); 5414514f5e3Sopenharmony_ci } else if (secondValue.IsTransWithProtoHandler()) { 5424514f5e3Sopenharmony_ci HandleTransWithProtoHandler(abcId, bcOffset, hclass, secondValue); 5434514f5e3Sopenharmony_ci } else if (secondValue.IsPrototypeHandler()) { 5444514f5e3Sopenharmony_ci HandleOtherTypesPrototypeHandler(abcId, bcOffset, hclass, secondValue, slotId); 5454514f5e3Sopenharmony_ci } else if (secondValue.IsPropertyBox()) { 5464514f5e3Sopenharmony_ci // StoreGlobal 5474514f5e3Sopenharmony_ci } else if (secondValue.IsStoreTSHandler()) { 5484514f5e3Sopenharmony_ci HandleStoreTSHandler(abcId, bcOffset, hclass, secondValue); 5494514f5e3Sopenharmony_ci } 5504514f5e3Sopenharmony_ci} 5514514f5e3Sopenharmony_ci 5524514f5e3Sopenharmony_civoid JITProfiler::HandleTransitionHandler(ApEntityId &abcId, int32_t &bcOffset, 5534514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 5544514f5e3Sopenharmony_ci{ 5554514f5e3Sopenharmony_ci auto transitionHandler = TransitionHandler::Cast(secondValue.GetTaggedObject()); 5564514f5e3Sopenharmony_ci auto transitionHClassVal = transitionHandler->GetTransitionHClass(); 5574514f5e3Sopenharmony_ci if (transitionHClassVal.IsJSHClass()) { 5584514f5e3Sopenharmony_ci auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); 5594514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); 5604514f5e3Sopenharmony_ci } 5614514f5e3Sopenharmony_ci} 5624514f5e3Sopenharmony_ci 5634514f5e3Sopenharmony_civoid JITProfiler::HandleTransWithProtoHandler(ApEntityId &abcId, int32_t &bcOffset, 5644514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 5654514f5e3Sopenharmony_ci{ 5664514f5e3Sopenharmony_ci auto transWithProtoHandler = TransWithProtoHandler::Cast(secondValue.GetTaggedObject()); 5674514f5e3Sopenharmony_ci auto cellValue = transWithProtoHandler->GetProtoCell(); 5684514f5e3Sopenharmony_ci ASSERT(cellValue.IsProtoChangeMarker()); 5694514f5e3Sopenharmony_ci ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); 5704514f5e3Sopenharmony_ci if (cell->GetHasChanged()) { 5714514f5e3Sopenharmony_ci return; 5724514f5e3Sopenharmony_ci } 5734514f5e3Sopenharmony_ci auto transitionHClassVal = transWithProtoHandler->GetTransitionHClass(); 5744514f5e3Sopenharmony_ci if (transitionHClassVal.IsJSHClass()) { 5754514f5e3Sopenharmony_ci auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); 5764514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); 5774514f5e3Sopenharmony_ci } 5784514f5e3Sopenharmony_ci} 5794514f5e3Sopenharmony_ci 5804514f5e3Sopenharmony_civoid JITProfiler::HandleOtherTypesPrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 5814514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue, uint32_t slotId) 5824514f5e3Sopenharmony_ci{ 5834514f5e3Sopenharmony_ci auto prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject()); 5844514f5e3Sopenharmony_ci auto cellValue = prototypeHandler->GetProtoCell(); 5854514f5e3Sopenharmony_ci if (cellValue.IsUndefined()) { 5864514f5e3Sopenharmony_ci return; 5874514f5e3Sopenharmony_ci } 5884514f5e3Sopenharmony_ci ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); 5894514f5e3Sopenharmony_ci if (cell->GetHasChanged()) { 5904514f5e3Sopenharmony_ci return; 5914514f5e3Sopenharmony_ci } 5924514f5e3Sopenharmony_ci auto holder = prototypeHandler->GetHolder(); 5934514f5e3Sopenharmony_ci auto holderHClass = holder.GetTaggedObject()->GetClass(); 5944514f5e3Sopenharmony_ci auto accessorMethodId = prototypeHandler->GetAccessorMethodId(); 5954514f5e3Sopenharmony_ci auto accessor = prototypeHandler->GetAccessorJSFunction(); 5964514f5e3Sopenharmony_ci if (accessor.IsJSFunction()) { 5974514f5e3Sopenharmony_ci auto accessorFunction = JSFunction::Cast(accessor); 5984514f5e3Sopenharmony_ci auto methodId = Method::Cast(accessorFunction->GetMethod())->GetMethodId().GetOffset(); 5994514f5e3Sopenharmony_ci ASSERT(accessorMethodId == methodId); 6004514f5e3Sopenharmony_ci accessorMethodId = methodId; 6014514f5e3Sopenharmony_ci static_cast<JitCompilationEnv *>(compilationEnv_) 6024514f5e3Sopenharmony_ci ->UpdateFuncSlotIdMap(accessorMethodId, methodId_.GetOffset(), slotId); 6034514f5e3Sopenharmony_ci } 6044514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass, accessorMethodId); 6054514f5e3Sopenharmony_ci} 6064514f5e3Sopenharmony_ci 6074514f5e3Sopenharmony_civoid JITProfiler::HandleStoreTSHandler(ApEntityId &abcId, int32_t &bcOffset, 6084514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 6094514f5e3Sopenharmony_ci{ 6104514f5e3Sopenharmony_ci StoreTSHandler *storeTSHandler = StoreTSHandler::Cast(secondValue.GetTaggedObject()); 6114514f5e3Sopenharmony_ci auto cellValue = storeTSHandler->GetProtoCell(); 6124514f5e3Sopenharmony_ci ASSERT(cellValue.IsProtoChangeMarker()); 6134514f5e3Sopenharmony_ci ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); 6144514f5e3Sopenharmony_ci if (cell->GetHasChanged()) { 6154514f5e3Sopenharmony_ci return; 6164514f5e3Sopenharmony_ci } 6174514f5e3Sopenharmony_ci auto holder = storeTSHandler->GetHolder(); 6184514f5e3Sopenharmony_ci auto holderHClass = holder.GetTaggedObject()->GetClass(); 6194514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass); 6204514f5e3Sopenharmony_ci} 6214514f5e3Sopenharmony_ci 6224514f5e3Sopenharmony_civoid JITProfiler::ConvertICByNameWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type, 6234514f5e3Sopenharmony_ci uint32_t slotId) 6244514f5e3Sopenharmony_ci{ 6254514f5e3Sopenharmony_ci if (cacheValue.IsWeak()) { 6264514f5e3Sopenharmony_ci return; 6274514f5e3Sopenharmony_ci } 6284514f5e3Sopenharmony_ci ASSERT(cacheValue.IsTaggedArray()); 6294514f5e3Sopenharmony_ci auto array = TaggedArray::Cast(cacheValue); 6304514f5e3Sopenharmony_ci uint32_t length = array->GetLength(); 6314514f5e3Sopenharmony_ci for (uint32_t i = 0; i < length; i += 2) { // 2 means one ic, two slot 6324514f5e3Sopenharmony_ci auto result = array->Get(i); 6334514f5e3Sopenharmony_ci auto handler = array->Get(i + 1); 6344514f5e3Sopenharmony_ci if (!result.IsHeapObject() || !result.IsWeak()) { 6354514f5e3Sopenharmony_ci continue; 6364514f5e3Sopenharmony_ci } 6374514f5e3Sopenharmony_ci TaggedObject *object = result.GetWeakReferentUnChecked(); 6384514f5e3Sopenharmony_ci if (!object->GetClass()->IsHClass()) { 6394514f5e3Sopenharmony_ci continue; 6404514f5e3Sopenharmony_ci } 6414514f5e3Sopenharmony_ci JSHClass *hclass = JSHClass::Cast(object); 6424514f5e3Sopenharmony_ci ConvertICByNameWithHandler(abcId, bcOffset, hclass, handler, type, slotId); 6434514f5e3Sopenharmony_ci } 6444514f5e3Sopenharmony_ci} 6454514f5e3Sopenharmony_ci 6464514f5e3Sopenharmony_civoid JITProfiler::ConvertICByValue(int32_t bcOffset, uint32_t slotId, BCType type) 6474514f5e3Sopenharmony_ci{ 6484514f5e3Sopenharmony_ci ProfileTypeAccessorLockScope accessorLockScope(vm_->GetJSThreadNoCheck()); 6494514f5e3Sopenharmony_ci JSTaggedValue firstValue = profileTypeInfo_->Get(slotId); 6504514f5e3Sopenharmony_ci if (!firstValue.IsHeapObject()) { 6514514f5e3Sopenharmony_ci if (firstValue.IsHole()) { 6524514f5e3Sopenharmony_ci // Mega state 6534514f5e3Sopenharmony_ci AddObjectInfoWithMega(bcOffset); 6544514f5e3Sopenharmony_ci } 6554514f5e3Sopenharmony_ci return; 6564514f5e3Sopenharmony_ci } 6574514f5e3Sopenharmony_ci if (firstValue.IsWeak()) { 6584514f5e3Sopenharmony_ci TaggedObject *object = firstValue.GetWeakReferentUnChecked(); 6594514f5e3Sopenharmony_ci if (object->GetClass()->IsHClass()) { 6604514f5e3Sopenharmony_ci JSTaggedValue secondValue = profileTypeInfo_->Get(slotId + 1); 6614514f5e3Sopenharmony_ci JSHClass *hclass = JSHClass::Cast(object); 6624514f5e3Sopenharmony_ci ConvertICByValueWithHandler(abcId_, bcOffset, hclass, secondValue, type); 6634514f5e3Sopenharmony_ci } 6644514f5e3Sopenharmony_ci return; 6654514f5e3Sopenharmony_ci } 6664514f5e3Sopenharmony_ci // Check key 6674514f5e3Sopenharmony_ci if ((firstValue.IsString() || firstValue.IsSymbol())) { 6684514f5e3Sopenharmony_ci return; 6694514f5e3Sopenharmony_ci } 6704514f5e3Sopenharmony_ci // Check without key 6714514f5e3Sopenharmony_ci ConvertICByValueWithPoly(abcId_, bcOffset, firstValue, type); 6724514f5e3Sopenharmony_ci} 6734514f5e3Sopenharmony_ci 6744514f5e3Sopenharmony_civoid JITProfiler::ConvertICByValueWithHandler(ApEntityId abcId, int32_t bcOffset, 6754514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue secondValue, 6764514f5e3Sopenharmony_ci BCType type) 6774514f5e3Sopenharmony_ci{ 6784514f5e3Sopenharmony_ci if (type == BCType::LOAD) { 6794514f5e3Sopenharmony_ci if (secondValue.IsInt()) { 6804514f5e3Sopenharmony_ci auto handlerInfo = static_cast<uint32_t>(secondValue.GetInt()); 6814514f5e3Sopenharmony_ci if (HandlerBase::IsNormalElement(handlerInfo) || HandlerBase::IsStringElement(handlerInfo)) { 6824514f5e3Sopenharmony_ci if (HandlerBase::NeedSkipInPGODump(handlerInfo)) { 6834514f5e3Sopenharmony_ci return; 6844514f5e3Sopenharmony_ci } 6854514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, hclass, hclass); 6864514f5e3Sopenharmony_ci return; 6874514f5e3Sopenharmony_ci } 6884514f5e3Sopenharmony_ci if (HandlerBase::IsTypedArrayElement(handlerInfo)) { 6894514f5e3Sopenharmony_ci OnHeapMode onHeap = HandlerBase::IsOnHeap(handlerInfo) ? OnHeapMode::ON_HEAP : OnHeapMode::NOT_ON_HEAP; 6904514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, hclass, hclass, onHeap); 6914514f5e3Sopenharmony_ci return; 6924514f5e3Sopenharmony_ci } 6934514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, hclass); 6944514f5e3Sopenharmony_ci } 6954514f5e3Sopenharmony_ci return; 6964514f5e3Sopenharmony_ci } 6974514f5e3Sopenharmony_ci HandleStoreType(abcId, bcOffset, hclass, secondValue); 6984514f5e3Sopenharmony_ci} 6994514f5e3Sopenharmony_ci 7004514f5e3Sopenharmony_civoid JITProfiler::HandleStoreType(ApEntityId &abcId, int32_t &bcOffset, 7014514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 7024514f5e3Sopenharmony_ci{ 7034514f5e3Sopenharmony_ci if (secondValue.IsInt()) { 7044514f5e3Sopenharmony_ci auto handlerInfo = static_cast<uint32_t>(secondValue.GetInt()); 7054514f5e3Sopenharmony_ci if (HandlerBase::IsNormalElement(handlerInfo) || HandlerBase::IsStringElement(handlerInfo)) { 7064514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, hclass, hclass, 7074514f5e3Sopenharmony_ci OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo)); 7084514f5e3Sopenharmony_ci return; 7094514f5e3Sopenharmony_ci } 7104514f5e3Sopenharmony_ci if (HandlerBase::IsTypedArrayElement(handlerInfo)) { 7114514f5e3Sopenharmony_ci OnHeapMode onHeap = HandlerBase::IsOnHeap(handlerInfo) ? OnHeapMode::ON_HEAP : OnHeapMode::NOT_ON_HEAP; 7124514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, hclass, hclass, onHeap, 7134514f5e3Sopenharmony_ci HandlerBase::IsStoreOutOfBounds(handlerInfo)); 7144514f5e3Sopenharmony_ci return; 7154514f5e3Sopenharmony_ci } 7164514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, hclass); 7174514f5e3Sopenharmony_ci } else if (secondValue.IsTransitionHandler()) { 7184514f5e3Sopenharmony_ci HandleTransition(abcId, bcOffset, hclass, secondValue); 7194514f5e3Sopenharmony_ci } else if (secondValue.IsTransWithProtoHandler()) { 7204514f5e3Sopenharmony_ci HandleTransWithProto(abcId, bcOffset, hclass, secondValue); 7214514f5e3Sopenharmony_ci } else { 7224514f5e3Sopenharmony_ci HandlePrototypeHandler(abcId, bcOffset, hclass, secondValue); 7234514f5e3Sopenharmony_ci } 7244514f5e3Sopenharmony_ci} 7254514f5e3Sopenharmony_ci 7264514f5e3Sopenharmony_civoid JITProfiler::HandleTransition(ApEntityId &abcId, int32_t &bcOffset, 7274514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 7284514f5e3Sopenharmony_ci{ 7294514f5e3Sopenharmony_ci auto transitionHandler = TransitionHandler::Cast(secondValue.GetTaggedObject()); 7304514f5e3Sopenharmony_ci auto transitionHClassVal = transitionHandler->GetTransitionHClass(); 7314514f5e3Sopenharmony_ci 7324514f5e3Sopenharmony_ci auto handlerInfoValue = transitionHandler->GetHandlerInfo(); 7334514f5e3Sopenharmony_ci ASSERT(handlerInfoValue.IsInt()); 7344514f5e3Sopenharmony_ci auto handlerInfo = static_cast<uint32_t>(handlerInfoValue.GetInt()); 7354514f5e3Sopenharmony_ci if (transitionHClassVal.IsJSHClass()) { 7364514f5e3Sopenharmony_ci auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); 7374514f5e3Sopenharmony_ci if (HandlerBase::IsElement(handlerInfo)) { 7384514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, hclass, transitionHClass, 7394514f5e3Sopenharmony_ci OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo)); 7404514f5e3Sopenharmony_ci } else { 7414514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); 7424514f5e3Sopenharmony_ci } 7434514f5e3Sopenharmony_ci } 7444514f5e3Sopenharmony_ci} 7454514f5e3Sopenharmony_ci 7464514f5e3Sopenharmony_civoid JITProfiler::HandleTransWithProto(ApEntityId &abcId, int32_t &bcOffset, 7474514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 7484514f5e3Sopenharmony_ci{ 7494514f5e3Sopenharmony_ci auto transWithProtoHandler = TransWithProtoHandler::Cast(secondValue.GetTaggedObject()); 7504514f5e3Sopenharmony_ci auto transitionHClassVal = transWithProtoHandler->GetTransitionHClass(); 7514514f5e3Sopenharmony_ci auto handlerInfoValue = transWithProtoHandler->GetHandlerInfo(); 7524514f5e3Sopenharmony_ci ASSERT(handlerInfoValue.IsInt()); 7534514f5e3Sopenharmony_ci auto handlerInfo = static_cast<uint32_t>(handlerInfoValue.GetInt()); 7544514f5e3Sopenharmony_ci if (transitionHClassVal.IsJSHClass()) { 7554514f5e3Sopenharmony_ci auto transitionHClass = JSHClass::Cast(transitionHClassVal.GetTaggedObject()); 7564514f5e3Sopenharmony_ci if (HandlerBase::IsElement(handlerInfo)) { 7574514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, hclass, transitionHClass, 7584514f5e3Sopenharmony_ci OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo)); 7594514f5e3Sopenharmony_ci } else { 7604514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, hclass, transitionHClass); 7614514f5e3Sopenharmony_ci } 7624514f5e3Sopenharmony_ci } 7634514f5e3Sopenharmony_ci} 7644514f5e3Sopenharmony_ci 7654514f5e3Sopenharmony_civoid JITProfiler::HandlePrototypeHandler(ApEntityId &abcId, int32_t &bcOffset, 7664514f5e3Sopenharmony_ci JSHClass *hclass, JSTaggedValue &secondValue) 7674514f5e3Sopenharmony_ci{ 7684514f5e3Sopenharmony_ci ASSERT(secondValue.IsPrototypeHandler()); 7694514f5e3Sopenharmony_ci PrototypeHandler *prototypeHandler = PrototypeHandler::Cast(secondValue.GetTaggedObject()); 7704514f5e3Sopenharmony_ci auto cellValue = prototypeHandler->GetProtoCell(); 7714514f5e3Sopenharmony_ci if (!cellValue.IsProtoChangeMarker()) { 7724514f5e3Sopenharmony_ci return; 7734514f5e3Sopenharmony_ci } 7744514f5e3Sopenharmony_ci ASSERT(cellValue.IsProtoChangeMarker()); 7754514f5e3Sopenharmony_ci ProtoChangeMarker *cell = ProtoChangeMarker::Cast(cellValue.GetTaggedObject()); 7764514f5e3Sopenharmony_ci if (cell->GetHasChanged()) { 7774514f5e3Sopenharmony_ci return; 7784514f5e3Sopenharmony_ci } 7794514f5e3Sopenharmony_ci JSTaggedValue handlerInfoValue = prototypeHandler->GetHandlerInfo(); 7804514f5e3Sopenharmony_ci ASSERT(handlerInfoValue.IsInt()); 7814514f5e3Sopenharmony_ci auto handlerInfo = static_cast<uint32_t>(handlerInfoValue.GetInt()); 7824514f5e3Sopenharmony_ci if (HandlerBase::IsElement(handlerInfo)) { 7834514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, hclass, hclass, 7844514f5e3Sopenharmony_ci OnHeapMode::NONE, HandlerBase::IsStoreOutOfBounds(handlerInfo)); 7854514f5e3Sopenharmony_ci return; 7864514f5e3Sopenharmony_ci } 7874514f5e3Sopenharmony_ci auto holder = prototypeHandler->GetHolder(); 7884514f5e3Sopenharmony_ci auto holderHClass = holder.GetTaggedObject()->GetClass(); 7894514f5e3Sopenharmony_ci AddObjectInfo(abcId, bcOffset, hclass, holderHClass, holderHClass); 7904514f5e3Sopenharmony_ci} 7914514f5e3Sopenharmony_ci 7924514f5e3Sopenharmony_civoid JITProfiler::ConvertICByValueWithPoly(ApEntityId abcId, int32_t bcOffset, JSTaggedValue cacheValue, BCType type) 7934514f5e3Sopenharmony_ci{ 7944514f5e3Sopenharmony_ci if (cacheValue.IsWeak()) { 7954514f5e3Sopenharmony_ci return; 7964514f5e3Sopenharmony_ci } 7974514f5e3Sopenharmony_ci ASSERT(cacheValue.IsTaggedArray()); 7984514f5e3Sopenharmony_ci auto array = TaggedArray::Cast(cacheValue); 7994514f5e3Sopenharmony_ci uint32_t length = array->GetLength(); 8004514f5e3Sopenharmony_ci for (uint32_t i = 0; i < length; i += 2) { // 2 means one ic, two slot 8014514f5e3Sopenharmony_ci auto result = array->Get(i); 8024514f5e3Sopenharmony_ci auto handler = array->Get(i + 1); 8034514f5e3Sopenharmony_ci if (!result.IsHeapObject() || !result.IsWeak()) { 8044514f5e3Sopenharmony_ci continue; 8054514f5e3Sopenharmony_ci } 8064514f5e3Sopenharmony_ci TaggedObject *object = result.GetWeakReferentUnChecked(); 8074514f5e3Sopenharmony_ci if (!object->GetClass()->IsHClass()) { 8084514f5e3Sopenharmony_ci continue; 8094514f5e3Sopenharmony_ci } 8104514f5e3Sopenharmony_ci JSHClass *hclass = JSHClass::Cast(object); 8114514f5e3Sopenharmony_ci ConvertICByValueWithHandler(abcId, bcOffset, hclass, handler, type); 8124514f5e3Sopenharmony_ci } 8134514f5e3Sopenharmony_ci} 8144514f5e3Sopenharmony_ci 8154514f5e3Sopenharmony_civoid JITProfiler::ConvertInstanceof(int32_t bcOffset, uint32_t slotId) 8164514f5e3Sopenharmony_ci{ 8174514f5e3Sopenharmony_ci JSTaggedValue firstValue = profileTypeInfo_->Get(slotId); 8184514f5e3Sopenharmony_ci if (!firstValue.IsHeapObject()) { 8194514f5e3Sopenharmony_ci if (firstValue.IsHole()) { 8204514f5e3Sopenharmony_ci // Mega state 8214514f5e3Sopenharmony_ci AddObjectInfoWithMega(bcOffset); 8224514f5e3Sopenharmony_ci } 8234514f5e3Sopenharmony_ci return; 8244514f5e3Sopenharmony_ci } 8254514f5e3Sopenharmony_ci if (firstValue.IsWeak()) { 8264514f5e3Sopenharmony_ci TaggedObject *object = firstValue.GetWeakReferentUnChecked(); 8274514f5e3Sopenharmony_ci if (object->GetClass()->IsHClass()) { 8284514f5e3Sopenharmony_ci JSHClass *hclass = JSHClass::Cast(object); 8294514f5e3Sopenharmony_ci // Since pgo does not support symbol, we choose to return if hclass having @@hasInstance 8304514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = vm_->GetGlobalEnv(); 8314514f5e3Sopenharmony_ci JSTaggedValue key = env->GetHasInstanceSymbol().GetTaggedValue(); 8324514f5e3Sopenharmony_ci JSHClass *functionPrototypeHC = JSObject::Cast(env->GetFunctionPrototype().GetTaggedValue())->GetClass(); 8334514f5e3Sopenharmony_ci JSTaggedValue foundHClass = TryFindKeyInPrototypeChain(object, hclass, key); 8344514f5e3Sopenharmony_ci if (!foundHClass.IsUndefined() && JSHClass::Cast(foundHClass.GetTaggedObject()) != functionPrototypeHC) { 8354514f5e3Sopenharmony_ci return; 8364514f5e3Sopenharmony_ci } 8374514f5e3Sopenharmony_ci AddObjectInfo(abcId_, bcOffset, hclass, hclass, hclass); 8384514f5e3Sopenharmony_ci } 8394514f5e3Sopenharmony_ci return; 8404514f5e3Sopenharmony_ci } 8414514f5e3Sopenharmony_ci // Poly Not Consider now 8424514f5e3Sopenharmony_ci return; 8434514f5e3Sopenharmony_ci} 8444514f5e3Sopenharmony_ci 8454514f5e3Sopenharmony_ciJSTaggedValue JITProfiler::TryFindKeyInPrototypeChain(TaggedObject *currObj, JSHClass *currHC, JSTaggedValue key) 8464514f5e3Sopenharmony_ci{ 8474514f5e3Sopenharmony_ci // This is a temporary solution for Instanceof Only! 8484514f5e3Sopenharmony_ci // Do NOT use this function for other purpose. 8494514f5e3Sopenharmony_ci if (currHC->IsDictionaryMode()) { 8504514f5e3Sopenharmony_ci return JSTaggedValue(currHC); 8514514f5e3Sopenharmony_ci } 8524514f5e3Sopenharmony_ci while (!JSTaggedValue(currHC).IsUndefinedOrNull()) { 8534514f5e3Sopenharmony_ci if (LIKELY(!currHC->IsDictionaryMode())) { 8544514f5e3Sopenharmony_ci int entry = JSHClass::FindPropertyEntry(vm_->GetJSThread(), currHC, key); 8554514f5e3Sopenharmony_ci if (entry != -1) { 8564514f5e3Sopenharmony_ci return JSTaggedValue(currHC); 8574514f5e3Sopenharmony_ci } 8584514f5e3Sopenharmony_ci } else { 8594514f5e3Sopenharmony_ci TaggedArray *array = TaggedArray::Cast(JSObject::Cast(currObj)->GetProperties().GetTaggedObject()); 8604514f5e3Sopenharmony_ci ASSERT(array->IsDictionaryMode()); 8614514f5e3Sopenharmony_ci NameDictionary *dict = NameDictionary::Cast(array); 8624514f5e3Sopenharmony_ci int entry = dict->FindEntry(key); 8634514f5e3Sopenharmony_ci if (entry != -1) { 8644514f5e3Sopenharmony_ci return JSTaggedValue(currHC); 8654514f5e3Sopenharmony_ci } 8664514f5e3Sopenharmony_ci } 8674514f5e3Sopenharmony_ci currObj = currHC->GetProto().GetTaggedObject(); 8684514f5e3Sopenharmony_ci if (JSTaggedValue(currObj).IsUndefinedOrNull()) { 8694514f5e3Sopenharmony_ci break; 8704514f5e3Sopenharmony_ci } 8714514f5e3Sopenharmony_ci currHC = currObj->GetClass(); 8724514f5e3Sopenharmony_ci } 8734514f5e3Sopenharmony_ci return JSTaggedValue::Undefined(); 8744514f5e3Sopenharmony_ci} 8754514f5e3Sopenharmony_ci 8764514f5e3Sopenharmony_civoid JITProfiler::AddObjectInfoWithMega(int32_t bcOffset) 8774514f5e3Sopenharmony_ci{ 8784514f5e3Sopenharmony_ci auto megaType = ProfileType::CreateMegaType(); 8794514f5e3Sopenharmony_ci PGOObjectInfo info(megaType, megaType, megaType, megaType, megaType, megaType, PGOSampleType()); 8804514f5e3Sopenharmony_ci AddObjectInfoImplement(bcOffset, info); 8814514f5e3Sopenharmony_ci} 8824514f5e3Sopenharmony_ci 8834514f5e3Sopenharmony_civoid JITProfiler::AddObjectInfoImplement(int32_t bcOffset, const PGOObjectInfo &info) 8844514f5e3Sopenharmony_ci{ 8854514f5e3Sopenharmony_ci PGORWOpType *cur = nullptr; 8864514f5e3Sopenharmony_ci if (bcOffsetPGORwTypeMap_.find(bcOffset) == bcOffsetPGORwTypeMap_.end()) { 8874514f5e3Sopenharmony_ci cur = chunk_->New<PGORWOpType>(); 8884514f5e3Sopenharmony_ci bcOffsetPGORwTypeMap_[bcOffset] = cur; 8894514f5e3Sopenharmony_ci } else { 8904514f5e3Sopenharmony_ci cur = const_cast<PGORWOpType*>(bcOffsetPGORwTypeMap_.at(bcOffset)); 8914514f5e3Sopenharmony_ci } 8924514f5e3Sopenharmony_ci if (cur != nullptr) { 8934514f5e3Sopenharmony_ci cur->AddObjectInfo(info); 8944514f5e3Sopenharmony_ci } 8954514f5e3Sopenharmony_ci} 8964514f5e3Sopenharmony_ci 8974514f5e3Sopenharmony_cibool JITProfiler::AddObjectInfo(ApEntityId abcId, int32_t bcOffset, 8984514f5e3Sopenharmony_ci JSHClass *receiver, JSHClass *hold, JSHClass *holdTra, uint32_t accessorMethodId) 8994514f5e3Sopenharmony_ci{ 9004514f5e3Sopenharmony_ci PGOSampleType accessor = PGOSampleType::CreateProfileType(abcId, accessorMethodId, ProfileType::Kind::MethodId); 9014514f5e3Sopenharmony_ci // case: obj = Object.create(null) => LowerProtoChangeMarkerCheck Crash 9024514f5e3Sopenharmony_ci if (receiver->GetPrototype().IsNull()) { 9034514f5e3Sopenharmony_ci return false; 9044514f5e3Sopenharmony_ci } 9054514f5e3Sopenharmony_ci return AddTranstionObjectInfo(bcOffset, receiver, hold, holdTra, accessor); 9064514f5e3Sopenharmony_ci} 9074514f5e3Sopenharmony_ci 9084514f5e3Sopenharmony_cibool JITProfiler::AddTranstionObjectInfo( 9094514f5e3Sopenharmony_ci int32_t bcOffset, JSHClass *receiver, JSHClass *hold, JSHClass *holdTra, PGOSampleType accessorMethod) 9104514f5e3Sopenharmony_ci{ 9114514f5e3Sopenharmony_ci ptManager_->RecordAndGetHclassIndexForJIT(receiver); 9124514f5e3Sopenharmony_ci ptManager_->RecordAndGetHclassIndexForJIT(hold); 9134514f5e3Sopenharmony_ci ptManager_->RecordAndGetHclassIndexForJIT(holdTra); 9144514f5e3Sopenharmony_ci PGOObjectInfo info(ProfileType::CreateJITType(), receiver, hold, holdTra, accessorMethod); 9154514f5e3Sopenharmony_ci AddObjectInfoImplement(bcOffset, info); 9164514f5e3Sopenharmony_ci return true; 9174514f5e3Sopenharmony_ci} 9184514f5e3Sopenharmony_ci 9194514f5e3Sopenharmony_civoid JITProfiler::AddBuiltinsInfo(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, 9204514f5e3Sopenharmony_ci JSHClass *transitionHClass, OnHeapMode onHeap, bool everOutOfBounds) 9214514f5e3Sopenharmony_ci{ 9224514f5e3Sopenharmony_ci if (receiver->IsJSArray()) { 9234514f5e3Sopenharmony_ci auto type = receiver->GetObjectType(); 9244514f5e3Sopenharmony_ci auto elementsKind = receiver->GetElementsKind(); 9254514f5e3Sopenharmony_ci auto transitionElementsKind = transitionHClass->GetElementsKind(); 9264514f5e3Sopenharmony_ci auto profileType = ProfileType::CreateBuiltinsArray(abcId, type, elementsKind, transitionElementsKind, 9274514f5e3Sopenharmony_ci everOutOfBounds); 9284514f5e3Sopenharmony_ci PGOObjectInfo info(profileType); 9294514f5e3Sopenharmony_ci AddObjectInfoImplement(bcOffset, info); 9304514f5e3Sopenharmony_ci } else if (receiver->IsTypedArray()) { 9314514f5e3Sopenharmony_ci JSType jsType = receiver->GetObjectType(); 9324514f5e3Sopenharmony_ci auto profileType = ProfileType::CreateBuiltinsTypedArray(abcId, jsType, onHeap, everOutOfBounds); 9334514f5e3Sopenharmony_ci PGOObjectInfo info(profileType); 9344514f5e3Sopenharmony_ci AddObjectInfoImplement(bcOffset, info); 9354514f5e3Sopenharmony_ci } else { 9364514f5e3Sopenharmony_ci auto type = receiver->GetObjectType(); 9374514f5e3Sopenharmony_ci PGOObjectInfo info(ProfileType::CreateBuiltins(abcId, type)); 9384514f5e3Sopenharmony_ci AddObjectInfoImplement(bcOffset, info); 9394514f5e3Sopenharmony_ci } 9404514f5e3Sopenharmony_ci} 9414514f5e3Sopenharmony_ci 9424514f5e3Sopenharmony_civoid JITProfiler::AddBuiltinsGlobalInfo(ApEntityId abcId, int32_t bcOffset, GlobalIndex globalsId) 9434514f5e3Sopenharmony_ci{ 9444514f5e3Sopenharmony_ci PGOObjectInfo info(ProfileType::CreateGlobals(abcId, globalsId)); 9454514f5e3Sopenharmony_ci AddObjectInfoImplement(bcOffset, info); 9464514f5e3Sopenharmony_ci} 9474514f5e3Sopenharmony_ci 9484514f5e3Sopenharmony_cibool JITProfiler::AddBuiltinsInfoByNameInInstance(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver) 9494514f5e3Sopenharmony_ci{ 9504514f5e3Sopenharmony_ci auto thread = vm_->GetJSThread(); 9514514f5e3Sopenharmony_ci auto type = receiver->GetObjectType(); 9524514f5e3Sopenharmony_ci const auto &ctorEntries = thread->GetCtorHclassEntries(); 9534514f5e3Sopenharmony_ci auto entry = ctorEntries.find(receiver); 9544514f5e3Sopenharmony_ci if (entry != ctorEntries.end()) { 9554514f5e3Sopenharmony_ci AddBuiltinsGlobalInfo(abcId, bcOffset, entry->second); 9564514f5e3Sopenharmony_ci return true; 9574514f5e3Sopenharmony_ci } 9584514f5e3Sopenharmony_ci 9594514f5e3Sopenharmony_ci auto builtinsId = ToBuiltinsTypeId(type); 9604514f5e3Sopenharmony_ci if (!builtinsId.has_value()) { 9614514f5e3Sopenharmony_ci return false; 9624514f5e3Sopenharmony_ci } 9634514f5e3Sopenharmony_ci JSHClass *exceptRecvHClass = nullptr; 9644514f5e3Sopenharmony_ci if (builtinsId == BuiltinTypeId::ARRAY) { 9654514f5e3Sopenharmony_ci bool receiverIsPrototype = receiver->IsPrototype(); 9664514f5e3Sopenharmony_ci exceptRecvHClass = thread->GetArrayInstanceHClass(receiver->GetElementsKind(), receiverIsPrototype); 9674514f5e3Sopenharmony_ci } else if (builtinsId == BuiltinTypeId::STRING) { 9684514f5e3Sopenharmony_ci exceptRecvHClass = receiver; 9694514f5e3Sopenharmony_ci } else { 9704514f5e3Sopenharmony_ci exceptRecvHClass = thread->GetBuiltinInstanceHClass(builtinsId.value()); 9714514f5e3Sopenharmony_ci } 9724514f5e3Sopenharmony_ci 9734514f5e3Sopenharmony_ci if (exceptRecvHClass != receiver) { 9744514f5e3Sopenharmony_ci // When JSType cannot uniquely identify builtins object, it is necessary to 9754514f5e3Sopenharmony_ci // query the receiver on the global constants. 9764514f5e3Sopenharmony_ci if (builtinsId == BuiltinTypeId::OBJECT) { 9774514f5e3Sopenharmony_ci exceptRecvHClass = JSHClass::Cast(thread->GlobalConstants()->GetIteratorResultClass().GetTaggedObject()); 9784514f5e3Sopenharmony_ci if (exceptRecvHClass == receiver) { 9794514f5e3Sopenharmony_ci GlobalIndex globalsId; 9804514f5e3Sopenharmony_ci globalsId.UpdateGlobalConstId(static_cast<size_t>(ConstantIndex::ITERATOR_RESULT_CLASS)); 9814514f5e3Sopenharmony_ci AddBuiltinsGlobalInfo(abcId, bcOffset, globalsId); 9824514f5e3Sopenharmony_ci return true; 9834514f5e3Sopenharmony_ci } 9844514f5e3Sopenharmony_ci return false; 9854514f5e3Sopenharmony_ci } 9864514f5e3Sopenharmony_ci return true; 9874514f5e3Sopenharmony_ci } 9884514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, receiver, receiver); 9894514f5e3Sopenharmony_ci return true; 9904514f5e3Sopenharmony_ci} 9914514f5e3Sopenharmony_ci 9924514f5e3Sopenharmony_cibool JITProfiler::AddBuiltinsInfoByNameInProt(ApEntityId abcId, int32_t bcOffset, JSHClass *receiver, JSHClass *hold) 9934514f5e3Sopenharmony_ci{ 9944514f5e3Sopenharmony_ci auto type = receiver->GetObjectType(); 9954514f5e3Sopenharmony_ci auto builtinsId = ToBuiltinsTypeId(type); 9964514f5e3Sopenharmony_ci if (!builtinsId.has_value()) { 9974514f5e3Sopenharmony_ci return false; 9984514f5e3Sopenharmony_ci } 9994514f5e3Sopenharmony_ci auto thread = vm_->GetJSThread(); 10004514f5e3Sopenharmony_ci JSHClass *exceptRecvHClass = nullptr; 10014514f5e3Sopenharmony_ci if (builtinsId == BuiltinTypeId::ARRAY) { 10024514f5e3Sopenharmony_ci bool receiverIsPrototype = receiver->IsPrototype(); 10034514f5e3Sopenharmony_ci exceptRecvHClass = thread->GetArrayInstanceHClass(receiver->GetElementsKind(), receiverIsPrototype); 10044514f5e3Sopenharmony_ci } else if (builtinsId == BuiltinTypeId::STRING) { 10054514f5e3Sopenharmony_ci exceptRecvHClass = receiver; 10064514f5e3Sopenharmony_ci } else { 10074514f5e3Sopenharmony_ci exceptRecvHClass = thread->GetBuiltinInstanceHClass(builtinsId.value()); 10084514f5e3Sopenharmony_ci } 10094514f5e3Sopenharmony_ci 10104514f5e3Sopenharmony_ci auto exceptHoldHClass = thread->GetBuiltinPrototypeHClass(builtinsId.value()); 10114514f5e3Sopenharmony_ci auto exceptPrototypeOfPrototypeHClass = 10124514f5e3Sopenharmony_ci thread->GetBuiltinPrototypeOfPrototypeHClass(builtinsId.value()); 10134514f5e3Sopenharmony_ci // iterator needs to find two layers of prototype 10144514f5e3Sopenharmony_ci if (builtinsId == BuiltinTypeId::ARRAY_ITERATOR) { 10154514f5e3Sopenharmony_ci if ((exceptRecvHClass != receiver) || 10164514f5e3Sopenharmony_ci (exceptHoldHClass != hold && exceptPrototypeOfPrototypeHClass != hold)) { 10174514f5e3Sopenharmony_ci return true; 10184514f5e3Sopenharmony_ci } 10194514f5e3Sopenharmony_ci } else if (IsTypedArrayType(builtinsId.value())) { 10204514f5e3Sopenharmony_ci auto exceptRecvHClassOnHeap = thread->GetBuiltinExtraHClass(builtinsId.value()); 10214514f5e3Sopenharmony_ci ASSERT_PRINT(exceptRecvHClassOnHeap == nullptr || exceptRecvHClassOnHeap->IsOnHeapFromBitField(), 10224514f5e3Sopenharmony_ci "must be on heap"); 10234514f5e3Sopenharmony_ci if (JITProfiler::IsJSHClassNotEqual(receiver, hold, exceptRecvHClass, exceptRecvHClassOnHeap, exceptHoldHClass, 10244514f5e3Sopenharmony_ci exceptPrototypeOfPrototypeHClass)) { 10254514f5e3Sopenharmony_ci return true; 10264514f5e3Sopenharmony_ci } 10274514f5e3Sopenharmony_ci } else if (exceptRecvHClass != receiver || exceptHoldHClass != hold) { 10284514f5e3Sopenharmony_ci if (builtinsId == BuiltinTypeId::OBJECT) { 10294514f5e3Sopenharmony_ci return false; 10304514f5e3Sopenharmony_ci } else { 10314514f5e3Sopenharmony_ci return true; 10324514f5e3Sopenharmony_ci } 10334514f5e3Sopenharmony_ci } 10344514f5e3Sopenharmony_ci AddBuiltinsInfo(abcId, bcOffset, receiver, receiver); 10354514f5e3Sopenharmony_ci return true; 10364514f5e3Sopenharmony_ci} 10374514f5e3Sopenharmony_ci 10384514f5e3Sopenharmony_cibool JITProfiler::IsJSHClassNotEqual(JSHClass *receiver, JSHClass *hold, JSHClass *exceptRecvHClass, 10394514f5e3Sopenharmony_ci JSHClass *exceptRecvHClassOnHeap, JSHClass *exceptHoldHClass, 10404514f5e3Sopenharmony_ci JSHClass *exceptPrototypeOfPrototypeHClass) 10414514f5e3Sopenharmony_ci{ 10424514f5e3Sopenharmony_ci //exceptRecvHClass = IHC, exceptRecvHClassOnHeap = IHC OnHeap 10434514f5e3Sopenharmony_ci //exceptHoldHClass = PHC, exceptPrototypeOfPrototypeHClass = HClass of X.prototype.prototype 10444514f5e3Sopenharmony_ci return ((exceptRecvHClass != receiver && exceptRecvHClassOnHeap != receiver) || 10454514f5e3Sopenharmony_ci (exceptHoldHClass != hold && exceptPrototypeOfPrototypeHClass != hold)); 10464514f5e3Sopenharmony_ci} 10474514f5e3Sopenharmony_ci 10484514f5e3Sopenharmony_civoid JITProfiler::Clear() 10494514f5e3Sopenharmony_ci{ 10504514f5e3Sopenharmony_ci bcOffsetPGOOpTypeMap_.clear(); 10514514f5e3Sopenharmony_ci bcOffsetPGODefOpTypeMap_.clear(); 10524514f5e3Sopenharmony_ci bcOffsetPGORwTypeMap_.clear(); 10534514f5e3Sopenharmony_ci abcId_ = 0; 10544514f5e3Sopenharmony_ci profileTypeInfo_ = nullptr; 10554514f5e3Sopenharmony_ci methodId_ = (EntityId)0; 10564514f5e3Sopenharmony_ci} 10574514f5e3Sopenharmony_ci 10584514f5e3Sopenharmony_ci 10594514f5e3Sopenharmony_ciJITProfiler::~JITProfiler() 10604514f5e3Sopenharmony_ci{ 10614514f5e3Sopenharmony_ci} 10624514f5e3Sopenharmony_ci} 1063