1 /* 2 * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef ECMASCRIPT_COMPILER_AOT_SNAPSHOT_AOT_SNAPSHOT_DATA_H 16 #define ECMASCRIPT_COMPILER_AOT_SNAPSHOT_AOT_SNAPSHOT_DATA_H 17 18 #include "ecmascript/compiler/aot_snapshot/snapshot_global_data.h" 19 #include "ecmascript/compiler/pgo_type/pgo_type_location.h" 20 #include "ecmascript/jspandafile/js_pandafile.h" 21 #include "ecmascript/mem/c_containers.h" 22 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h" 23 #include "libpandafile/bytecode_instruction.h" 24 25 namespace panda::ecmascript::kungfu { 26 using ApEntityId = pgo::ApEntityId; 27 using PGOProfilerDecoder = pgo::PGOProfilerDecoder; 28 29 #define DATA_TYPE_LIST(V) \ 30 V(STRING, StringSnapshot) \ 31 V(METHOD, MethodSnapshot) \ 32 V(CLASS_LITERAL, ClassLiteralSnapshot) \ 33 V(OBJECT_LITERAL, ObjectLiteralSnapshot) \ 34 V(ARRAY_LITERAL, ArrayLiteralSnapshot) 35 36 class BaseSnapshotInfo { 37 public: 38 struct ItemData { 39 CString recordName_; 40 int32_t constantPoolId_ {0}; 41 uint32_t constantPoolIdx_ {0}; 42 uint32_t methodOffset_ {0}; 43 uint32_t bcIndex_ {0}; 44 uint32_t ctorMethodOffset_ {0}; // class constructor 45 }; 46 BaseSnapshotInfo(EcmaVM * vm,const JSPandaFile * jsPandaFile,const PGOProfilerDecoder * pfDecoder)47 BaseSnapshotInfo(EcmaVM *vm, 48 const JSPandaFile *jsPandaFile, 49 const PGOProfilerDecoder *pfDecoder) 50 : vm_(vm), 51 thread_(vm->GetJSThread()), 52 jsPandaFile_(jsPandaFile), 53 pfDecoder_(pfDecoder) 54 {} 55 56 virtual ~BaseSnapshotInfo() = default; 57 58 virtual void StoreDataToGlobalData(SnapshotGlobalData &globalData, const std::set<uint32_t> &skippedMethods) = 0; 59 60 void Record(ItemData &data); 61 62 protected: 63 using ItemKey = uint64_t; 64 65 static constexpr uint32_t CONSTPOOL_MASK = 32; 66 67 static ItemKey GetItemKey(uint32_t constantPoolId, uint32_t constantPoolIdx); 68 69 bool TryGetABCId(ApEntityId &abcId); 70 71 JSHandle<JSTaggedValue> TryGetIHClass(ProfileType rootType, ProfileType childType, const ItemData &data, 72 const JSHandle<TaggedArray> &properties, const SnapshotGlobalData &globalData) const; 73 74 JSHandle<JSTaggedValue> TryGetHClass(ProfileType rootType, ProfileType childType) const; 75 76 JSHandle<JSTaggedValue> TryGetHClassByPGOTypeLocation(PGOTypeLocation loc) const; 77 78 JSHandle<JSTaggedValue> TryGetHClassFromCached(const JSHandle<TaggedArray> &properties, 79 const SnapshotGlobalData &globalData) const; 80 81 void CollectLiteralInfo(JSHandle<TaggedArray> array, uint32_t constantPoolIndex, 82 JSHandle<ConstantPool> snapshotConstantPool, const std::set<uint32_t> &skippedMethods, 83 JSHandle<JSTaggedValue> ihc, JSHandle<JSTaggedValue> chc); 84 JSHandle<ConstantPool> GetUnsharedConstpool(const ItemData &data); 85 86 static bool CheckAOTPropertiesForRep(const JSThread *thread, const JSHandle<TaggedArray> &properties, 87 const JSHandle<JSHClass> &hclass); 88 89 static bool CheckAOTIhcPropertiesForRep(JSThread *thread, const JSHandle<JSTaggedValue> &ihc, 90 const JSHandle<ClassInfoExtractor> &extractor); 91 92 static bool CheckAOTChcPropertiesForRep(JSThread *thread, const JSHandle<JSTaggedValue> &chc, 93 const JSHandle<ClassInfoExtractor> &extractor); 94 95 CUnorderedMap<ItemKey, ItemData> info_ {}; 96 EcmaVM *vm_ {nullptr}; 97 JSThread *thread_ {nullptr}; 98 const JSPandaFile *jsPandaFile_ {nullptr}; 99 const PGOProfilerDecoder *pfDecoder_ {nullptr}; 100 }; 101 102 #define DEFINE_INFO_CLASS(V, name) \ 103 class PUBLIC_API name##Info final : public BaseSnapshotInfo { \ 104 public: \ 105 name##Info(EcmaVM *vm, \ 106 const JSPandaFile *jsPandaFile, \ 107 const PGOProfilerDecoder *pfDecoder) \ 108 : BaseSnapshotInfo(vm, jsPandaFile, pfDecoder) {} \ 109 \ 110 virtual void StoreDataToGlobalData(SnapshotGlobalData &globalData, \ 111 const std::set<uint32_t> &skippedMethods) override; \ 112 }; 113 DATA_TYPE_LIST(DEFINE_INFO_CLASS)114 DATA_TYPE_LIST(DEFINE_INFO_CLASS) 115 #undef DEFINE_INFO_CLASS 116 117 class SnapshotConstantPoolData { 118 public: 119 SnapshotConstantPoolData(EcmaVM *vm, const JSPandaFile *jsPandaFile, const PGOProfilerDecoder *pfDecoder) 120 : jsPandaFile_(jsPandaFile) 121 { 122 #define ADD_INFO(V, name) \ 123 infos_.emplace_back(std::make_unique<name##Info>(vm, jsPandaFile, pfDecoder)); 124 DATA_TYPE_LIST(ADD_INFO) 125 #undef ADD_INFO 126 } 127 ~SnapshotConstantPoolData() = default; 128 129 void PUBLIC_API Record(const BytecodeInstruction &bcIns, int32_t bcIndex, 130 const CString &recordName, const MethodLiteral *method); 131 132 void StoreDataToGlobalData(SnapshotGlobalData &snapshotData, const std::set<uint32_t> &skippedMethods) const; 133 134 private: 135 enum class Type { 136 #define DEFINE_TYPE(type, ...) type, 137 DATA_TYPE_LIST(DEFINE_TYPE) 138 #undef DEFINE_TYPE 139 }; 140 141 void RecordInfo(Type type, BaseSnapshotInfo::ItemData &itemData) 142 { 143 size_t infoIdx = static_cast<size_t>(type); 144 infos_.at(infoIdx)->Record(itemData); 145 } 146 147 const JSPandaFile *jsPandaFile_; 148 CVector<std::unique_ptr<BaseSnapshotInfo>> infos_ {}; 149 }; 150 #undef DATA_TYPE_LIST 151 } // panda::ecmascript::kungfu 152 #endif // ECMASCRIPT_COMPILER_AOT_SNAPSHOT_AOT_SNAPSHOT_DATA_H 153 154