• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
16 #ifndef ECMASCRIPT_SERIALIZER_BASE_DESERIALIZER_H
17 #define ECMASCRIPT_SERIALIZER_BASE_DESERIALIZER_H
18 
19 #include "ecmascript/serializer/serialize_data.h"
20 
21 namespace panda::ecmascript {
22 class Heap;
23 class JSThread;
24 struct NativeBindingAttachInfo {
25     AttachFunc af_ {nullptr};
26     void *bufferPointer_ {nullptr};
27     void *hint_ = {nullptr};
28     void *attachData_ = {nullptr};
29     JSHandle<JSTaggedValue> obj_;
30     size_t offset_ {0U};
31 
NativeBindingAttachInfoNativeBindingAttachInfo32     NativeBindingAttachInfo(AttachFunc af, void *bufferPointer, void *hint, void *attachData,
33                             JSHandle<JSTaggedValue> obj, size_t offset) : af_(af), bufferPointer_(bufferPointer),
34         hint_(hint), attachData_(attachData), obj_(obj), offset_(offset) {}
35 
GetObjAddrNativeBindingAttachInfo36     uintptr_t GetObjAddr() const
37     {
38         return static_cast<uintptr_t>(obj_.GetTaggedType());
39     }
40 
GetFieldOffsetNativeBindingAttachInfo41     size_t GetFieldOffset() const
42     {
43         return offset_;
44     }
45 
GetSlotNativeBindingAttachInfo46     ObjectSlot GetSlot() const
47     {
48         return ObjectSlot(GetObjAddr() + offset_);
49     }
50 };
51 
52 struct JSErrorInfo {
53     uint8_t errorType_ {0};
54     JSHandle<JSTaggedValue> errorMsg_;
55     JSHandle<JSTaggedValue> obj_;
56     size_t offset_ {0U};
57 
JSErrorInfoJSErrorInfo58     JSErrorInfo(uint8_t errorType, JSHandle<JSTaggedValue> errorMsg, JSHandle<JSTaggedValue> obj, size_t offset)
59         : errorType_(errorType), errorMsg_(errorMsg), obj_(obj), offset_(offset) {}
60 
GetObjAddrJSErrorInfo61     uintptr_t GetObjAddr() const
62     {
63         return static_cast<uintptr_t>(obj_.GetTaggedType());
64     }
65 
GetFieldOffsetJSErrorInfo66     size_t GetFieldOffset() const
67     {
68         return offset_;
69     }
70 
GetSlotJSErrorInfo71     ObjectSlot GetSlot() const
72     {
73         return ObjectSlot(GetObjAddr() + offset_);
74     }
75 };
76 
77 class BaseDeserializer {
78 public:
79     explicit BaseDeserializer(JSThread *thread, SerializeData *data, void *hint = nullptr);
80 
~BaseDeserializer()81     virtual ~BaseDeserializer()
82     {
83         objectVector_.clear();
84         regionVector_.clear();
85     }
86 
87     NO_COPY_SEMANTIC(BaseDeserializer);
88     NO_MOVE_SEMANTIC(BaseDeserializer);
89 
90     JSHandle<JSTaggedValue> ReadValue();
91 
92 protected:
93     virtual uintptr_t DeserializeTaggedObject(SerializedObjectSpace space);
94 
95 private:
96     JSHandle<JSTaggedValue> DeserializeJSTaggedValue();
97     void DeserializeNativeBindingObject(NativeBindingAttachInfo *info);
98     void DeserializeJSError(JSErrorInfo *info);
99     uintptr_t RelocateObjectAddr(SerializedObjectSpace space, size_t objSize);
100     JSTaggedType RelocateObjectProtoAddr(uint8_t objectType);
101     void DeserializeObjectField(uintptr_t start, uintptr_t end);
102     size_t ReadSingleEncodeData(uint8_t encodeFlag, uintptr_t objAddr, size_t fieldOffset);
103     virtual size_t DerivedExtraReadSingleEncodeData(uint8_t encodeFlag, uintptr_t objAddr, size_t fieldOffset);
104     void HandleNewObjectEncodeFlag(SerializedObjectSpace space, uintptr_t objAddr, size_t fieldOffset);
105 
106     void TransferArrayBufferAttach(uintptr_t objAddr);
107     void IncreaseSharedArrayBufferReference(uintptr_t objAddr);
108     void ResetNativePointerBuffer(uintptr_t objAddr, void *bufferPointer);
109 
110     void AllocateToDifferentSpaces();
111     enum class RegionType : uint8_t {
112         RegularRegion,
113         PinRegion,
114     };
115     void AllocateToRegularSpace(size_t regularSpaceSize);
116     void AllocateToPinSpace(size_t pinSpaceSize);
117     uintptr_t AllocateMultiCMCRegion(size_t spaceObjSize, size_t &regionIndex, RegionType regionType);
118     void AllocateMultiRegion(SparseSpace *space, size_t spaceObjSize, size_t &regionIndex,
119                              SerializedObjectSpace spaceType);
120     void AllocateMultiNonmovableRegion(SparseSpace *space, size_t spaceObjSize, size_t &regionIndex,
121                                        SerializedObjectSpace spaceType);
122     void AllocateMultiSharedRegion(SharedSparseSpace *space, size_t spaceObjSize, size_t &regionIndex,
123                                    SerializedObjectSpace spaceType);
124     void AllocateToOldSpace(size_t oldSpaceSize);
125     void AllocateToNonMovableSpace(size_t nonMovableSpaceSize);
126     void AllocateToMachineCodeSpace(size_t machineCodeSpaceSize);
127     void AllocateToSharedOldSpace(size_t sOldSpaceSize);
128     void AllocateToSharedNonMovableSpace(size_t sNonMovableSpaceSize);
GetAndResetWeak()129     bool GetAndResetWeak()
130     {
131         bool isWeak = isWeak_;
132         if (isWeak_) {
133             isWeak_ = false;
134         }
135         return isWeak;
136     }
137 
GetAndResetTransferBuffer()138     bool GetAndResetTransferBuffer()
139     {
140         bool isTransferArrayBuffer = isTransferArrayBuffer_;
141         if (isTransferArrayBuffer_) {
142             isTransferArrayBuffer_ = false;
143         }
144         return isTransferArrayBuffer;
145     }
146 
GetAndResetSharedArrayBuffer()147     bool GetAndResetSharedArrayBuffer()
148     {
149         bool isSharedArrayBuffer = isSharedArrayBuffer_;
150         if (isSharedArrayBuffer_) {
151             isSharedArrayBuffer_ = false;
152         }
153         return isSharedArrayBuffer;
154     }
155 
GetAndResetIsErrorMsg()156     bool GetAndResetIsErrorMsg()
157     {
158         bool isErrorMsg = isErrorMsg_;
159         if (isErrorMsg_) {
160             isErrorMsg_ = false;
161         }
162         return isErrorMsg;
163     }
164 
GetAndResetFunctionInShared()165     bool GetAndResetFunctionInShared()
166     {
167         bool functionInShared = functionInShared_;
168         if (functionInShared_) {
169             functionInShared_ = false;
170         }
171         return functionInShared;
172     }
173 
GetAndResetBufferPointer()174     void *GetAndResetBufferPointer()
175     {
176         if (bufferPointer_) {
177             void *buffer = bufferPointer_;
178             bufferPointer_ = nullptr;
179             return buffer;
180         }
181         return nullptr;
182     }
183 
184     void DeserializeFatalOutOfMemory(size_t size, bool dump = true, bool isShared = false)
185     {
186         if (isShared) {
187             if (dump) {
188                 sheap_->DumpHeapSnapshotBeforeOOM(thread_, SharedHeapOOMSource::DESERIALIZE);
189             }
190             LOG_ECMA(FATAL) << "BaseDeserializer::OutOfMemory when deserialize shared obj size: " << size
191                 << ", old space heap object size: "
192                 << sheap_->GetOldSpace()->GetHeapObjectSize()
193                 << ", old space committed size: "
194                 << sheap_->GetOldSpace()->GetCommittedSize()
195                 << ", non movable space heap object size: "
196                 << sheap_->GetNonMovableSpace()->GetHeapObjectSize()
197                 << ", non movable space committed size: "
198                 << sheap_->GetNonMovableSpace()->GetCommittedSize()
199                 << ", huge space committed size: "
200                 << sheap_->GetHugeObjectSpace()->GetCommittedSize();
201         } else {
202             if (dump) {
203                 heap_->StatisticHeapDetail();
204                 heap_->DumpHeapSnapshotBeforeOOM();
205             }
206             LOG_ECMA(FATAL) << "BaseDeserializer::OutOfMemory when deserialize obj size: " << size
207                 << ", old space heap object size: "
208                 << heap_->GetOldSpace()->GetHeapObjectSize()
209                 << ", old space committed size: "
210                 << heap_->GetOldSpace()->GetCommittedSize()
211                 << ", non movable space heap object size: "
212                 << heap_->GetNonMovableSpace()->GetHeapObjectSize()
213                 << ", non movable space committed size: "
214                 << heap_->GetNonMovableSpace()->GetCommittedSize()
215                 << ", huge space committed size: "
216                 << heap_->GetHugeObjectSpace()->GetCommittedSize();
217         }
218     }
219 
UpdateMaybeWeak(ObjectSlot slot,uintptr_t addr,bool isWeak)220     void UpdateMaybeWeak(ObjectSlot slot, uintptr_t addr, bool isWeak)
221     {
222         isWeak ? slot.UpdateWeak(addr) : slot.Update(addr);
223     }
224 
GetLazyArray()225     bool *GetLazyArray()
226     {
227         if (moduleLazyArray_) {
228             bool *buffer = moduleLazyArray_;
229             moduleLazyArray_ = nullptr;
230             return buffer;
231         }
232         return nullptr;
233     }
234 
235 protected:
236     JSThread *thread_;
237     SerializeData *data_;
238     void *engine_;
239     size_t position_ {0};
240     CVector<JSTaggedType> objectVector_ {};
241 
DeserializeSpecialRecordedObjects()242     virtual void DeserializeSpecialRecordedObjects() {}
243 
244 private:
245     Heap *heap_;
246     SharedHeap *sheap_;
247     uintptr_t currentRegularObjectAddr_ {0};
248     uintptr_t currentRegularRegionBeginAddr_ {0};
249     uintptr_t currentPinObjectAddr_ {0};
250     uintptr_t currentPinRegionBeginAddr_ {0};
251     size_t regularRegionIndex_ {0};
252     size_t pinRegionIndex_ {0};
253     CVector<uintptr_t> regionVector_;
254     uintptr_t oldSpaceBeginAddr_ {0};
255     uintptr_t nonMovableSpaceBeginAddr_ {0};
256     uintptr_t machineCodeSpaceBeginAddr_ {0};
257     uintptr_t sOldSpaceBeginAddr_ {0};
258     uintptr_t sNonMovableSpaceBeginAddr_ {0};
259     size_t oldRegionIndex_ {0};
260     size_t nonMovableRegionIndex_ {0};
261     size_t machineCodeRegionIndex_ {0};
262     size_t sOldRegionIndex_ {0};
263     size_t sNonMovableRegionIndex_ {0};
264     // SerializationChunk store shared objects which have been serialized
265     SerializationChunk *sharedObjChunk_ {nullptr};
266     bool isWeak_ {false};
267     bool isTransferArrayBuffer_ {false};
268     bool isSharedArrayBuffer_ {false};
269     bool isErrorMsg_ {false};
270     void *bufferPointer_ {nullptr};
271     bool functionInShared_ {false};
272     CVector<NativeBindingAttachInfo> nativeBindingAttachInfos_;
273     CVector<JSErrorInfo> jsErrorInfos_;
274     CVector<JSHandle<JSFunction>> concurrentFunctions_;
275     // module deserialize
276     CString moduleFileName_ {};
277     CString moduleRecordName_ {};
278     bool* moduleLazyArray_ {nullptr};
279 };
280 }
281 
282 #endif  // ECMASCRIPT_SERIALIZER_BASE_DESERIALIZER_H
283