14514f5e3Sopenharmony_ci/* 24514f5e3Sopenharmony_ci * Copyright (c) 2021-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 164514f5e3Sopenharmony_ci#ifndef ECMASCRIPT_JSPANDAFILE_PROGRAM_OBJECT_H 174514f5e3Sopenharmony_ci#define ECMASCRIPT_JSPANDAFILE_PROGRAM_OBJECT_H 184514f5e3Sopenharmony_ci 194514f5e3Sopenharmony_ci#include <atomic> 204514f5e3Sopenharmony_ci#include "ecmascript/compiler/aot_file/aot_file_manager.h" 214514f5e3Sopenharmony_ci#include "ecmascript/ecma_context.h" 224514f5e3Sopenharmony_ci#include "ecmascript/ecma_macros.h" 234514f5e3Sopenharmony_ci#include "ecmascript/global_env.h" 244514f5e3Sopenharmony_ci#include "ecmascript/js_array.h" 254514f5e3Sopenharmony_ci#include "ecmascript/js_tagged_value-inl.h" 264514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/class_info_extractor.h" 274514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/class_literal.h" 284514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/constpool_value.h" 294514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/js_pandafile_manager.h" 304514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/literal_data_extractor.h" 314514f5e3Sopenharmony_ci#include "ecmascript/module/js_module_manager.h" 324514f5e3Sopenharmony_ci#include "ecmascript/module/js_shared_module.h" 334514f5e3Sopenharmony_ci#include "ecmascript/patch/quick_fix_manager.h" 344514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler.h" 354514f5e3Sopenharmony_ci#include "ecmascript/tagged_array-inl.h" 364514f5e3Sopenharmony_ci 374514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 384514f5e3Sopenharmony_ci#include "ecmascript/pgo_profiler/pgo_utils.h" 394514f5e3Sopenharmony_ci#include "libpandafile/class_data_accessor-inl.h" 404514f5e3Sopenharmony_ci#include "libpandafile/index_accessor.h" 414514f5e3Sopenharmony_ci 424514f5e3Sopenharmony_cinamespace panda { 434514f5e3Sopenharmony_cinamespace ecmascript { 444514f5e3Sopenharmony_ciclass JSThread; 454514f5e3Sopenharmony_ci 464514f5e3Sopenharmony_ciclass Program : public ECMAObject { 474514f5e3Sopenharmony_cipublic: 484514f5e3Sopenharmony_ci DECL_CAST(Program) 494514f5e3Sopenharmony_ci 504514f5e3Sopenharmony_ci static constexpr size_t MAIN_FUNCTION_OFFSET = ECMAObject::SIZE; 514514f5e3Sopenharmony_ci ACCESSORS(MainFunction, MAIN_FUNCTION_OFFSET, SIZE) 524514f5e3Sopenharmony_ci 534514f5e3Sopenharmony_ci DECL_VISIT_OBJECT(MAIN_FUNCTION_OFFSET, SIZE) 544514f5e3Sopenharmony_ci DECL_DUMP() 554514f5e3Sopenharmony_ci}; 564514f5e3Sopenharmony_ci 574514f5e3Sopenharmony_ci/* ConstantPool(TaggedArray) 584514f5e3Sopenharmony_ci * +--------------------------------+---------------------------------- 594514f5e3Sopenharmony_ci * | ... | ^ ^ ^ index 0 604514f5e3Sopenharmony_ci * | Method / AOTLiteralInfo / Int | | | | 614514f5e3Sopenharmony_ci * | String | | | | 624514f5e3Sopenharmony_ci * | Array Literal | ConstpoolLength | | 634514f5e3Sopenharmony_ci * | Class Literal | | | | 644514f5e3Sopenharmony_ci * | Object Literal | | | | 654514f5e3Sopenharmony_ci * | ... | v | | 664514f5e3Sopenharmony_ci * +--------------------------------+--------------- | | 674514f5e3Sopenharmony_ci * | ProtoTransTableInfo |PointerToIndexDic | | 684514f5e3Sopenharmony_ci * +--------------------------------+--------------- | | 694514f5e3Sopenharmony_ci * | AOTSymbolInfo |TaggedArray | | 704514f5e3Sopenharmony_ci * +--------------------------------+--------------- | | 714514f5e3Sopenharmony_ci * | unshared constpool index |int32_t CacheLength | 724514f5e3Sopenharmony_ci * +--------------------------------+--------------- | Length 734514f5e3Sopenharmony_ci * | shared constpool id |int32_t | | 744514f5e3Sopenharmony_ci * +--------------------------------+--------------- | | 754514f5e3Sopenharmony_ci * | AOTHClassInfo |TaggedArray | | 764514f5e3Sopenharmony_ci * +--------------------------------+--------------- | | 774514f5e3Sopenharmony_ci * | AOTArrayInfo |TaggedArray | | 784514f5e3Sopenharmony_ci * +--------------------------------+--------------- | | 794514f5e3Sopenharmony_ci * | constIndexInfo |TaggedArray v | 804514f5e3Sopenharmony_ci * +--------------------------------+-------------------------- | 814514f5e3Sopenharmony_ci * | IndexHeader | | 824514f5e3Sopenharmony_ci * +--------------------------------+ | 834514f5e3Sopenharmony_ci * | JSPandaFile | v index: Length-1 844514f5e3Sopenharmony_ci * +--------------------------------+----------------------------------- 854514f5e3Sopenharmony_ci */ 864514f5e3Sopenharmony_ciclass ConstantPool : public TaggedArray { 874514f5e3Sopenharmony_cipublic: 884514f5e3Sopenharmony_ci static constexpr size_t JS_PANDA_FILE_INDEX = 1; // not need gc 894514f5e3Sopenharmony_ci static constexpr size_t INDEX_HEADER_INDEX = 2; // not need gc 904514f5e3Sopenharmony_ci static constexpr size_t CONSTANT_INDEX_INFO_INDEX = 3; 914514f5e3Sopenharmony_ci static constexpr size_t AOT_ARRAY_INFO_INDEX = 4; 924514f5e3Sopenharmony_ci static constexpr size_t AOT_HCLASS_INFO_INDEX = 5; 934514f5e3Sopenharmony_ci static constexpr size_t UNSHARED_CONSTPOOL_INDEX = 6; 944514f5e3Sopenharmony_ci static constexpr size_t SHARED_CONSTPOOL_ID = 7; 954514f5e3Sopenharmony_ci static constexpr size_t AOT_SYMBOL_INFO_INDEX = 8; 964514f5e3Sopenharmony_ci static constexpr size_t PROTO_TRANS_TABLE_INFO_INDEX = 9; 974514f5e3Sopenharmony_ci static constexpr size_t RESERVED_POOL_LENGTH = INDEX_HEADER_INDEX; // divide the gc area 984514f5e3Sopenharmony_ci 994514f5e3Sopenharmony_ci // AOTHClassInfo, AOTArrayInfo, ConstIndexInfo, unsharedConstpoolIndex, constpoolId, AOTSymbolInfo, 1004514f5e3Sopenharmony_ci // ProtoTransTableInfo 1014514f5e3Sopenharmony_ci static constexpr size_t EXTEND_DATA_NUM = 7; 1024514f5e3Sopenharmony_ci 1034514f5e3Sopenharmony_ci static constexpr int32_t CONSTPOOL_TYPE_FLAG = INT32_MAX; // INT32_MAX : unshared constpool. 1044514f5e3Sopenharmony_ci static constexpr int32_t CONSTPOOL_INVALID_ID = 0; 1054514f5e3Sopenharmony_ci 1064514f5e3Sopenharmony_ci static ConstantPool *Cast(TaggedObject *object) 1074514f5e3Sopenharmony_ci { 1084514f5e3Sopenharmony_ci ASSERT(JSTaggedValue(object).IsConstantPool()); 1094514f5e3Sopenharmony_ci return static_cast<ConstantPool *>(object); 1104514f5e3Sopenharmony_ci } 1114514f5e3Sopenharmony_ci 1124514f5e3Sopenharmony_ci static JSHandle<ConstantPool> CreateUnSharedConstPool(EcmaVM *vm, const JSPandaFile *jsPandaFile, 1134514f5e3Sopenharmony_ci panda_file::File::EntityId id) 1144514f5e3Sopenharmony_ci { 1154514f5e3Sopenharmony_ci const panda_file::File::IndexHeader *mainIndex = jsPandaFile->GetPandaFile()->GetIndexHeader(id); 1164514f5e3Sopenharmony_ci LOG_ECMA_IF(mainIndex == nullptr, FATAL) << "Unknown methodId: " << id.GetOffset(); 1174514f5e3Sopenharmony_ci auto constpoolSize = mainIndex->method_idx_size; 1184514f5e3Sopenharmony_ci 1194514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> constpool(vm->GetJSThread(), JSTaggedValue::Hole()); 1204514f5e3Sopenharmony_ci bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 1214514f5e3Sopenharmony_ci if (isLoadedAOT) { 1224514f5e3Sopenharmony_ci#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS) 1234514f5e3Sopenharmony_ci panda_file::IndexAccessor indexAccessor(*jsPandaFile->GetPandaFile(), id); 1244514f5e3Sopenharmony_ci int32_t index = static_cast<int32_t>(indexAccessor.GetHeaderIndex()); 1254514f5e3Sopenharmony_ci constpool = GetDeserializedConstantPool(vm, jsPandaFile, index); 1264514f5e3Sopenharmony_ci#else 1274514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "Aot don't support Windows and MacOS platform"; 1284514f5e3Sopenharmony_ci UNREACHABLE(); 1294514f5e3Sopenharmony_ci#endif 1304514f5e3Sopenharmony_ci } 1314514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolObj; 1324514f5e3Sopenharmony_ci if (constpool.GetTaggedValue().IsHole()) { 1334514f5e3Sopenharmony_ci ObjectFactory *factory = vm->GetFactory(); 1344514f5e3Sopenharmony_ci constpoolObj = factory->NewConstantPool(constpoolSize); 1354514f5e3Sopenharmony_ci } else { 1364514f5e3Sopenharmony_ci constpoolObj = JSHandle<ConstantPool>(constpool); 1374514f5e3Sopenharmony_ci } 1384514f5e3Sopenharmony_ci 1394514f5e3Sopenharmony_ci constpoolObj->SetJSPandaFile(jsPandaFile); 1404514f5e3Sopenharmony_ci constpoolObj->SetIndexHeader(mainIndex); 1414514f5e3Sopenharmony_ci 1424514f5e3Sopenharmony_ci return constpoolObj; 1434514f5e3Sopenharmony_ci } 1444514f5e3Sopenharmony_ci 1454514f5e3Sopenharmony_ci static JSHandle<ConstantPool> CreateUnSharedConstPoolBySharedConstpool( 1464514f5e3Sopenharmony_ci EcmaVM *vm, const JSPandaFile *jsPandaFile, ConstantPool *shareCp) 1474514f5e3Sopenharmony_ci { 1484514f5e3Sopenharmony_ci const panda_file::File::IndexHeader *mainIndex = shareCp->GetIndexHeader(); 1494514f5e3Sopenharmony_ci auto constpoolSize = mainIndex->method_idx_size; 1504514f5e3Sopenharmony_ci 1514514f5e3Sopenharmony_ci JSHandle<JSTaggedValue> constpool(vm->GetJSThread(), JSTaggedValue::Hole()); 1524514f5e3Sopenharmony_ci bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 1534514f5e3Sopenharmony_ci if (isLoadedAOT) { 1544514f5e3Sopenharmony_ci#if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS) 1554514f5e3Sopenharmony_ci int32_t cpId = shareCp->GetSharedConstpoolId().GetInt(); 1564514f5e3Sopenharmony_ci constpool = GetDeserializedConstantPool(vm, jsPandaFile, cpId); 1574514f5e3Sopenharmony_ci#else 1584514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "Aot don't support Windows and MacOS platform"; 1594514f5e3Sopenharmony_ci UNREACHABLE(); 1604514f5e3Sopenharmony_ci#endif 1614514f5e3Sopenharmony_ci } 1624514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolObj; 1634514f5e3Sopenharmony_ci if (constpool.GetTaggedValue().IsHole()) { 1644514f5e3Sopenharmony_ci ObjectFactory *factory = vm->GetFactory(); 1654514f5e3Sopenharmony_ci constpoolObj = factory->NewConstantPool(constpoolSize); 1664514f5e3Sopenharmony_ci } else { 1674514f5e3Sopenharmony_ci constpoolObj = JSHandle<ConstantPool>(constpool); 1684514f5e3Sopenharmony_ci } 1694514f5e3Sopenharmony_ci 1704514f5e3Sopenharmony_ci constpoolObj->SetJSPandaFile(jsPandaFile); 1714514f5e3Sopenharmony_ci constpoolObj->SetIndexHeader(mainIndex); 1724514f5e3Sopenharmony_ci 1734514f5e3Sopenharmony_ci return constpoolObj; 1744514f5e3Sopenharmony_ci } 1754514f5e3Sopenharmony_ci 1764514f5e3Sopenharmony_ci static JSHandle<ConstantPool> CreateSharedConstPool(EcmaVM *vm, const JSPandaFile *jsPandaFile, 1774514f5e3Sopenharmony_ci panda_file::File::EntityId id, 1784514f5e3Sopenharmony_ci int32_t cpId = 0) 1794514f5e3Sopenharmony_ci { 1804514f5e3Sopenharmony_ci const panda_file::File::IndexHeader *mainIndex = jsPandaFile->GetPandaFile()->GetIndexHeader(id); 1814514f5e3Sopenharmony_ci LOG_ECMA_IF(mainIndex == nullptr, FATAL) << "Unknown methodId: " << id.GetOffset(); 1824514f5e3Sopenharmony_ci auto constpoolSize = mainIndex->method_idx_size; 1834514f5e3Sopenharmony_ci 1844514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpool(vm->GetJSThread(), JSTaggedValue::Hole()); 1854514f5e3Sopenharmony_ci if (constpool.GetTaggedValue().IsHole()) { 1864514f5e3Sopenharmony_ci ObjectFactory *factory = vm->GetFactory(); 1874514f5e3Sopenharmony_ci constpool = factory->NewSConstantPool(constpoolSize); 1884514f5e3Sopenharmony_ci } 1894514f5e3Sopenharmony_ci 1904514f5e3Sopenharmony_ci constpool->SetJSPandaFile(jsPandaFile); 1914514f5e3Sopenharmony_ci constpool->SetIndexHeader(mainIndex); 1924514f5e3Sopenharmony_ci constpool->SetUnsharedConstpoolIndex(JSTaggedValue(0)); 1934514f5e3Sopenharmony_ci constpool->SetSharedConstpoolId(JSTaggedValue(cpId)); 1944514f5e3Sopenharmony_ci 1954514f5e3Sopenharmony_ci return constpool; 1964514f5e3Sopenharmony_ci } 1974514f5e3Sopenharmony_ci 1984514f5e3Sopenharmony_ci static bool IsAotSymbolInfoExist(JSHandle<TaggedArray> symbolInfo, JSTaggedValue symbol) 1994514f5e3Sopenharmony_ci { 2004514f5e3Sopenharmony_ci return symbolInfo->GetLength() > 0 && !symbol.IsHole(); 2014514f5e3Sopenharmony_ci } 2024514f5e3Sopenharmony_ci 2034514f5e3Sopenharmony_ci static JSHandle<ConstantPool> CreateSharedConstPoolForAOT( 2044514f5e3Sopenharmony_ci EcmaVM *vm, JSHandle<ConstantPool> constpool, int32_t cpId = 0) 2054514f5e3Sopenharmony_ci { 2064514f5e3Sopenharmony_ci JSHandle<ConstantPool> sconstpool(vm->GetJSThread(), JSTaggedValue::Hole()); 2074514f5e3Sopenharmony_ci uint32_t capacity = constpool->GetConstpoolLength(); 2084514f5e3Sopenharmony_ci if (sconstpool.GetTaggedValue().IsHole()) { 2094514f5e3Sopenharmony_ci ObjectFactory *factory = vm->GetFactory(); 2104514f5e3Sopenharmony_ci sconstpool = factory->NewSConstantPool(capacity); 2114514f5e3Sopenharmony_ci } 2124514f5e3Sopenharmony_ci JSThread *thread = vm->GetJSThread(); 2134514f5e3Sopenharmony_ci for (uint32_t i = 0; i < capacity; i++) { 2144514f5e3Sopenharmony_ci JSTaggedValue val = constpool->GetObjectFromCache(i); 2154514f5e3Sopenharmony_ci if (val.IsString()) { 2164514f5e3Sopenharmony_ci sconstpool->SetObjectToCache(thread, i, val); 2174514f5e3Sopenharmony_ci } else if (IsAotMethodLiteralInfo(val)) { 2184514f5e3Sopenharmony_ci JSHandle<AOTLiteralInfo> valHandle(thread, val); 2194514f5e3Sopenharmony_ci JSHandle<AOTLiteralInfo> methodLiteral = CopySharedMethodAOTLiteralInfo(vm, valHandle); 2204514f5e3Sopenharmony_ci sconstpool->SetObjectToCache(thread, i, methodLiteral.GetTaggedValue()); 2214514f5e3Sopenharmony_ci } else if (val.IsInt()) { 2224514f5e3Sopenharmony_ci // Here is to copy methodCodeEntry which does not have ihc infos from aot. 2234514f5e3Sopenharmony_ci sconstpool->SetObjectToCache(thread, i, val); 2244514f5e3Sopenharmony_ci } 2254514f5e3Sopenharmony_ci } 2264514f5e3Sopenharmony_ci 2274514f5e3Sopenharmony_ci JSHandle<TaggedArray> array(thread->GlobalConstants()->GetHandledEmptyArray()); 2284514f5e3Sopenharmony_ci sconstpool->SetAotSymbolInfo(thread, array.GetTaggedValue()); 2294514f5e3Sopenharmony_ci sconstpool->SetProtoTransTableInfo(thread, JSTaggedValue::Undefined()); 2304514f5e3Sopenharmony_ci sconstpool->SetAotHClassInfo(thread, array.GetTaggedValue()); 2314514f5e3Sopenharmony_ci sconstpool->SetAotArrayInfo(thread, array.GetTaggedValue()); 2324514f5e3Sopenharmony_ci sconstpool->SetConstantIndexInfo(thread, array.GetTaggedValue()); 2334514f5e3Sopenharmony_ci sconstpool->SetJSPandaFile(constpool->GetJSPandaFile()); 2344514f5e3Sopenharmony_ci sconstpool->SetIndexHeader(constpool->GetIndexHeader()); 2354514f5e3Sopenharmony_ci sconstpool->SetUnsharedConstpoolIndex(JSTaggedValue(0)); 2364514f5e3Sopenharmony_ci sconstpool->SetSharedConstpoolId(JSTaggedValue(cpId)); 2374514f5e3Sopenharmony_ci return sconstpool; 2384514f5e3Sopenharmony_ci } 2394514f5e3Sopenharmony_ci 2404514f5e3Sopenharmony_ci static JSHandle<AOTLiteralInfo> CopySharedMethodAOTLiteralInfo(EcmaVM *vm, 2414514f5e3Sopenharmony_ci JSHandle<AOTLiteralInfo> src) 2424514f5e3Sopenharmony_ci { 2434514f5e3Sopenharmony_ci ObjectFactory *factory = vm->GetFactory(); 2444514f5e3Sopenharmony_ci JSHandle<AOTLiteralInfo> dst = factory->NewSAOTLiteralInfo(1); 2454514f5e3Sopenharmony_ci for (uint32_t i = 0; i < src->GetCacheLength(); i++) { 2464514f5e3Sopenharmony_ci JSTaggedValue val = src->GetObjectFromCache(i); 2474514f5e3Sopenharmony_ci ASSERT(!val.IsHeapObject() || val.IsJSShared()); 2484514f5e3Sopenharmony_ci dst->SetObjectToCache(vm->GetJSThread(), i, val); 2494514f5e3Sopenharmony_ci } 2504514f5e3Sopenharmony_ci dst->SetLiteralType(JSTaggedValue(src->GetLiteralType())); 2514514f5e3Sopenharmony_ci return dst; 2524514f5e3Sopenharmony_ci } 2534514f5e3Sopenharmony_ci 2544514f5e3Sopenharmony_ci static bool CheckUnsharedConstpool(JSTaggedValue constpool) 2554514f5e3Sopenharmony_ci { 2564514f5e3Sopenharmony_ci int32_t index = ConstantPool::Cast(constpool.GetTaggedObject())->GetUnsharedConstpoolIndex(); 2574514f5e3Sopenharmony_ci if (index == CONSTPOOL_TYPE_FLAG) { 2584514f5e3Sopenharmony_ci return true; 2594514f5e3Sopenharmony_ci } 2604514f5e3Sopenharmony_ci return false; 2614514f5e3Sopenharmony_ci } 2624514f5e3Sopenharmony_ci 2634514f5e3Sopenharmony_ci inline void SetUnsharedConstpoolIndex(const JSTaggedValue index) 2644514f5e3Sopenharmony_ci { 2654514f5e3Sopenharmony_ci Barriers::SetPrimitive(GetData(), GetUnsharedConstpoolIndexOffset(), index); 2664514f5e3Sopenharmony_ci } 2674514f5e3Sopenharmony_ci 2684514f5e3Sopenharmony_ci inline int32_t GetUnsharedConstpoolIndex() const 2694514f5e3Sopenharmony_ci { 2704514f5e3Sopenharmony_ci return Barriers::GetValue<JSTaggedValue>(GetData(), GetUnsharedConstpoolIndexOffset()).GetInt(); 2714514f5e3Sopenharmony_ci } 2724514f5e3Sopenharmony_ci 2734514f5e3Sopenharmony_ci inline void SetSharedConstpoolId(const JSTaggedValue index) 2744514f5e3Sopenharmony_ci { 2754514f5e3Sopenharmony_ci Barriers::SetPrimitive(GetData(), GetSharedConstpoolIdOffset(), index); 2764514f5e3Sopenharmony_ci } 2774514f5e3Sopenharmony_ci 2784514f5e3Sopenharmony_ci inline JSTaggedValue GetSharedConstpoolId() const 2794514f5e3Sopenharmony_ci { 2804514f5e3Sopenharmony_ci return Barriers::GetValue<JSTaggedValue>(GetData(), GetSharedConstpoolIdOffset()); 2814514f5e3Sopenharmony_ci } 2824514f5e3Sopenharmony_ci 2834514f5e3Sopenharmony_ci panda_file::File::EntityId GetEntityId(uint32_t index) const 2844514f5e3Sopenharmony_ci { 2854514f5e3Sopenharmony_ci JSPandaFile *jsPandaFile = GetJSPandaFile(); 2864514f5e3Sopenharmony_ci panda_file::File::IndexHeader *indexHeader = GetIndexHeader(); 2874514f5e3Sopenharmony_ci Span<const panda_file::File::EntityId> indexs = jsPandaFile->GetMethodIndex(indexHeader); 2884514f5e3Sopenharmony_ci return indexs[index]; 2894514f5e3Sopenharmony_ci } 2904514f5e3Sopenharmony_ci 2914514f5e3Sopenharmony_ci int GetMethodIndexByEntityId(panda_file::File::EntityId entityId) const 2924514f5e3Sopenharmony_ci { 2934514f5e3Sopenharmony_ci JSPandaFile *jsPandaFile = GetJSPandaFile(); 2944514f5e3Sopenharmony_ci panda_file::File::IndexHeader *indexHeader = GetIndexHeader(); 2954514f5e3Sopenharmony_ci Span<const panda_file::File::EntityId> indexs = jsPandaFile->GetMethodIndex(indexHeader); 2964514f5e3Sopenharmony_ci int size = static_cast<int>(indexs.size()); 2974514f5e3Sopenharmony_ci for (int i = 0; i < size; i++) { 2984514f5e3Sopenharmony_ci if (indexs[i] == entityId) { 2994514f5e3Sopenharmony_ci return i; 3004514f5e3Sopenharmony_ci } 3014514f5e3Sopenharmony_ci } 3024514f5e3Sopenharmony_ci return -1; 3034514f5e3Sopenharmony_ci } 3044514f5e3Sopenharmony_ci 3054514f5e3Sopenharmony_ci inline void SetIndexHeader(const panda_file::File::IndexHeader *indexHeader) 3064514f5e3Sopenharmony_ci { 3074514f5e3Sopenharmony_ci Barriers::SetPrimitive(GetData(), GetIndexHeaderOffset(), indexHeader); 3084514f5e3Sopenharmony_ci } 3094514f5e3Sopenharmony_ci 3104514f5e3Sopenharmony_ci inline panda_file::File::IndexHeader *GetIndexHeader() const 3114514f5e3Sopenharmony_ci { 3124514f5e3Sopenharmony_ci return Barriers::GetValue<panda_file::File::IndexHeader *>(GetData(), GetIndexHeaderOffset()); 3134514f5e3Sopenharmony_ci } 3144514f5e3Sopenharmony_ci 3154514f5e3Sopenharmony_ci static size_t ComputeSize(uint32_t cacheSize) 3164514f5e3Sopenharmony_ci { 3174514f5e3Sopenharmony_ci return TaggedArray::ComputeSize( 3184514f5e3Sopenharmony_ci JSTaggedValue::TaggedTypeSize(), cacheSize + EXTEND_DATA_NUM + RESERVED_POOL_LENGTH); 3194514f5e3Sopenharmony_ci } 3204514f5e3Sopenharmony_ci 3214514f5e3Sopenharmony_ci void InitializeWithSpecialValue(JSThread *thread, JSTaggedValue initValue, 3224514f5e3Sopenharmony_ci uint32_t capacity, uint32_t extraLength = 0) 3234514f5e3Sopenharmony_ci { 3244514f5e3Sopenharmony_ci ASSERT(initValue.IsSpecial()); 3254514f5e3Sopenharmony_ci SetLength(capacity + EXTEND_DATA_NUM + RESERVED_POOL_LENGTH); 3264514f5e3Sopenharmony_ci SetExtraLength(extraLength); 3274514f5e3Sopenharmony_ci for (uint32_t i = 0; i < capacity; i++) { 3284514f5e3Sopenharmony_ci size_t offset = JSTaggedValue::TaggedTypeSize() * i; 3294514f5e3Sopenharmony_ci Barriers::SetPrimitive<JSTaggedType>(GetData(), offset, initValue.GetRawData()); 3304514f5e3Sopenharmony_ci } 3314514f5e3Sopenharmony_ci JSHandle<TaggedArray> array(thread->GlobalConstants()->GetHandledEmptyArray()); 3324514f5e3Sopenharmony_ci SetAotSymbolInfo(thread, array.GetTaggedValue()); 3334514f5e3Sopenharmony_ci SetProtoTransTableInfo(thread, JSTaggedValue::Undefined()); 3344514f5e3Sopenharmony_ci SetAotHClassInfo(thread, array.GetTaggedValue()); 3354514f5e3Sopenharmony_ci SetAotArrayInfo(thread, array.GetTaggedValue()); 3364514f5e3Sopenharmony_ci SetConstantIndexInfo(thread, array.GetTaggedValue()); 3374514f5e3Sopenharmony_ci SetJSPandaFile(nullptr); 3384514f5e3Sopenharmony_ci SetIndexHeader(nullptr); 3394514f5e3Sopenharmony_ci SetUnsharedConstpoolIndex(JSTaggedValue(CONSTPOOL_TYPE_FLAG)); 3404514f5e3Sopenharmony_ci SetSharedConstpoolId(JSTaggedValue(CONSTPOOL_INVALID_ID)); 3414514f5e3Sopenharmony_ci } 3424514f5e3Sopenharmony_ci 3434514f5e3Sopenharmony_ci inline uint32_t GetCacheLength() const 3444514f5e3Sopenharmony_ci { 3454514f5e3Sopenharmony_ci return GetLength() - RESERVED_POOL_LENGTH; 3464514f5e3Sopenharmony_ci } 3474514f5e3Sopenharmony_ci 3484514f5e3Sopenharmony_ci inline uint32_t GetConstpoolLength() const 3494514f5e3Sopenharmony_ci { 3504514f5e3Sopenharmony_ci return GetLength() - RESERVED_POOL_LENGTH - EXTEND_DATA_NUM; 3514514f5e3Sopenharmony_ci } 3524514f5e3Sopenharmony_ci 3534514f5e3Sopenharmony_ci inline void SetJSPandaFile(const void *jsPandaFile) 3544514f5e3Sopenharmony_ci { 3554514f5e3Sopenharmony_ci Barriers::SetPrimitive(GetData(), GetJSPandaFileOffset(), jsPandaFile); 3564514f5e3Sopenharmony_ci } 3574514f5e3Sopenharmony_ci 3584514f5e3Sopenharmony_ci inline JSPandaFile *GetJSPandaFile() const 3594514f5e3Sopenharmony_ci { 3604514f5e3Sopenharmony_ci return Barriers::GetValue<JSPandaFile *>(GetData(), GetJSPandaFileOffset()); 3614514f5e3Sopenharmony_ci } 3624514f5e3Sopenharmony_ci 3634514f5e3Sopenharmony_ci inline void InitConstantPoolTail(const JSThread *thread, JSHandle<ConstantPool> constPool) 3644514f5e3Sopenharmony_ci { 3654514f5e3Sopenharmony_ci SetAotArrayInfo(thread, constPool->GetAotArrayInfo()); 3664514f5e3Sopenharmony_ci SetAotHClassInfo(thread, constPool->GetAotHClassInfo()); 3674514f5e3Sopenharmony_ci SetConstantIndexInfo(thread, constPool->GetConstantIndexInfo()); 3684514f5e3Sopenharmony_ci SetAotSymbolInfo(thread, constPool->GetAotSymbolInfo()); 3694514f5e3Sopenharmony_ci SetProtoTransTableInfo(thread, constPool->GetProtoTransTableInfo()); 3704514f5e3Sopenharmony_ci } 3714514f5e3Sopenharmony_ci 3724514f5e3Sopenharmony_ci inline void SetConstantIndexInfo(const JSThread *thread, JSTaggedValue info) 3734514f5e3Sopenharmony_ci { 3744514f5e3Sopenharmony_ci Set(thread, (GetLength() - CONSTANT_INDEX_INFO_INDEX), info); 3754514f5e3Sopenharmony_ci } 3764514f5e3Sopenharmony_ci 3774514f5e3Sopenharmony_ci inline JSTaggedValue GetConstantIndexInfo() const 3784514f5e3Sopenharmony_ci { 3794514f5e3Sopenharmony_ci return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetConstantIndexInfoOffset())); 3804514f5e3Sopenharmony_ci } 3814514f5e3Sopenharmony_ci 3824514f5e3Sopenharmony_ci inline void SetAotArrayInfo(const JSThread *thread, JSTaggedValue info) 3834514f5e3Sopenharmony_ci { 3844514f5e3Sopenharmony_ci Set(thread, (GetLength() - AOT_ARRAY_INFO_INDEX), info); 3854514f5e3Sopenharmony_ci } 3864514f5e3Sopenharmony_ci 3874514f5e3Sopenharmony_ci inline JSTaggedValue GetAotArrayInfo() const 3884514f5e3Sopenharmony_ci { 3894514f5e3Sopenharmony_ci return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetAotArrayInfoOffset())); 3904514f5e3Sopenharmony_ci } 3914514f5e3Sopenharmony_ci 3924514f5e3Sopenharmony_ci inline JSTaggedValue GetAotSymbolInfo() const 3934514f5e3Sopenharmony_ci { 3944514f5e3Sopenharmony_ci return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetAotSymbolInfoOffset())); 3954514f5e3Sopenharmony_ci } 3964514f5e3Sopenharmony_ci 3974514f5e3Sopenharmony_ci inline JSTaggedValue GetProtoTransTableInfo() const 3984514f5e3Sopenharmony_ci { 3994514f5e3Sopenharmony_ci return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetProtoTransTableInfoOffset())); 4004514f5e3Sopenharmony_ci } 4014514f5e3Sopenharmony_ci 4024514f5e3Sopenharmony_ci static JSTaggedValue GetSymbolFromSymbolInfo(JSHandle<TaggedArray> symbolInfoHandler, uint64_t id) 4034514f5e3Sopenharmony_ci { 4044514f5e3Sopenharmony_ci uint32_t len = symbolInfoHandler->GetLength(); 4054514f5e3Sopenharmony_ci for (uint32_t j = 0; j < len; j += 2) { // 2: symbolId, symbol 4064514f5e3Sopenharmony_ci ASSERT(j + 1 < len); 4074514f5e3Sopenharmony_ci uint64_t symbolId = symbolInfoHandler->Get(j).GetRawData(); 4084514f5e3Sopenharmony_ci if (symbolId == id) { 4094514f5e3Sopenharmony_ci return symbolInfoHandler->Get(j + 1); 4104514f5e3Sopenharmony_ci } 4114514f5e3Sopenharmony_ci } 4124514f5e3Sopenharmony_ci return JSTaggedValue::Hole(); 4134514f5e3Sopenharmony_ci } 4144514f5e3Sopenharmony_ci 4154514f5e3Sopenharmony_ci static JSTaggedValue GetSymbolFromSymbolInfo(JSTaggedValue symbolInfo, uint64_t id) 4164514f5e3Sopenharmony_ci { 4174514f5e3Sopenharmony_ci TaggedArray* info = TaggedArray::Cast(symbolInfo.GetTaggedObject()); 4184514f5e3Sopenharmony_ci uint32_t len = info->GetLength(); 4194514f5e3Sopenharmony_ci for (uint32_t j = 0; j < len; j += 2) { // 2: symbolId, symbol 4204514f5e3Sopenharmony_ci ASSERT(j + 1 < len); 4214514f5e3Sopenharmony_ci uint64_t symbolId = info->Get(j).GetRawData(); 4224514f5e3Sopenharmony_ci if (symbolId == id) { 4234514f5e3Sopenharmony_ci return info->Get(j + 1); 4244514f5e3Sopenharmony_ci } 4254514f5e3Sopenharmony_ci } 4264514f5e3Sopenharmony_ci return JSTaggedValue::Hole(); 4274514f5e3Sopenharmony_ci } 4284514f5e3Sopenharmony_ci 4294514f5e3Sopenharmony_ci inline void SetAotHClassInfo(const JSThread *thread, JSTaggedValue info) 4304514f5e3Sopenharmony_ci { 4314514f5e3Sopenharmony_ci Set(thread, (GetLength() - AOT_HCLASS_INFO_INDEX), info); 4324514f5e3Sopenharmony_ci } 4334514f5e3Sopenharmony_ci 4344514f5e3Sopenharmony_ci inline JSTaggedValue GetAotHClassInfo() const 4354514f5e3Sopenharmony_ci { 4364514f5e3Sopenharmony_ci return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetAotHClassInfoOffset())); 4374514f5e3Sopenharmony_ci } 4384514f5e3Sopenharmony_ci 4394514f5e3Sopenharmony_ci inline void SetAotSymbolInfo(const JSThread *thread, JSTaggedValue info) 4404514f5e3Sopenharmony_ci { 4414514f5e3Sopenharmony_ci Set(thread, (GetLength() - AOT_SYMBOL_INFO_INDEX), info); 4424514f5e3Sopenharmony_ci } 4434514f5e3Sopenharmony_ci 4444514f5e3Sopenharmony_ci inline void SetProtoTransTableInfo(const JSThread *thread, JSTaggedValue info) 4454514f5e3Sopenharmony_ci { 4464514f5e3Sopenharmony_ci Set(thread, (GetLength() - PROTO_TRANS_TABLE_INFO_INDEX), info); 4474514f5e3Sopenharmony_ci } 4484514f5e3Sopenharmony_ci 4494514f5e3Sopenharmony_ci inline void SetObjectToCache(JSThread *thread, uint32_t index, JSTaggedValue value) 4504514f5e3Sopenharmony_ci { 4514514f5e3Sopenharmony_ci Set(thread, index, value); 4524514f5e3Sopenharmony_ci } 4534514f5e3Sopenharmony_ci 4544514f5e3Sopenharmony_ci static void CASSetObjectToCache( 4554514f5e3Sopenharmony_ci JSThread *thread, const JSTaggedValue constpool, uint32_t index, JSTaggedValue value) 4564514f5e3Sopenharmony_ci { 4574514f5e3Sopenharmony_ci const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 4584514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolHandle(thread, constpool); 4594514f5e3Sopenharmony_ci std::atomic<JSTaggedValue> *atomicVal = reinterpret_cast<std::atomic<JSTaggedValue> *>( 4604514f5e3Sopenharmony_ci reinterpret_cast<uintptr_t>(taggedPool) + DATA_OFFSET + index * JSTaggedValue::TaggedTypeSize()); 4614514f5e3Sopenharmony_ci JSTaggedValue tempVal = taggedPool->GetObjectFromCache(index); 4624514f5e3Sopenharmony_ci JSTaggedValue expected = IsLoadedMethodInfoFromAOT(taggedPool->GetJSPandaFile(), tempVal) ? tempVal : 4634514f5e3Sopenharmony_ci JSTaggedValue::Hole(); 4644514f5e3Sopenharmony_ci JSTaggedValue desired = value; 4654514f5e3Sopenharmony_ci if (std::atomic_compare_exchange_strong_explicit(atomicVal, &expected, desired, 4664514f5e3Sopenharmony_ci std::memory_order_release, std::memory_order_relaxed)) { 4674514f5e3Sopenharmony_ci // set val by Barrier. 4684514f5e3Sopenharmony_ci constpoolHandle->SetObjectToCache(thread, index, value); 4694514f5e3Sopenharmony_ci } 4704514f5e3Sopenharmony_ci } 4714514f5e3Sopenharmony_ci 4724514f5e3Sopenharmony_ci inline JSTaggedValue GetObjectFromCache(uint32_t index) const 4734514f5e3Sopenharmony_ci { 4744514f5e3Sopenharmony_ci return Get(index); 4754514f5e3Sopenharmony_ci } 4764514f5e3Sopenharmony_ci 4774514f5e3Sopenharmony_ci static JSTaggedValue GetMethodFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index) 4784514f5e3Sopenharmony_ci { 4794514f5e3Sopenharmony_ci const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 4804514f5e3Sopenharmony_ci auto val = taggedPool->GetObjectFromCache(index); 4814514f5e3Sopenharmony_ci JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile(); 4824514f5e3Sopenharmony_ci 4834514f5e3Sopenharmony_ci // For AOT 4844514f5e3Sopenharmony_ci bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 4854514f5e3Sopenharmony_ci bool hasEntryIndex = false; 4864514f5e3Sopenharmony_ci uint32_t entryIndex = 0; 4874514f5e3Sopenharmony_ci if (IsLoadedMethodInfoFromAOT(jsPandaFile, val)) { 4884514f5e3Sopenharmony_ci int entryIndexVal = 0; // 0: only one method 4894514f5e3Sopenharmony_ci if (val.IsInt()) { 4904514f5e3Sopenharmony_ci // For MethodInfo which does not have ihc infos, we store codeEntry directly. 4914514f5e3Sopenharmony_ci entryIndexVal = val.GetInt(); 4924514f5e3Sopenharmony_ci } else { 4934514f5e3Sopenharmony_ci JSHandle<AOTLiteralInfo> entryIndexes(thread, val); 4944514f5e3Sopenharmony_ci entryIndexVal = entryIndexes->GetObjectFromCache(0).GetInt(); // 0: only one method 4954514f5e3Sopenharmony_ci } 4964514f5e3Sopenharmony_ci if (entryIndexVal != static_cast<int>(AOTLiteralInfo::NO_FUNC_ENTRY_VALUE)) { 4974514f5e3Sopenharmony_ci hasEntryIndex = true; 4984514f5e3Sopenharmony_ci entryIndex = static_cast<uint32_t>(entryIndexVal); 4994514f5e3Sopenharmony_ci } 5004514f5e3Sopenharmony_ci val = JSTaggedValue::Hole(); 5014514f5e3Sopenharmony_ci } 5024514f5e3Sopenharmony_ci 5034514f5e3Sopenharmony_ci if (!val.IsHole()) { 5044514f5e3Sopenharmony_ci return val; 5054514f5e3Sopenharmony_ci } 5064514f5e3Sopenharmony_ci 5074514f5e3Sopenharmony_ci if (!taggedPool->GetJSPandaFile()->IsNewVersion()) { 5084514f5e3Sopenharmony_ci JSTaggedValue unsharedCp = thread->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(constpool); 5094514f5e3Sopenharmony_ci taggedPool = ConstantPool::Cast(unsharedCp.GetTaggedObject()); 5104514f5e3Sopenharmony_ci return taggedPool->Get(index); 5114514f5e3Sopenharmony_ci } 5124514f5e3Sopenharmony_ci 5134514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 5144514f5e3Sopenharmony_ci ASSERT(jsPandaFile->IsNewVersion()); 5154514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolHandle(thread, constpool); 5164514f5e3Sopenharmony_ci EcmaVM *vm = thread->GetEcmaVM(); 5174514f5e3Sopenharmony_ci 5184514f5e3Sopenharmony_ci EntityId id = constpoolHandle->GetEntityId(index); 5194514f5e3Sopenharmony_ci MethodLiteral *methodLiteral = jsPandaFile->FindMethodLiteral(id.GetOffset()); 5204514f5e3Sopenharmony_ci CHECK_INPUT_NULLPTR(methodLiteral, 5214514f5e3Sopenharmony_ci "GetMethodFromCache:methodLiteral is nullptr, offset: " + std::to_string(id.GetOffset())); 5224514f5e3Sopenharmony_ci ObjectFactory *factory = vm->GetFactory(); 5234514f5e3Sopenharmony_ci JSHandle<Method> method = factory->NewSMethod( 5244514f5e3Sopenharmony_ci jsPandaFile, methodLiteral, constpoolHandle, entryIndex, isLoadedAOT && hasEntryIndex); 5254514f5e3Sopenharmony_ci 5264514f5e3Sopenharmony_ci CASSetObjectToCache(thread, constpoolHandle.GetTaggedValue(), index, method.GetTaggedValue()); 5274514f5e3Sopenharmony_ci return method.GetTaggedValue(); 5284514f5e3Sopenharmony_ci } 5294514f5e3Sopenharmony_ci 5304514f5e3Sopenharmony_ci static JSTaggedValue PUBLIC_API GetMethodFromCache(JSTaggedValue constpool, uint32_t index); 5314514f5e3Sopenharmony_ci 5324514f5e3Sopenharmony_ci static void PUBLIC_API UpdateConstpoolWhenDeserialAI(EcmaVM *vm, JSHandle<ConstantPool> aiCP, 5334514f5e3Sopenharmony_ci JSHandle<ConstantPool> sharedCP, JSHandle<ConstantPool> unsharedCP); 5344514f5e3Sopenharmony_ci 5354514f5e3Sopenharmony_ci static bool PUBLIC_API IsAotMethodLiteralInfo(JSTaggedValue literalInfo); 5364514f5e3Sopenharmony_ci 5374514f5e3Sopenharmony_ci static JSTaggedValue GetClassLiteralFromCache(JSThread *thread, JSHandle<ConstantPool> constpool, 5384514f5e3Sopenharmony_ci uint32_t literal, CString entry, JSHandle<JSTaggedValue> sendableEnv = JSHandle<JSTaggedValue>(), 5394514f5e3Sopenharmony_ci ClassKind kind = ClassKind::NON_SENDABLE); 5404514f5e3Sopenharmony_ci 5414514f5e3Sopenharmony_ci static JSHandle<TaggedArray> GetFieldLiteral(JSThread *thread, JSHandle<ConstantPool> constpool, 5424514f5e3Sopenharmony_ci uint32_t literal, CString entry); 5434514f5e3Sopenharmony_ci 5444514f5e3Sopenharmony_ci template <ConstPoolType type> 5454514f5e3Sopenharmony_ci static JSTaggedValue GetLiteralFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index, CString entry) 5464514f5e3Sopenharmony_ci { 5474514f5e3Sopenharmony_ci static_assert(type == ConstPoolType::OBJECT_LITERAL || type == ConstPoolType::ARRAY_LITERAL); 5484514f5e3Sopenharmony_ci [[maybe_unused]] EcmaHandleScope handleScope(thread); 5494514f5e3Sopenharmony_ci const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 5504514f5e3Sopenharmony_ci auto val = taggedPool->GetObjectFromCache(index); 5514514f5e3Sopenharmony_ci JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile(); 5524514f5e3Sopenharmony_ci 5534514f5e3Sopenharmony_ci // For AOT 5544514f5e3Sopenharmony_ci bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 5554514f5e3Sopenharmony_ci JSHandle<AOTLiteralInfo> entryIndexes(thread, JSTaggedValue::Undefined()); 5564514f5e3Sopenharmony_ci if (isLoadedAOT && val.IsAOTLiteralInfo()) { 5574514f5e3Sopenharmony_ci entryIndexes = JSHandle<AOTLiteralInfo>(thread, val); 5584514f5e3Sopenharmony_ci val = JSTaggedValue::Hole(); 5594514f5e3Sopenharmony_ci } 5604514f5e3Sopenharmony_ci 5614514f5e3Sopenharmony_ci if (val.IsHole()) { 5624514f5e3Sopenharmony_ci JSHandle<ConstantPool> constpoolHandle(thread, constpool); 5634514f5e3Sopenharmony_ci 5644514f5e3Sopenharmony_ci ASSERT(jsPandaFile->IsNewVersion()); 5654514f5e3Sopenharmony_ci panda_file::File::EntityId id = taggedPool->GetEntityId(index); 5664514f5e3Sopenharmony_ci bool needSetAotFlag = isLoadedAOT && !entryIndexes.GetTaggedValue().IsUndefined(); 5674514f5e3Sopenharmony_ci // New inst 5684514f5e3Sopenharmony_ci switch (type) { 5694514f5e3Sopenharmony_ci case ConstPoolType::OBJECT_LITERAL: { 5704514f5e3Sopenharmony_ci JSMutableHandle<TaggedArray> elements(thread, JSTaggedValue::Undefined()); 5714514f5e3Sopenharmony_ci JSMutableHandle<TaggedArray> properties(thread, JSTaggedValue::Undefined()); 5724514f5e3Sopenharmony_ci LiteralDataExtractor::ExtractObjectDatas(thread, jsPandaFile, id, elements, 5734514f5e3Sopenharmony_ci properties, constpoolHandle, entry, needSetAotFlag, entryIndexes); 5744514f5e3Sopenharmony_ci JSTaggedValue ihcVal = JSTaggedValue::Undefined(); 5754514f5e3Sopenharmony_ci if (needSetAotFlag) { 5764514f5e3Sopenharmony_ci ihcVal = entryIndexes->GetIhc(); 5774514f5e3Sopenharmony_ci if (!ihcVal.IsUndefined()) { 5784514f5e3Sopenharmony_ci JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 5794514f5e3Sopenharmony_ci JSHClass::Cast(ihcVal.GetTaggedObject())->SetPrototype(thread, 5804514f5e3Sopenharmony_ci env->GetObjectFunctionPrototype()); 5814514f5e3Sopenharmony_ci } 5824514f5e3Sopenharmony_ci } 5834514f5e3Sopenharmony_ci JSHandle<JSObject> obj = JSObject::CreateObjectFromProperties(thread, properties, ihcVal); 5844514f5e3Sopenharmony_ci auto profiler = thread->GetEcmaVM()->GetPGOProfiler(); 5854514f5e3Sopenharmony_ci profiler->RecordProfileType(obj->GetClass(), jsPandaFile, id.GetOffset()); 5864514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined()); 5874514f5e3Sopenharmony_ci JSMutableHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined()); 5884514f5e3Sopenharmony_ci size_t elementsLen = elements->GetLength(); 5894514f5e3Sopenharmony_ci for (size_t i = 0; i < elementsLen; i += 2) { // 2: Each literal buffer has a pair of key-value. 5904514f5e3Sopenharmony_ci key.Update(elements->Get(i)); 5914514f5e3Sopenharmony_ci if (key->IsHole()) { 5924514f5e3Sopenharmony_ci break; 5934514f5e3Sopenharmony_ci } 5944514f5e3Sopenharmony_ci valueHandle.Update(elements->Get(i + 1)); 5954514f5e3Sopenharmony_ci JSObject::DefinePropertyByLiteral(thread, obj, key, valueHandle); 5964514f5e3Sopenharmony_ci } 5974514f5e3Sopenharmony_ci val = obj.GetTaggedValue(); 5984514f5e3Sopenharmony_ci break; 5994514f5e3Sopenharmony_ci } 6004514f5e3Sopenharmony_ci case ConstPoolType::ARRAY_LITERAL: { 6014514f5e3Sopenharmony_ci // literal fetching from AOT ArrayInfos 6024514f5e3Sopenharmony_ci JSMutableHandle<TaggedArray> literal(thread, JSTaggedValue::Undefined()); 6034514f5e3Sopenharmony_ci #if ECMASCRIPT_ENABLE_ELEMENTSKIND_ALWAY_GENERIC 6044514f5e3Sopenharmony_ci ElementsKind dataKind = ElementsKind::GENERIC; 6054514f5e3Sopenharmony_ci #else 6064514f5e3Sopenharmony_ci ElementsKind dataKind = ElementsKind::NONE; 6074514f5e3Sopenharmony_ci #endif 6084514f5e3Sopenharmony_ci literal.Update(LiteralDataExtractor::GetDatasIgnoreType(thread, jsPandaFile, id, 6094514f5e3Sopenharmony_ci constpoolHandle, entry, 6104514f5e3Sopenharmony_ci needSetAotFlag, entryIndexes, 6114514f5e3Sopenharmony_ci &dataKind)); 6124514f5e3Sopenharmony_ci uint32_t length = literal->GetLength(); 6134514f5e3Sopenharmony_ci JSHandle<JSArray> arr(JSArray::ArrayCreate(thread, JSTaggedNumber(length), ArrayMode::LITERAL)); 6144514f5e3Sopenharmony_ci RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 6154514f5e3Sopenharmony_ci arr->SetElements(thread, literal); 6164514f5e3Sopenharmony_ci if (thread->GetEcmaVM()->IsEnablePGOProfiler() || thread->GetEcmaVM()->IsEnableElementsKind()) { 6174514f5e3Sopenharmony_ci // for all JSArray, the initial ElementsKind should be NONE 6184514f5e3Sopenharmony_ci // Because AOT Stable Array Deopt check, we have support arrayLiteral elementskind 6194514f5e3Sopenharmony_ci // If array is loaded from AOT, no need to do migration. 6204514f5e3Sopenharmony_ci auto globalConstant = const_cast<GlobalEnvConstants *>(thread->GlobalConstants()); 6214514f5e3Sopenharmony_ci auto classIndex = static_cast<size_t>(ConstantIndex::ELEMENT_NONE_HCLASS_INDEX); 6224514f5e3Sopenharmony_ci auto hclassVal = globalConstant->GetGlobalConstantObject(classIndex); 6234514f5e3Sopenharmony_ci arr->SynchronizedSetClass(thread, JSHClass::Cast(hclassVal.GetTaggedObject())); 6244514f5e3Sopenharmony_ci ElementsKind oldKind = arr->GetClass()->GetElementsKind(); 6254514f5e3Sopenharmony_ci JSHClass::TransitToElementsKind(thread, arr, dataKind); 6264514f5e3Sopenharmony_ci ElementsKind newKind = arr->GetClass()->GetElementsKind(); 6274514f5e3Sopenharmony_ci JSHandle<JSObject> receiver(arr); 6284514f5e3Sopenharmony_ci Elements::MigrateArrayWithKind(thread, receiver, oldKind, newKind); 6294514f5e3Sopenharmony_ci } 6304514f5e3Sopenharmony_ci val = arr.GetTaggedValue(); 6314514f5e3Sopenharmony_ci break; 6324514f5e3Sopenharmony_ci } 6334514f5e3Sopenharmony_ci default: 6344514f5e3Sopenharmony_ci LOG_FULL(FATAL) << "Unknown type: " << static_cast<uint8_t>(type); 6354514f5e3Sopenharmony_ci UNREACHABLE(); 6364514f5e3Sopenharmony_ci } 6374514f5e3Sopenharmony_ci constpoolHandle->SetObjectToCache(thread, index, val); 6384514f5e3Sopenharmony_ci } 6394514f5e3Sopenharmony_ci 6404514f5e3Sopenharmony_ci return val; 6414514f5e3Sopenharmony_ci } 6424514f5e3Sopenharmony_ci 6434514f5e3Sopenharmony_ci template <ConstPoolType type> 6444514f5e3Sopenharmony_ci static JSTaggedValue GetLiteralFromCache(JSTaggedValue constpool, uint32_t index, [[maybe_unused]] CString entry) 6454514f5e3Sopenharmony_ci { 6464514f5e3Sopenharmony_ci const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 6474514f5e3Sopenharmony_ci auto val = taggedPool->GetObjectFromCache(index); 6484514f5e3Sopenharmony_ci JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile(); 6494514f5e3Sopenharmony_ci 6504514f5e3Sopenharmony_ci bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 6514514f5e3Sopenharmony_ci if (isLoadedAOT && val.IsAOTLiteralInfo()) { 6524514f5e3Sopenharmony_ci val = JSTaggedValue::Hole(); 6534514f5e3Sopenharmony_ci } 6544514f5e3Sopenharmony_ci return val.IsHole() ? JSTaggedValue::Undefined() : val; 6554514f5e3Sopenharmony_ci } 6564514f5e3Sopenharmony_ci 6574514f5e3Sopenharmony_ci static panda_file::File::EntityId GetIdFromCache(JSTaggedValue constpool, uint32_t index) 6584514f5e3Sopenharmony_ci { 6594514f5e3Sopenharmony_ci const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 6604514f5e3Sopenharmony_ci panda_file::File::EntityId id = taggedPool->GetEntityId(index); 6614514f5e3Sopenharmony_ci return id; 6624514f5e3Sopenharmony_ci } 6634514f5e3Sopenharmony_ci 6644514f5e3Sopenharmony_ci template <ConstPoolType type> 6654514f5e3Sopenharmony_ci static JSTaggedValue GetLiteralFromCache(JSThread *thread, JSTaggedValue constpool, 6664514f5e3Sopenharmony_ci uint32_t index, JSTaggedValue module) 6674514f5e3Sopenharmony_ci { 6684514f5e3Sopenharmony_ci CString entry = ModuleManager::GetRecordName(module); 6694514f5e3Sopenharmony_ci return GetLiteralFromCache<type>(thread, constpool, index, entry); 6704514f5e3Sopenharmony_ci } 6714514f5e3Sopenharmony_ci 6724514f5e3Sopenharmony_ci static JSTaggedValue PUBLIC_API GetStringFromCacheForJit(JSThread *thread, JSTaggedValue constpool, uint32_t index, 6734514f5e3Sopenharmony_ci bool allowAlloc = true); 6744514f5e3Sopenharmony_ci 6754514f5e3Sopenharmony_ci static JSTaggedValue PUBLIC_API GetStringFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index); 6764514f5e3Sopenharmony_ci 6774514f5e3Sopenharmony_ci DECL_VISIT_ARRAY(DATA_OFFSET, GetCacheLength(), GetLength()); 6784514f5e3Sopenharmony_ci 6794514f5e3Sopenharmony_ci DECL_DUMP() 6804514f5e3Sopenharmony_ci 6814514f5e3Sopenharmony_ciprivate: 6824514f5e3Sopenharmony_ci inline size_t GetJSPandaFileOffset() const 6834514f5e3Sopenharmony_ci { 6844514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - JS_PANDA_FILE_INDEX); 6854514f5e3Sopenharmony_ci } 6864514f5e3Sopenharmony_ci 6874514f5e3Sopenharmony_ci inline size_t GetIndexHeaderOffset() const 6884514f5e3Sopenharmony_ci { 6894514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - INDEX_HEADER_INDEX); 6904514f5e3Sopenharmony_ci } 6914514f5e3Sopenharmony_ci 6924514f5e3Sopenharmony_ci inline size_t GetConstantIndexInfoOffset() const 6934514f5e3Sopenharmony_ci { 6944514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - CONSTANT_INDEX_INFO_INDEX); 6954514f5e3Sopenharmony_ci } 6964514f5e3Sopenharmony_ci 6974514f5e3Sopenharmony_ci inline size_t GetAotArrayInfoOffset() const 6984514f5e3Sopenharmony_ci { 6994514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_ARRAY_INFO_INDEX); 7004514f5e3Sopenharmony_ci } 7014514f5e3Sopenharmony_ci 7024514f5e3Sopenharmony_ci inline size_t GetAotHClassInfoOffset() const 7034514f5e3Sopenharmony_ci { 7044514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_HCLASS_INFO_INDEX); 7054514f5e3Sopenharmony_ci } 7064514f5e3Sopenharmony_ci 7074514f5e3Sopenharmony_ci inline size_t GetUnsharedConstpoolIndexOffset() const 7084514f5e3Sopenharmony_ci { 7094514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - UNSHARED_CONSTPOOL_INDEX); 7104514f5e3Sopenharmony_ci } 7114514f5e3Sopenharmony_ci 7124514f5e3Sopenharmony_ci inline size_t GetSharedConstpoolIdOffset() const 7134514f5e3Sopenharmony_ci { 7144514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - SHARED_CONSTPOOL_ID); 7154514f5e3Sopenharmony_ci } 7164514f5e3Sopenharmony_ci 7174514f5e3Sopenharmony_ci inline size_t GetAotSymbolInfoOffset() const 7184514f5e3Sopenharmony_ci { 7194514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_SYMBOL_INFO_INDEX); 7204514f5e3Sopenharmony_ci } 7214514f5e3Sopenharmony_ci 7224514f5e3Sopenharmony_ci inline size_t GetProtoTransTableInfoOffset() const 7234514f5e3Sopenharmony_ci { 7244514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * (GetLength() - PROTO_TRANS_TABLE_INFO_INDEX); 7254514f5e3Sopenharmony_ci } 7264514f5e3Sopenharmony_ci 7274514f5e3Sopenharmony_ci inline size_t GetLastOffset() const 7284514f5e3Sopenharmony_ci { 7294514f5e3Sopenharmony_ci return JSTaggedValue::TaggedTypeSize() * GetLength() + DATA_OFFSET; 7304514f5e3Sopenharmony_ci } 7314514f5e3Sopenharmony_ci 7324514f5e3Sopenharmony_ci static bool IsLoadedMethodInfoFromAOT(const JSPandaFile *pf, JSTaggedValue cachedVal) 7334514f5e3Sopenharmony_ci { 7344514f5e3Sopenharmony_ci return pf->IsLoadedAOT() && (cachedVal.IsAOTLiteralInfo() || cachedVal.IsInt()); 7354514f5e3Sopenharmony_ci }; 7364514f5e3Sopenharmony_ci 7374514f5e3Sopenharmony_ci static JSHandle<JSTaggedValue> GetDeserializedConstantPool( 7384514f5e3Sopenharmony_ci EcmaVM *vm, const JSPandaFile *jsPandaFile, int32_t cpID); 7394514f5e3Sopenharmony_ci static void MergeObjectLiteralHClassCache(EcmaVM *vm, const JSHandle<JSTaggedValue> &pool); 7404514f5e3Sopenharmony_ci}; 7414514f5e3Sopenharmony_ci} // namespace ecmascript 7424514f5e3Sopenharmony_ci} // namespace panda 7434514f5e3Sopenharmony_ci#endif // ECMASCRIPT_JSPANDAFILE_PROGRAM_OBJECT_H 744