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 JSHandle<TaggedArray> &properties, const JSHandle<JSHClass> &hclass); 87 88 static bool CheckAOTIhcPropertiesForRep(JSThread *thread, const JSHandle<JSTaggedValue> &ihc, 89 const JSHandle<ClassInfoExtractor> &extractor); 90 91 static bool CheckAOTChcPropertiesForRep(JSThread *thread, const JSHandle<JSTaggedValue> &chc, 92 const JSHandle<ClassInfoExtractor> &extractor); 93 94 CUnorderedMap<ItemKey, ItemData> info_ {}; 95 EcmaVM *vm_ {nullptr}; 96 JSThread *thread_ {nullptr}; 97 const JSPandaFile *jsPandaFile_ {nullptr}; 98 const PGOProfilerDecoder *pfDecoder_ {nullptr}; 99 }; 100 101 #define DEFINE_INFO_CLASS(V, name) \ 102 class PUBLIC_API name##Info final : public BaseSnapshotInfo { \ 103 public: \ 104 name##Info(EcmaVM *vm, \ 105 const JSPandaFile *jsPandaFile, \ 106 const PGOProfilerDecoder *pfDecoder) \ 107 : BaseSnapshotInfo(vm, jsPandaFile, pfDecoder) {} \ 108 \ 109 virtual void StoreDataToGlobalData(SnapshotGlobalData &globalData, \ 110 const std::set<uint32_t> &skippedMethods) override; \ 111 }; 112 113 DATA_TYPE_LIST(DEFINE_INFO_CLASS) 114 #undef DEFINE_INFO_CLASS 115 116 class SnapshotConstantPoolData { 117 public: SnapshotConstantPoolData(EcmaVM *vm, const JSPandaFile *jsPandaFile, const PGOProfilerDecoder *pfDecoder)118 SnapshotConstantPoolData(EcmaVM *vm, const JSPandaFile *jsPandaFile, const PGOProfilerDecoder *pfDecoder) 119 : jsPandaFile_(jsPandaFile) 120 { 121 #define ADD_INFO(V, name) \ 122 infos_.emplace_back(std::make_unique<name##Info>(vm, jsPandaFile, pfDecoder)); 123 DATA_TYPE_LIST(ADD_INFO) 124 #undef ADD_INFO 125 } 126 ~SnapshotConstantPoolData() = default; 127 128 void PUBLIC_API Record(const BytecodeInstruction &bcIns, int32_t bcIndex, 129 const CString &recordName, const MethodLiteral *method); 130 131 void StoreDataToGlobalData(SnapshotGlobalData &snapshotData, const std::set<uint32_t> &skippedMethods) const; 132 133 private: 134 enum class Type { 135 #define DEFINE_TYPE(type, ...) type, 136 DATA_TYPE_LIST(DEFINE_TYPE) 137 #undef DEFINE_TYPE 138 }; 139 RecordInfo(Type type, BaseSnapshotInfo::ItemData &itemData)140 void RecordInfo(Type type, BaseSnapshotInfo::ItemData &itemData) 141 { 142 size_t infoIdx = static_cast<size_t>(type); 143 infos_.at(infoIdx)->Record(itemData); 144 } 145 146 const JSPandaFile *jsPandaFile_; 147 CVector<std::unique_ptr<BaseSnapshotInfo>> infos_ {}; 148 }; 149 #undef DATA_TYPE_LIST 150 } // panda::ecmascript::kungfu 151 #endif // ECMASCRIPT_COMPILER_AOT_SNAPSHOT_AOT_SNAPSHOT_DATA_H 152 153