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