1 /* 2 * Copyright (c) 2021 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 16 #ifndef ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_PROCESSOR_H 17 #define ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_PROCESSOR_H 18 19 #include <iostream> 20 #include <fstream> 21 #include <sstream> 22 23 #include "ecmascript/snapshot/mem/encode_bit.h" 24 #include "ecmascript/jspandafile/method_literal.h" 25 #include "ecmascript/js_tagged_value.h" 26 #include "ecmascript/mem/object_xray.h" 27 28 #include "libpandabase/macros.h" 29 30 namespace panda::ecmascript { 31 class EcmaVM; 32 class JSPandaFile; 33 class AOTFileManager; 34 35 enum class SnapshotType { 36 VM_ROOT, 37 BUILTINS, 38 AI 39 }; 40 41 using ObjectEncode = std::pair<uint64_t, ecmascript::EncodeBit>; 42 43 class SnapshotProcessor final { 44 public: 45 explicit SnapshotProcessor(EcmaVM *vm, const CString &fileName = "") vm_(vm)46 : vm_(vm), objXRay_(vm), fileName_(fileName) {} 47 ~SnapshotProcessor(); 48 49 void Initialize(); 50 void StopAllocate(); 51 void WriteObjectToFile(std::fstream &write); 52 std::vector<uint32_t> StatisticsObjectSize(); 53 void ProcessObjectQueue(CQueue<TaggedObject *> *queue, std::unordered_map<uint64_t, ObjectEncode> *data); 54 void SerializeObject(TaggedObject *objectHeader, CQueue<TaggedObject *> *queue, 55 std::unordered_map<uint64_t, ObjectEncode> *data); 56 void Relocate(SnapshotType type, const JSPandaFile *jsPandaFile, uint64_t rootObjSize); 57 void RelocateSpaceObject(Space* space, SnapshotType type, MethodLiteral* methods, 58 size_t methodNums, size_t rootObjSize); 59 void SerializePandaFileMethod(); 60 EncodeBit EncodeTaggedObject(TaggedObject *objectHeader, CQueue<TaggedObject *> *queue, 61 std::unordered_map<uint64_t, ObjectEncode> *data); 62 void EncodeTaggedObjectRange(ObjectSlot start, ObjectSlot end, CQueue<TaggedObject *> *queue, 63 std::unordered_map<uint64_t, ObjectEncode> *data); 64 void DeserializeObjectExcludeString(uintptr_t oldSpaceBegin, size_t oldSpaceObjSize, size_t nonMovableObjSize, 65 size_t machineCodeObjSize, size_t snapshotObjSize, size_t hugeSpaceObjSize); 66 void DeserializeString(uintptr_t stringBegin, uintptr_t stringEnd); 67 SetProgramSerializeStart()68 void SetProgramSerializeStart() 69 { 70 programSerialize_ = true; 71 } 72 SetBuiltinsSerializeStart()73 void SetBuiltinsSerializeStart() 74 { 75 builtinsSerialize_ = true; 76 } 77 SetBuiltinsDeserializeStart()78 void SetBuiltinsDeserializeStart() 79 { 80 builtinsDeserialize_ = true; 81 } 82 GetStringVector()83 const CVector<uintptr_t> GetStringVector() const 84 { 85 return stringVector_; 86 } 87 GetOldLocalSpace()88 LocalSpace* GetOldLocalSpace() const 89 { 90 return oldLocalSpace_; 91 } 92 93 size_t GetNativeTableSize() const; 94 95 private: GetMarkGCBitSetSize()96 size_t GetMarkGCBitSetSize() const 97 { 98 return GCBitset::SizeOfGCBitset(DEFAULT_REGION_SIZE - 99 AlignUp(sizeof(Region), static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION))); 100 } 101 102 void SetObjectEncodeField(uintptr_t obj, size_t offset, uint64_t value); 103 104 EncodeBit SerializeObjectHeader(TaggedObject *objectHeader, size_t objectType, CQueue<TaggedObject *> *queue, 105 std::unordered_map<uint64_t, ObjectEncode> *data); 106 uint64_t SerializeTaggedField(JSTaggedType *tagged, CQueue<TaggedObject *> *queue, 107 std::unordered_map<uint64_t, ObjectEncode> *data); 108 void DeserializeField(TaggedObject *objectHeader); 109 void DeserializeTaggedField(uint64_t *value, TaggedObject *root); 110 void DeserializeNativePointer(uint64_t *value); 111 void DeserializeClassWord(TaggedObject *object); 112 void DeserializePandaMethod(uintptr_t begin, uintptr_t end, MethodLiteral *methods, 113 size_t &methodNums, size_t &others); 114 void DeserializeSpaceObject(uintptr_t beginAddr, Space* space, size_t spaceObjSize); 115 void DeserializeHugeSpaceObject(uintptr_t beginAddr, HugeObjectSpace* space, size_t hugeSpaceObjSize); 116 void HandleRootObject(SnapshotType type, uintptr_t rootObjectAddr, size_t objType, size_t &constSpecialIndex); 117 118 EncodeBit NativePointerToEncodeBit(void *nativePointer); 119 size_t SearchNativeMethodIndex(void *nativePointer); 120 uintptr_t TaggedObjectEncodeBitToAddr(EncodeBit taggedBit); 121 void WriteSpaceObjectToFile(Space* space, std::fstream &write); 122 void WriteHugeObjectToFile(HugeObjectSpace* space, std::fstream &writer); 123 uint32_t StatisticsSpaceObjectSize(Space* space); 124 uint32_t StatisticsHugeObjectSize(HugeObjectSpace* space); 125 uintptr_t AllocateObjectToLocalSpace(Space *space, size_t objectSize); 126 127 EcmaVM *vm_ {nullptr}; 128 LocalSpace *oldLocalSpace_ {nullptr}; 129 LocalSpace *nonMovableLocalSpace_ {nullptr}; 130 LocalSpace *machineCodeLocalSpace_ {nullptr}; 131 SnapshotSpace *snapshotLocalSpace_ {nullptr}; 132 HugeObjectSpace *hugeObjectLocalSpace_ {nullptr}; 133 ObjectXRay objXRay_; 134 bool programSerialize_ {false}; 135 bool builtinsSerialize_ {false}; 136 bool builtinsDeserialize_ {false}; 137 CVector<uintptr_t> pandaMethod_; 138 CVector<uintptr_t> stringVector_; 139 std::unordered_map<size_t, Region *> regionIndexMap_; 140 size_t regionIndex_ {0}; 141 bool isRootObjRelocate_ {false}; 142 const CString &fileName_; 143 144 NO_COPY_SEMANTIC(SnapshotProcessor); 145 NO_MOVE_SEMANTIC(SnapshotProcessor); 146 }; 147 148 class SnapshotHelper { 149 public: 150 // when snapshot serialize, huge obj size is writed to region snapshotData_ high 32 bits EncodeHugeObjectSize(uint64_t objSize)151 static inline uint64_t EncodeHugeObjectSize(uint64_t objSize) 152 { 153 return objSize << Constants::UINT_32_BITS_COUNT; 154 } 155 156 // get huge object size which is saved in region snapshotData_ high 32 bits GetHugeObjectSize(uint64_t snapshotData)157 static inline size_t GetHugeObjectSize(uint64_t snapshotData) 158 { 159 return snapshotData >> Constants::UINT_32_BITS_COUNT; 160 } 161 162 // get huge object region index which is saved in region snapshotMark_ low 32 bits GetHugeObjectRegionIndex(uint64_t snapshotData)163 static inline size_t GetHugeObjectRegionIndex(uint64_t snapshotData) 164 { 165 return snapshotData & Constants::MAX_UINT_32; 166 } 167 }; 168 } // namespace panda::ecmascript 169 170 #endif // ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_PROCESSOR_H 171