14514f5e3Sopenharmony_ci/*
24514f5e3Sopenharmony_ci * Copyright (c) 2023-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#include "ecmascript/compiler/aot_snapshot/snapshot_constantpool_data.h"
174514f5e3Sopenharmony_ci
184514f5e3Sopenharmony_ci#include "ecmascript/compiler/pgo_type/pgo_type_manager.h"
194514f5e3Sopenharmony_ci#include "ecmascript/js_object-inl.h"
204514f5e3Sopenharmony_ci#include "ecmascript/jspandafile/program_object.h"
214514f5e3Sopenharmony_ci
224514f5e3Sopenharmony_cinamespace panda::ecmascript::kungfu {
234514f5e3Sopenharmony_ciuint64_t BaseSnapshotInfo::GetItemKey(uint32_t constantPoolId, uint32_t constantPoolIdx)
244514f5e3Sopenharmony_ci{
254514f5e3Sopenharmony_ci    uint64_t result = constantPoolId;
264514f5e3Sopenharmony_ci    result = result << CONSTPOOL_MASK;
274514f5e3Sopenharmony_ci    result |= constantPoolIdx;
284514f5e3Sopenharmony_ci    return result;
294514f5e3Sopenharmony_ci}
304514f5e3Sopenharmony_ci
314514f5e3Sopenharmony_cibool BaseSnapshotInfo::TryGetABCId(ApEntityId &abcId)
324514f5e3Sopenharmony_ci{
334514f5e3Sopenharmony_ci    return pfDecoder_->GetABCIdByJSPandaFile(jsPandaFile_, abcId);
344514f5e3Sopenharmony_ci}
354514f5e3Sopenharmony_ci
364514f5e3Sopenharmony_ciJSHandle<JSTaggedValue> BaseSnapshotInfo::TryGetIHClass(ProfileType rootType, ProfileType childType,
374514f5e3Sopenharmony_ci    const ItemData &data, const JSHandle<TaggedArray> &properties, const SnapshotGlobalData &globalData) const
384514f5e3Sopenharmony_ci{
394514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> ihc = TryGetHClass(rootType, childType);
404514f5e3Sopenharmony_ci    if (ihc->IsUndefined()) {
414514f5e3Sopenharmony_ci        PGOTypeLocation loc(jsPandaFile_, data.methodOffset_, data.bcIndex_);
424514f5e3Sopenharmony_ci        ihc = TryGetHClassByPGOTypeLocation(loc);
434514f5e3Sopenharmony_ci        if (ihc->IsUndefined()) {
444514f5e3Sopenharmony_ci            ihc = TryGetHClassFromCached(properties, globalData);
454514f5e3Sopenharmony_ci        }
464514f5e3Sopenharmony_ci    }
474514f5e3Sopenharmony_ci    return ihc;
484514f5e3Sopenharmony_ci}
494514f5e3Sopenharmony_ci
504514f5e3Sopenharmony_ciJSHandle<JSTaggedValue> BaseSnapshotInfo::TryGetHClass(ProfileType rootType, ProfileType childType) const
514514f5e3Sopenharmony_ci{
524514f5e3Sopenharmony_ci    PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
534514f5e3Sopenharmony_ci    JSTaggedValue hclass = ptManager->QueryHClass(rootType, childType);
544514f5e3Sopenharmony_ci    return JSHandle<JSTaggedValue>(thread_, hclass);
554514f5e3Sopenharmony_ci}
564514f5e3Sopenharmony_ci
574514f5e3Sopenharmony_ciJSHandle<JSTaggedValue> BaseSnapshotInfo::TryGetHClassByPGOTypeLocation(PGOTypeLocation loc) const
584514f5e3Sopenharmony_ci{
594514f5e3Sopenharmony_ci    PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
604514f5e3Sopenharmony_ci    ProfileType  pt = ptManager->GetRootIdByLocation(loc);
614514f5e3Sopenharmony_ci    return TryGetHClass(pt, pt);
624514f5e3Sopenharmony_ci}
634514f5e3Sopenharmony_ci
644514f5e3Sopenharmony_ciJSHandle<JSTaggedValue> BaseSnapshotInfo::TryGetHClassFromCached(const JSHandle<TaggedArray> &properties,
654514f5e3Sopenharmony_ci                                                                 const SnapshotGlobalData &globalData) const
664514f5e3Sopenharmony_ci{
674514f5e3Sopenharmony_ci    DISALLOW_GARBAGE_COLLECTION;
684514f5e3Sopenharmony_ci    JSHandle<JSTaggedValue> maybeCache(thread_, globalData.GetObjectLiteralHClassCache());
694514f5e3Sopenharmony_ci    if (maybeCache->IsTaggedArray()) {
704514f5e3Sopenharmony_ci        size_t length = properties->GetLength();
714514f5e3Sopenharmony_ci        uint32_t propsLen = 0;
724514f5e3Sopenharmony_ci        for (size_t i = 0; i < length; i += 2) { // 2: skip a pair of key and value
734514f5e3Sopenharmony_ci            if (properties->Get(i).IsHole()) {
744514f5e3Sopenharmony_ci                break;
754514f5e3Sopenharmony_ci            }
764514f5e3Sopenharmony_ci            propsLen++;
774514f5e3Sopenharmony_ci        }
784514f5e3Sopenharmony_ci
794514f5e3Sopenharmony_ci        if (!ObjectFactory::CanObjectLiteralHClassCache(propsLen)) {
804514f5e3Sopenharmony_ci            return thread_->GlobalConstants()->GetHandledUndefined();
814514f5e3Sopenharmony_ci        }
824514f5e3Sopenharmony_ci
834514f5e3Sopenharmony_ci        JSHandle<TaggedArray> hclassCacheArr = JSHandle<TaggedArray>::Cast(maybeCache);
844514f5e3Sopenharmony_ci        JSTaggedValue maybeHClass = hclassCacheArr->Get(propsLen);
854514f5e3Sopenharmony_ci        if (!maybeHClass.IsJSHClass()) {
864514f5e3Sopenharmony_ci            return thread_->GlobalConstants()->GetHandledUndefined();
874514f5e3Sopenharmony_ci        }
884514f5e3Sopenharmony_ci        JSHClass *newClass = JSHClass::Cast(maybeHClass.GetTaggedObject());
894514f5e3Sopenharmony_ci        JSMutableHandle<JSTaggedValue> key(thread_, JSTaggedValue::Undefined());
904514f5e3Sopenharmony_ci
914514f5e3Sopenharmony_ci        for (size_t fieldOffset = 0; fieldOffset < propsLen; fieldOffset++) {
924514f5e3Sopenharmony_ci            key.Update(properties->Get(fieldOffset * 2)); // 2 : pair of key and value
934514f5e3Sopenharmony_ci            ASSERT_PRINT(JSTaggedValue::IsPropertyKey(key), "Key is not a property key");
944514f5e3Sopenharmony_ci            PropertyAttributes attributes = PropertyAttributes::Default();
954514f5e3Sopenharmony_ci            auto value = properties->Get(fieldOffset * 2 + 1);
964514f5e3Sopenharmony_ci            if (value.IsAccessor()) {  // 2: Meaning to double
974514f5e3Sopenharmony_ci                attributes.SetIsAccessor(true);
984514f5e3Sopenharmony_ci            }
994514f5e3Sopenharmony_ci            attributes.SetIsInlinedProps(true);
1004514f5e3Sopenharmony_ci            attributes.SetRepresentation(Representation::TAGGED);
1014514f5e3Sopenharmony_ci            attributes.SetOffset(fieldOffset);
1024514f5e3Sopenharmony_ci
1034514f5e3Sopenharmony_ci            auto metadata = JSTaggedValue(attributes.GetPropertyMetaData());
1044514f5e3Sopenharmony_ci            auto rep = PropertyAttributes::TranslateToRep(value);
1054514f5e3Sopenharmony_ci            newClass = newClass->FindTransitions(key.GetTaggedValue(), metadata, rep);
1064514f5e3Sopenharmony_ci            if (newClass == nullptr) {
1074514f5e3Sopenharmony_ci                return thread_->GlobalConstants()->GetHandledUndefined();
1084514f5e3Sopenharmony_ci            }
1094514f5e3Sopenharmony_ci        }
1104514f5e3Sopenharmony_ci
1114514f5e3Sopenharmony_ci        auto result = JSHandle<JSHClass>(thread_, newClass);
1124514f5e3Sopenharmony_ci        if (JSObject::CheckPropertiesForRep(properties, propsLen, result)) {
1134514f5e3Sopenharmony_ci            return JSHandle<JSTaggedValue>(result);
1144514f5e3Sopenharmony_ci        }
1154514f5e3Sopenharmony_ci    }
1164514f5e3Sopenharmony_ci    return thread_->GlobalConstants()->GetHandledUndefined();
1174514f5e3Sopenharmony_ci}
1184514f5e3Sopenharmony_ci
1194514f5e3Sopenharmony_civoid BaseSnapshotInfo::Record(ItemData &data)
1204514f5e3Sopenharmony_ci{
1214514f5e3Sopenharmony_ci    ItemKey key = GetItemKey(data.constantPoolId_, data.constantPoolIdx_);
1224514f5e3Sopenharmony_ci    info_.emplace(key, data);
1234514f5e3Sopenharmony_ci}
1244514f5e3Sopenharmony_ci
1254514f5e3Sopenharmony_civoid BaseSnapshotInfo::CollectLiteralInfo(JSHandle<TaggedArray> array, uint32_t constantPoolIndex,
1264514f5e3Sopenharmony_ci                                          JSHandle<ConstantPool> snapshotConstantPool,
1274514f5e3Sopenharmony_ci                                          const std::set<uint32_t> &skippedMethods,
1284514f5e3Sopenharmony_ci                                          JSHandle<JSTaggedValue> ihc, JSHandle<JSTaggedValue> chc)
1294514f5e3Sopenharmony_ci{
1304514f5e3Sopenharmony_ci    ObjectFactory *factory = vm_->GetFactory();
1314514f5e3Sopenharmony_ci    JSMutableHandle<JSTaggedValue> valueHandle(thread_, JSTaggedValue::Undefined());
1324514f5e3Sopenharmony_ci    uint32_t len = array->GetLength();
1334514f5e3Sopenharmony_ci    std::vector<int> methodOffsetVec;
1344514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < len; i++) {
1354514f5e3Sopenharmony_ci        valueHandle.Update(array->Get(i));
1364514f5e3Sopenharmony_ci        uint32_t methodOffset = 0;
1374514f5e3Sopenharmony_ci        if (valueHandle->IsJSFunction()) {
1384514f5e3Sopenharmony_ci            methodOffset = JSHandle<JSFunction>(valueHandle)->GetCallTarget()->GetMethodId().GetOffset();
1394514f5e3Sopenharmony_ci        } else if (valueHandle->IsFunctionTemplate()) {
1404514f5e3Sopenharmony_ci            auto method = Method::Cast(JSHandle<FunctionTemplate>(valueHandle)->GetMethod());
1414514f5e3Sopenharmony_ci            methodOffset = method->GetMethodId().GetOffset();
1424514f5e3Sopenharmony_ci        }
1434514f5e3Sopenharmony_ci        if (methodOffset != 0) {
1444514f5e3Sopenharmony_ci            if (skippedMethods.find(methodOffset) != skippedMethods.end()) {
1454514f5e3Sopenharmony_ci                methodOffsetVec.emplace_back(AOTLiteralInfo::NO_FUNC_ENTRY_VALUE);
1464514f5e3Sopenharmony_ci            } else {
1474514f5e3Sopenharmony_ci                methodOffsetVec.emplace_back(methodOffset);
1484514f5e3Sopenharmony_ci            }
1494514f5e3Sopenharmony_ci        }
1504514f5e3Sopenharmony_ci    }
1514514f5e3Sopenharmony_ci
1524514f5e3Sopenharmony_ci    uint32_t methodSize = methodOffsetVec.size();
1534514f5e3Sopenharmony_ci    JSHandle<AOTLiteralInfo> aotLiteralInfo = factory->NewAOTLiteralInfo(methodSize);
1544514f5e3Sopenharmony_ci    for (uint32_t i = 0; i < methodSize; ++i) {
1554514f5e3Sopenharmony_ci        auto methodOffset = methodOffsetVec[i];
1564514f5e3Sopenharmony_ci        aotLiteralInfo->SetObjectToCache(thread_, i, JSTaggedValue(methodOffset));
1574514f5e3Sopenharmony_ci    }
1584514f5e3Sopenharmony_ci
1594514f5e3Sopenharmony_ci    if (!ihc->IsUndefined()) {
1604514f5e3Sopenharmony_ci        aotLiteralInfo->SetIhc(ihc.GetTaggedValue());
1614514f5e3Sopenharmony_ci    }
1624514f5e3Sopenharmony_ci
1634514f5e3Sopenharmony_ci    if (!chc->IsUndefined()) {
1644514f5e3Sopenharmony_ci        aotLiteralInfo->SetChc(chc.GetTaggedValue());
1654514f5e3Sopenharmony_ci    }
1664514f5e3Sopenharmony_ci
1674514f5e3Sopenharmony_ci    snapshotConstantPool->SetObjectToCache(thread_, constantPoolIndex, aotLiteralInfo.GetTaggedValue());
1684514f5e3Sopenharmony_ci}
1694514f5e3Sopenharmony_ci
1704514f5e3Sopenharmony_cibool BaseSnapshotInfo::CheckAOTPropertiesForRep(const JSHandle<TaggedArray> &properties,
1714514f5e3Sopenharmony_ci                                                const JSHandle<JSHClass> &hclass)
1724514f5e3Sopenharmony_ci{
1734514f5e3Sopenharmony_ci    auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject());
1744514f5e3Sopenharmony_ci    for (size_t i = 0; i < properties->GetLength(); i++) {
1754514f5e3Sopenharmony_ci        auto attr = layout->GetAttr(i);
1764514f5e3Sopenharmony_ci        auto value = JSObject::ConvertValueWithRep(attr, properties->Get(i));
1774514f5e3Sopenharmony_ci        // If value.first is false, indicating that value cannot be converted to the expected value of
1784514f5e3Sopenharmony_ci        // representation. For example, the representation is INT, but the value type is string.
1794514f5e3Sopenharmony_ci        if (!value.first) {
1804514f5e3Sopenharmony_ci            return false;
1814514f5e3Sopenharmony_ci        }
1824514f5e3Sopenharmony_ci    }
1834514f5e3Sopenharmony_ci    return true;
1844514f5e3Sopenharmony_ci}
1854514f5e3Sopenharmony_ci
1864514f5e3Sopenharmony_cibool BaseSnapshotInfo::CheckAOTIhcPropertiesForRep(JSThread *thread, const JSHandle<JSTaggedValue> &ihc,
1874514f5e3Sopenharmony_ci                                                   const JSHandle<ClassInfoExtractor> &extractor)
1884514f5e3Sopenharmony_ci{
1894514f5e3Sopenharmony_ci    if (ihc->IsUndefinedOrNull()) {
1904514f5e3Sopenharmony_ci        return false;
1914514f5e3Sopenharmony_ci    }
1924514f5e3Sopenharmony_ci    JSHandle<JSObject> prototype;
1934514f5e3Sopenharmony_ci    if (ihc->IsJSHClass()) {
1944514f5e3Sopenharmony_ci        JSHandle<JSHClass> ihclass(ihc);
1954514f5e3Sopenharmony_ci        prototype = JSHandle<JSObject>(thread, ihclass->GetProto());
1964514f5e3Sopenharmony_ci    } else {
1974514f5e3Sopenharmony_ci        prototype = JSHandle<JSObject>(ihc);
1984514f5e3Sopenharmony_ci    }
1994514f5e3Sopenharmony_ci
2004514f5e3Sopenharmony_ci    ASSERT(!prototype->GetJSHClass()->IsDictionaryMode());
2014514f5e3Sopenharmony_ci    JSHandle<TaggedArray> nonStaticProperties(thread, extractor->GetNonStaticProperties());
2024514f5e3Sopenharmony_ci    JSHandle<JSHClass> protohclass(thread, prototype->GetJSHClass());
2034514f5e3Sopenharmony_ci    return CheckAOTPropertiesForRep(nonStaticProperties, protohclass);
2044514f5e3Sopenharmony_ci}
2054514f5e3Sopenharmony_ci
2064514f5e3Sopenharmony_cibool BaseSnapshotInfo::CheckAOTChcPropertiesForRep(JSThread *thread, const JSHandle<JSTaggedValue> &chc,
2074514f5e3Sopenharmony_ci                                                   const JSHandle<ClassInfoExtractor> &extractor)
2084514f5e3Sopenharmony_ci{
2094514f5e3Sopenharmony_ci    if (chc->IsUndefinedOrNull()) {
2104514f5e3Sopenharmony_ci        return false;
2114514f5e3Sopenharmony_ci    }
2124514f5e3Sopenharmony_ci    JSHandle<JSHClass> chclass(thread, JSHClass::Cast(chc->GetTaggedObject()));
2134514f5e3Sopenharmony_ci    ASSERT(!chclass->IsDictionaryMode());
2144514f5e3Sopenharmony_ci    JSHandle<TaggedArray> staticProperties(thread, extractor->GetStaticProperties());
2154514f5e3Sopenharmony_ci    return CheckAOTPropertiesForRep(staticProperties, chclass);
2164514f5e3Sopenharmony_ci}
2174514f5e3Sopenharmony_ci
2184514f5e3Sopenharmony_civoid StringSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalData, const std::set<uint32_t>&)
2194514f5e3Sopenharmony_ci{
2204514f5e3Sopenharmony_ci    for (auto item : info_) {
2214514f5e3Sopenharmony_ci        const ItemData &data = item.second;
2224514f5e3Sopenharmony_ci        uint32_t snapshotCpArrIdx = globalData.GetCpArrIdxByConstanPoolId(data.constantPoolId_);
2234514f5e3Sopenharmony_ci        JSHandle<TaggedArray> snapshotCpArr(thread_, globalData.GetCurSnapshotCpArray());
2244514f5e3Sopenharmony_ci        JSHandle<ConstantPool> snapshotCp(thread_, snapshotCpArr->Get(snapshotCpArrIdx));
2254514f5e3Sopenharmony_ci        // Lazy ConstantPool String Loading
2264514f5e3Sopenharmony_ci        snapshotCp->SetObjectToCache(thread_, data.constantPoolIdx_, JSTaggedValue::Hole());
2274514f5e3Sopenharmony_ci    }
2284514f5e3Sopenharmony_ci
2294514f5e3Sopenharmony_ci    if (vm_->GetJSOptions().IsEnableCompilerLogSnapshot()) {
2304514f5e3Sopenharmony_ci        vm_->AddAOTSnapShotStats("String", info_.size());
2314514f5e3Sopenharmony_ci    }
2324514f5e3Sopenharmony_ci}
2334514f5e3Sopenharmony_ci
2344514f5e3Sopenharmony_civoid MethodSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalData,
2354514f5e3Sopenharmony_ci                                               const std::set<uint32_t> &skippedMethods)
2364514f5e3Sopenharmony_ci{
2374514f5e3Sopenharmony_ci    ApEntityId abcId = INVALID_INDEX;
2384514f5e3Sopenharmony_ci    bool hasAbcId = TryGetABCId(abcId);
2394514f5e3Sopenharmony_ci    ObjectFactory *factory = vm_->GetFactory();
2404514f5e3Sopenharmony_ci    for (auto item : info_) {
2414514f5e3Sopenharmony_ci        const ItemData &data = item.second;
2424514f5e3Sopenharmony_ci        JSHandle<ConstantPool> cp(thread_,
2434514f5e3Sopenharmony_ci            thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, data.constantPoolId_));
2444514f5e3Sopenharmony_ci        uint32_t methodOffset = cp->GetEntityId(data.constantPoolIdx_).GetOffset();
2454514f5e3Sopenharmony_ci
2464514f5e3Sopenharmony_ci        uint32_t snapshotCpArrIdx = globalData.GetCpArrIdxByConstanPoolId(data.constantPoolId_);
2474514f5e3Sopenharmony_ci        JSHandle<TaggedArray> snapshotCpArr(thread_, globalData.GetCurSnapshotCpArray());
2484514f5e3Sopenharmony_ci        JSHandle<ConstantPool> snapshotCp(thread_, snapshotCpArr->Get(snapshotCpArrIdx));
2494514f5e3Sopenharmony_ci
2504514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> ihc = thread_->GlobalConstants()->GetHandledUndefined();
2514514f5e3Sopenharmony_ci        if (hasAbcId) {
2524514f5e3Sopenharmony_ci            ProfileType pt(abcId, methodOffset, ProfileType::Kind::ClassId, true);
2534514f5e3Sopenharmony_ci            ihc = TryGetHClass(pt, pt);
2544514f5e3Sopenharmony_ci        }
2554514f5e3Sopenharmony_ci        JSHandle<AOTLiteralInfo> aotLiteralInfo = factory->NewAOTLiteralInfo(1); // 1: only one method
2564514f5e3Sopenharmony_ci        int initValue = static_cast<int>(AOTLiteralInfo::NO_FUNC_ENTRY_VALUE);
2574514f5e3Sopenharmony_ci        aotLiteralInfo->SetObjectToCache(thread_, 0, JSTaggedValue(initValue));
2584514f5e3Sopenharmony_ci        aotLiteralInfo->SetLiteralType(JSTaggedValue(AOTLiteralInfo::METHOD_LITERAL_TYPE));
2594514f5e3Sopenharmony_ci        if (!ihc->IsUndefined()) {
2604514f5e3Sopenharmony_ci            aotLiteralInfo->SetIhc(ihc.GetTaggedValue());
2614514f5e3Sopenharmony_ci            if (skippedMethods.find(methodOffset) == skippedMethods.end()) {
2624514f5e3Sopenharmony_ci                aotLiteralInfo->SetObjectToCache(thread_, 0, JSTaggedValue(methodOffset));
2634514f5e3Sopenharmony_ci                globalData.RecordReviseData(
2644514f5e3Sopenharmony_ci                    ReviseData::ItemData {globalData.GetCurDataIdx(), snapshotCpArrIdx, data.constantPoolIdx_});
2654514f5e3Sopenharmony_ci            }
2664514f5e3Sopenharmony_ci            snapshotCp->SetObjectToCache(thread_, data.constantPoolIdx_, aotLiteralInfo.GetTaggedValue());
2674514f5e3Sopenharmony_ci        } else if (skippedMethods.find(methodOffset) == skippedMethods.end()) {
2684514f5e3Sopenharmony_ci            // For MethodSnaphotInfo which does not have ihc info, we insert JSTaggedValue(methodOffset) as revervation.
2694514f5e3Sopenharmony_ci            // For the purpose of reducing ai size.
2704514f5e3Sopenharmony_ci            globalData.RecordReviseData(
2714514f5e3Sopenharmony_ci                ReviseData::ItemData {globalData.GetCurDataIdx(), snapshotCpArrIdx, data.constantPoolIdx_});
2724514f5e3Sopenharmony_ci            snapshotCp->SetObjectToCache(thread_, data.constantPoolIdx_, JSTaggedValue(methodOffset));
2734514f5e3Sopenharmony_ci        } else {
2744514f5e3Sopenharmony_ci            snapshotCp->SetObjectToCache(thread_, data.constantPoolIdx_, JSTaggedValue::Hole());
2754514f5e3Sopenharmony_ci        }
2764514f5e3Sopenharmony_ci    }
2774514f5e3Sopenharmony_ci    if (vm_->GetJSOptions().IsEnableCompilerLogSnapshot()) {
2784514f5e3Sopenharmony_ci        vm_->AddAOTSnapShotStats("Method", info_.size());
2794514f5e3Sopenharmony_ci    }
2804514f5e3Sopenharmony_ci}
2814514f5e3Sopenharmony_ci
2824514f5e3Sopenharmony_civoid ClassLiteralSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalData,
2834514f5e3Sopenharmony_ci                                                     const std::set<uint32_t> &skippedMethods)
2844514f5e3Sopenharmony_ci{
2854514f5e3Sopenharmony_ci    ApEntityId abcId = INVALID_INDEX;
2864514f5e3Sopenharmony_ci    bool hasAbcId = TryGetABCId(abcId);
2874514f5e3Sopenharmony_ci    for (auto item : info_) {
2884514f5e3Sopenharmony_ci        const ItemData &data = item.second;
2894514f5e3Sopenharmony_ci        JSHandle<ConstantPool> cp = GetUnsharedConstpool(data);
2904514f5e3Sopenharmony_ci        auto literalObj = ConstantPool::GetClassLiteralFromCache(thread_, cp, data.constantPoolIdx_, data.recordName_);
2914514f5e3Sopenharmony_ci        JSHandle<ClassLiteral> classLiteral(thread_, literalObj);
2924514f5e3Sopenharmony_ci        JSHandle<TaggedArray> arrayHandle(thread_, classLiteral->GetArray());
2934514f5e3Sopenharmony_ci
2944514f5e3Sopenharmony_ci        uint32_t snapshotCpArrIdx = globalData.GetCpArrIdxByConstanPoolId(data.constantPoolId_);
2954514f5e3Sopenharmony_ci        JSHandle<TaggedArray> snapshotCpArr(thread_, globalData.GetCurSnapshotCpArray());
2964514f5e3Sopenharmony_ci        JSHandle<ConstantPool> snapshotCp(thread_, snapshotCpArr->Get(snapshotCpArrIdx));
2974514f5e3Sopenharmony_ci
2984514f5e3Sopenharmony_ci        uint32_t methodId = cp->GetEntityId(data.ctorMethodOffset_).GetOffset();
2994514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> undefinedHandle = thread_->GlobalConstants()->GetHandledUndefined();
3004514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> ihc = undefinedHandle;
3014514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> chc = undefinedHandle;
3024514f5e3Sopenharmony_ci        if (hasAbcId) {
3034514f5e3Sopenharmony_ci            ProfileType pt(abcId, methodId, ProfileType::Kind::ClassId, true);
3044514f5e3Sopenharmony_ci            ProfileType ctorPt(abcId, methodId, ProfileType::Kind::ConstructorId, true);
3054514f5e3Sopenharmony_ci            ihc = TryGetHClass(pt, pt);
3064514f5e3Sopenharmony_ci            chc = TryGetHClass(ctorPt, ctorPt);
3074514f5e3Sopenharmony_ci
3084514f5e3Sopenharmony_ci            auto method = ConstantPool::GetMethodFromCache(thread_, cp.GetTaggedValue(), data.ctorMethodOffset_);
3094514f5e3Sopenharmony_ci            auto *factory = thread_->GetEcmaVM()->GetFactory();
3104514f5e3Sopenharmony_ci            auto extractor = factory->NewClassInfoExtractor(JSHandle<JSTaggedValue>(thread_, method));
3114514f5e3Sopenharmony_ci            ClassInfoExtractor::BuildClassInfoExtractorFromLiteral(thread_, extractor, arrayHandle,
3124514f5e3Sopenharmony_ci                arrayHandle->GetLength());
3134514f5e3Sopenharmony_ci            if (!CheckAOTIhcPropertiesForRep(thread_, ihc, extractor)) {
3144514f5e3Sopenharmony_ci                ihc = undefinedHandle;
3154514f5e3Sopenharmony_ci            }
3164514f5e3Sopenharmony_ci            if (!CheckAOTChcPropertiesForRep(thread_, chc, extractor)) {
3174514f5e3Sopenharmony_ci                chc = undefinedHandle;
3184514f5e3Sopenharmony_ci            }
3194514f5e3Sopenharmony_ci        }
3204514f5e3Sopenharmony_ci
3214514f5e3Sopenharmony_ci        CollectLiteralInfo(arrayHandle, data.constantPoolIdx_, snapshotCp, skippedMethods, ihc, chc);
3224514f5e3Sopenharmony_ci        globalData.RecordReviseData(
3234514f5e3Sopenharmony_ci            ReviseData::ItemData {globalData.GetCurDataIdx(), snapshotCpArrIdx, data.constantPoolIdx_});
3244514f5e3Sopenharmony_ci    }
3254514f5e3Sopenharmony_ci    if (vm_->GetJSOptions().IsEnableCompilerLogSnapshot()) {
3264514f5e3Sopenharmony_ci        vm_->AddAOTSnapShotStats("ClassLiteral", info_.size());
3274514f5e3Sopenharmony_ci    }
3284514f5e3Sopenharmony_ci}
3294514f5e3Sopenharmony_ci
3304514f5e3Sopenharmony_civoid ObjectLiteralSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalData,
3314514f5e3Sopenharmony_ci                                                      const std::set<uint32_t> &skippedMethods)
3324514f5e3Sopenharmony_ci{
3334514f5e3Sopenharmony_ci    ApEntityId abcId = INVALID_INDEX;
3344514f5e3Sopenharmony_ci    bool hasAbcId = TryGetABCId(abcId);
3354514f5e3Sopenharmony_ci    for (auto item : info_) {
3364514f5e3Sopenharmony_ci        const ItemData &data = item.second;
3374514f5e3Sopenharmony_ci        JSHandle<ConstantPool> cp = GetUnsharedConstpool(data);
3384514f5e3Sopenharmony_ci        panda_file::File::EntityId id = cp->GetEntityId(data.constantPoolIdx_);
3394514f5e3Sopenharmony_ci        JSMutableHandle<TaggedArray> elements(thread_, JSTaggedValue::Undefined());
3404514f5e3Sopenharmony_ci        JSMutableHandle<TaggedArray> properties(thread_, JSTaggedValue::Undefined());
3414514f5e3Sopenharmony_ci        LiteralDataExtractor::ExtractObjectDatas(thread_, jsPandaFile_, id, elements,
3424514f5e3Sopenharmony_ci                                                 properties, cp, data.recordName_);
3434514f5e3Sopenharmony_ci
3444514f5e3Sopenharmony_ci        uint32_t snapshotCpArrIdx = globalData.GetCpArrIdxByConstanPoolId(data.constantPoolId_);
3454514f5e3Sopenharmony_ci        JSHandle<TaggedArray> snapshotCpArr(thread_, globalData.GetCurSnapshotCpArray());
3464514f5e3Sopenharmony_ci        JSHandle<ConstantPool> snapshotCp(thread_, snapshotCpArr->Get(snapshotCpArrIdx));
3474514f5e3Sopenharmony_ci
3484514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> ihc = thread_->GlobalConstants()->GetHandledUndefined();
3494514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> chc = thread_->GlobalConstants()->GetHandledUndefined();
3504514f5e3Sopenharmony_ci        if (hasAbcId) {
3514514f5e3Sopenharmony_ci            ProfileType pt(abcId, id.GetOffset(), ProfileType::Kind::ObjectLiteralId, true);
3524514f5e3Sopenharmony_ci            ProfileType ctorPt(abcId, id.GetOffset(), ProfileType::Kind::ConstructorId, true);
3534514f5e3Sopenharmony_ci            chc = TryGetHClass(ctorPt, ctorPt);
3544514f5e3Sopenharmony_ci            ihc = TryGetIHClass(pt, pt, data, properties, globalData);
3554514f5e3Sopenharmony_ci        }
3564514f5e3Sopenharmony_ci
3574514f5e3Sopenharmony_ci        CollectLiteralInfo(properties, data.constantPoolIdx_, snapshotCp, skippedMethods, ihc, chc);
3584514f5e3Sopenharmony_ci        globalData.RecordReviseData(
3594514f5e3Sopenharmony_ci            ReviseData::ItemData {globalData.GetCurDataIdx(), snapshotCpArrIdx, data.constantPoolIdx_});
3604514f5e3Sopenharmony_ci    }
3614514f5e3Sopenharmony_ci    if (vm_->GetJSOptions().IsEnableCompilerLogSnapshot()) {
3624514f5e3Sopenharmony_ci        vm_->AddAOTSnapShotStats("ObjectLiteral", info_.size());
3634514f5e3Sopenharmony_ci    }
3644514f5e3Sopenharmony_ci}
3654514f5e3Sopenharmony_ci
3664514f5e3Sopenharmony_civoid ArrayLiteralSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalData,
3674514f5e3Sopenharmony_ci                                                     const std::set<uint32_t> &skippedMethods)
3684514f5e3Sopenharmony_ci{
3694514f5e3Sopenharmony_ci    for (auto item : info_) {
3704514f5e3Sopenharmony_ci        const ItemData &data = item.second;
3714514f5e3Sopenharmony_ci        JSHandle<ConstantPool> cp = GetUnsharedConstpool(data);
3724514f5e3Sopenharmony_ci        panda_file::File::EntityId id = cp->GetEntityId(data.constantPoolIdx_);
3734514f5e3Sopenharmony_ci        JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreType(
3744514f5e3Sopenharmony_ci            thread_, jsPandaFile_, id, cp, data.recordName_);
3754514f5e3Sopenharmony_ci        uint32_t snapshotCpArrIdx = globalData.GetCpArrIdxByConstanPoolId(data.constantPoolId_);
3764514f5e3Sopenharmony_ci        JSHandle<TaggedArray> snapshotCpArr(thread_, globalData.GetCurSnapshotCpArray());
3774514f5e3Sopenharmony_ci        JSHandle<ConstantPool> snapshotCp(thread_, snapshotCpArr->Get(snapshotCpArrIdx));
3784514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> ihc = thread_->GlobalConstants()->GetHandledUndefined();
3794514f5e3Sopenharmony_ci        JSHandle<JSTaggedValue> chc = thread_->GlobalConstants()->GetHandledUndefined();
3804514f5e3Sopenharmony_ci        CollectLiteralInfo(literal, data.constantPoolIdx_, snapshotCp, skippedMethods, ihc, chc);
3814514f5e3Sopenharmony_ci        globalData.RecordReviseData(
3824514f5e3Sopenharmony_ci            ReviseData::ItemData {globalData.GetCurDataIdx(), snapshotCpArrIdx, data.constantPoolIdx_});
3834514f5e3Sopenharmony_ci    }
3844514f5e3Sopenharmony_ci    if (vm_->GetJSOptions().IsEnableCompilerLogSnapshot()) {
3854514f5e3Sopenharmony_ci        vm_->AddAOTSnapShotStats("ArrayLiteral", info_.size());
3864514f5e3Sopenharmony_ci    }
3874514f5e3Sopenharmony_ci}
3884514f5e3Sopenharmony_ci
3894514f5e3Sopenharmony_ciJSHandle<ConstantPool> BaseSnapshotInfo::GetUnsharedConstpool(const ItemData &data)
3904514f5e3Sopenharmony_ci{
3914514f5e3Sopenharmony_ci    EcmaContext *context = thread_->GetCurrentEcmaContext();
3924514f5e3Sopenharmony_ci    JSTaggedValue shareCp = context->FindConstpool(jsPandaFile_, data.constantPoolId_);
3934514f5e3Sopenharmony_ci    JSHandle<ConstantPool> cp(thread_, context->FindOrCreateUnsharedConstpool(shareCp));
3944514f5e3Sopenharmony_ci    return cp;
3954514f5e3Sopenharmony_ci}
3964514f5e3Sopenharmony_ci
3974514f5e3Sopenharmony_civoid SnapshotConstantPoolData::Record(const BytecodeInstruction &bcIns, int32_t bcIndex,
3984514f5e3Sopenharmony_ci                                      const CString &recordName, const MethodLiteral *method)
3994514f5e3Sopenharmony_ci{
4004514f5e3Sopenharmony_ci    BytecodeInstruction::Opcode opcode = static_cast<BytecodeInstruction::Opcode>(bcIns.GetOpcode());
4014514f5e3Sopenharmony_ci    uint32_t methodOffset = method->GetMethodId().GetOffset();
4024514f5e3Sopenharmony_ci    panda_file::IndexAccessor indexAccessor(*jsPandaFile_->GetPandaFile(),
4034514f5e3Sopenharmony_ci                                            panda_file::File::EntityId(methodOffset));
4044514f5e3Sopenharmony_ci    uint32_t constantPoolId = static_cast<uint32_t>(indexAccessor.GetHeaderIndex());
4054514f5e3Sopenharmony_ci
4064514f5e3Sopenharmony_ci    switch (opcode) {
4074514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDA_STR_ID16:
4084514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STOWNBYNAME_IMM8_ID16_V8:
4094514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STOWNBYNAME_IMM16_ID16_V8:
4104514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::CREATEREGEXPWITHLITERAL_IMM8_ID16_IMM8:
4114514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::CREATEREGEXPWITHLITERAL_IMM16_ID16_IMM8:
4124514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STCONSTTOGLOBALRECORD_IMM16_ID16:
4134514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::TRYLDGLOBALBYNAME_IMM8_ID16:
4144514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::TRYLDGLOBALBYNAME_IMM16_ID16:
4154514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::TRYSTGLOBALBYNAME_IMM8_ID16:
4164514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::TRYSTGLOBALBYNAME_IMM16_ID16:
4174514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STTOGLOBALRECORD_IMM16_ID16:
4184514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STOWNBYNAMEWITHNAMESET_IMM8_ID16_V8:
4194514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STOWNBYNAMEWITHNAMESET_IMM16_ID16_V8:
4204514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDTHISBYNAME_IMM8_ID16:
4214514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDTHISBYNAME_IMM16_ID16:
4224514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STTHISBYNAME_IMM8_ID16:
4234514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STTHISBYNAME_IMM16_ID16:
4244514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDGLOBALVAR_IMM16_ID16:
4254514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDOBJBYNAME_IMM8_ID16:
4264514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDOBJBYNAME_IMM16_ID16:
4274514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STOBJBYNAME_IMM8_ID16_V8:
4284514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STOBJBYNAME_IMM16_ID16_V8:
4294514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINEFIELDBYNAME_IMM8_ID16_V8:
4304514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINEPROPERTYBYNAME_IMM8_ID16_V8:
4314514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDSUPERBYNAME_IMM8_ID16:
4324514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDSUPERBYNAME_IMM16_ID16:
4334514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STSUPERBYNAME_IMM8_ID16_V8:
4344514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STSUPERBYNAME_IMM16_ID16_V8:
4354514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::STGLOBALVAR_IMM16_ID16:
4364514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::LDBIGINT_ID16: {
4374514f5e3Sopenharmony_ci            auto constantPoolIdx = bcIns.GetId().AsRawValue();
4384514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData itemData = {recordName, constantPoolId, constantPoolIdx, methodOffset, bcIndex};
4394514f5e3Sopenharmony_ci            RecordInfo(Type::STRING, itemData);
4404514f5e3Sopenharmony_ci            break;
4414514f5e3Sopenharmony_ci        }
4424514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINEFUNC_IMM8_ID16_IMM8:
4434514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINEFUNC_IMM16_ID16_IMM8:
4444514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINEMETHOD_IMM8_ID16_IMM8:
4454514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINEMETHOD_IMM16_ID16_IMM8: {
4464514f5e3Sopenharmony_ci            auto constantPoolIdx = bcIns.GetId().AsRawValue();
4474514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData itemData = {recordName, constantPoolId, constantPoolIdx, methodOffset, bcIndex};
4484514f5e3Sopenharmony_ci            RecordInfo(Type::METHOD, itemData);
4494514f5e3Sopenharmony_ci            break;
4504514f5e3Sopenharmony_ci        }
4514514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::CREATEOBJECTWITHBUFFER_IMM8_ID16:
4524514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::CREATEOBJECTWITHBUFFER_IMM16_ID16: {
4534514f5e3Sopenharmony_ci            auto constantPoolIdx = bcIns.GetId().AsRawValue();
4544514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData itemData = {recordName, constantPoolId, constantPoolIdx, methodOffset, bcIndex};
4554514f5e3Sopenharmony_ci            RecordInfo(Type::OBJECT_LITERAL, itemData);
4564514f5e3Sopenharmony_ci            break;
4574514f5e3Sopenharmony_ci        }
4584514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::CREATEARRAYWITHBUFFER_IMM8_ID16:
4594514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::CREATEARRAYWITHBUFFER_IMM16_ID16: {
4604514f5e3Sopenharmony_ci            auto constantPoolIdx = bcIns.GetId().AsRawValue();
4614514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData itemData = {recordName, constantPoolId, constantPoolIdx, methodOffset, bcIndex};
4624514f5e3Sopenharmony_ci            RecordInfo(Type::ARRAY_LITERAL, itemData);
4634514f5e3Sopenharmony_ci            break;
4644514f5e3Sopenharmony_ci        }
4654514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM8_ID16_ID16_IMM16_V8: {
4664514f5e3Sopenharmony_ci            auto methodCPIdx = (bcIns.GetId <BytecodeInstruction::Format::IMM8_ID16_ID16_IMM16_V8, 0>()).AsRawValue();
4674514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData methodItemData = {recordName, constantPoolId,
4684514f5e3Sopenharmony_ci                methodCPIdx, methodOffset, bcIndex};
4694514f5e3Sopenharmony_ci            RecordInfo(Type::METHOD, methodItemData);
4704514f5e3Sopenharmony_ci
4714514f5e3Sopenharmony_ci            auto literalCPIdx = (bcIns.GetId <BytecodeInstruction::Format::IMM8_ID16_ID16_IMM16_V8, 1>()).AsRawValue();
4724514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData literalItemData = {recordName, constantPoolId,
4734514f5e3Sopenharmony_ci                literalCPIdx, methodOffset, bcIndex, methodCPIdx};
4744514f5e3Sopenharmony_ci            RecordInfo(Type::CLASS_LITERAL, literalItemData);
4754514f5e3Sopenharmony_ci            break;
4764514f5e3Sopenharmony_ci        }
4774514f5e3Sopenharmony_ci        case BytecodeInstruction::Opcode::DEFINECLASSWITHBUFFER_IMM16_ID16_ID16_IMM16_V8: {
4784514f5e3Sopenharmony_ci            auto methodCPIdx = (bcIns.GetId <BytecodeInstruction::Format::IMM16_ID16_ID16_IMM16_V8, 0>()).AsRawValue();
4794514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData methodItemData = {recordName, constantPoolId,
4804514f5e3Sopenharmony_ci                methodCPIdx, methodOffset, bcIndex};
4814514f5e3Sopenharmony_ci            RecordInfo(Type::METHOD, methodItemData);
4824514f5e3Sopenharmony_ci
4834514f5e3Sopenharmony_ci            auto literalCPIdx = (bcIns.GetId <BytecodeInstruction::Format::IMM16_ID16_ID16_IMM16_V8, 1>()).AsRawValue();
4844514f5e3Sopenharmony_ci            BaseSnapshotInfo::ItemData literalItemData = {recordName, constantPoolId,
4854514f5e3Sopenharmony_ci                literalCPIdx, methodOffset, bcIndex, methodCPIdx};
4864514f5e3Sopenharmony_ci            RecordInfo(Type::CLASS_LITERAL, literalItemData);
4874514f5e3Sopenharmony_ci            break;
4884514f5e3Sopenharmony_ci        }
4894514f5e3Sopenharmony_ci        default:
4904514f5e3Sopenharmony_ci            break;
4914514f5e3Sopenharmony_ci    }
4924514f5e3Sopenharmony_ci}
4934514f5e3Sopenharmony_ci
4944514f5e3Sopenharmony_civoid SnapshotConstantPoolData::StoreDataToGlobalData(SnapshotGlobalData &snapshotData,
4954514f5e3Sopenharmony_ci                                                     const std::set<uint32_t> &skippedMethods) const
4964514f5e3Sopenharmony_ci{
4974514f5e3Sopenharmony_ci    for (auto &info : infos_) {
4984514f5e3Sopenharmony_ci        info->StoreDataToGlobalData(snapshotData, skippedMethods);
4994514f5e3Sopenharmony_ci    }
5004514f5e3Sopenharmony_ci}
5014514f5e3Sopenharmony_ci}  // namespace panda::ecmascript
502