1 /* 2 * Copyright (c) 2023 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/jspandafile/js_pandafile.h" 20 #include "ecmascript/mem/c_containers.h" 21 #include "ecmascript/pgo_profiler/pgo_profiler_decoder.h" 22 23 namespace panda::ecmascript::kungfu { 24 using ApEntityId = pgo::ApEntityId; 25 using PGOProfilerDecoder = pgo::PGOProfilerDecoder; 26 27 #define DATA_TYPE_LIST(V) \ 28 V(STRING, StringSnapshot) \ 29 V(METHOD, MethodSnapshot) \ 30 V(CLASS_LITERAL, ClassLiteralSnapshot) \ 31 V(OBJECT_LITERAL, ObjectLiteralSnapshot) \ 32 V(ARRAY_LITERAL, ArrayLiteralSnapshot) 33 34 class BaseSnapshotInfo { 35 public: 36 static constexpr int32_t AOT_ELEMENT_INDEX_DEFAULT_VALUE = -1; 37 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> TryGetHClass(ProfileType rootType, ProfileType childType) const; 72 73 JSHandle<JSTaggedValue> TryGetHClassByPGOTypeLocation(PGOTypeLocation loc) const; 74 75 void CollectLiteralInfo(JSHandle<TaggedArray> array, uint32_t constantPoolIndex, 76 JSHandle<ConstantPool> snapshotConstantPool, const std::set<uint32_t> &skippedMethods, 77 JSHandle<JSTaggedValue> ihc, JSHandle<JSTaggedValue> chc, 78 int32_t elementIndex = AOT_ELEMENT_INDEX_DEFAULT_VALUE); 79 80 CUnorderedMap<ItemKey, ItemData> info_ {}; 81 EcmaVM *vm_ {nullptr}; 82 JSThread *thread_ {nullptr}; 83 const JSPandaFile *jsPandaFile_ {nullptr}; 84 const PGOProfilerDecoder *pfDecoder_ {nullptr}; 85 }; 86 87 #define DEFINE_INFO_CLASS(V, name) \ 88 class name##Info final : public BaseSnapshotInfo { \ 89 public: \ 90 name##Info(EcmaVM *vm, \ 91 const JSPandaFile *jsPandaFile, \ 92 const PGOProfilerDecoder *pfDecoder) \ 93 : BaseSnapshotInfo(vm, jsPandaFile, pfDecoder) {} \ 94 \ 95 virtual void StoreDataToGlobalData(SnapshotGlobalData &globalData, \ 96 const std::set<uint32_t> &skippedMethods) override; \ 97 }; 98 DATA_TYPE_LIST(DEFINE_INFO_CLASS)99 DATA_TYPE_LIST(DEFINE_INFO_CLASS) 100 #undef DEFINE_INFO_CLASS 101 102 class SnapshotConstantPoolData { 103 public: 104 SnapshotConstantPoolData(EcmaVM *vm, const JSPandaFile *jsPandaFile, const PGOProfilerDecoder *pfDecoder) 105 : jsPandaFile_(jsPandaFile) 106 { 107 #define ADD_INFO(V, name) \ 108 infos_.emplace_back(std::make_unique<name##Info>(vm, jsPandaFile, pfDecoder)); 109 DATA_TYPE_LIST(ADD_INFO) 110 #undef ADD_INFO 111 } 112 ~SnapshotConstantPoolData() = default; 113 114 void Record(const BytecodeInstruction &bcIns, int32_t bcIndex, 115 const CString &recordName, const MethodLiteral *method); 116 117 void StoreDataToGlobalData(SnapshotGlobalData &snapshotData, const std::set<uint32_t> &skippedMethods) const; 118 119 private: 120 enum class Type { 121 #define DEFINE_TYPE(type, ...) type, 122 DATA_TYPE_LIST(DEFINE_TYPE) 123 #undef DEFINE_TYPE 124 }; 125 126 void RecordInfo(Type type, BaseSnapshotInfo::ItemData &itemData) 127 { 128 size_t infoIdx = static_cast<size_t>(type); 129 infos_.at(infoIdx)->Record(itemData); 130 } 131 132 const JSPandaFile *jsPandaFile_; 133 CVector<std::unique_ptr<BaseSnapshotInfo>> infos_ {}; 134 }; 135 #undef DATA_TYPE_LIST 136 } // panda::ecmascript::kungfu 137 #endif // ECMASCRIPT_COMPILER_AOT_SNAPSHOT_AOT_SNAPSHOT_DATA_H 138 139