• 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     uintptr_t objAddr_ {0U};
30     size_t offset_ {0U};
31     bool root_ {false};
32 
NativeBindingAttachInfoNativeBindingAttachInfo33     NativeBindingAttachInfo(AttachFunc af, void *bufferPointer, void *hint, void *attachData,
34                             uintptr_t objAddr, size_t offset, bool root) : af_(af), bufferPointer_(bufferPointer),
35         hint_(hint), attachData_(attachData), objAddr_(objAddr), offset_(offset), root_(root) {}
36 
GetObjAddrNativeBindingAttachInfo37     uintptr_t GetObjAddr() const
38     {
39         return objAddr_;
40     }
41 
GetFieldOffsetNativeBindingAttachInfo42     size_t GetFieldOffset() const
43     {
44         return offset_;
45     }
46 
GetSlotNativeBindingAttachInfo47     ObjectSlot GetSlot() const
48     {
49         return ObjectSlot(objAddr_ + offset_);
50     }
51 };
52 
53 struct JSErrorInfo {
54     uint8_t errorType_ {0};
55     JSTaggedValue errorMsg_;
56     uintptr_t objAddr_ {0U};
57     size_t offset_ {0U};
58     bool root_ {false};
59 
JSErrorInfoJSErrorInfo60     JSErrorInfo(uint8_t errorType, JSTaggedValue errorMsg, uintptr_t objAddr, size_t offset, bool root)
61         : errorType_(errorType), errorMsg_(errorMsg), objAddr_(objAddr), offset_(offset), root_(root) {}
62 
GetObjAddrJSErrorInfo63     uintptr_t GetObjAddr() const
64     {
65         return objAddr_;
66     }
67 
GetFieldOffsetJSErrorInfo68     size_t GetFieldOffset() const
69     {
70         return offset_;
71     }
72 
GetSlotJSErrorInfo73     ObjectSlot GetSlot() const
74     {
75         return ObjectSlot(objAddr_ + offset_);
76     }
77 };
78 
79 class BaseDeserializer {
80 public:
81     explicit BaseDeserializer(JSThread *thread, SerializeData *data, void *hint = nullptr);
82 
~BaseDeserializer()83     ~BaseDeserializer()
84     {
85         objectVector_.clear();
86         regionVector_.clear();
87     }
88 
89     NO_COPY_SEMANTIC(BaseDeserializer);
90     NO_MOVE_SEMANTIC(BaseDeserializer);
91 
92     JSHandle<JSTaggedValue> ReadValue();
93 
94 private:
95     JSHandle<JSTaggedValue> DeserializeJSTaggedValue();
96     uintptr_t DeserializeTaggedObject(SerializedObjectSpace space);
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, bool isRoot = false);
103     void HandleNewObjectEncodeFlag(SerializedObjectSpace space, uintptr_t objAddr, size_t fieldOffset, bool isRoot);
104 
105     void TransferArrayBufferAttach(uintptr_t objAddr);
106     void IncreaseSharedArrayBufferReference(uintptr_t objAddr);
107     void ResetNativePointerBuffer(uintptr_t objAddr, void *bufferPointer);
108 
109     void AllocateToDifferentSpaces();
110     void AllocateMultiRegion(SparseSpace *space, size_t spaceObjSize, size_t &regionIndex);
111     void AllocateMultiSharedRegion(SharedSparseSpace *space, size_t spaceObjSize, size_t &regionIndex);
112     void AllocateToOldSpace(size_t oldSpaceSize);
113     void AllocateToNonMovableSpace(size_t nonMovableSpaceSize);
114     void AllocateToMachineCodeSpace(size_t machineCodeSpaceSize);
115     void AllocateToSharedOldSpace(size_t sOldSpaceSize);
116     void AllocateToSharedNonMovableSpace(size_t sNonMovableSpaceSize);
117 
GetAndResetWeak()118     bool GetAndResetWeak()
119     {
120         bool isWeak = isWeak_;
121         if (isWeak_) {
122             isWeak_ = false;
123         }
124         return isWeak;
125     }
126 
GetAndResetTransferBuffer()127     bool GetAndResetTransferBuffer()
128     {
129         bool isTransferArrayBuffer = isTransferArrayBuffer_;
130         if (isTransferArrayBuffer_) {
131             isTransferArrayBuffer_ = false;
132         }
133         return isTransferArrayBuffer;
134     }
135 
GetAndResetSharedArrayBuffer()136     bool GetAndResetSharedArrayBuffer()
137     {
138         bool isSharedArrayBuffer = isSharedArrayBuffer_;
139         if (isSharedArrayBuffer_) {
140             isSharedArrayBuffer_ = false;
141         }
142         return isSharedArrayBuffer;
143     }
144 
GetAndResetIsErrorMsg()145     bool GetAndResetIsErrorMsg()
146     {
147         bool isErrorMsg = isErrorMsg_;
148         if (isErrorMsg_) {
149             isErrorMsg_ = false;
150         }
151         return isErrorMsg;
152     }
153 
GetAndResetFunctionInShared()154     bool GetAndResetFunctionInShared()
155     {
156         bool functionInShared = functionInShared_;
157         if (functionInShared_) {
158             functionInShared_ = false;
159         }
160         return functionInShared;
161     }
162 
GetAndResetBufferPointer()163     void *GetAndResetBufferPointer()
164     {
165         if (bufferPointer_) {
166             void *buffer = bufferPointer_;
167             bufferPointer_ = nullptr;
168             return buffer;
169         }
170         return nullptr;
171     }
172 
173     void DeserializeFatalOutOfMemory(size_t size, bool dump = true, bool isShared = false)
174     {
175         if (isShared) {
176             if (dump) {
177                 sheap_->DumpHeapSnapshotBeforeOOM(false, thread_, SharedHeapOOMSource::DESERIALIZE);
178             }
179             LOG_ECMA(FATAL) << "BaseDeserializer::OutOfMemory when deserialize shared obj size: " << size
180                 << ", old space heap object size: "
181                 << sheap_->GetOldSpace()->GetHeapObjectSize()
182                 << ", old space committed size: "
183                 << sheap_->GetOldSpace()->GetCommittedSize()
184                 << ", non movable space heap object size: "
185                 << sheap_->GetNonMovableSpace()->GetHeapObjectSize()
186                 << ", non movable space committed size: "
187                 << sheap_->GetNonMovableSpace()->GetCommittedSize()
188                 << ", huge space committed size: "
189                 << sheap_->GetHugeObjectSpace()->GetCommittedSize();
190         } else {
191             if (dump) {
192                 heap_->StatisticHeapDetail();
193                 heap_->DumpHeapSnapshotBeforeOOM(false);
194             }
195             LOG_ECMA(FATAL) << "BaseDeserializer::OutOfMemory when deserialize obj size: " << size
196                 << ", old space heap object size: "
197                 << heap_->GetOldSpace()->GetHeapObjectSize()
198                 << ", old space committed size: "
199                 << heap_->GetOldSpace()->GetCommittedSize()
200                 << ", non movable space heap object size: "
201                 << heap_->GetNonMovableSpace()->GetHeapObjectSize()
202                 << ", non movable space committed size: "
203                 << heap_->GetNonMovableSpace()->GetCommittedSize()
204                 << ", huge space committed size: "
205                 << heap_->GetHugeObjectSpace()->GetCommittedSize();
206         }
207     }
208 
UpdateMaybeWeak(ObjectSlot slot,uintptr_t addr,bool isWeak)209     void UpdateMaybeWeak(ObjectSlot slot, uintptr_t addr, bool isWeak)
210     {
211         isWeak ? slot.UpdateWeak(addr) : slot.Update(addr);
212     }
213 
214 private:
215     JSThread *thread_;
216     Heap *heap_;
217     SharedHeap *sheap_;
218     SerializeData* data_;
219     void *engine_;
220     uintptr_t oldSpaceBeginAddr_ {0};
221     uintptr_t nonMovableSpaceBeginAddr_ {0};
222     uintptr_t machineCodeSpaceBeginAddr_ {0};
223     uintptr_t sOldSpaceBeginAddr_ {0};
224     uintptr_t sNonMovableSpaceBeginAddr_ {0};
225     // SerializationChunk store shared objects which have been serialized
226     SerializationChunk *sharedObjChunk_ {nullptr};
227     CVector<JSTaggedType> objectVector_;
228     CVector<Region *> regionVector_;
229     size_t oldRegionIndex_ {0};
230     size_t nonMovableRegionIndex_ {0};
231     size_t machineCodeRegionIndex_ {0};
232     size_t sOldRegionIndex_ {0};
233     size_t sNonMovableRegionIndex_ {0};
234     size_t regionRemainSizeIndex_ {0};
235     bool isWeak_ {false};
236     bool isTransferArrayBuffer_ {false};
237     bool isSharedArrayBuffer_ {false};
238     bool isErrorMsg_ {false};
239     void *bufferPointer_ {nullptr};
240     bool functionInShared_ {false};
241     CVector<NativeBindingAttachInfo *> nativeBindingAttachInfos_;
242     CVector<JSErrorInfo *> jsErrorInfos_;
243     CVector<JSHandle<JSFunction>> concurrentFunctions_;
244     size_t position_ {0};
245 };
246 }
247 
248 #endif  // ECMASCRIPT_SERIALIZER_BASE_DESERIALIZER_H