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