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