1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef ECMASCRIPT_JSPANDAFILE_PROGRAM_OBJECT_H 17 #define ECMASCRIPT_JSPANDAFILE_PROGRAM_OBJECT_H 18 19 #include "ecmascript/compiler/aot_file/aot_file_manager.h" 20 #include "ecmascript/ecma_macros.h" 21 #include "ecmascript/global_env.h" 22 #include "ecmascript/js_tagged_value-inl.h" 23 #include "ecmascript/jspandafile/class_info_extractor.h" 24 #include "ecmascript/jspandafile/class_literal.h" 25 #include "ecmascript/jspandafile/constpool_value.h" 26 #include "ecmascript/jspandafile/js_pandafile_manager.h" 27 #include "ecmascript/jspandafile/literal_data_extractor.h" 28 #include "ecmascript/module/js_module_manager.h" 29 #include "ecmascript/patch/quick_fix_manager.h" 30 #include "ecmascript/pgo_profiler/pgo_profiler.h" 31 32 #include "ecmascript/pgo_profiler/pgo_profiler_manager.h" 33 #include "ecmascript/pgo_profiler/pgo_utils.h" 34 #include "libpandafile/class_data_accessor-inl.h" 35 #include "libpandafile/index_accessor.h" 36 37 namespace panda { 38 namespace ecmascript { 39 class JSThread; 40 41 class Program : public ECMAObject { 42 public: 43 DECL_CAST(Program) 44 45 static constexpr size_t MAIN_FUNCTION_OFFSET = ECMAObject::SIZE; 46 ACCESSORS(MainFunction, MAIN_FUNCTION_OFFSET, SIZE) 47 48 DECL_VISIT_OBJECT(MAIN_FUNCTION_OFFSET, SIZE) 49 DECL_DUMP() 50 }; 51 52 /* ConstantPool 53 * +--------------------------------+---- 54 * | ReviseData | ^ 55 * | ... | | 56 * | string(EcmaString) | | 57 * | method(Method) |cacheLength 58 * | array literal(JSArray) | | 59 * | object literal(JSObject) | | 60 * | class literal(ClassLiteral) | v 61 * +--------------------------------+---- 62 * | AOTHClassInfo |TaggedArray 63 * +--------------------------------+---- 64 * | AOTArrayInfo |TaggedArray 65 * +--------------------------------+---- 66 * | constIndexInfo |TaggedArray 67 * +--------------------------------+---- 68 * | IndexHeader | 69 * +--------------------------------+ 70 * | JSPandaFile | 71 * +--------------------------------+ 72 */ 73 class ConstantPool : public TaggedArray { 74 public: 75 static constexpr size_t JS_PANDA_FILE_INDEX = 1; // not need gc 76 static constexpr size_t INDEX_HEADER_INDEX = 2; // not need gc 77 static constexpr size_t CONSTANT_INDEX_INFO_INDEX = 3; 78 static constexpr size_t AOT_ARRAY_INFO_INDEX = 4; 79 static constexpr size_t AOT_HCLASS_INFO_INDEX = 5; 80 static constexpr size_t RESERVED_POOL_LENGTH = INDEX_HEADER_INDEX; // divide the gc area 81 82 static constexpr size_t EXTEND_DATA_NUM = 3; // AOTHClassInfo, AOTArrayInfo, ConstIndexInfo 83 Cast(TaggedObject * object)84 static ConstantPool *Cast(TaggedObject *object) 85 { 86 ASSERT(JSTaggedValue(object).IsConstantPool()); 87 return static_cast<ConstantPool *>(object); 88 } 89 CreateConstPool(EcmaVM * vm,const JSPandaFile * jsPandaFile,panda_file::File::EntityId id)90 static JSHandle<ConstantPool> CreateConstPool(EcmaVM *vm, const JSPandaFile *jsPandaFile, 91 panda_file::File::EntityId id) 92 { 93 const panda_file::File::IndexHeader *mainIndex = jsPandaFile->GetPandaFile()->GetIndexHeader(id); 94 LOG_ECMA_IF(mainIndex == nullptr, FATAL) << "Unknown methodId: " << id.GetOffset(); 95 auto constpoolSize = mainIndex->method_idx_size; 96 97 JSHandle<ConstantPool> constpool(vm->GetJSThread(), JSTaggedValue::Hole()); 98 bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 99 if (isLoadedAOT) { 100 #if !defined(PANDA_TARGET_WINDOWS) && !defined(PANDA_TARGET_MACOS) 101 panda_file::IndexAccessor indexAccessor(*jsPandaFile->GetPandaFile(), id); 102 int32_t index = static_cast<int32_t>(indexAccessor.GetHeaderIndex()); 103 constpool = GetDeserializedConstantPool(vm, jsPandaFile, index); 104 #else 105 LOG_FULL(FATAL) << "Aot don't support Windows and MacOS platform"; 106 UNREACHABLE(); 107 #endif 108 } 109 if (constpool.GetTaggedValue().IsHole()) { 110 ObjectFactory *factory = vm->GetFactory(); 111 constpool = factory->NewConstantPool(constpoolSize); 112 } 113 114 constpool->SetJSPandaFile(jsPandaFile); 115 constpool->SetIndexHeader(mainIndex); 116 117 return constpool; 118 } 119 GetEntityId(uint32_t index)120 panda_file::File::EntityId GetEntityId(uint32_t index) const 121 { 122 JSPandaFile *jsPandaFile = GetJSPandaFile(); 123 panda_file::File::IndexHeader *indexHeader = GetIndexHeader(); 124 Span<const panda_file::File::EntityId> indexs = jsPandaFile->GetMethodIndex(indexHeader); 125 return indexs[index]; 126 } 127 GetMethodIndexByEntityId(panda_file::File::EntityId entityId)128 int GetMethodIndexByEntityId(panda_file::File::EntityId entityId) const 129 { 130 JSPandaFile *jsPandaFile = GetJSPandaFile(); 131 panda_file::File::IndexHeader *indexHeader = GetIndexHeader(); 132 Span<const panda_file::File::EntityId> indexs = jsPandaFile->GetMethodIndex(indexHeader); 133 int size = static_cast<int>(indexs.size()); 134 for (int i = 0; i < size; i++) { 135 if (indexs[i] == entityId) { 136 return i; 137 } 138 } 139 return -1; 140 } 141 SetIndexHeader(const panda_file::File::IndexHeader * indexHeader)142 inline void SetIndexHeader(const panda_file::File::IndexHeader *indexHeader) 143 { 144 Barriers::SetPrimitive(GetData(), GetIndexHeaderOffset(), indexHeader); 145 } 146 GetIndexHeader()147 inline panda_file::File::IndexHeader *GetIndexHeader() const 148 { 149 return Barriers::GetValue<panda_file::File::IndexHeader *>(GetData(), GetIndexHeaderOffset()); 150 } 151 ComputeSize(uint32_t cacheSize)152 static size_t ComputeSize(uint32_t cacheSize) 153 { 154 return TaggedArray::ComputeSize( 155 JSTaggedValue::TaggedTypeSize(), cacheSize + EXTEND_DATA_NUM + RESERVED_POOL_LENGTH); 156 } 157 158 void InitializeWithSpecialValue(JSThread *thread, JSTaggedValue initValue, 159 uint32_t capacity, uint32_t extraLength = 0) 160 { 161 ASSERT(initValue.IsSpecial()); 162 SetLength(capacity + EXTEND_DATA_NUM + RESERVED_POOL_LENGTH); 163 SetExtraLength(extraLength); 164 for (uint32_t i = 0; i < capacity; i++) { 165 size_t offset = JSTaggedValue::TaggedTypeSize() * i; 166 Barriers::SetPrimitive<JSTaggedType>(GetData(), offset, initValue.GetRawData()); 167 } 168 JSHandle<TaggedArray> array(thread->GlobalConstants()->GetHandledEmptyArray()); 169 SetAotHClassInfo(array.GetTaggedValue()); 170 SetAotArrayInfo(array.GetTaggedValue()); 171 SetConstantIndexInfo(array.GetTaggedValue()); 172 SetJSPandaFile(nullptr); 173 SetIndexHeader(nullptr); 174 } 175 GetCacheLength()176 inline uint32_t GetCacheLength() const 177 { 178 return GetLength() - RESERVED_POOL_LENGTH; 179 } 180 SetJSPandaFile(const void * jsPandaFile)181 inline void SetJSPandaFile(const void *jsPandaFile) 182 { 183 Barriers::SetPrimitive(GetData(), GetJSPandaFileOffset(), jsPandaFile); 184 } 185 GetJSPandaFile()186 inline JSPandaFile *GetJSPandaFile() const 187 { 188 return Barriers::GetValue<JSPandaFile *>(GetData(), GetJSPandaFileOffset()); 189 } 190 SetConstantIndexInfo(JSTaggedValue info)191 inline void SetConstantIndexInfo(JSTaggedValue info) 192 { 193 Barriers::SetPrimitive(GetData(), GetConstantIndexInfoOffset(), info.GetRawData()); 194 } 195 SetAotArrayInfo(JSTaggedValue info)196 inline void SetAotArrayInfo(JSTaggedValue info) 197 { 198 Barriers::SetPrimitive(GetData(), GetAotArrayInfoOffset(), info.GetRawData()); 199 } 200 GetAotArrayInfo()201 inline JSTaggedValue GetAotArrayInfo() 202 { 203 return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetAotArrayInfoOffset())); 204 } 205 SetAotHClassInfo(JSTaggedValue info)206 inline void SetAotHClassInfo(JSTaggedValue info) 207 { 208 Barriers::SetPrimitive(GetData(), GetAotHClassInfoOffset(), info.GetRawData()); 209 } 210 SetObjectToCache(JSThread * thread,uint32_t index,JSTaggedValue value)211 inline void SetObjectToCache(JSThread *thread, uint32_t index, JSTaggedValue value) 212 { 213 Set(thread, index, value); 214 } 215 GetObjectFromCache(uint32_t index)216 inline JSTaggedValue GetObjectFromCache(uint32_t index) const 217 { 218 return Get(index); 219 } 220 GetMethodFromCache(JSThread * thread,JSTaggedValue constpool,JSTaggedValue module,uint32_t index)221 static JSTaggedValue GetMethodFromCache( 222 JSThread *thread, JSTaggedValue constpool, JSTaggedValue module, uint32_t index) 223 { 224 const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 225 auto val = taggedPool->GetObjectFromCache(index); 226 JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile(); 227 228 // For AOT 229 bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 230 bool hasEntryIndex = false; 231 uint32_t entryIndex = 0; 232 if (isLoadedAOT && val.IsAOTLiteralInfo()) { 233 JSHandle<AOTLiteralInfo> entryIndexes(thread, val); 234 int entryIndexVal = entryIndexes->GetObjectFromCache(0).GetInt(); // 0: only one method 235 if (entryIndexVal != static_cast<int>(AOTLiteralInfo::NO_FUNC_ENTRY_VALUE)) { 236 hasEntryIndex = true; 237 entryIndex = static_cast<uint32_t>(entryIndexVal); 238 } 239 val = JSTaggedValue::Hole(); 240 } 241 242 if (!val.IsHole()) { 243 return val; 244 } 245 246 [[maybe_unused]] EcmaHandleScope handleScope(thread); 247 ASSERT(jsPandaFile->IsNewVersion()); 248 JSHandle<ConstantPool> constpoolHandle(thread, constpool); 249 JSHandle<JSTaggedValue> moduleHandle(thread, module); 250 EcmaVM *vm = thread->GetEcmaVM(); 251 252 EntityId id = constpoolHandle->GetEntityId(index); 253 MethodLiteral *methodLiteral = jsPandaFile->FindMethodLiteral(id.GetOffset()); 254 ASSERT(methodLiteral != nullptr); 255 ObjectFactory *factory = vm->GetFactory(); 256 JSHandle<Method> method = factory->NewMethod(jsPandaFile, methodLiteral, constpoolHandle, moduleHandle, 257 entryIndex, isLoadedAOT && hasEntryIndex); 258 constpoolHandle->SetObjectToCache(thread, index, method.GetTaggedValue()); 259 return method.GetTaggedValue(); 260 } 261 262 static JSTaggedValue GetClassLiteralFromCache(JSThread *thread, JSHandle<ConstantPool> constpool, 263 uint32_t literal, CString entry, ClassKind kind = ClassKind::NON_SENDABLE) 264 { 265 [[maybe_unused]] EcmaHandleScope handleScope(thread); 266 // Do not use cache when sendable for get wrong obj from cache, 267 // shall be fix or refactor during shared object implements 268 JSTaggedValue val = (kind == ClassKind::NON_SENDABLE) ? constpool->GetObjectFromCache(literal) : 269 JSTaggedValue::Hole(); 270 JSPandaFile *jsPandaFile = constpool->GetJSPandaFile(); 271 272 // For AOT 273 bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 274 JSHandle<AOTLiteralInfo> entryIndexes(thread, JSTaggedValue::Undefined()); 275 if (isLoadedAOT && val.IsAOTLiteralInfo()) { 276 entryIndexes = JSHandle<AOTLiteralInfo>(thread, val); 277 val = JSTaggedValue::Hole(); 278 } 279 280 if (val.IsHole()) { 281 EcmaVM *vm = thread->GetEcmaVM(); 282 ObjectFactory *factory = vm->GetFactory(); 283 ASSERT(jsPandaFile->IsNewVersion()); 284 panda_file::File::EntityId literalId = constpool->GetEntityId(literal); 285 bool needSetAotFlag = isLoadedAOT && !entryIndexes.GetTaggedValue().IsUndefined(); 286 JSHandle<TaggedArray> literalArray = LiteralDataExtractor::GetDatasIgnoreType( 287 thread, jsPandaFile, literalId, constpool, entry, needSetAotFlag, entryIndexes, nullptr, 288 kind); 289 JSHandle<ClassLiteral> classLiteral = factory->NewClassLiteral(); 290 classLiteral->SetArray(thread, literalArray); 291 val = classLiteral.GetTaggedValue(); 292 constpool->SetObjectToCache(thread, literal, val); 293 } 294 295 return val; 296 } 297 GetFieldLiteral(JSThread * thread,JSHandle<ConstantPool> constpool,uint32_t literal,CString entry)298 static JSHandle<TaggedArray> GetFieldLiteral(JSThread *thread, JSHandle<ConstantPool> constpool, 299 uint32_t literal, CString entry) 300 { 301 JSPandaFile *jsPandaFile = constpool->GetJSPandaFile(); 302 JSHandle<AOTLiteralInfo> entryIndexes(thread, JSTaggedValue::Undefined()); 303 ASSERT(jsPandaFile->IsNewVersion()); 304 panda_file::File::EntityId literalId(literal); 305 JSHandle<TaggedArray> literalArray = LiteralDataExtractor::GetDatasIgnoreType( 306 thread, jsPandaFile, literalId, constpool, entry, false, entryIndexes); 307 return literalArray; 308 } 309 310 template <ConstPoolType type> GetLiteralFromCache(JSThread * thread,JSTaggedValue constpool,uint32_t index,CString entry)311 static JSTaggedValue GetLiteralFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index, CString entry) 312 { 313 static_assert(type == ConstPoolType::OBJECT_LITERAL || type == ConstPoolType::ARRAY_LITERAL); 314 [[maybe_unused]] EcmaHandleScope handleScope(thread); 315 const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 316 auto val = taggedPool->GetObjectFromCache(index); 317 JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile(); 318 319 // For AOT 320 bool isLoadedAOT = jsPandaFile->IsLoadedAOT(); 321 JSHandle<AOTLiteralInfo> entryIndexes(thread, JSTaggedValue::Undefined()); 322 if (isLoadedAOT && val.IsAOTLiteralInfo()) { 323 entryIndexes = JSHandle<AOTLiteralInfo>(thread, val); 324 val = JSTaggedValue::Hole(); 325 } 326 327 if (val.IsHole()) { 328 JSHandle<ConstantPool> constpoolHandle(thread, constpool); 329 330 ASSERT(jsPandaFile->IsNewVersion()); 331 panda_file::File::EntityId id = taggedPool->GetEntityId(index); 332 bool needSetAotFlag = isLoadedAOT && !entryIndexes.GetTaggedValue().IsUndefined(); 333 // New inst 334 switch (type) { 335 case ConstPoolType::OBJECT_LITERAL: { 336 JSMutableHandle<TaggedArray> elements(thread, JSTaggedValue::Undefined()); 337 JSMutableHandle<TaggedArray> properties(thread, JSTaggedValue::Undefined()); 338 LiteralDataExtractor::ExtractObjectDatas(thread, jsPandaFile, id, elements, 339 properties, constpoolHandle, entry, needSetAotFlag, entryIndexes); 340 JSTaggedValue ihcVal = JSTaggedValue::Undefined(); 341 if (needSetAotFlag) { 342 ihcVal = entryIndexes->GetIhc(); 343 if (!ihcVal.IsUndefined()) { 344 JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv(); 345 JSHClass::Cast(ihcVal.GetTaggedObject())->SetPrototype(thread, 346 env->GetObjectFunctionPrototype()); 347 } 348 } 349 JSHandle<JSObject> obj = JSObject::CreateObjectFromProperties(thread, properties, ihcVal); 350 if (thread->GetEcmaVM()->IsEnablePGOProfiler()) { 351 pgo::ApEntityId abcId(0); 352 pgo::PGOProfilerManager::GetInstance()->GetPandaFileId(jsPandaFile->GetJSPandaFileDesc(), 353 abcId); 354 thread->GetEcmaVM()->GetPGOProfiler()->ProfileCreateObject(obj.GetTaggedType(), abcId, 355 id.GetOffset()); 356 } 357 JSMutableHandle<JSTaggedValue> key(thread, JSTaggedValue::Undefined()); 358 JSMutableHandle<JSTaggedValue> valueHandle(thread, JSTaggedValue::Undefined()); 359 size_t elementsLen = elements->GetLength(); 360 for (size_t i = 0; i < elementsLen; i += 2) { // 2: Each literal buffer has a pair of key-value. 361 key.Update(elements->Get(i)); 362 if (key->IsHole()) { 363 break; 364 } 365 valueHandle.Update(elements->Get(i + 1)); 366 JSObject::DefinePropertyByLiteral(thread, obj, key, valueHandle); 367 } 368 val = obj.GetTaggedValue(); 369 break; 370 } 371 case ConstPoolType::ARRAY_LITERAL: { 372 // literal fetching from AOT ArrayInfos 373 JSMutableHandle<TaggedArray> literal(thread, JSTaggedValue::Undefined()); 374 ElementsKind dataKind = ElementsKind::NONE; 375 if (!constpoolHandle->TryGetAOTArrayLiteral(thread, needSetAotFlag, 376 entryIndexes, literal, &dataKind)) { 377 literal.Update(LiteralDataExtractor::GetDatasIgnoreType(thread, jsPandaFile, id, 378 constpoolHandle, entry, 379 needSetAotFlag, entryIndexes, 380 &dataKind)); 381 } 382 uint32_t length = literal->GetLength(); 383 JSHandle<JSArray> arr(JSArray::ArrayCreate(thread, JSTaggedNumber(length), ArrayMode::LITERAL)); 384 RETURN_EXCEPTION_IF_ABRUPT_COMPLETION(thread); 385 arr->SetElements(thread, literal); 386 if (thread->GetEcmaVM()->IsEnablePGOProfiler() || thread->GetEcmaVM()->IsEnableElementsKind()) { 387 // for all JSArray, the initial ElementsKind should be NONE 388 // Because AOT Stable Array Deopt check, we have support arrayLiteral elementskind 389 auto globalConstant = const_cast<GlobalEnvConstants *>(thread->GlobalConstants()); 390 auto classIndex = static_cast<size_t>(ConstantIndex::ELEMENT_NONE_HCLASS_INDEX); 391 auto hclassVal = globalConstant->GetGlobalConstantObject(classIndex); 392 arr->SynchronizedSetClass(thread, JSHClass::Cast(hclassVal.GetTaggedObject())); 393 ElementsKind oldKind = arr->GetClass()->GetElementsKind(); 394 JSHClass::TransitToElementsKind(thread, arr, dataKind); 395 ElementsKind newKind = arr->GetClass()->GetElementsKind(); 396 JSHandle<JSObject> receiver(arr); 397 Elements::MigrateArrayWithKind(thread, receiver, oldKind, newKind); 398 } 399 val = arr.GetTaggedValue(); 400 break; 401 } 402 default: 403 LOG_FULL(FATAL) << "Unknown type: " << static_cast<uint8_t>(type); 404 UNREACHABLE(); 405 } 406 constpoolHandle->SetObjectToCache(thread, index, val); 407 } 408 409 return val; 410 } 411 TryGetAOTArrayLiteral(JSThread * thread,bool loadAOT,JSHandle<AOTLiteralInfo> entryIndexes,JSMutableHandle<TaggedArray> literal,ElementsKind * dataKind)412 bool TryGetAOTArrayLiteral(JSThread *thread, bool loadAOT, JSHandle<AOTLiteralInfo> entryIndexes, 413 JSMutableHandle<TaggedArray> literal, ElementsKind *dataKind) 414 { 415 if (loadAOT) { 416 int elementIndex = entryIndexes->GetElementIndex(); 417 if (elementIndex != kungfu::BaseSnapshotInfo::AOT_ELEMENT_INDEX_DEFAULT_VALUE) { 418 JSTaggedValue arrayInfos = GetAotArrayInfo(); 419 JSHandle<TaggedArray> aotArrayInfos(thread, arrayInfos); 420 literal.Update(aotArrayInfos->Get(elementIndex)); 421 *dataKind = ElementsKind::HOLE_TAGGED; 422 return true; 423 } 424 } 425 return false; 426 } 427 GetIdFromCache(JSTaggedValue constpool,uint32_t index)428 static panda_file::File::EntityId GetIdFromCache(JSTaggedValue constpool, uint32_t index) 429 { 430 const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 431 panda_file::File::EntityId id = taggedPool->GetEntityId(index); 432 return id; 433 } 434 435 template <ConstPoolType type> GetLiteralFromCache(JSThread * thread,JSTaggedValue constpool,uint32_t index,JSTaggedValue module)436 static JSTaggedValue GetLiteralFromCache(JSThread *thread, JSTaggedValue constpool, 437 uint32_t index, JSTaggedValue module) 438 { 439 CString entry = ModuleManager::GetRecordName(module); 440 return GetLiteralFromCache<type>(thread, constpool, index, entry); 441 } 442 GetStringFromCache(JSThread * thread,JSTaggedValue constpool,uint32_t index)443 static JSTaggedValue PUBLIC_API GetStringFromCache(JSThread *thread, JSTaggedValue constpool, uint32_t index) 444 { 445 const ConstantPool *taggedPool = ConstantPool::Cast(constpool.GetTaggedObject()); 446 auto val = taggedPool->Get(index); 447 if (val.IsHole()) { 448 [[maybe_unused]] EcmaHandleScope handleScope(thread); 449 450 JSPandaFile *jsPandaFile = taggedPool->GetJSPandaFile(); 451 panda_file::File::EntityId id = taggedPool->GetEntityId(index); 452 auto foundStr = jsPandaFile->GetStringData(id); 453 454 EcmaVM *vm = thread->GetEcmaVM(); 455 ObjectFactory *factory = vm->GetFactory(); 456 JSHandle<ConstantPool> constpoolHandle(thread, constpool); 457 auto string = factory->GetRawStringFromStringTable(foundStr, MemSpaceType::OLD_SPACE, 458 jsPandaFile->IsFirstMergedAbc(), id.GetOffset()); 459 460 val = JSTaggedValue(string); 461 constpoolHandle->SetObjectToCache(thread, index, val); 462 } 463 464 return val; 465 } 466 467 DECL_VISIT_ARRAY(DATA_OFFSET, GetCacheLength(), GetLength()); 468 DECL_DUMP()469 DECL_DUMP() 470 471 private: 472 inline size_t GetJSPandaFileOffset() const 473 { 474 return JSTaggedValue::TaggedTypeSize() * (GetLength() - JS_PANDA_FILE_INDEX); 475 } 476 GetIndexHeaderOffset()477 inline size_t GetIndexHeaderOffset() const 478 { 479 return JSTaggedValue::TaggedTypeSize() * (GetLength() - INDEX_HEADER_INDEX); 480 } 481 GetConstantIndexInfoOffset()482 inline size_t GetConstantIndexInfoOffset() const 483 { 484 return JSTaggedValue::TaggedTypeSize() * (GetLength() - CONSTANT_INDEX_INFO_INDEX); 485 } 486 GetAotArrayInfoOffset()487 inline size_t GetAotArrayInfoOffset() const 488 { 489 return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_ARRAY_INFO_INDEX); 490 } 491 GetAotHClassInfoOffset()492 inline size_t GetAotHClassInfoOffset() const 493 { 494 return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_HCLASS_INFO_INDEX); 495 } 496 GetLastOffset()497 inline size_t GetLastOffset() const 498 { 499 return JSTaggedValue::TaggedTypeSize() * GetLength() + DATA_OFFSET; 500 } 501 502 static JSHandle<ConstantPool> GetDeserializedConstantPool(EcmaVM *vm, const JSPandaFile *jsPandaFile, int32_t cpID); 503 }; 504 } // namespace ecmascript 505 } // namespace panda 506 #endif // ECMASCRIPT_JSPANDAFILE_PROGRAM_OBJECT_H 507