• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SnapshotProcessor(EcmaVM * vm)45     explicit SnapshotProcessor(EcmaVM *vm)
46         : vm_(vm), objXRay_(vm) {}
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,
57                   uint64_t rootObjSize);
58     void RelocateSpaceObject(const JSPandaFile *jsPandaFile, Space* space, SnapshotType type, MethodLiteral* methods,
59                              size_t methodNums, size_t rootObjSize);
60     void SerializePandaFileMethod();
61     uintptr_t GetNewObj(size_t objectSize, TaggedObject *objectHeader);
62     EncodeBit EncodeTaggedObject(TaggedObject *objectHeader, CQueue<TaggedObject *> *queue,
63                                  std::unordered_map<uint64_t, ObjectEncode> *data);
64     EncodeBit GetObjectEncode(JSTaggedValue object, CQueue<TaggedObject *> *queue,
65                               std::unordered_map<uint64_t, ObjectEncode> *data);
66     void EncodeTaggedObjectRange(ObjectSlot start, ObjectSlot end, CQueue<TaggedObject *> *queue,
67                                  std::unordered_map<uint64_t, ObjectEncode> *data);
68     void DeserializeObjectExcludeString(uintptr_t oldSpaceBegin, size_t oldSpaceObjSize, size_t nonMovableObjSize,
69                                         size_t machineCodeObjSize, size_t snapshotObjSize, size_t hugeSpaceObjSize);
70     void DeserializeString(uintptr_t stringBegin, uintptr_t stringEnd);
71 
72     void AddRootObjectToAOTFileManager(SnapshotType type, const CString &fileName);
73 
SetProgramSerializeStart()74     void SetProgramSerializeStart()
75     {
76         programSerialize_ = true;
77     }
78 
SetBuiltinsSerializeStart()79     void SetBuiltinsSerializeStart()
80     {
81         builtinsSerialize_ = true;
82     }
83 
SetBuiltinsDeserializeStart()84     void SetBuiltinsDeserializeStart()
85     {
86         builtinsDeserialize_ = true;
87     }
88 
GetStringVector()89     const CVector<uintptr_t> GetStringVector() const
90     {
91         return stringVector_;
92     }
93 
GetOldLocalSpace()94     LocalSpace* GetOldLocalSpace() const
95     {
96         return oldLocalSpace_;
97     }
98 
99     size_t GetNativeTableSize() const;
100 
101 private:
GetMarkGCBitSetSize()102     size_t GetMarkGCBitSetSize() const
103     {
104         return GCBitset::SizeOfGCBitset(DEFAULT_REGION_SIZE -
105             AlignUp(sizeof(Region), static_cast<size_t>(MemAlignment::MEM_ALIGN_REGION)));
106     }
107 
108     bool VisitObjectBodyWithRep(TaggedObject *root, ObjectSlot slot, uintptr_t obj, int index, VisitObjectArea area);
109     void SetObjectEncodeField(uintptr_t obj, size_t offset, uint64_t value);
110 
111     EncodeBit SerializeObjectHeader(TaggedObject *objectHeader, size_t objectType, CQueue<TaggedObject *> *queue,
112                                     std::unordered_map<uint64_t, ObjectEncode> *data);
113     uint64_t SerializeTaggedField(JSTaggedType *tagged, CQueue<TaggedObject *> *queue,
114                                   std::unordered_map<uint64_t, ObjectEncode> *data);
115     void DeserializeField(TaggedObject *objectHeader);
116     void DeserializeTaggedField(uint64_t *value, TaggedObject *root);
117     void DeserializeNativePointer(uint64_t *value);
118     void DeserializeClassWord(TaggedObject *object);
119     void DeserializePandaMethod(uintptr_t begin, uintptr_t end, MethodLiteral *methods,
120                                 size_t &methodNums, size_t &others);
121     void DeserializeSpaceObject(uintptr_t beginAddr, Space* space, size_t spaceObjSize);
122     void DeserializeHugeSpaceObject(uintptr_t beginAddr, HugeObjectSpace* space, size_t hugeSpaceObjSize);
123     void HandleRootObject(SnapshotType type, uintptr_t rootObjectAddr, size_t objType, size_t &constSpecialIndex);
124 
125     EncodeBit NativePointerToEncodeBit(void *nativePointer);
126     size_t SearchNativeMethodIndex(void *nativePointer);
127     uintptr_t TaggedObjectEncodeBitToAddr(EncodeBit taggedBit);
128     void WriteSpaceObjectToFile(Space* space, std::fstream &write);
129     void WriteHugeObjectToFile(HugeObjectSpace* space, std::fstream &writer);
130     uint32_t StatisticsSpaceObjectSize(Space* space);
131     uint32_t StatisticsHugeObjectSize(HugeObjectSpace* space);
132     uintptr_t AllocateObjectToLocalSpace(Space *space, size_t objectSize);
133 
134     EcmaVM *vm_ {nullptr};
135     LocalSpace *oldLocalSpace_ {nullptr};
136     LocalSpace *nonMovableLocalSpace_ {nullptr};
137     LocalSpace *machineCodeLocalSpace_ {nullptr};
138     SnapshotSpace *snapshotLocalSpace_ {nullptr};
139     HugeObjectSpace *hugeObjectLocalSpace_ {nullptr};
140     ObjectXRay objXRay_;
141     bool programSerialize_ {false};
142     bool builtinsSerialize_ {false};
143     bool builtinsDeserialize_ {false};
144     CVector<uintptr_t> pandaMethod_;
145     CVector<uintptr_t> stringVector_;
146     std::unordered_map<size_t, Region *> regionIndexMap_;
147     size_t regionIndex_ {0};
148     bool isRootObjRelocate_ {false};
149     JSTaggedValue root_ {JSTaggedValue::Hole()};
150 
151     NO_COPY_SEMANTIC(SnapshotProcessor);
152     NO_MOVE_SEMANTIC(SnapshotProcessor);
153 };
154 
155 class SnapshotHelper {
156 public:
157     // when snapshot serialize, huge obj size is writed to region snapshotData_ high 32 bits
EncodeHugeObjectSize(uint64_t objSize)158     static inline uint64_t EncodeHugeObjectSize(uint64_t objSize)
159     {
160         return objSize << Constants::UINT_32_BITS_COUNT;
161     }
162 
163     // get huge object size which is saved in region snapshotData_ high 32 bits
GetHugeObjectSize(uint64_t snapshotData)164     static inline size_t GetHugeObjectSize(uint64_t snapshotData)
165     {
166         return snapshotData >> Constants::UINT_32_BITS_COUNT;
167     }
168 
169     // get huge object region index which is saved in region snapshotMark_ low 32 bits
GetHugeObjectRegionIndex(uint64_t snapshotData)170     static inline size_t GetHugeObjectRegionIndex(uint64_t snapshotData)
171     {
172         return snapshotData & Constants::MAX_UINT_32;
173     }
174 };
175 }  // namespace panda::ecmascript
176 
177 #endif  // ECMASCRIPT_SNAPSHOT_MEM_SNAPSHOT_PROCESSOR_H
178