• 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 #include "ecmascript/snapshot/mem/snapshot_serialize.h"
17 
18 #include "ecmascript/base/error_type.h"
19 #include "ecmascript/builtins/builtins_array.h"
20 #include "ecmascript/builtins/builtins_arraybuffer.h"
21 #include "ecmascript/builtins/builtins_async_function.h"
22 #include "ecmascript/builtins/builtins_bigint.h"
23 #include "ecmascript/builtins/builtins_boolean.h"
24 #include "ecmascript/builtins/builtins_collator.h"
25 #include "ecmascript/builtins/builtins_dataview.h"
26 #include "ecmascript/builtins/builtins_date.h"
27 #include "ecmascript/builtins/builtins_date_time_format.h"
28 #include "ecmascript/builtins/builtins_errors.h"
29 #include "ecmascript/builtins/builtins_function.h"
30 #include "ecmascript/builtins/builtins_generator.h"
31 #include "ecmascript/builtins/builtins_global.h"
32 #include "ecmascript/builtins/builtins_intl.h"
33 #include "ecmascript/builtins/builtins_iterator.h"
34 #include "ecmascript/builtins/builtins_json.h"
35 #include "ecmascript/builtins/builtins_locale.h"
36 #include "ecmascript/builtins/builtins_map.h"
37 #include "ecmascript/builtins/builtins_math.h"
38 #include "ecmascript/builtins/builtins_number.h"
39 #include "ecmascript/builtins/builtins_number_format.h"
40 #include "ecmascript/builtins/builtins_object.h"
41 #include "ecmascript/builtins/builtins_plural_rules.h"
42 #include "ecmascript/builtins/builtins_promise.h"
43 #include "ecmascript/builtins/builtins_promise_handler.h"
44 #include "ecmascript/builtins/builtins_promise_job.h"
45 #include "ecmascript/builtins/builtins_proxy.h"
46 #include "ecmascript/builtins/builtins_reflect.h"
47 #include "ecmascript/builtins/builtins_regexp.h"
48 #include "ecmascript/builtins/builtins_relative_time_format.h"
49 #include "ecmascript/builtins/builtins_set.h"
50 #include "ecmascript/builtins/builtins_string.h"
51 #include "ecmascript/builtins/builtins_string_iterator.h"
52 #include "ecmascript/builtins/builtins_symbol.h"
53 #include "ecmascript/builtins/builtins_typedarray.h"
54 #include "ecmascript/builtins/builtins_weak_map.h"
55 #include "ecmascript/builtins/builtins_weak_set.h"
56 #include "ecmascript/jspandafile/program_object.h"
57 #include "ecmascript/containers/containers_arraylist.h"
58 #include "ecmascript/containers/containers_treemap.h"
59 #include "ecmascript/containers/containers_treeset.h"
60 #include "ecmascript/global_env.h"
61 #include "ecmascript/js_api_tree_map_iterator.h"
62 #include "ecmascript/js_api_tree_set_iterator.h"
63 #include "ecmascript/js_array_iterator.h"
64 #include "ecmascript/js_api_arraylist_iterator.h"
65 #include "ecmascript/js_for_in_iterator.h"
66 #include "ecmascript/js_hclass.h"
67 #include "ecmascript/js_map_iterator.h"
68 #include "ecmascript/js_set_iterator.h"
69 #include "ecmascript/js_tagged_value-inl.h"
70 #include "ecmascript/mem/heap.h"
71 #include "ecmascript/mem/heap_region_allocator.h"
72 #include "ecmascript/mem/space-inl.h"
73 #include "ecmascript/object_factory.h"
74 
75 namespace panda::ecmascript {
76 using Number = builtins::BuiltinsNumber;
77 using BuiltinsBigInt = builtins::BuiltinsBigInt;
78 using Object = builtins::BuiltinsObject;
79 using Date = builtins::BuiltinsDate;
80 using Symbol = builtins::BuiltinsSymbol;
81 using Boolean = builtins::BuiltinsBoolean;
82 using BuiltinsMap = builtins::BuiltinsMap;
83 using BuiltinsSet = builtins::BuiltinsSet;
84 using BuiltinsWeakMap = builtins::BuiltinsWeakMap;
85 using BuiltinsWeakSet = builtins::BuiltinsWeakSet;
86 using BuiltinsArray = builtins::BuiltinsArray;
87 using BuiltinsTypedArray = builtins::BuiltinsTypedArray;
88 using BuiltinsIterator = builtins::BuiltinsIterator;
89 using Error = builtins::BuiltinsError;
90 using RangeError = builtins::BuiltinsRangeError;
91 using ReferenceError = builtins::BuiltinsReferenceError;
92 using TypeError = builtins::BuiltinsTypeError;
93 using URIError = builtins::BuiltinsURIError;
94 using SyntaxError = builtins::BuiltinsSyntaxError;
95 using EvalError = builtins::BuiltinsEvalError;
96 using ErrorType = base::ErrorType;
97 using Global = builtins::BuiltinsGlobal;
98 using BuiltinsString = builtins::BuiltinsString;
99 using StringIterator = builtins::BuiltinsStringIterator;
100 using RegExp = builtins::BuiltinsRegExp;
101 using Function = builtins::BuiltinsFunction;
102 using Math = builtins::BuiltinsMath;
103 using ArrayBuffer = builtins::BuiltinsArrayBuffer;
104 using Json = builtins::BuiltinsJson;
105 using Proxy = builtins::BuiltinsProxy;
106 using Reflect = builtins::BuiltinsReflect;
107 using AsyncFunction = builtins::BuiltinsAsyncFunction;
108 using GeneratorObject = builtins::BuiltinsGenerator;
109 using Promise = builtins::BuiltinsPromise;
110 using BuiltinsPromiseHandler = builtins::BuiltinsPromiseHandler;
111 using BuiltinsPromiseJob = builtins::BuiltinsPromiseJob;
112 using ErrorType = base::ErrorType;
113 using DataView = builtins::BuiltinsDataView;
114 using Intl = builtins::BuiltinsIntl;
115 using Locale = builtins::BuiltinsLocale;
116 using DateTimeFormat = builtins::BuiltinsDateTimeFormat;
117 using NumberFormat = builtins::BuiltinsNumberFormat;
118 using RelativeTimeFormat = builtins::BuiltinsRelativeTimeFormat;
119 using Collator = builtins::BuiltinsCollator;
120 using PluralRules = builtins::BuiltinsPluralRules;
121 using ArrayList = containers::ContainersArrayList;
122 using TreeMap = containers::ContainersTreeMap;
123 using TreeSet = containers::ContainersTreeSet;
124 
125 constexpr int TAGGED_SIZE = JSTaggedValue::TaggedTypeSize();
126 constexpr int OBJECT_HEADER_SIZE = TaggedObject::TaggedObjectSize();
127 constexpr int METHOD_SIZE = sizeof(JSMethod);
128 
129 // NOLINTNEXTLINE(modernize-avoid-c-arrays)
130 static uintptr_t g_nativeTable[] = {
131     reinterpret_cast<uintptr_t>(nullptr),
132     reinterpret_cast<uintptr_t>(BuiltinsMap::Species),
133     reinterpret_cast<uintptr_t>(StringIterator::Next),
134     reinterpret_cast<uintptr_t>(Function::FunctionPrototypeInvokeSelf),
135     reinterpret_cast<uintptr_t>(Function::FunctionConstructor),
136     reinterpret_cast<uintptr_t>(JSFunction::AccessCallerArgumentsThrowTypeError),
137     reinterpret_cast<uintptr_t>(Function::FunctionPrototypeApply),
138     reinterpret_cast<uintptr_t>(Function::FunctionPrototypeBind),
139     reinterpret_cast<uintptr_t>(Function::FunctionPrototypeCall),
140     reinterpret_cast<uintptr_t>(Function::FunctionPrototypeToString),
141     reinterpret_cast<uintptr_t>(Object::ObjectConstructor),
142     reinterpret_cast<uintptr_t>(Error::ErrorConstructor),
143     reinterpret_cast<uintptr_t>(Error::ToString),
144     reinterpret_cast<uintptr_t>(RangeError::RangeErrorConstructor),
145     reinterpret_cast<uintptr_t>(RangeError::ToString),
146     reinterpret_cast<uintptr_t>(ReferenceError::ReferenceErrorConstructor),
147     reinterpret_cast<uintptr_t>(ReferenceError::ToString),
148     reinterpret_cast<uintptr_t>(TypeError::TypeErrorConstructor),
149     reinterpret_cast<uintptr_t>(TypeError::ToString),
150     reinterpret_cast<uintptr_t>(TypeError::ThrowTypeError),
151     reinterpret_cast<uintptr_t>(URIError::URIErrorConstructor),
152     reinterpret_cast<uintptr_t>(URIError::ToString),
153     reinterpret_cast<uintptr_t>(SyntaxError::SyntaxErrorConstructor),
154     reinterpret_cast<uintptr_t>(SyntaxError::ToString),
155     reinterpret_cast<uintptr_t>(EvalError::EvalErrorConstructor),
156     reinterpret_cast<uintptr_t>(EvalError::ToString),
157     reinterpret_cast<uintptr_t>(Number::NumberConstructor),
158     reinterpret_cast<uintptr_t>(Number::ToExponential),
159     reinterpret_cast<uintptr_t>(Number::ToFixed),
160     reinterpret_cast<uintptr_t>(Number::ToLocaleString),
161     reinterpret_cast<uintptr_t>(Number::ToPrecision),
162     reinterpret_cast<uintptr_t>(Number::ToString),
163     reinterpret_cast<uintptr_t>(Number::ValueOf),
164     reinterpret_cast<uintptr_t>(Number::IsFinite),
165     reinterpret_cast<uintptr_t>(Number::IsInteger),
166     reinterpret_cast<uintptr_t>(Number::IsNaN),
167     reinterpret_cast<uintptr_t>(Number::IsSafeInteger),
168     reinterpret_cast<uintptr_t>(Number::ParseFloat),
169     reinterpret_cast<uintptr_t>(Number::ParseInt),
170     reinterpret_cast<uintptr_t>(BuiltinsBigInt::BigIntConstructor),
171     reinterpret_cast<uintptr_t>(BuiltinsBigInt::AsUintN),
172     reinterpret_cast<uintptr_t>(BuiltinsBigInt::AsIntN),
173     reinterpret_cast<uintptr_t>(BuiltinsBigInt::ToLocaleString),
174     reinterpret_cast<uintptr_t>(BuiltinsBigInt::ToString),
175     reinterpret_cast<uintptr_t>(BuiltinsBigInt::ValueOf),
176     reinterpret_cast<uintptr_t>(Symbol::SymbolConstructor),
177     reinterpret_cast<uintptr_t>(Symbol::For),
178     reinterpret_cast<uintptr_t>(Symbol::KeyFor),
179     reinterpret_cast<uintptr_t>(Symbol::DescriptionGetter),
180     reinterpret_cast<uintptr_t>(Symbol::ToPrimitive),
181     reinterpret_cast<uintptr_t>(Symbol::ToString),
182     reinterpret_cast<uintptr_t>(Symbol::ValueOf),
183     reinterpret_cast<uintptr_t>(Function::FunctionPrototypeHasInstance),
184     reinterpret_cast<uintptr_t>(Date::DateConstructor),
185     reinterpret_cast<uintptr_t>(Date::GetDate),
186     reinterpret_cast<uintptr_t>(Date::GetDay),
187     reinterpret_cast<uintptr_t>(Date::GetFullYear),
188     reinterpret_cast<uintptr_t>(Date::GetHours),
189     reinterpret_cast<uintptr_t>(Date::GetMilliseconds),
190     reinterpret_cast<uintptr_t>(Date::GetMinutes),
191     reinterpret_cast<uintptr_t>(Date::GetMonth),
192     reinterpret_cast<uintptr_t>(Date::GetSeconds),
193     reinterpret_cast<uintptr_t>(Date::GetTime),
194     reinterpret_cast<uintptr_t>(Date::GetTimezoneOffset),
195     reinterpret_cast<uintptr_t>(Date::GetUTCDate),
196     reinterpret_cast<uintptr_t>(Date::GetUTCDay),
197     reinterpret_cast<uintptr_t>(Date::GetUTCFullYear),
198     reinterpret_cast<uintptr_t>(Date::GetUTCHours),
199     reinterpret_cast<uintptr_t>(Date::GetUTCMilliseconds),
200     reinterpret_cast<uintptr_t>(Date::GetUTCMinutes),
201     reinterpret_cast<uintptr_t>(Date::GetUTCMonth),
202     reinterpret_cast<uintptr_t>(Date::GetUTCSeconds),
203     reinterpret_cast<uintptr_t>(Date::SetDate),
204     reinterpret_cast<uintptr_t>(Date::SetFullYear),
205     reinterpret_cast<uintptr_t>(Date::SetHours),
206     reinterpret_cast<uintptr_t>(Date::SetMilliseconds),
207     reinterpret_cast<uintptr_t>(Date::SetMinutes),
208     reinterpret_cast<uintptr_t>(Date::SetMonth),
209     reinterpret_cast<uintptr_t>(Date::SetSeconds),
210     reinterpret_cast<uintptr_t>(Date::SetTime),
211     reinterpret_cast<uintptr_t>(Date::SetUTCDate),
212     reinterpret_cast<uintptr_t>(Date::SetUTCFullYear),
213     reinterpret_cast<uintptr_t>(Date::SetUTCHours),
214     reinterpret_cast<uintptr_t>(Date::SetUTCMilliseconds),
215     reinterpret_cast<uintptr_t>(Date::SetUTCMinutes),
216     reinterpret_cast<uintptr_t>(Date::SetUTCMonth),
217     reinterpret_cast<uintptr_t>(Date::SetUTCSeconds),
218     reinterpret_cast<uintptr_t>(Date::ToDateString),
219     reinterpret_cast<uintptr_t>(Date::ToISOString),
220     reinterpret_cast<uintptr_t>(Date::ToJSON),
221     reinterpret_cast<uintptr_t>(Date::ToLocaleDateString),
222     reinterpret_cast<uintptr_t>(Date::ToLocaleString),
223     reinterpret_cast<uintptr_t>(Date::ToLocaleTimeString),
224     reinterpret_cast<uintptr_t>(Date::ToString),
225     reinterpret_cast<uintptr_t>(Date::ToTimeString),
226     reinterpret_cast<uintptr_t>(Date::ToUTCString),
227     reinterpret_cast<uintptr_t>(Date::ValueOf),
228     reinterpret_cast<uintptr_t>(Date::ToPrimitive),
229     reinterpret_cast<uintptr_t>(Date::Now),
230     reinterpret_cast<uintptr_t>(Date::Parse),
231     reinterpret_cast<uintptr_t>(Date::UTC),
232     reinterpret_cast<uintptr_t>(Object::Assign),
233     reinterpret_cast<uintptr_t>(Object::Create),
234     reinterpret_cast<uintptr_t>(Object::DefineProperties),
235     reinterpret_cast<uintptr_t>(Object::DefineProperty),
236     reinterpret_cast<uintptr_t>(Object::Freeze),
237     reinterpret_cast<uintptr_t>(Object::GetOwnPropertyDesciptor),
238     reinterpret_cast<uintptr_t>(Object::GetOwnPropertyNames),
239     reinterpret_cast<uintptr_t>(Object::GetOwnPropertySymbols),
240     reinterpret_cast<uintptr_t>(Object::GetPrototypeOf),
241     reinterpret_cast<uintptr_t>(Object::Is),
242     reinterpret_cast<uintptr_t>(Object::IsExtensible),
243     reinterpret_cast<uintptr_t>(Object::IsFrozen),
244     reinterpret_cast<uintptr_t>(Object::IsSealed),
245     reinterpret_cast<uintptr_t>(Object::Keys),
246     reinterpret_cast<uintptr_t>(Object::PreventExtensions),
247     reinterpret_cast<uintptr_t>(Object::Seal),
248     reinterpret_cast<uintptr_t>(Object::SetPrototypeOf),
249     reinterpret_cast<uintptr_t>(Object::HasOwnProperty),
250     reinterpret_cast<uintptr_t>(Object::IsPrototypeOf),
251     reinterpret_cast<uintptr_t>(Object::PropertyIsEnumerable),
252     reinterpret_cast<uintptr_t>(Object::ToLocaleString),
253     reinterpret_cast<uintptr_t>(Object::ToString),
254     reinterpret_cast<uintptr_t>(Object::ValueOf),
255     reinterpret_cast<uintptr_t>(Object::ProtoGetter),
256     reinterpret_cast<uintptr_t>(Object::ProtoSetter),
257     reinterpret_cast<uintptr_t>(Object::CreateRealm),
258     reinterpret_cast<uintptr_t>(Object::Entries),
259     reinterpret_cast<uintptr_t>(Boolean::BooleanConstructor),
260     reinterpret_cast<uintptr_t>(Boolean::BooleanPrototypeToString),
261     reinterpret_cast<uintptr_t>(Boolean::BooleanPrototypeValueOf),
262     reinterpret_cast<uintptr_t>(RegExp::RegExpConstructor),
263     reinterpret_cast<uintptr_t>(RegExp::Exec),
264     reinterpret_cast<uintptr_t>(RegExp::Test),
265     reinterpret_cast<uintptr_t>(RegExp::ToString),
266     reinterpret_cast<uintptr_t>(RegExp::GetFlags),
267     reinterpret_cast<uintptr_t>(RegExp::GetSource),
268     reinterpret_cast<uintptr_t>(RegExp::GetGlobal),
269     reinterpret_cast<uintptr_t>(RegExp::GetIgnoreCase),
270     reinterpret_cast<uintptr_t>(RegExp::GetMultiline),
271     reinterpret_cast<uintptr_t>(RegExp::GetDotAll),
272     reinterpret_cast<uintptr_t>(RegExp::GetSticky),
273     reinterpret_cast<uintptr_t>(RegExp::GetUnicode),
274     reinterpret_cast<uintptr_t>(RegExp::Split),
275     reinterpret_cast<uintptr_t>(RegExp::Search),
276     reinterpret_cast<uintptr_t>(RegExp::Match),
277     reinterpret_cast<uintptr_t>(RegExp::Replace),
278     reinterpret_cast<uintptr_t>(BuiltinsSet::SetConstructor),
279     reinterpret_cast<uintptr_t>(BuiltinsSet::Add),
280     reinterpret_cast<uintptr_t>(BuiltinsSet::Clear),
281     reinterpret_cast<uintptr_t>(BuiltinsSet::Delete),
282     reinterpret_cast<uintptr_t>(BuiltinsSet::Has),
283     reinterpret_cast<uintptr_t>(BuiltinsSet::ForEach),
284     reinterpret_cast<uintptr_t>(BuiltinsSet::Entries),
285     reinterpret_cast<uintptr_t>(BuiltinsSet::Values),
286     reinterpret_cast<uintptr_t>(BuiltinsSet::GetSize),
287     reinterpret_cast<uintptr_t>(BuiltinsSet::Species),
288     reinterpret_cast<uintptr_t>(BuiltinsMap::MapConstructor),
289     reinterpret_cast<uintptr_t>(BuiltinsMap::Set),
290     reinterpret_cast<uintptr_t>(BuiltinsMap::Clear),
291     reinterpret_cast<uintptr_t>(BuiltinsMap::Delete),
292     reinterpret_cast<uintptr_t>(BuiltinsMap::Has),
293     reinterpret_cast<uintptr_t>(BuiltinsMap::Get),
294     reinterpret_cast<uintptr_t>(BuiltinsMap::ForEach),
295     reinterpret_cast<uintptr_t>(BuiltinsMap::Keys),
296     reinterpret_cast<uintptr_t>(BuiltinsMap::Values),
297     reinterpret_cast<uintptr_t>(BuiltinsMap::Entries),
298     reinterpret_cast<uintptr_t>(BuiltinsMap::GetSize),
299     reinterpret_cast<uintptr_t>(BuiltinsWeakMap::WeakMapConstructor),
300     reinterpret_cast<uintptr_t>(BuiltinsWeakMap::Set),
301     reinterpret_cast<uintptr_t>(BuiltinsWeakMap::Delete),
302     reinterpret_cast<uintptr_t>(BuiltinsWeakMap::Has),
303     reinterpret_cast<uintptr_t>(BuiltinsWeakMap::Get),
304     reinterpret_cast<uintptr_t>(BuiltinsWeakSet::WeakSetConstructor),
305     reinterpret_cast<uintptr_t>(BuiltinsWeakSet::Add),
306     reinterpret_cast<uintptr_t>(BuiltinsWeakSet::Delete),
307     reinterpret_cast<uintptr_t>(BuiltinsWeakSet::Has),
308     reinterpret_cast<uintptr_t>(BuiltinsArray::ArrayConstructor),
309     reinterpret_cast<uintptr_t>(BuiltinsArray::Concat),
310     reinterpret_cast<uintptr_t>(BuiltinsArray::CopyWithin),
311     reinterpret_cast<uintptr_t>(BuiltinsArray::Entries),
312     reinterpret_cast<uintptr_t>(BuiltinsArray::Every),
313     reinterpret_cast<uintptr_t>(BuiltinsArray::Fill),
314     reinterpret_cast<uintptr_t>(BuiltinsArray::Filter),
315     reinterpret_cast<uintptr_t>(BuiltinsArray::Find),
316     reinterpret_cast<uintptr_t>(BuiltinsArray::FindIndex),
317     reinterpret_cast<uintptr_t>(BuiltinsArray::ForEach),
318     reinterpret_cast<uintptr_t>(BuiltinsArray::IndexOf),
319     reinterpret_cast<uintptr_t>(BuiltinsArray::Join),
320     reinterpret_cast<uintptr_t>(BuiltinsArray::Keys),
321     reinterpret_cast<uintptr_t>(BuiltinsArray::LastIndexOf),
322     reinterpret_cast<uintptr_t>(BuiltinsArray::Map),
323     reinterpret_cast<uintptr_t>(BuiltinsArray::Pop),
324     reinterpret_cast<uintptr_t>(BuiltinsArray::Push),
325     reinterpret_cast<uintptr_t>(BuiltinsArray::Reduce),
326     reinterpret_cast<uintptr_t>(BuiltinsArray::ReduceRight),
327     reinterpret_cast<uintptr_t>(BuiltinsArray::Reverse),
328     reinterpret_cast<uintptr_t>(BuiltinsArray::Shift),
329     reinterpret_cast<uintptr_t>(BuiltinsArray::Slice),
330     reinterpret_cast<uintptr_t>(BuiltinsArray::Some),
331     reinterpret_cast<uintptr_t>(BuiltinsArray::Sort),
332     reinterpret_cast<uintptr_t>(BuiltinsArray::Splice),
333     reinterpret_cast<uintptr_t>(BuiltinsArray::ToLocaleString),
334     reinterpret_cast<uintptr_t>(BuiltinsArray::ToString),
335     reinterpret_cast<uintptr_t>(BuiltinsArray::Unshift),
336     reinterpret_cast<uintptr_t>(BuiltinsArray::Values),
337     reinterpret_cast<uintptr_t>(BuiltinsArray::From),
338     reinterpret_cast<uintptr_t>(BuiltinsArray::IsArray),
339     reinterpret_cast<uintptr_t>(BuiltinsArray::Of),
340     reinterpret_cast<uintptr_t>(BuiltinsArray::Species),
341     reinterpret_cast<uintptr_t>(BuiltinsArray::Unscopables),
342     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::TypedArrayBaseConstructor),
343     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::CopyWithin),
344     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Entries),
345     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Every),
346     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Fill),
347     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Filter),
348     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Find),
349     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::FindIndex),
350     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::ForEach),
351     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::IndexOf),
352     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Join),
353     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Keys),
354     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::LastIndexOf),
355     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Map),
356     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Reduce),
357     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::ReduceRight),
358     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Reverse),
359     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Set),
360     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Slice),
361     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Some),
362     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Sort),
363     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Subarray),
364     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::ToLocaleString),
365     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Values),
366     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::GetBuffer),
367     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::GetByteLength),
368     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::GetByteOffset),
369     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::GetLength),
370     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::ToStringTag),
371     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::From),
372     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Of),
373     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Species),
374     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Int8ArrayConstructor),
375     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Uint8ArrayConstructor),
376     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Uint8ClampedArrayConstructor),
377     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Int16ArrayConstructor),
378     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Uint16ArrayConstructor),
379     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Int32ArrayConstructor),
380     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Uint32ArrayConstructor),
381     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Float32ArrayConstructor),
382     reinterpret_cast<uintptr_t>(BuiltinsTypedArray::Float64ArrayConstructor),
383     reinterpret_cast<uintptr_t>(BuiltinsString::StringConstructor),
384     reinterpret_cast<uintptr_t>(BuiltinsString::CharAt),
385     reinterpret_cast<uintptr_t>(BuiltinsString::CharCodeAt),
386     reinterpret_cast<uintptr_t>(BuiltinsString::CodePointAt),
387     reinterpret_cast<uintptr_t>(BuiltinsString::Concat),
388     reinterpret_cast<uintptr_t>(BuiltinsString::EndsWith),
389     reinterpret_cast<uintptr_t>(BuiltinsString::Includes),
390     reinterpret_cast<uintptr_t>(BuiltinsString::IndexOf),
391     reinterpret_cast<uintptr_t>(BuiltinsString::LastIndexOf),
392     reinterpret_cast<uintptr_t>(BuiltinsString::LocaleCompare),
393     reinterpret_cast<uintptr_t>(BuiltinsString::Match),
394     reinterpret_cast<uintptr_t>(BuiltinsString::Normalize),
395     reinterpret_cast<uintptr_t>(BuiltinsString::Repeat),
396     reinterpret_cast<uintptr_t>(BuiltinsString::Replace),
397     reinterpret_cast<uintptr_t>(BuiltinsString::Search),
398     reinterpret_cast<uintptr_t>(BuiltinsString::Slice),
399     reinterpret_cast<uintptr_t>(BuiltinsString::Split),
400     reinterpret_cast<uintptr_t>(BuiltinsString::StartsWith),
401     reinterpret_cast<uintptr_t>(BuiltinsString::Substring),
402     reinterpret_cast<uintptr_t>(BuiltinsString::SubStr),
403     reinterpret_cast<uintptr_t>(BuiltinsString::ToLocaleLowerCase),
404     reinterpret_cast<uintptr_t>(BuiltinsString::ToLocaleUpperCase),
405     reinterpret_cast<uintptr_t>(BuiltinsString::ToLowerCase),
406     reinterpret_cast<uintptr_t>(BuiltinsString::ToString),
407     reinterpret_cast<uintptr_t>(BuiltinsString::ToUpperCase),
408     reinterpret_cast<uintptr_t>(BuiltinsString::Trim),
409     reinterpret_cast<uintptr_t>(BuiltinsString::ValueOf),
410     reinterpret_cast<uintptr_t>(BuiltinsString::GetStringIterator),
411     reinterpret_cast<uintptr_t>(BuiltinsString::FromCharCode),
412     reinterpret_cast<uintptr_t>(BuiltinsString::FromCodePoint),
413     reinterpret_cast<uintptr_t>(BuiltinsString::Raw),
414     reinterpret_cast<uintptr_t>(BuiltinsString::GetLength),
415     reinterpret_cast<uintptr_t>(ArrayBuffer::ArrayBufferConstructor),
416     reinterpret_cast<uintptr_t>(ArrayBuffer::Slice),
417     reinterpret_cast<uintptr_t>(ArrayBuffer::IsView),
418     reinterpret_cast<uintptr_t>(ArrayBuffer::Species),
419     reinterpret_cast<uintptr_t>(ArrayBuffer::GetByteLength),
420     reinterpret_cast<uintptr_t>(DataView::DataViewConstructor),
421     reinterpret_cast<uintptr_t>(DataView::GetFloat32),
422     reinterpret_cast<uintptr_t>(DataView::GetFloat64),
423     reinterpret_cast<uintptr_t>(DataView::GetInt8),
424     reinterpret_cast<uintptr_t>(DataView::GetInt16),
425     reinterpret_cast<uintptr_t>(DataView::GetInt32),
426     reinterpret_cast<uintptr_t>(DataView::GetUint8),
427     reinterpret_cast<uintptr_t>(DataView::GetUint16),
428     reinterpret_cast<uintptr_t>(DataView::GetUint32),
429     reinterpret_cast<uintptr_t>(DataView::SetFloat32),
430     reinterpret_cast<uintptr_t>(DataView::SetFloat64),
431     reinterpret_cast<uintptr_t>(DataView::SetInt8),
432     reinterpret_cast<uintptr_t>(DataView::SetInt16),
433     reinterpret_cast<uintptr_t>(DataView::SetInt32),
434     reinterpret_cast<uintptr_t>(DataView::SetUint8),
435     reinterpret_cast<uintptr_t>(DataView::SetUint16),
436     reinterpret_cast<uintptr_t>(DataView::SetUint32),
437     reinterpret_cast<uintptr_t>(DataView::GetBuffer),
438     reinterpret_cast<uintptr_t>(DataView::GetByteLength),
439     reinterpret_cast<uintptr_t>(DataView::GetOffset),
440     reinterpret_cast<uintptr_t>(Global::PrintEntrypoint),
441     reinterpret_cast<uintptr_t>(Global::NotSupportEval),
442     reinterpret_cast<uintptr_t>(Global::IsFinite),
443     reinterpret_cast<uintptr_t>(Global::IsNaN),
444     reinterpret_cast<uintptr_t>(Global::DecodeURI),
445     reinterpret_cast<uintptr_t>(Global::DecodeURIComponent),
446     reinterpret_cast<uintptr_t>(Global::EncodeURI),
447     reinterpret_cast<uintptr_t>(Global::EncodeURIComponent),
448     reinterpret_cast<uintptr_t>(Math::Abs),
449     reinterpret_cast<uintptr_t>(Math::Acos),
450     reinterpret_cast<uintptr_t>(Math::Acosh),
451     reinterpret_cast<uintptr_t>(Math::Asin),
452     reinterpret_cast<uintptr_t>(Math::Asinh),
453     reinterpret_cast<uintptr_t>(Math::Atan),
454     reinterpret_cast<uintptr_t>(Math::Atanh),
455     reinterpret_cast<uintptr_t>(Math::Atan2),
456     reinterpret_cast<uintptr_t>(Math::Cbrt),
457     reinterpret_cast<uintptr_t>(Math::Ceil),
458     reinterpret_cast<uintptr_t>(Math::Clz32),
459     reinterpret_cast<uintptr_t>(Math::Cos),
460     reinterpret_cast<uintptr_t>(Math::Cosh),
461     reinterpret_cast<uintptr_t>(Math::Exp),
462     reinterpret_cast<uintptr_t>(Math::Expm1),
463     reinterpret_cast<uintptr_t>(Math::Floor),
464     reinterpret_cast<uintptr_t>(Math::Fround),
465     reinterpret_cast<uintptr_t>(Math::Hypot),
466     reinterpret_cast<uintptr_t>(Math::Imul),
467     reinterpret_cast<uintptr_t>(Math::Log),
468     reinterpret_cast<uintptr_t>(Math::Log1p),
469     reinterpret_cast<uintptr_t>(Math::Log10),
470     reinterpret_cast<uintptr_t>(Math::Log2),
471     reinterpret_cast<uintptr_t>(Math::Max),
472     reinterpret_cast<uintptr_t>(Math::Min),
473     reinterpret_cast<uintptr_t>(Math::Pow),
474     reinterpret_cast<uintptr_t>(Math::Random),
475     reinterpret_cast<uintptr_t>(Math::Round),
476     reinterpret_cast<uintptr_t>(Math::Sign),
477     reinterpret_cast<uintptr_t>(Math::Sin),
478     reinterpret_cast<uintptr_t>(Math::Sinh),
479     reinterpret_cast<uintptr_t>(Math::Sqrt),
480     reinterpret_cast<uintptr_t>(Math::Tan),
481     reinterpret_cast<uintptr_t>(Math::Tanh),
482     reinterpret_cast<uintptr_t>(Math::Trunc),
483     reinterpret_cast<uintptr_t>(Json::Parse),
484     reinterpret_cast<uintptr_t>(Json::Stringify),
485     reinterpret_cast<uintptr_t>(BuiltinsIterator::Next),
486     reinterpret_cast<uintptr_t>(BuiltinsIterator::Return),
487     reinterpret_cast<uintptr_t>(BuiltinsIterator::Throw),
488     reinterpret_cast<uintptr_t>(BuiltinsIterator::GetIteratorObj),
489     reinterpret_cast<uintptr_t>(JSForInIterator::Next),
490     reinterpret_cast<uintptr_t>(JSSetIterator::Next),
491     reinterpret_cast<uintptr_t>(JSMapIterator::Next),
492     reinterpret_cast<uintptr_t>(JSArrayIterator::Next),
493     reinterpret_cast<uintptr_t>(Proxy::ProxyConstructor),
494     reinterpret_cast<uintptr_t>(Proxy::Revocable),
495     reinterpret_cast<uintptr_t>(Reflect::ReflectApply),
496     reinterpret_cast<uintptr_t>(Reflect::ReflectConstruct),
497     reinterpret_cast<uintptr_t>(Reflect::ReflectDefineProperty),
498     reinterpret_cast<uintptr_t>(Reflect::ReflectDeleteProperty),
499     reinterpret_cast<uintptr_t>(Reflect::ReflectGet),
500     reinterpret_cast<uintptr_t>(Reflect::ReflectGetOwnPropertyDescriptor),
501     reinterpret_cast<uintptr_t>(Reflect::ReflectGetPrototypeOf),
502     reinterpret_cast<uintptr_t>(Reflect::ReflectHas),
503     reinterpret_cast<uintptr_t>(Reflect::ReflectIsExtensible),
504     reinterpret_cast<uintptr_t>(Reflect::ReflectOwnKeys),
505     reinterpret_cast<uintptr_t>(Reflect::ReflectPreventExtensions),
506     reinterpret_cast<uintptr_t>(Reflect::ReflectSet),
507     reinterpret_cast<uintptr_t>(Reflect::ReflectSetPrototypeOf),
508     reinterpret_cast<uintptr_t>(AsyncFunction::AsyncFunctionConstructor),
509     reinterpret_cast<uintptr_t>(GeneratorObject::GeneratorPrototypeNext),
510     reinterpret_cast<uintptr_t>(GeneratorObject::GeneratorPrototypeReturn),
511     reinterpret_cast<uintptr_t>(GeneratorObject::GeneratorPrototypeThrow),
512     reinterpret_cast<uintptr_t>(GeneratorObject::GeneratorFunctionConstructor),
513     reinterpret_cast<uintptr_t>(Promise::PromiseConstructor),
514     reinterpret_cast<uintptr_t>(Promise::All),
515     reinterpret_cast<uintptr_t>(Promise::Race),
516     reinterpret_cast<uintptr_t>(Promise::Resolve),
517     reinterpret_cast<uintptr_t>(Promise::Reject),
518     reinterpret_cast<uintptr_t>(Promise::Catch),
519     reinterpret_cast<uintptr_t>(Promise::Then),
520     reinterpret_cast<uintptr_t>(Promise::GetSpecies),
521     reinterpret_cast<uintptr_t>(BuiltinsPromiseJob::PromiseReactionJob),
522     reinterpret_cast<uintptr_t>(BuiltinsPromiseJob::PromiseResolveThenableJob),
523     reinterpret_cast<uintptr_t>(Intl::GetCanonicalLocales),
524     reinterpret_cast<uintptr_t>(Locale::LocaleConstructor),
525     reinterpret_cast<uintptr_t>(Locale::Maximize),
526     reinterpret_cast<uintptr_t>(Locale::Minimize),
527     reinterpret_cast<uintptr_t>(Locale::ToString),
528     reinterpret_cast<uintptr_t>(Locale::GetBaseName),
529     reinterpret_cast<uintptr_t>(Locale::GetCalendar),
530     reinterpret_cast<uintptr_t>(Locale::GetCaseFirst),
531     reinterpret_cast<uintptr_t>(Locale::GetCollation),
532     reinterpret_cast<uintptr_t>(Locale::GetHourCycle),
533     reinterpret_cast<uintptr_t>(Locale::GetNumeric),
534     reinterpret_cast<uintptr_t>(Locale::GetNumberingSystem),
535     reinterpret_cast<uintptr_t>(Locale::GetLanguage),
536     reinterpret_cast<uintptr_t>(Locale::GetScript),
537     reinterpret_cast<uintptr_t>(Locale::GetRegion),
538     reinterpret_cast<uintptr_t>(DateTimeFormat::DateTimeFormatConstructor),
539     reinterpret_cast<uintptr_t>(DateTimeFormat::SupportedLocalesOf),
540     reinterpret_cast<uintptr_t>(DateTimeFormat::Format),
541     reinterpret_cast<uintptr_t>(DateTimeFormat::FormatToParts),
542     reinterpret_cast<uintptr_t>(DateTimeFormat::ResolvedOptions),
543     reinterpret_cast<uintptr_t>(DateTimeFormat::FormatRange),
544     reinterpret_cast<uintptr_t>(DateTimeFormat::FormatRangeToParts),
545     reinterpret_cast<uintptr_t>(NumberFormat::NumberFormatConstructor),
546     reinterpret_cast<uintptr_t>(NumberFormat::SupportedLocalesOf),
547     reinterpret_cast<uintptr_t>(NumberFormat::Format),
548     reinterpret_cast<uintptr_t>(NumberFormat::FormatToParts),
549     reinterpret_cast<uintptr_t>(NumberFormat::ResolvedOptions),
550     reinterpret_cast<uintptr_t>(NumberFormat::NumberFormatInternalFormatNumber),
551     reinterpret_cast<uintptr_t>(RelativeTimeFormat::RelativeTimeFormatConstructor),
552     reinterpret_cast<uintptr_t>(RelativeTimeFormat::SupportedLocalesOf),
553     reinterpret_cast<uintptr_t>(RelativeTimeFormat::Format),
554     reinterpret_cast<uintptr_t>(RelativeTimeFormat::FormatToParts),
555     reinterpret_cast<uintptr_t>(RelativeTimeFormat::ResolvedOptions),
556     reinterpret_cast<uintptr_t>(Collator::CollatorConstructor),
557     reinterpret_cast<uintptr_t>(Collator::SupportedLocalesOf),
558     reinterpret_cast<uintptr_t>(Collator::Compare),
559     reinterpret_cast<uintptr_t>(Collator::ResolvedOptions),
560     reinterpret_cast<uintptr_t>(PluralRules::PluralRulesConstructor),
561     reinterpret_cast<uintptr_t>(PluralRules::SupportedLocalesOf),
562     reinterpret_cast<uintptr_t>(PluralRules::Select),
563     reinterpret_cast<uintptr_t>(PluralRules::ResolvedOptions),
564 
565     // non ECMA standard jsapi containers.
566     reinterpret_cast<uintptr_t>(ArrayList::ArrayListConstructor),
567     reinterpret_cast<uintptr_t>(ArrayList::Add),
568     reinterpret_cast<uintptr_t>(ArrayList::Insert),
569     reinterpret_cast<uintptr_t>(ArrayList::Clear),
570     reinterpret_cast<uintptr_t>(ArrayList::Clone),
571     reinterpret_cast<uintptr_t>(ArrayList::Has),
572     reinterpret_cast<uintptr_t>(ArrayList::GetCapacity),
573     reinterpret_cast<uintptr_t>(ArrayList::IncreaseCapacityTo),
574     reinterpret_cast<uintptr_t>(ArrayList::TrimToCurrentLength),
575     reinterpret_cast<uintptr_t>(ArrayList::GetIndexOf),
576     reinterpret_cast<uintptr_t>(ArrayList::IsEmpty),
577     reinterpret_cast<uintptr_t>(ArrayList::GetLastIndexOf),
578     reinterpret_cast<uintptr_t>(ArrayList::RemoveByIndex),
579     reinterpret_cast<uintptr_t>(ArrayList::Remove),
580     reinterpret_cast<uintptr_t>(ArrayList::RemoveByRange),
581     reinterpret_cast<uintptr_t>(ArrayList::ReplaceAllElements),
582     reinterpret_cast<uintptr_t>(ArrayList::SubArrayList),
583     reinterpret_cast<uintptr_t>(ArrayList::ConvertToArray),
584     reinterpret_cast<uintptr_t>(ArrayList::ForEach),
585     reinterpret_cast<uintptr_t>(ArrayList::GetIteratorObj),
586     reinterpret_cast<uintptr_t>(ArrayList::Get),
587     reinterpret_cast<uintptr_t>(ArrayList::Set),
588     reinterpret_cast<uintptr_t>(ArrayList::GetSize),
589     reinterpret_cast<uintptr_t>(JSAPIArrayListIterator::Next),
590     reinterpret_cast<uintptr_t>(TreeMap::TreeMapConstructor),
591     reinterpret_cast<uintptr_t>(TreeMap::Set),
592     reinterpret_cast<uintptr_t>(TreeMap::Get),
593     reinterpret_cast<uintptr_t>(TreeMap::Remove),
594     reinterpret_cast<uintptr_t>(TreeMap::GetFirstKey),
595     reinterpret_cast<uintptr_t>(TreeMap::GetLastKey),
596     reinterpret_cast<uintptr_t>(TreeMap::GetLowerKey),
597     reinterpret_cast<uintptr_t>(TreeMap::GetHigherKey),
598     reinterpret_cast<uintptr_t>(TreeMap::HasKey),
599     reinterpret_cast<uintptr_t>(TreeMap::HasValue),
600     reinterpret_cast<uintptr_t>(TreeMap::SetAll),
601     reinterpret_cast<uintptr_t>(TreeMap::Replace),
602     reinterpret_cast<uintptr_t>(TreeMap::Keys),
603     reinterpret_cast<uintptr_t>(TreeMap::Values),
604     reinterpret_cast<uintptr_t>(TreeMap::Entries),
605     reinterpret_cast<uintptr_t>(TreeMap::ForEach),
606     reinterpret_cast<uintptr_t>(TreeMap::Clear),
607     reinterpret_cast<uintptr_t>(TreeMap::IsEmpty),
608     reinterpret_cast<uintptr_t>(TreeMap::GetLength),
609     reinterpret_cast<uintptr_t>(TreeSet::TreeSetConstructor),
610     reinterpret_cast<uintptr_t>(TreeSet::Add),
611     reinterpret_cast<uintptr_t>(TreeSet::Has),
612     reinterpret_cast<uintptr_t>(TreeSet::Remove),
613     reinterpret_cast<uintptr_t>(TreeSet::GetFirstValue),
614     reinterpret_cast<uintptr_t>(TreeSet::GetLastValue),
615     reinterpret_cast<uintptr_t>(TreeSet::GetLowerValue),
616     reinterpret_cast<uintptr_t>(TreeSet::GetHigherValue),
617     reinterpret_cast<uintptr_t>(TreeSet::PopFirst),
618     reinterpret_cast<uintptr_t>(TreeSet::PopLast),
619     reinterpret_cast<uintptr_t>(TreeSet::IsEmpty),
620     reinterpret_cast<uintptr_t>(TreeSet::Values),
621     reinterpret_cast<uintptr_t>(TreeSet::Entries),
622     reinterpret_cast<uintptr_t>(TreeSet::ForEach),
623     reinterpret_cast<uintptr_t>(TreeSet::Clear),
624     reinterpret_cast<uintptr_t>(TreeSet::GetLength),
625     reinterpret_cast<uintptr_t>(JSAPITreeMapIterator::Next),
626     reinterpret_cast<uintptr_t>(JSAPITreeSetIterator::Next),
627 
628     // not builtins method
629     reinterpret_cast<uintptr_t>(JSFunction::PrototypeSetter),
630     reinterpret_cast<uintptr_t>(JSFunction::PrototypeGetter),
631     reinterpret_cast<uintptr_t>(JSFunction::NameGetter),
632     reinterpret_cast<uintptr_t>(JSArray::LengthSetter),
633     reinterpret_cast<uintptr_t>(JSArray::LengthGetter),
634 };
635 
SnapShotSerialize(EcmaVM * vm,bool serialize)636 SnapShotSerialize::SnapShotSerialize(EcmaVM *vm, bool serialize) : vm_(vm), serialize_(serialize)
637 {
638     objectArraySize_ = OBJECT_SIZE_EXTEND_PAGE;
639     if (serialize_) {
640         addressSlot_ = ToUintPtr(vm_->GetNativeAreaAllocator()->Allocate(sizeof(uintptr_t) * OBJECT_SIZE_EXTEND_PAGE));
641     } else {
642         addressSlot_ = ToUintPtr(vm_->GetNativeAreaAllocator()->Allocate(sizeof(uintptr_t) * objectArraySize_));
643     }
644 }
645 
~SnapShotSerialize()646 SnapShotSerialize::~SnapShotSerialize()
647 {
648     if (serialize_) {
649         vm_->GetNativeAreaAllocator()->Free(ToVoidPtr(addressSlot_), sizeof(uintptr_t) * OBJECT_SIZE_EXTEND_PAGE);
650     } else {
651         vm_->GetNativeAreaAllocator()->Free(ToVoidPtr(addressSlot_), sizeof(uintptr_t) * objectArraySize_);
652     }
653 }
654 
SetObjectSlotField(uintptr_t obj,size_t offset,uint64_t value)655 void SnapShotSerialize::SetObjectSlotField(uintptr_t obj, size_t offset, uint64_t value)
656 {
657     *reinterpret_cast<uint64_t *>(obj + offset) = value;
658 }
659 
SetObjectSlotFieldUint32(uintptr_t obj,size_t offset,uint32_t value)660 void SnapShotSerialize::SetObjectSlotFieldUint32(uintptr_t obj, size_t offset, uint32_t value)
661 {
662     *reinterpret_cast<uint32_t *>(obj + offset) = value;
663 }
664 
Serialize(TaggedObject * objectHeader,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)665 void SnapShotSerialize::Serialize(TaggedObject *objectHeader, CQueue<TaggedObject *> *queue,
666                                   std::unordered_map<uint64_t, SlotBit> *data)
667 {
668     uint8_t objectType = SerializeHelper::GetObjectType(objectHeader);
669     size_t objectSize = objectHeader->GetClass()->SizeFromJSHClass(objectHeader);
670     if (objectSize > MAX_REGULAR_HEAP_OBJECT_SIZE) {
671         LOG_ECMA_MEM(FATAL) << "It is a huge object. Not Support.";
672     }
673 
674     if (objectSize == 0) {
675         LOG_ECMA_MEM(FATAL) << "It is a zero object. Not Support.";
676     }
677 
678     uintptr_t snapshotObj = vm_->GetFactory()->NewSpaceBySnapShotAllocator(objectSize);
679     if (snapshotObj == 0) {
680         LOG_ECMA(DEBUG) << "SnapShotAllocator OOM";
681         return;
682     }
683     if (memcpy_s(ToVoidPtr(snapshotObj), objectSize, objectHeader, objectSize) != EOK) {
684         LOG_ECMA(FATAL) << "memcpy_s failed";
685         UNREACHABLE();
686     }
687 
688     // header
689     SlotBit headSlot = HandleObjectHeader(objectHeader, objectType, objectSize, queue, data);
690     SetObjectSlotField(snapshotObj, 0, headSlot.GetValue());
691 
692     count_++;
693     LOG_IF(count_ > MAX_OBJECT_INDEX, FATAL, RUNTIME) << "objectCount: " + ToCString(count_);
694     LOG_IF(objectSize > MAX_OBJECT_SIZE_INDEX, FATAL, RUNTIME) << "objectSize: " + ToCString(objectSize);
695     switch (JSType(objectType)) {
696         case JSType::HCLASS:
697             DynClassSerialize(objectHeader, snapshotObj, objectSize, queue, data);
698             break;
699         case JSType::STRING:
700             DynStringSerialize(objectHeader, snapshotObj);
701             break;
702         case JSType::TAGGED_ARRAY:
703         case JSType::TAGGED_DICTIONARY:
704             DynArraySerialize(objectHeader, snapshotObj, queue, data);
705             break;
706         case JSType::JS_NATIVE_POINTER:
707             NativePointerSerialize(objectHeader, snapshotObj);
708             break;
709         case JSType::PROGRAM:
710             DynProgramSerialize(objectHeader, snapshotObj, queue, data);
711             break;
712         case JSType::JS_FUNCTION_BASE:
713         case JSType::JS_FUNCTION:
714         case JSType::JS_PROXY_REVOC_FUNCTION:
715         case JSType::JS_PROMISE_REACTIONS_FUNCTION:
716         case JSType::JS_PROMISE_EXECUTOR_FUNCTION:
717         case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION:
718         case JSType::JS_GENERATOR_FUNCTION:
719         case JSType::JS_ASYNC_FUNCTION:
720         case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION:
721         case JSType::JS_BOUND_FUNCTION:
722             JSFunctionBaseSerialize(objectHeader, snapshotObj, objectSize, queue, data);
723             break;
724         case JSType::JS_PROXY:
725             JSProxySerialize(objectHeader, snapshotObj, objectSize, queue, data);
726             break;
727         default:
728             JSObjectSerialize(objectHeader, snapshotObj, objectSize, queue, data);
729             break;
730     }
731 }
732 
ExtendObjectArray()733 void SnapShotSerialize::ExtendObjectArray()
734 {
735     int countNow = objectArraySize_;
736     objectArraySize_ = objectArraySize_ + OBJECT_SIZE_EXTEND_PAGE;
737 
738     auto addr = vm_->GetNativeAreaAllocator()->Allocate(sizeof(uintptr_t) * objectArraySize_);
739     int size = countNow * ADDRESS_SIZE;
740     if (memcpy_s(addr, size, ToVoidPtr(addressSlot_), size) != EOK) {
741         LOG_ECMA(FATAL) << "memcpy_s failed";
742         UNREACHABLE();
743     }
744 
745     vm_->GetNativeAreaAllocator()->Free(ToVoidPtr(addressSlot_), sizeof(uintptr_t) * objectArraySize_);
746     addressSlot_ = ToUintPtr(addr);
747 }
748 
RedirectSlot(const panda_file::File * pf)749 void SnapShotSerialize::RedirectSlot(const panda_file::File *pf)
750 {
751     SnapShotSpace *space = vm_->GetHeap()->GetSnapShotSpace();
752     EcmaStringTable *stringTable = vm_->GetEcmaStringTable();
753 
754     size_t others = 0;
755     space->EnumerateRegions([stringTable, &others, this, pf](Region *current) {
756         size_t allocated = current->GetAllocatedBytes();
757         uintptr_t begin = current->GetBegin();
758         uintptr_t end = begin + allocated;
759         while (begin < end) {
760             if (others != 0) {
761                 for (size_t i = 0; i < others; i++) {
762                     pandaMethod_.emplace_back(begin);
763                     auto method = reinterpret_cast<JSMethod *>(begin);
764                     method->SetPandaFile(pf);
765                     method->SetBytecodeArray(method->GetInstructions());
766                     vm_->frameworkProgramMethods_.emplace_back(method);
767                     begin += METHOD_SIZE;
768                     if (begin >= end) {
769                         others = others - i - 1;
770                     }
771                 }
772                 break;
773             }
774 
775             if (count_ == objectArraySize_) {
776                 ExtendObjectArray();
777             }
778             SlotBit slot(*reinterpret_cast<uint64_t *>(begin));
779             if (slot.GetObjectType() == MASK_METHOD_SPACE_BEGIN) {
780                 begin += sizeof(uint64_t);
781                 for (size_t i = 0; i < slot.GetObjectSize(); i++) {
782                     pandaMethod_.emplace_back(begin);
783                     auto method = reinterpret_cast<JSMethod *>(begin);
784                     method->SetPandaFile(pf);
785                     method->SetBytecodeArray(method->GetInstructions());
786                     vm_->frameworkProgramMethods_.emplace_back(method);
787                     begin += METHOD_SIZE;
788                     if (begin >= end) {
789                         others = slot.GetObjectSize() - i - 1;
790                         break;
791                     }
792                 }
793                 break;
794             }
795 
796             if (JSType(slot.GetObjectType()) == JSType::STRING) {
797                 stringTable->InsertStringIfNotExist(reinterpret_cast<EcmaString *>(begin));
798             }
799 
800             SetAddressToSlot(count_, begin);
801             begin = begin + AlignUp(slot.GetObjectSize(), static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT));
802             count_++;
803         }
804     });
805 
806     auto constants = const_cast<GlobalEnvConstants *>(vm_->GetJSThread()->GlobalConstants());
807     for (int i = 0; i < count_; i++) {
808         SlotBit slot(*GetAddress<uint64_t *>(i));
809         size_t objectSize = slot.GetObjectSize();
810         uint8_t objectType = slot.GetObjectType();
811         size_t index = slot.GetObjectInConstantsIndex();
812 
813         switch (JSType(objectType)) {
814             case JSType::HCLASS:
815                 DynClassDeserialize(GetAddress<uint64_t *>(i));
816                 break;
817             case JSType::STRING:
818                 DynStringDeserialize(GetAddress<uint64_t *>(i));
819                 break;
820             case JSType::TAGGED_ARRAY:
821             case JSType::TAGGED_DICTIONARY:
822                 DynArrayDeserialize(GetAddress<uint64_t *>(i));
823                 break;
824             case JSType::JS_NATIVE_POINTER:
825                 NativePointerDeserialize(GetAddress<uint64_t *>(i));
826                 break;
827             case JSType::GLOBAL_ENV:
828                 JSObjectDeserialize(GetAddress<uint64_t *>(i), objectSize);
829                 vm_->SetGlobalEnv(GetAddress<GlobalEnv *>(i));
830                 break;
831             case JSType::MICRO_JOB_QUEUE:
832                 JSObjectDeserialize(GetAddress<uint64_t *>(i), objectSize);
833                 vm_->SetMicroJobQueue(GetAddress<job::MicroJobQueue *>(i));
834                 break;
835             case JSType::PROGRAM:
836                 DynProgramDeserialize(GetAddress<uint64_t *>(i), objectSize);
837                 vm_->frameworkProgram_ = JSTaggedValue(GetAddress<Program *>(i));
838                 break;
839             case JSType::JS_FUNCTION_BASE:
840             case JSType::JS_FUNCTION:
841             case JSType::JS_PROXY_REVOC_FUNCTION:
842             case JSType::JS_PROMISE_REACTIONS_FUNCTION:
843             case JSType::JS_PROMISE_EXECUTOR_FUNCTION:
844             case JSType::JS_PROMISE_ALL_RESOLVE_ELEMENT_FUNCTION:
845             case JSType::JS_GENERATOR_FUNCTION:
846             case JSType::JS_ASYNC_FUNCTION:
847             case JSType::JS_ASYNC_AWAIT_STATUS_FUNCTION:
848             case JSType::JS_BOUND_FUNCTION:
849                 JSFunctionBaseDeserialize(GetAddress<uint64_t *>(i), objectSize);
850                 break;
851             case JSType::JS_PROXY:
852                 JSProxyDeserialize(GetAddress<uint64_t *>(i), objectSize);
853                 break;
854             default:
855                 JSObjectDeserialize(GetAddress<uint64_t *>(i), objectSize);
856                 break;
857         }
858         if (index != 0) {
859             JSTaggedValue result(GetAddress<TaggedObject *>(i));
860             constants->SetConstant(ConstantIndex(index - 1), result);
861         }
862     }
863 }
864 
HandleObjectHeader(TaggedObject * objectHeader,uint8_t objectType,size_t objectSize,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)865 SlotBit SnapShotSerialize::HandleObjectHeader(TaggedObject *objectHeader, uint8_t objectType, size_t objectSize,
866                                               CQueue<TaggedObject *> *queue,
867                                               std::unordered_map<uint64_t, SlotBit> *data)
868 {
869     auto *hclassClass = objectHeader->GetClass();
870     SlotBit slot(0);
871 
872     ASSERT(hclassClass != nullptr);
873     if (data->find(ToUintPtr(hclassClass)) == data->end()) {
874         slot = SerializeHelper::AddObjectHeaderToData(hclassClass, queue, data);
875     } else {
876         slot = data->find(ToUintPtr(hclassClass))->second;
877     }
878 
879     SlotBit objectSlotBit = data->find(ToUintPtr(objectHeader))->second;
880     slot.SetObjectInConstantsIndex(objectSlotBit.GetObjectInConstantsIndex());
881     slot.SetObjectSize(objectSize);
882     slot.SetObjectType(objectType);
883     return slot;
884 }
885 
HandleTaggedField(JSTaggedType * tagged,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)886 uint64_t SnapShotSerialize::HandleTaggedField(JSTaggedType *tagged, CQueue<TaggedObject *> *queue,
887                                               std::unordered_map<uint64_t, SlotBit> *data)
888 {
889     JSTaggedValue taggedValue(*tagged);
890     if (taggedValue.IsWeak()) {
891         return JSTaggedValue::Undefined().GetRawData();  // Undefind
892     }
893 
894     if (taggedValue.IsSpecial()) {
895         SlotBit special(taggedValue.GetRawData());
896         special.SetObjectSpecial();
897         return special.GetValue();  // special slot
898     }
899 
900     if (!taggedValue.IsHeapObject()) {
901         return taggedValue.GetRawData();  // not object
902     }
903 
904     SlotBit slotBit(0);
905     if (data->find(*tagged) == data->end()) {
906         slotBit = SerializeHelper::AddObjectHeaderToData(taggedValue.GetTaggedObject(), queue, data);
907     } else {
908         slotBit = data->find(taggedValue.GetRawData())->second;
909     }
910 
911     if (taggedValue.IsString()) {
912         slotBit.SetReferenceToString(true);
913     }
914     return slotBit.GetValue();  // object
915 }
916 
DeserializeHandleTaggedField(uint64_t * value)917 void SnapShotSerialize::DeserializeHandleTaggedField(uint64_t *value)
918 {
919     SlotBit slot(*value);
920     if (slot.IsReferenceSlot() && !slot.IsSpecial()) {
921         uint32_t index = slot.GetObjectIndex();
922 
923         if (slot.IsReferenceToString()) {
924             auto str = vm_->GetEcmaStringTable()->GetString(GetAddress<EcmaString *>(index));
925             ASSERT(str != nullptr);
926             *value = ToUintPtr(str);
927         } else {
928             *value = GetAddress<uintptr_t>(index);
929         }
930         return;
931     }
932 
933     if (slot.IsSpecial()) {
934         slot.ClearObjectSpecialFlag();
935         *value = slot.GetValue();
936     }
937 }
938 
DeserializeHandleClassWord(TaggedObject * object)939 void SnapShotSerialize::DeserializeHandleClassWord(TaggedObject *object)
940 {
941     SlotBit slot(*reinterpret_cast<uint64_t *>(object));
942     ASSERT(slot.IsReferenceSlot());
943     uint32_t index = slot.GetObjectIndex();
944     *reinterpret_cast<uint64_t *>(object) = 0;
945 
946     object->SetClass(GetAddress<JSHClass *>(index));
947 }
948 
DynClassSerialize(TaggedObject * objectHeader,uintptr_t snapshotObj,size_t objectSize,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)949 void SnapShotSerialize::DynClassSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize,
950                                           CQueue<TaggedObject *> *queue, std::unordered_map<uint64_t, SlotBit> *data)
951 {
952     size_t beginOffset = JSHClass::PROTOTYPE_OFFSET;
953     int numOfFields = static_cast<int>((objectSize - beginOffset) / TAGGED_SIZE);
954     uintptr_t startAddr = ToUintPtr(objectHeader) + beginOffset;
955     for (int i = 0; i < numOfFields; i++) {
956         auto fieldAddr = reinterpret_cast<JSTaggedType *>(startAddr + i * TAGGED_SIZE);
957         SetObjectSlotField(snapshotObj, beginOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data));
958     }
959 }
960 
DynClassDeserialize(uint64_t * objectHeader)961 void SnapShotSerialize::DynClassDeserialize(uint64_t *objectHeader)
962 {
963     auto dynClass = reinterpret_cast<JSHClass *>(objectHeader);
964     // handle object_header
965     DeserializeHandleClassWord(dynClass);
966 
967     uintptr_t startAddr = ToUintPtr(dynClass) + JSHClass::PROTOTYPE_OFFSET;
968     int numOfFields = static_cast<int>((JSHClass::SIZE - JSHClass::PROTOTYPE_OFFSET) / TAGGED_SIZE);
969     for (int i = 0; i < numOfFields; i++) {
970         auto fieldAddr = reinterpret_cast<uint64_t *>(startAddr + i * TAGGED_SIZE);
971         DeserializeHandleTaggedField(fieldAddr);
972     }
973 }
974 
DynStringSerialize(TaggedObject * objectHeader,uintptr_t snapshotObj)975 void SnapShotSerialize::DynStringSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj)
976 {
977     auto *str = EcmaString::Cast(objectHeader);
978     SetObjectSlotFieldUint32(snapshotObj, OBJECT_HEADER_SIZE, str->GetLength() << 2U);
979 }
980 
DynStringDeserialize(uint64_t * objectHeader)981 void SnapShotSerialize::DynStringDeserialize(uint64_t *objectHeader)
982 {
983     auto object = reinterpret_cast<EcmaString *>(objectHeader);
984     // handle object_header
985     DeserializeHandleClassWord(object);
986 }
987 
DynArraySerialize(TaggedObject * objectHeader,uintptr_t snapshotObj,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)988 void SnapShotSerialize::DynArraySerialize(TaggedObject *objectHeader, uintptr_t snapshotObj,
989                                           CQueue<TaggedObject *> *queue, std::unordered_map<uint64_t, SlotBit> *data)
990 {
991     auto arrayObject = reinterpret_cast<TaggedArray *>(objectHeader);
992     size_t beginOffset = TaggedArray::DATA_OFFSET;
993     auto arrayLength = arrayObject->GetLength();
994     uintptr_t startAddr = ToUintPtr(objectHeader) + beginOffset;
995     for (uint32_t i = 0; i < arrayLength; i++) {
996         auto fieldAddr = reinterpret_cast<JSTaggedType *>(startAddr + i * TAGGED_SIZE);
997         SetObjectSlotField(snapshotObj, beginOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data));
998     }
999 }
1000 
DynArrayDeserialize(uint64_t * objectHeader)1001 void SnapShotSerialize::DynArrayDeserialize(uint64_t *objectHeader)
1002 {
1003     auto object = reinterpret_cast<TaggedArray *>(objectHeader);
1004     // handle object_header
1005     DeserializeHandleClassWord(object);
1006 
1007     auto arrayLength = object->GetLength();
1008     size_t dataOffset = TaggedArray::DATA_OFFSET;
1009     uintptr_t startAddr = ToUintPtr(objectHeader) + dataOffset;
1010     for (uint32_t i = 0; i < arrayLength; i++) {
1011         auto fieldAddr = reinterpret_cast<uint64_t *>(startAddr + i * TAGGED_SIZE);
1012         DeserializeHandleTaggedField(fieldAddr);
1013     }
1014 }
1015 
NativePointerToSlotBit(void * nativePointer)1016 SlotBit SnapShotSerialize::NativePointerToSlotBit(void *nativePointer)
1017 {
1018     SlotBit native(0);
1019     if (nativePointer != nullptr) {  // nativePointer
1020         uint32_t index = MAX_UINT_32;
1021 
1022         if (programSerialize_) {
1023             pandaMethod_.emplace_back(ToUintPtr(nativePointer));
1024             // NOLINTNEXTLINE(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions)
1025             index = pandaMethod_.size() + PROGRAM_NATIVE_METHOD_BEGIN + NATIVE_METHOD_SIZE - 1;
1026         } else {
1027             for (size_t i = 0; i < PROGRAM_NATIVE_METHOD_BEGIN; i++) {
1028                 if (nativePointer == reinterpret_cast<void *>(g_nativeTable[i + NATIVE_METHOD_SIZE])) {
1029                     index = i + NATIVE_METHOD_SIZE;
1030                     break;
1031                 }
1032             }
1033 
1034             // not found
1035             if (index == MAX_UINT_32) {
1036                 auto nativeMethod = reinterpret_cast<JSMethod *>(nativePointer)->GetNativePointer();
1037                 for (size_t i = 0; i < NATIVE_METHOD_SIZE; i++) {
1038                     if (nativeMethod == GetAddress<void *>(i)) {
1039                         index = i;
1040                         break;
1041                     }
1042                 }
1043             }
1044         }
1045 
1046         ASSERT(index != MAX_UINT_32);
1047         LOG_IF(index > MAX_C_POINTER_INDEX, FATAL, RUNTIME) << "MAX_C_POINTER_INDEX: " + ToCString(index);
1048         native.SetObjectIndex(index);
1049     }
1050     return native;
1051 }
1052 
NativePointerSlotBitToAddr(SlotBit native)1053 void *SnapShotSerialize::NativePointerSlotBitToAddr(SlotBit native)
1054 {
1055     uint32_t index = native.GetObjectIndex();
1056     void *addr = nullptr;
1057 
1058     if (index < NATIVE_METHOD_SIZE + PROGRAM_NATIVE_METHOD_BEGIN) {
1059         addr = reinterpret_cast<void *>(g_nativeTable[index]);
1060     } else {
1061         addr = ToVoidPtr(pandaMethod_.at(index - PROGRAM_NATIVE_METHOD_BEGIN - NATIVE_METHOD_SIZE));
1062     }
1063     return addr;
1064 }
1065 
NativePointerSerialize(TaggedObject * objectHeader,uintptr_t snapshotObj)1066 void SnapShotSerialize::NativePointerSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj)
1067 {
1068     void *nativePointer = JSNativePointer::Cast(objectHeader)->GetExternalPointer();
1069     SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE, NativePointerToSlotBit(nativePointer).GetValue());
1070 }
1071 
NativePointerDeserialize(uint64_t * objectHeader)1072 void SnapShotSerialize::NativePointerDeserialize(uint64_t *objectHeader)
1073 {
1074     auto object = reinterpret_cast<TaggedObject *>(objectHeader);
1075     // handle object_header
1076     DeserializeHandleClassWord(object);
1077 
1078     size_t nativeAddr = ToUintPtr(object) + OBJECT_HEADER_SIZE;
1079     SlotBit native(*reinterpret_cast<uint64_t *>(nativeAddr));
1080     if (native.GetObjectIndex() == MAX_OBJECT_INDEX) {
1081         return;
1082     }
1083     JSNativePointer::Cast(object)->ResetExternalPointer(NativePointerSlotBitToAddr(native));
1084 }
1085 
JSObjectSerialize(TaggedObject * objectHeader,uintptr_t snapshotObj,size_t objectSize,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)1086 void SnapShotSerialize::JSObjectSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize,
1087                                           CQueue<TaggedObject *> *queue, std::unordered_map<uint64_t, SlotBit> *data)
1088 {
1089     int numOfFields = static_cast<int>((objectSize - OBJECT_HEADER_SIZE) / TAGGED_SIZE);
1090     uintptr_t startAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE;
1091     for (int i = 0; i < numOfFields; i++) {
1092         auto fieldAddr = reinterpret_cast<JSTaggedType *>(startAddr + i * TAGGED_SIZE);
1093         SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE + i * TAGGED_SIZE,
1094                            HandleTaggedField(fieldAddr, queue, data));
1095     }
1096 }
1097 
JSFunctionBaseSerialize(TaggedObject * objectHeader,uintptr_t snapshotObj,size_t objectSize,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)1098 void SnapShotSerialize::JSFunctionBaseSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize,
1099                                                 CQueue<TaggedObject *> *queue,
1100                                                 std::unordered_map<uint64_t, SlotBit> *data)
1101 {
1102     // befour
1103     int befourFields = static_cast<int>((JSFunctionBase::METHOD_OFFSET - OBJECT_HEADER_SIZE) / TAGGED_SIZE);
1104     uintptr_t befourStartAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE;
1105     for (int i = 0; i < befourFields; i++) {
1106         auto fieldAddr = reinterpret_cast<JSTaggedType *>(befourStartAddr + i * TAGGED_SIZE);
1107         SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE + i * TAGGED_SIZE,
1108                            HandleTaggedField(fieldAddr, queue, data));
1109     }
1110 
1111     // method
1112     auto functionBase = static_cast<JSFunctionBase *>(objectHeader);
1113     size_t methodOffset = JSFunctionBase::METHOD_OFFSET;
1114     auto nativePointer = reinterpret_cast<void *>(functionBase->GetMethod());
1115     SetObjectSlotField(snapshotObj, methodOffset, NativePointerToSlotBit(nativePointer).GetValue());
1116 
1117     // after
1118     size_t afterOffset = JSFunctionBase::METHOD_OFFSET + TAGGED_SIZE;
1119     int afterFields = static_cast<int>((objectSize - afterOffset) / TAGGED_SIZE);
1120     uintptr_t afterStartAddr = ToUintPtr(objectHeader) + JSFunctionBase::METHOD_OFFSET + TAGGED_SIZE;
1121     for (int i = 0; i < afterFields; i++) {
1122         auto fieldAddr = reinterpret_cast<JSTaggedType *>(afterStartAddr + i * TAGGED_SIZE);
1123         SetObjectSlotField(snapshotObj, afterOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data));
1124     }
1125 }
1126 
JSProxySerialize(TaggedObject * objectHeader,uintptr_t snapshotObj,size_t objectSize,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,SlotBit> * data)1127 void SnapShotSerialize::JSProxySerialize(TaggedObject *objectHeader, uintptr_t snapshotObj, size_t objectSize,
1128                                          CQueue<TaggedObject *> *queue, std::unordered_map<uint64_t, SlotBit> *data)
1129 {
1130     // befour
1131     int befourFields = static_cast<int>((JSProxy::METHOD_OFFSET - OBJECT_HEADER_SIZE) / TAGGED_SIZE);
1132     uintptr_t befourStartAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE;
1133     for (int i = 0; i < befourFields; i++) {
1134         auto fieldAddr = reinterpret_cast<JSTaggedType *>(befourStartAddr + i * TAGGED_SIZE);
1135         SetObjectSlotField(snapshotObj, OBJECT_HEADER_SIZE + i * TAGGED_SIZE,
1136                            HandleTaggedField(fieldAddr, queue, data));
1137     }
1138 
1139     // method
1140     auto jsproxy = static_cast<JSProxy *>(objectHeader);
1141     size_t methodOffset = JSProxy::METHOD_OFFSET;
1142     auto nativePointer = reinterpret_cast<void *>(jsproxy->GetMethod());
1143     SetObjectSlotField(snapshotObj, methodOffset, NativePointerToSlotBit(nativePointer).GetValue());
1144 
1145     // after
1146     size_t afterOffset = JSProxy::METHOD_OFFSET + TAGGED_SIZE;
1147     int afterFields = static_cast<int>((objectSize - afterOffset) / TAGGED_SIZE);
1148     uintptr_t afterStartAddr = ToUintPtr(objectHeader) + JSProxy::METHOD_OFFSET + TAGGED_SIZE;
1149     for (int i = 0; i < afterFields; i++) {
1150         auto fieldAddr = reinterpret_cast<JSTaggedType *>(afterStartAddr + i * TAGGED_SIZE);
1151         SetObjectSlotField(snapshotObj, afterOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data));
1152     }
1153 }
1154 
DeserializeRangeTaggedField(size_t beginAddr,int numOfFields)1155 void SnapShotSerialize::DeserializeRangeTaggedField(size_t beginAddr, int numOfFields)
1156 {
1157     for (int i = 0; i < numOfFields; i++) {
1158         auto fieldAddr = reinterpret_cast<uint64_t *>(beginAddr + i * TAGGED_SIZE);
1159         DeserializeHandleTaggedField(fieldAddr);
1160     }
1161 }
1162 
JSObjectDeserialize(uint64_t * objectHeader,size_t objectSize)1163 void SnapShotSerialize::JSObjectDeserialize(uint64_t *objectHeader, size_t objectSize)
1164 {
1165     auto object = reinterpret_cast<TaggedObject *>(objectHeader);
1166     // handle object_header
1167     DeserializeHandleClassWord(object);
1168 
1169     auto objBodySize = objectSize - OBJECT_HEADER_SIZE;
1170     ASSERT(objBodySize % TAGGED_SIZE == 0);
1171     int numOfFields = static_cast<int>(objBodySize / TAGGED_SIZE);
1172     size_t addr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE;
1173     DeserializeRangeTaggedField(addr, numOfFields);
1174 }
1175 
JSFunctionBaseDeserialize(uint64_t * objectHeader,size_t objectSize)1176 void SnapShotSerialize::JSFunctionBaseDeserialize(uint64_t *objectHeader, size_t objectSize)
1177 {
1178     auto object = reinterpret_cast<JSFunctionBase *>(objectHeader);
1179     DeserializeHandleClassWord(object);
1180 
1181     // befour
1182     auto befourMethod = JSFunctionBase::METHOD_OFFSET - OBJECT_HEADER_SIZE;
1183     ASSERT(befourMethod % TAGGED_SIZE == 0);
1184     int befourMethodFields = static_cast<int>(befourMethod / TAGGED_SIZE);
1185     size_t befourAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE;
1186     DeserializeRangeTaggedField(befourAddr, befourMethodFields);
1187 
1188     // method
1189     size_t nativeAddr = ToUintPtr(object) + JSFunctionBase::METHOD_OFFSET;
1190     SlotBit native(*reinterpret_cast<uint64_t *>(nativeAddr));
1191     if (native.GetObjectIndex() != MAX_OBJECT_INDEX) {
1192         object->SetMethod(reinterpret_cast<JSMethod *>(NativePointerSlotBitToAddr(native)));
1193     }
1194 
1195     // after
1196     auto afterMethod = objectSize - JSFunctionBase::METHOD_OFFSET - TAGGED_SIZE;
1197     ASSERT(afterMethod % TAGGED_SIZE == 0);
1198     int afterMethodFields = static_cast<int>(afterMethod / TAGGED_SIZE);
1199     size_t afterAddr = ToUintPtr(objectHeader) + JSFunctionBase::METHOD_OFFSET + TAGGED_SIZE;
1200     DeserializeRangeTaggedField(afterAddr, afterMethodFields);
1201 }
1202 
JSProxyDeserialize(uint64_t * objectHeader,size_t objectSize)1203 void SnapShotSerialize::JSProxyDeserialize(uint64_t *objectHeader, size_t objectSize)
1204 {
1205     auto object = reinterpret_cast<JSProxy *>(objectHeader);
1206     DeserializeHandleClassWord(object);
1207 
1208     // befour
1209     auto befourMethod = JSProxy::METHOD_OFFSET - OBJECT_HEADER_SIZE;
1210     ASSERT(befourMethod % TAGGED_SIZE == 0);
1211     int befourMethodFields = static_cast<int>(befourMethod / TAGGED_SIZE);
1212     size_t befourAddr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE;
1213     DeserializeRangeTaggedField(befourAddr, befourMethodFields);
1214 
1215     // method
1216     size_t nativeAddr = ToUintPtr(object) + JSProxy::METHOD_OFFSET;
1217     SlotBit native(*reinterpret_cast<uint64_t *>(nativeAddr));
1218     if (native.GetObjectIndex() != MAX_OBJECT_INDEX) {
1219         object->SetMethod(reinterpret_cast<JSMethod *>(NativePointerSlotBitToAddr(native)));
1220     }
1221 
1222     // after
1223     auto afterMethod = objectSize - JSProxy::METHOD_OFFSET - TAGGED_SIZE;
1224     ASSERT(afterMethod % TAGGED_SIZE == 0);
1225     int afterMethodFields = static_cast<int>(afterMethod / TAGGED_SIZE);
1226     size_t afterAddr = ToUintPtr(objectHeader) + JSProxy::METHOD_OFFSET + TAGGED_SIZE;
1227     DeserializeRangeTaggedField(afterAddr, afterMethodFields);
1228 }
1229 
DynProgramSerialize(TaggedObject * objectHeader,uintptr_t snapshotObj,CQueue<TaggedObject * > * queue,std::unordered_map<uint64_t,ecmascript::SlotBit> * data)1230 void SnapShotSerialize::DynProgramSerialize(TaggedObject *objectHeader, uintptr_t snapshotObj,
1231                                             CQueue<TaggedObject *> *queue,
1232                                             std::unordered_map<uint64_t, ecmascript::SlotBit> *data)
1233 {
1234     size_t beginOffset = OBJECT_HEADER_SIZE;
1235     auto objBodySize = Program::SIZE - OBJECT_HEADER_SIZE;
1236     int numOfFields = static_cast<int>((objBodySize) / TAGGED_SIZE);
1237     uintptr_t startAddr = ToUintPtr(objectHeader) + beginOffset;
1238     for (int i = 0; i < numOfFields; i++) {
1239         auto fieldAddr = reinterpret_cast<JSTaggedType *>(startAddr + i * TAGGED_SIZE);
1240         SetObjectSlotField(snapshotObj, beginOffset + i * TAGGED_SIZE, HandleTaggedField(fieldAddr, queue, data));
1241     }
1242 }
1243 
DynProgramDeserialize(uint64_t * objectHeader,size_t objectSize)1244 void SnapShotSerialize::DynProgramDeserialize(uint64_t *objectHeader, [[maybe_unused]] size_t objectSize)
1245 {
1246     auto object = reinterpret_cast<TaggedObject *>(objectHeader);
1247     // handle object_header
1248     DeserializeHandleClassWord(object);
1249 
1250     auto objBodySize = Program::SIZE - OBJECT_HEADER_SIZE;
1251     ASSERT(objBodySize % TAGGED_SIZE == 0);
1252     int numOfFields = static_cast<int>(objBodySize / TAGGED_SIZE);
1253     size_t addr = ToUintPtr(objectHeader) + OBJECT_HEADER_SIZE;
1254     for (int i = 0; i < numOfFields; i++) {
1255         auto fieldAddr = reinterpret_cast<uint64_t *>(addr + i * TAGGED_SIZE);
1256         DeserializeHandleTaggedField(fieldAddr);
1257     }
1258 }
1259 
SerializePandaFileMethod()1260 void SnapShotSerialize::SerializePandaFileMethod()
1261 {
1262     SlotBit slot(0);
1263     slot.SetObjectType(MASK_METHOD_SPACE_BEGIN);
1264     slot.SetObjectSize(pandaMethod_.size());
1265 
1266     ObjectFactory *factory = vm_->GetFactory();
1267     // panda method space begin
1268     uintptr_t snapshotObj = factory->NewSpaceBySnapShotAllocator(sizeof(uint64_t));
1269     if (snapshotObj == 0) {
1270         LOG(ERROR, RUNTIME) << "SnapShotAllocator OOM";
1271         return;
1272     }
1273     SetObjectSlotField(snapshotObj, 0, slot.GetValue());  // methods
1274 
1275     // panda methods
1276     for (auto &it : pandaMethod_) {
1277         // write method
1278         size_t methodObjSize = METHOD_SIZE;
1279         uintptr_t methodObj = factory->NewSpaceBySnapShotAllocator(methodObjSize);
1280         if (methodObj == 0) {
1281             LOG(ERROR, RUNTIME) << "SnapShotAllocator OOM";
1282             return;
1283         }
1284         if (memcpy_s(ToVoidPtr(methodObj), methodObjSize, ToVoidPtr(it), METHOD_SIZE) != EOK) {
1285             LOG_ECMA(FATAL) << "memcpy_s failed";
1286             UNREACHABLE();
1287         }
1288     }
1289 }
1290 
RegisterNativeMethod()1291 void SnapShotSerialize::RegisterNativeMethod()  // NOLINT(readability-function-size)
1292 {
1293     constexpr int size = sizeof(g_nativeTable) / sizeof(uintptr_t);
1294     ASSERT(size == NATIVE_METHOD_SIZE + PROGRAM_NATIVE_METHOD_BEGIN);
1295     for (int i = 0; i < size; i++) {
1296         SetAddressToSlot(i, g_nativeTable[i]);
1297     }
1298 }
1299 
GeneratedNativeMethod()1300 void SnapShotSerialize::GeneratedNativeMethod()  // NOLINT(readability-function-size)
1301 {
1302     for (int i = 0; i < NATIVE_METHOD_SIZE; i++) {
1303         SetAddressToSlot(i, g_nativeTable[i]);
1304         vm_->GetMethodForNativeFunction(reinterpret_cast<void *>(g_nativeTable[i]));
1305     }
1306 }
1307 }  // namespace panda::ecmascript
1308