/* * Copyright (c) 2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ecmascript/snapshot/mem/snapshot_processor.h" #include "ecmascript/base/error_type.h" #include "ecmascript/builtins/builtins_ark_tools.h" #include "ecmascript/builtins/builtins_array.h" #include "ecmascript/builtins/builtins_arraybuffer.h" #include "ecmascript/builtins/builtins_async_function.h" #include "ecmascript/builtins/builtins_async_generator.h" #include "ecmascript/builtins/builtins_async_iterator.h" #include "ecmascript/builtins/builtins_atomics.h" #include "ecmascript/builtins/builtins_bigint.h" #include "ecmascript/builtins/builtins_boolean.h" #include "ecmascript/builtins/builtins_cjs_exports.h" #include "ecmascript/builtins/builtins_cjs_module.h" #include "ecmascript/builtins/builtins_cjs_require.h" #include "ecmascript/builtins/builtins_collator.h" #include "ecmascript/builtins/builtins_dataview.h" #include "ecmascript/builtins/builtins_date.h" #include "ecmascript/builtins/builtins_date_time_format.h" #include "ecmascript/builtins/builtins_displaynames.h" #include "ecmascript/builtins/builtins_errors.h" #include "ecmascript/builtins/builtins_finalization_registry.h" #include "ecmascript/builtins/builtins_function.h" #include "ecmascript/builtins/builtins_generator.h" #include "ecmascript/builtins/builtins_global.h" #include "ecmascript/builtins/builtins_intl.h" #include "ecmascript/builtins/builtins_iterator.h" #include "ecmascript/builtins/builtins_json.h" #include "ecmascript/builtins/builtins_list_format.h" #include "ecmascript/builtins/builtins_locale.h" #include "ecmascript/builtins/builtins_map.h" #include "ecmascript/builtins/builtins_math.h" #include "ecmascript/builtins/builtins_number.h" #include "ecmascript/builtins/builtins_number_format.h" #include "ecmascript/builtins/builtins_object.h" #include "ecmascript/builtins/builtins_plural_rules.h" #include "ecmascript/builtins/builtins_promise.h" #include "ecmascript/builtins/builtins_promise_handler.h" #include "ecmascript/builtins/builtins_promise_job.h" #include "ecmascript/builtins/builtins_proxy.h" #include "ecmascript/builtins/builtins_reflect.h" #include "ecmascript/builtins/builtins_regexp.h" #include "ecmascript/builtins/builtins_relative_time_format.h" #include "ecmascript/builtins/builtins_set.h" #include "ecmascript/builtins/builtins_sharedarraybuffer.h" #include "ecmascript/builtins/builtins_string.h" #include "ecmascript/builtins/builtins_string_iterator.h" #include "ecmascript/builtins/builtins_symbol.h" #include "ecmascript/builtins/builtins_typedarray.h" #include "ecmascript/builtins/builtins_weak_map.h" #include "ecmascript/builtins/builtins_weak_ref.h" #include "ecmascript/builtins/builtins_weak_set.h" #include "ecmascript/containers/containers_arraylist.h" #include "ecmascript/containers/containers_deque.h" #include "ecmascript/containers/containers_hashmap.h" #include "ecmascript/containers/containers_hashset.h" #include "ecmascript/containers/containers_lightweightmap.h" #include "ecmascript/containers/containers_lightweightset.h" #include "ecmascript/containers/containers_linked_list.h" #include "ecmascript/containers/containers_list.h" #include "ecmascript/containers/containers_plainarray.h" #include "ecmascript/containers/containers_private.h" #include "ecmascript/containers/containers_queue.h" #include "ecmascript/containers/containers_stack.h" #include "ecmascript/containers/containers_treemap.h" #include "ecmascript/containers/containers_treeset.h" #include "ecmascript/containers/containers_vector.h" #include "ecmascript/ecma_string_table.h" #include "ecmascript/jspandafile/js_pandafile_manager.h" #include "ecmascript/jspandafile/program_object.h" #include "ecmascript/global_env.h" #include "ecmascript/js_api/js_api_arraylist_iterator.h" #include "ecmascript/js_api/js_api_deque_iterator.h" #include "ecmascript/js_api/js_api_lightweightmap_iterator.h" #include "ecmascript/js_api/js_api_lightweightset_iterator.h" #include "ecmascript/js_api/js_api_linked_list_iterator.h" #include "ecmascript/js_api/js_api_list_iterator.h" #include "ecmascript/js_api/js_api_plain_array_iterator.h" #include "ecmascript/js_api/js_api_queue_iterator.h" #include "ecmascript/js_api/js_api_stack_iterator.h" #include "ecmascript/js_api/js_api_tree_map_iterator.h" #include "ecmascript/js_api/js_api_tree_set_iterator.h" #include "ecmascript/js_api/js_api_vector_iterator.h" #include "ecmascript/js_array_iterator.h" #include "ecmascript/js_for_in_iterator.h" #include "ecmascript/js_hclass.h" #include "ecmascript/js_map_iterator.h" #include "ecmascript/js_regexp_iterator.h" #include "ecmascript/js_set_iterator.h" #include "ecmascript/js_api/js_api_hashmap_iterator.h" #include "ecmascript/js_api/js_api_hashset_iterator.h" #include "ecmascript/js_tagged_value-inl.h" #include "ecmascript/jspandafile/js_pandafile.h" #include "ecmascript/mem/heap.h" #include "ecmascript/mem/heap_region_allocator.h" #include "ecmascript/mem/space-inl.h" #include "ecmascript/mem/visitor.h" #include "ecmascript/object_factory.h" #include "ecmascript/snapshot/mem/snapshot_env.h" #include "ecmascript/aot_file_manager.h" namespace panda::ecmascript { using Number = builtins::BuiltinsNumber; using BuiltinsBigInt = builtins::BuiltinsBigInt; using Object = builtins::BuiltinsObject; using Date = builtins::BuiltinsDate; using DisplayNames = builtins::BuiltinsDisplayNames; using Symbol = builtins::BuiltinsSymbol; using Boolean = builtins::BuiltinsBoolean; using BuiltinsMap = builtins::BuiltinsMap; using BuiltinsSet = builtins::BuiltinsSet; using BuiltinsWeakMap = builtins::BuiltinsWeakMap; using BuiltinsWeakSet = builtins::BuiltinsWeakSet; using BuiltinsWeakRef = builtins::BuiltinsWeakRef; using BuiltinsFinalizationRegistry = builtins::BuiltinsFinalizationRegistry; using BuiltinsArray = builtins::BuiltinsArray; using BuiltinsTypedArray = builtins::BuiltinsTypedArray; using BuiltinsIterator = builtins::BuiltinsIterator; using BuiltinsAsyncIterator = builtins::BuiltinsAsyncIterator; using Error = builtins::BuiltinsError; using RangeError = builtins::BuiltinsRangeError; using ReferenceError = builtins::BuiltinsReferenceError; using TypeError = builtins::BuiltinsTypeError; using AggregateError = builtins::BuiltinsAggregateError; using URIError = builtins::BuiltinsURIError; using SyntaxError = builtins::BuiltinsSyntaxError; using EvalError = builtins::BuiltinsEvalError; using OOMError = builtins::BuiltinsOOMError; using ErrorType = base::ErrorType; using Global = builtins::BuiltinsGlobal; using BuiltinsString = builtins::BuiltinsString; using StringIterator = builtins::BuiltinsStringIterator; using RegExp = builtins::BuiltinsRegExp; using Function = builtins::BuiltinsFunction; using Math = builtins::BuiltinsMath; using Atomics = builtins::BuiltinsAtomics; using ArrayBuffer = builtins::BuiltinsArrayBuffer; using SharedArrayBuffer = builtins::BuiltinsSharedArrayBuffer; using Json = builtins::BuiltinsJson; using Proxy = builtins::BuiltinsProxy; using Reflect = builtins::BuiltinsReflect; using AsyncFunction = builtins::BuiltinsAsyncFunction; using GeneratorObject = builtins::BuiltinsGenerator; using AsyncGeneratorObject = builtins::BuiltinsAsyncGenerator; using Promise = builtins::BuiltinsPromise; using BuiltinsPromiseHandler = builtins::BuiltinsPromiseHandler; using BuiltinsPromiseJob = builtins::BuiltinsPromiseJob; using ListFormat = builtins::BuiltinsListFormat; using BuiltinsCjsExports = builtins::BuiltinsCjsExports; using BuiltinsCjsModule = builtins::BuiltinsCjsModule; using BuiltinsCjsRequire = builtins::BuiltinsCjsRequire; using ArkTools = builtins::BuiltinsArkTools; using ErrorType = base::ErrorType; using DataView = builtins::BuiltinsDataView; using Intl = builtins::BuiltinsIntl; using Locale = builtins::BuiltinsLocale; using DateTimeFormat = builtins::BuiltinsDateTimeFormat; using NumberFormat = builtins::BuiltinsNumberFormat; using RelativeTimeFormat = builtins::BuiltinsRelativeTimeFormat; using Collator = builtins::BuiltinsCollator; using PluralRules = builtins::BuiltinsPluralRules; using ArrayList = containers::ContainersArrayList; using HashMap = containers::ContainersHashMap; using HashSet = containers::ContainersHashSet; using LightWeightMap = containers::ContainersLightWeightMap; using LightWeightSet = containers::ContainersLightWeightSet; using TreeMap = containers::ContainersTreeMap; using TreeSet = containers::ContainersTreeSet; using Vector = containers::ContainersVector; using Queue = containers::ContainersQueue; using List = containers::ContainersList; using LinkedList = containers::ContainersLinkedList; using PlainArray = containers::ContainersPlainArray; using Deque = containers::ContainersDeque; using ContainerStack = panda::ecmascript::containers::ContainersStack; using ContainersPrivate = containers::ContainersPrivate; // NOLINTNEXTLINE(modernize-avoid-c-arrays) static uintptr_t g_nativeTable[] = { reinterpret_cast(nullptr), reinterpret_cast(BuiltinsMap::Species), reinterpret_cast(StringIterator::Next), reinterpret_cast(Function::FunctionPrototypeInvokeSelf), reinterpret_cast(Function::FunctionConstructor), reinterpret_cast(JSFunction::AccessCallerArgumentsThrowTypeError), reinterpret_cast(Function::FunctionPrototypeApply), reinterpret_cast(Function::FunctionPrototypeBind), reinterpret_cast(Function::FunctionPrototypeCall), reinterpret_cast(Function::FunctionPrototypeToString), reinterpret_cast(Object::ObjectConstructor), reinterpret_cast(Object::FromEntries), reinterpret_cast(Error::ErrorConstructor), reinterpret_cast(Error::ToString), reinterpret_cast(RangeError::RangeErrorConstructor), reinterpret_cast(RangeError::ToString), reinterpret_cast(ReferenceError::ReferenceErrorConstructor), reinterpret_cast(ReferenceError::ToString), reinterpret_cast(TypeError::TypeErrorConstructor), reinterpret_cast(TypeError::ToString), reinterpret_cast(TypeError::ThrowTypeError), reinterpret_cast(AggregateError::AggregateErrorConstructor), reinterpret_cast(AggregateError::ToString), reinterpret_cast(URIError::URIErrorConstructor), reinterpret_cast(URIError::ToString), reinterpret_cast(SyntaxError::SyntaxErrorConstructor), reinterpret_cast(SyntaxError::ToString), reinterpret_cast(EvalError::EvalErrorConstructor), reinterpret_cast(EvalError::ToString), reinterpret_cast(OOMError::OOMErrorConstructor), reinterpret_cast(OOMError::ToString), reinterpret_cast(Number::NumberConstructor), reinterpret_cast(Number::ToExponential), reinterpret_cast(Number::ToFixed), reinterpret_cast(Number::ToLocaleString), reinterpret_cast(Number::ToPrecision), reinterpret_cast(Number::ToString), reinterpret_cast(Number::ValueOf), reinterpret_cast(Number::IsFinite), reinterpret_cast(Number::IsInteger), reinterpret_cast(Number::IsNaN), reinterpret_cast(Number::IsSafeInteger), reinterpret_cast(Number::ParseFloat), reinterpret_cast(Number::ParseInt), reinterpret_cast(BuiltinsBigInt::BigIntConstructor), reinterpret_cast(BuiltinsBigInt::AsUintN), reinterpret_cast(BuiltinsBigInt::AsIntN), reinterpret_cast(BuiltinsBigInt::ToLocaleString), reinterpret_cast(BuiltinsBigInt::ToString), reinterpret_cast(BuiltinsBigInt::ValueOf), reinterpret_cast(Symbol::SymbolConstructor), reinterpret_cast(Symbol::For), reinterpret_cast(Symbol::KeyFor), reinterpret_cast(Symbol::DescriptionGetter), reinterpret_cast(Symbol::ToPrimitive), reinterpret_cast(Symbol::ToString), reinterpret_cast(Symbol::ValueOf), reinterpret_cast(Function::FunctionPrototypeHasInstance), reinterpret_cast(Date::DateConstructor), reinterpret_cast(Date::GetDate), reinterpret_cast(Date::GetDay), reinterpret_cast(Date::GetFullYear), reinterpret_cast(Date::GetHours), reinterpret_cast(Date::GetMilliseconds), reinterpret_cast(Date::GetMinutes), reinterpret_cast(Date::GetMonth), reinterpret_cast(Date::GetSeconds), reinterpret_cast(Date::GetTime), reinterpret_cast(Date::GetTimezoneOffset), reinterpret_cast(Date::GetUTCDate), reinterpret_cast(Date::GetUTCDay), reinterpret_cast(Date::GetUTCFullYear), reinterpret_cast(Date::GetUTCHours), reinterpret_cast(Date::GetUTCMilliseconds), reinterpret_cast(Date::GetUTCMinutes), reinterpret_cast(Date::GetUTCMonth), reinterpret_cast(Date::GetUTCSeconds), reinterpret_cast(Date::SetDate), reinterpret_cast(Date::SetFullYear), reinterpret_cast(Date::SetHours), reinterpret_cast(Date::SetMilliseconds), reinterpret_cast(Date::SetMinutes), reinterpret_cast(Date::SetMonth), reinterpret_cast(Date::SetSeconds), reinterpret_cast(Date::SetTime), reinterpret_cast(Date::SetUTCDate), reinterpret_cast(Date::SetUTCFullYear), reinterpret_cast(Date::SetUTCHours), reinterpret_cast(Date::SetUTCMilliseconds), reinterpret_cast(Date::SetUTCMinutes), reinterpret_cast(Date::SetUTCMonth), reinterpret_cast(Date::SetUTCSeconds), reinterpret_cast(Date::ToDateString), reinterpret_cast(Date::ToISOString), reinterpret_cast(Date::ToJSON), reinterpret_cast(Date::ToLocaleDateString), reinterpret_cast(Date::ToLocaleString), reinterpret_cast(Date::ToLocaleTimeString), reinterpret_cast(Date::ToString), reinterpret_cast(Date::ToTimeString), reinterpret_cast(Date::ToUTCString), reinterpret_cast(Date::ValueOf), reinterpret_cast(Date::ToPrimitive), reinterpret_cast(Date::Now), reinterpret_cast(Date::Parse), reinterpret_cast(Date::UTC), reinterpret_cast(DisplayNames::DisplayNamesConstructor), reinterpret_cast(DisplayNames::SupportedLocalesOf), reinterpret_cast(DisplayNames::Of), reinterpret_cast(DisplayNames::ResolvedOptions), reinterpret_cast(Object::Assign), reinterpret_cast(Object::Create), reinterpret_cast(Object::DefineProperties), reinterpret_cast(Object::DefineProperty), reinterpret_cast(Object::Freeze), reinterpret_cast(Object::GetOwnPropertyDescriptor), reinterpret_cast(Object::GetOwnPropertyNames), reinterpret_cast(Object::GetOwnPropertySymbols), reinterpret_cast(Object::GetPrototypeOf), reinterpret_cast(Object::Is), reinterpret_cast(Object::IsExtensible), reinterpret_cast(Object::IsFrozen), reinterpret_cast(Object::IsSealed), reinterpret_cast(Object::Keys), reinterpret_cast(Object::Values), reinterpret_cast(Object::PreventExtensions), reinterpret_cast(Object::Seal), reinterpret_cast(Object::SetPrototypeOf), reinterpret_cast(Object::HasOwnProperty), reinterpret_cast(Object::IsPrototypeOf), reinterpret_cast(Object::PropertyIsEnumerable), reinterpret_cast(Object::ToLocaleString), reinterpret_cast(Object::ToString), reinterpret_cast(Object::ValueOf), reinterpret_cast(Object::ProtoGetter), reinterpret_cast(Object::ProtoSetter), reinterpret_cast(Object::CreateRealm), reinterpret_cast(Object::Entries), reinterpret_cast(Boolean::BooleanConstructor), reinterpret_cast(Boolean::BooleanPrototypeToString), reinterpret_cast(Boolean::BooleanPrototypeValueOf), reinterpret_cast(RegExp::RegExpConstructor), reinterpret_cast(RegExp::Exec), reinterpret_cast(RegExp::Test), reinterpret_cast(RegExp::ToString), reinterpret_cast(RegExp::GetFlags), reinterpret_cast(RegExp::GetSource), reinterpret_cast(RegExp::GetGlobal), reinterpret_cast(RegExp::GetIgnoreCase), reinterpret_cast(RegExp::GetMultiline), reinterpret_cast(RegExp::GetDotAll), reinterpret_cast(RegExp::GetSticky), reinterpret_cast(RegExp::GetUnicode), reinterpret_cast(RegExp::Split), reinterpret_cast(RegExp::Search), reinterpret_cast(RegExp::Match), reinterpret_cast(RegExp::MatchAll), reinterpret_cast(RegExp::Replace), reinterpret_cast(BuiltinsSet::SetConstructor), reinterpret_cast(BuiltinsSet::Add), reinterpret_cast(BuiltinsSet::Clear), reinterpret_cast(BuiltinsSet::Delete), reinterpret_cast(BuiltinsSet::Has), reinterpret_cast(BuiltinsSet::ForEach), reinterpret_cast(BuiltinsSet::Entries), reinterpret_cast(BuiltinsSet::Values), reinterpret_cast(BuiltinsSet::GetSize), reinterpret_cast(BuiltinsSet::Species), reinterpret_cast(BuiltinsMap::MapConstructor), reinterpret_cast(BuiltinsMap::Set), reinterpret_cast(BuiltinsMap::Clear), reinterpret_cast(BuiltinsMap::Delete), reinterpret_cast(BuiltinsMap::Has), reinterpret_cast(BuiltinsMap::Get), reinterpret_cast(BuiltinsMap::ForEach), reinterpret_cast(BuiltinsMap::Keys), reinterpret_cast(BuiltinsMap::Values), reinterpret_cast(BuiltinsMap::Entries), reinterpret_cast(BuiltinsMap::GetSize), reinterpret_cast(BuiltinsWeakMap::WeakMapConstructor), reinterpret_cast(BuiltinsWeakMap::Set), reinterpret_cast(BuiltinsWeakMap::Delete), reinterpret_cast(BuiltinsWeakMap::Has), reinterpret_cast(BuiltinsWeakMap::Get), reinterpret_cast(BuiltinsWeakSet::WeakSetConstructor), reinterpret_cast(BuiltinsWeakSet::Add), reinterpret_cast(BuiltinsWeakSet::Delete), reinterpret_cast(BuiltinsWeakSet::Has), reinterpret_cast(BuiltinsWeakRef::WeakRefConstructor), reinterpret_cast(BuiltinsWeakRef::Deref), reinterpret_cast(BuiltinsFinalizationRegistry::FinalizationRegistryConstructor), reinterpret_cast(BuiltinsFinalizationRegistry::Register), reinterpret_cast(BuiltinsFinalizationRegistry::Unregister), reinterpret_cast(BuiltinsArray::ArrayConstructor), reinterpret_cast(BuiltinsArray::Concat), reinterpret_cast(BuiltinsArray::CopyWithin), reinterpret_cast(BuiltinsArray::Entries), reinterpret_cast(BuiltinsArray::Every), reinterpret_cast(BuiltinsArray::Fill), reinterpret_cast(BuiltinsArray::Filter), reinterpret_cast(BuiltinsArray::Find), reinterpret_cast(BuiltinsArray::FindIndex), reinterpret_cast(BuiltinsArray::ForEach), reinterpret_cast(BuiltinsArray::IndexOf), reinterpret_cast(BuiltinsArray::Join), reinterpret_cast(BuiltinsArray::Keys), reinterpret_cast(BuiltinsArray::LastIndexOf), reinterpret_cast(BuiltinsArray::Map), reinterpret_cast(BuiltinsArray::Pop), reinterpret_cast(BuiltinsArray::Push), reinterpret_cast(BuiltinsArray::Reduce), reinterpret_cast(BuiltinsArray::ReduceRight), reinterpret_cast(BuiltinsArray::Reverse), reinterpret_cast(BuiltinsArray::Shift), reinterpret_cast(BuiltinsArray::Slice), reinterpret_cast(BuiltinsArray::Some), reinterpret_cast(BuiltinsArray::Sort), reinterpret_cast(BuiltinsArray::Splice), reinterpret_cast(BuiltinsArray::ToLocaleString), reinterpret_cast(BuiltinsArray::ToString), reinterpret_cast(BuiltinsArray::Unshift), reinterpret_cast(BuiltinsArray::Values), reinterpret_cast(BuiltinsArray::From), reinterpret_cast(BuiltinsArray::IsArray), reinterpret_cast(BuiltinsArray::Of), reinterpret_cast(BuiltinsArray::Species), reinterpret_cast(BuiltinsArray::Unscopables), reinterpret_cast(BuiltinsArray::Includes), reinterpret_cast(BuiltinsArray::Flat), reinterpret_cast(BuiltinsArray::FlatMap), reinterpret_cast(BuiltinsTypedArray::TypedArrayBaseConstructor), reinterpret_cast(BuiltinsTypedArray::CopyWithin), reinterpret_cast(BuiltinsTypedArray::Entries), reinterpret_cast(BuiltinsTypedArray::Every), reinterpret_cast(BuiltinsTypedArray::Fill), reinterpret_cast(BuiltinsTypedArray::Filter), reinterpret_cast(BuiltinsTypedArray::Find), reinterpret_cast(BuiltinsTypedArray::FindIndex), reinterpret_cast(BuiltinsTypedArray::ForEach), reinterpret_cast(BuiltinsTypedArray::IndexOf), reinterpret_cast(BuiltinsTypedArray::Join), reinterpret_cast(BuiltinsTypedArray::Keys), reinterpret_cast(BuiltinsTypedArray::LastIndexOf), reinterpret_cast(BuiltinsTypedArray::Map), reinterpret_cast(BuiltinsTypedArray::Reduce), reinterpret_cast(BuiltinsTypedArray::ReduceRight), reinterpret_cast(BuiltinsTypedArray::Reverse), reinterpret_cast(BuiltinsTypedArray::Set), reinterpret_cast(BuiltinsTypedArray::Slice), reinterpret_cast(BuiltinsTypedArray::Some), reinterpret_cast(BuiltinsTypedArray::Sort), reinterpret_cast(BuiltinsTypedArray::Subarray), reinterpret_cast(BuiltinsTypedArray::ToLocaleString), reinterpret_cast(BuiltinsTypedArray::Values), reinterpret_cast(BuiltinsTypedArray::GetBuffer), reinterpret_cast(BuiltinsTypedArray::GetByteLength), reinterpret_cast(BuiltinsTypedArray::GetByteOffset), reinterpret_cast(BuiltinsTypedArray::GetLength), reinterpret_cast(BuiltinsTypedArray::ToStringTag), reinterpret_cast(BuiltinsTypedArray::From), reinterpret_cast(BuiltinsTypedArray::Of), reinterpret_cast(BuiltinsTypedArray::Species), reinterpret_cast(BuiltinsTypedArray::Includes), reinterpret_cast(BuiltinsTypedArray::Int8ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Uint8ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Uint8ClampedArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Int16ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Uint16ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Int32ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Uint32ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Float32ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::Float64ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::BigInt64ArrayConstructor), reinterpret_cast(BuiltinsTypedArray::BigUint64ArrayConstructor), reinterpret_cast(BuiltinsString::StringConstructor), reinterpret_cast(BuiltinsString::CharAt), reinterpret_cast(BuiltinsString::CharCodeAt), reinterpret_cast(BuiltinsString::CodePointAt), reinterpret_cast(BuiltinsString::Concat), reinterpret_cast(BuiltinsString::EndsWith), reinterpret_cast(BuiltinsString::Includes), reinterpret_cast(BuiltinsString::IndexOf), reinterpret_cast(BuiltinsString::LastIndexOf), reinterpret_cast(BuiltinsString::LocaleCompare), reinterpret_cast(BuiltinsString::Match), reinterpret_cast(BuiltinsString::MatchAll), reinterpret_cast(BuiltinsString::Normalize), reinterpret_cast(BuiltinsString::PadEnd), reinterpret_cast(BuiltinsString::PadStart), reinterpret_cast(BuiltinsString::Repeat), reinterpret_cast(BuiltinsString::Replace), reinterpret_cast(BuiltinsString::ReplaceAll), reinterpret_cast(BuiltinsString::Search), reinterpret_cast(BuiltinsString::Slice), reinterpret_cast(BuiltinsString::Split), reinterpret_cast(BuiltinsString::StartsWith), reinterpret_cast(BuiltinsString::Substring), reinterpret_cast(BuiltinsString::SubStr), reinterpret_cast(BuiltinsString::ToLocaleLowerCase), reinterpret_cast(BuiltinsString::ToLocaleUpperCase), reinterpret_cast(BuiltinsString::ToLowerCase), reinterpret_cast(BuiltinsString::ToString), reinterpret_cast(BuiltinsString::ToUpperCase), reinterpret_cast(BuiltinsString::Trim), reinterpret_cast(BuiltinsString::TrimStart), reinterpret_cast(BuiltinsString::TrimEnd), reinterpret_cast(BuiltinsString::TrimLeft), reinterpret_cast(BuiltinsString::TrimRight), reinterpret_cast(BuiltinsString::ValueOf), reinterpret_cast(BuiltinsString::GetStringIterator), reinterpret_cast(BuiltinsString::FromCharCode), reinterpret_cast(BuiltinsString::FromCodePoint), reinterpret_cast(BuiltinsString::Raw), reinterpret_cast(BuiltinsString::GetLength), reinterpret_cast(ArrayBuffer::ArrayBufferConstructor), reinterpret_cast(ArrayBuffer::Slice), reinterpret_cast(ArrayBuffer::IsView), reinterpret_cast(ArrayBuffer::Species), reinterpret_cast(ArrayBuffer::GetByteLength), reinterpret_cast(SharedArrayBuffer::SharedArrayBufferConstructor), reinterpret_cast(SharedArrayBuffer::IsSharedArrayBuffer), reinterpret_cast(SharedArrayBuffer::Species), reinterpret_cast(SharedArrayBuffer::GetByteLength), reinterpret_cast(SharedArrayBuffer::Slice), reinterpret_cast(DataView::DataViewConstructor), reinterpret_cast(DataView::GetFloat32), reinterpret_cast(DataView::GetFloat64), reinterpret_cast(DataView::GetInt8), reinterpret_cast(DataView::GetInt16), reinterpret_cast(DataView::GetInt32), reinterpret_cast(DataView::GetUint8), reinterpret_cast(DataView::GetUint16), reinterpret_cast(DataView::GetUint32), reinterpret_cast(DataView::SetFloat32), reinterpret_cast(DataView::SetFloat64), reinterpret_cast(DataView::GetBigInt64), reinterpret_cast(DataView::GetBigUint64), reinterpret_cast(DataView::SetInt8), reinterpret_cast(DataView::SetInt16), reinterpret_cast(DataView::SetInt32), reinterpret_cast(DataView::SetUint8), reinterpret_cast(DataView::SetUint16), reinterpret_cast(DataView::SetUint32), reinterpret_cast(DataView::GetBuffer), reinterpret_cast(DataView::GetByteLength), reinterpret_cast(DataView::GetOffset), reinterpret_cast(DataView::SetBigInt64), reinterpret_cast(DataView::SetBigUint64), reinterpret_cast(Global::PrintEntrypoint), reinterpret_cast(Global::NotSupportEval), reinterpret_cast(Global::IsFinite), reinterpret_cast(Global::IsNaN), reinterpret_cast(Global::DecodeURI), reinterpret_cast(Global::DecodeURIComponent), reinterpret_cast(Global::EncodeURI), reinterpret_cast(Global::EncodeURIComponent), reinterpret_cast(Math::Abs), reinterpret_cast(Math::Acos), reinterpret_cast(Math::Acosh), reinterpret_cast(Math::Asin), reinterpret_cast(Math::Asinh), reinterpret_cast(Math::Atan), reinterpret_cast(Math::Atanh), reinterpret_cast(Math::Atan2), reinterpret_cast(Math::Cbrt), reinterpret_cast(Math::Ceil), reinterpret_cast(Math::Clz32), reinterpret_cast(Math::Cos), reinterpret_cast(Math::Cosh), reinterpret_cast(Math::Exp), reinterpret_cast(Math::Expm1), reinterpret_cast(Math::Floor), reinterpret_cast(Math::Fround), reinterpret_cast(Math::Hypot), reinterpret_cast(Math::Imul), reinterpret_cast(Math::Log), reinterpret_cast(Math::Log1p), reinterpret_cast(Math::Log10), reinterpret_cast(Math::Log2), reinterpret_cast(Math::Max), reinterpret_cast(Math::Min), reinterpret_cast(Math::Pow), reinterpret_cast(Math::Random), reinterpret_cast(Math::Round), reinterpret_cast(Math::Sign), reinterpret_cast(Math::Sin), reinterpret_cast(Math::Sinh), reinterpret_cast(Math::Sqrt), reinterpret_cast(Math::Tan), reinterpret_cast(Math::Tanh), reinterpret_cast(Math::Trunc), reinterpret_cast(Atomics::Wait), reinterpret_cast(Atomics::Exchange), reinterpret_cast(Atomics::CompareExchange), reinterpret_cast(Atomics::IsLockFree), reinterpret_cast(Atomics::Store), reinterpret_cast(Atomics::Load), reinterpret_cast(Atomics::Notify), reinterpret_cast(Atomics::Xor), reinterpret_cast(Atomics::Or), reinterpret_cast(Atomics::Sub), reinterpret_cast(Atomics::And), reinterpret_cast(Atomics::Add), reinterpret_cast(Json::Parse), reinterpret_cast(Json::Stringify), reinterpret_cast(BuiltinsIterator::Next), reinterpret_cast(BuiltinsIterator::Return), reinterpret_cast(BuiltinsIterator::Throw), reinterpret_cast(BuiltinsIterator::GetIteratorObj), reinterpret_cast(BuiltinsAsyncIterator::Next), reinterpret_cast(BuiltinsAsyncIterator::Return), reinterpret_cast(BuiltinsAsyncIterator::Throw), reinterpret_cast(BuiltinsAsyncIterator::GetAsyncIteratorObj), reinterpret_cast(JSForInIterator::Next), reinterpret_cast(JSRegExpIterator::Next), reinterpret_cast(JSSetIterator::Next), reinterpret_cast(JSMapIterator::Next), reinterpret_cast(JSArrayIterator::Next), reinterpret_cast(Proxy::ProxyConstructor), reinterpret_cast(Proxy::Revocable), reinterpret_cast(Reflect::ReflectApply), reinterpret_cast(Reflect::ReflectConstruct), reinterpret_cast(Reflect::ReflectDefineProperty), reinterpret_cast(Reflect::ReflectDeleteProperty), reinterpret_cast(Reflect::ReflectGet), reinterpret_cast(Reflect::ReflectGetOwnPropertyDescriptor), reinterpret_cast(Reflect::ReflectGetPrototypeOf), reinterpret_cast(Reflect::ReflectHas), reinterpret_cast(Reflect::ReflectIsExtensible), reinterpret_cast(Reflect::ReflectOwnKeys), reinterpret_cast(Reflect::ReflectPreventExtensions), reinterpret_cast(Reflect::ReflectSet), reinterpret_cast(Reflect::ReflectSetPrototypeOf), reinterpret_cast(AsyncFunction::AsyncFunctionConstructor), reinterpret_cast(GeneratorObject::GeneratorPrototypeNext), reinterpret_cast(GeneratorObject::GeneratorPrototypeReturn), reinterpret_cast(GeneratorObject::GeneratorPrototypeThrow), reinterpret_cast(GeneratorObject::GeneratorFunctionConstructor), reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorPrototypeNext), reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorPrototypeReturn), reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorPrototypeThrow), reinterpret_cast(AsyncGeneratorObject::AsyncGeneratorFunctionConstructor), reinterpret_cast(Promise::PromiseConstructor), reinterpret_cast(Promise::All), reinterpret_cast(Promise::Race), reinterpret_cast(Promise::Resolve), reinterpret_cast(Promise::Reject), reinterpret_cast(Promise::Catch), reinterpret_cast(Promise::Then), reinterpret_cast(Promise::Finally), reinterpret_cast(Promise::Any), reinterpret_cast(Promise::AllSettled), reinterpret_cast(Promise::GetSpecies), reinterpret_cast(BuiltinsPromiseJob::PromiseReactionJob), reinterpret_cast(BuiltinsPromiseJob::PromiseResolveThenableJob), reinterpret_cast(BuiltinsPromiseJob::DynamicImportJob), reinterpret_cast(Intl::GetCanonicalLocales), reinterpret_cast(Locale::LocaleConstructor), reinterpret_cast(Locale::Maximize), reinterpret_cast(Locale::Minimize), reinterpret_cast(Locale::ToString), reinterpret_cast(Locale::GetBaseName), reinterpret_cast(Locale::GetCalendar), reinterpret_cast(Locale::GetCaseFirst), reinterpret_cast(Locale::GetCollation), reinterpret_cast(Locale::GetHourCycle), reinterpret_cast(Locale::GetNumeric), reinterpret_cast(Locale::GetNumberingSystem), reinterpret_cast(Locale::GetLanguage), reinterpret_cast(Locale::GetScript), reinterpret_cast(Locale::GetRegion), reinterpret_cast(DateTimeFormat::DateTimeFormatConstructor), reinterpret_cast(DateTimeFormat::SupportedLocalesOf), reinterpret_cast(DateTimeFormat::Format), reinterpret_cast(DateTimeFormat::FormatToParts), reinterpret_cast(DateTimeFormat::ResolvedOptions), reinterpret_cast(DateTimeFormat::FormatRange), reinterpret_cast(DateTimeFormat::FormatRangeToParts), reinterpret_cast(NumberFormat::NumberFormatConstructor), reinterpret_cast(NumberFormat::SupportedLocalesOf), reinterpret_cast(NumberFormat::Format), reinterpret_cast(NumberFormat::FormatToParts), reinterpret_cast(NumberFormat::ResolvedOptions), reinterpret_cast(RelativeTimeFormat::RelativeTimeFormatConstructor), reinterpret_cast(RelativeTimeFormat::SupportedLocalesOf), reinterpret_cast(RelativeTimeFormat::Format), reinterpret_cast(RelativeTimeFormat::FormatToParts), reinterpret_cast(RelativeTimeFormat::ResolvedOptions), reinterpret_cast(Collator::CollatorConstructor), reinterpret_cast(Collator::SupportedLocalesOf), reinterpret_cast(Collator::Compare), reinterpret_cast(Collator::ResolvedOptions), reinterpret_cast(PluralRules::PluralRulesConstructor), reinterpret_cast(PluralRules::SupportedLocalesOf), reinterpret_cast(PluralRules::Select), reinterpret_cast(PluralRules::ResolvedOptions), reinterpret_cast(ListFormat::ListFormatConstructor), reinterpret_cast(ListFormat::SupportedLocalesOf), reinterpret_cast(ListFormat::Format), reinterpret_cast(ListFormat::FormatToParts), reinterpret_cast(ListFormat::ResolvedOptions), reinterpret_cast(BuiltinsCjsExports::CjsExportsConstructor), reinterpret_cast(BuiltinsCjsModule::CjsModuleConstructor), reinterpret_cast(BuiltinsCjsModule::Compiler), reinterpret_cast(BuiltinsCjsModule::Load), reinterpret_cast(BuiltinsCjsModule::Require), reinterpret_cast(BuiltinsCjsModule::GetExportsForCircularRequire), reinterpret_cast(BuiltinsCjsModule::UpdateChildren), reinterpret_cast(BuiltinsCjsModule::ResolveFilename), reinterpret_cast(BuiltinsCjsRequire::CjsRequireConstructor), reinterpret_cast(BuiltinsCjsRequire::Main), reinterpret_cast(BuiltinsCjsRequire::Resolve), reinterpret_cast(ArkTools::ObjectDump), reinterpret_cast(ArkTools::CompareHClass), reinterpret_cast(ArkTools::DumpHClass), // non ECMA standard jsapi containers. reinterpret_cast(ContainersPrivate::Load), reinterpret_cast(ArrayList::ArrayListConstructor), reinterpret_cast(ArrayList::Add), reinterpret_cast(ArrayList::Insert), reinterpret_cast(ArrayList::Clear), reinterpret_cast(ArrayList::Clone), reinterpret_cast(ArrayList::Has), reinterpret_cast(ArrayList::GetCapacity), reinterpret_cast(ArrayList::IncreaseCapacityTo), reinterpret_cast(ArrayList::TrimToCurrentLength), reinterpret_cast(ArrayList::GetIndexOf), reinterpret_cast(ArrayList::IsEmpty), reinterpret_cast(ArrayList::GetLastIndexOf), reinterpret_cast(ArrayList::RemoveByIndex), reinterpret_cast(ArrayList::Remove), reinterpret_cast(ArrayList::RemoveByRange), reinterpret_cast(ArrayList::ReplaceAllElements), reinterpret_cast(ArrayList::SubArrayList), reinterpret_cast(ArrayList::ConvertToArray), reinterpret_cast(ArrayList::ForEach), reinterpret_cast(ArrayList::GetIteratorObj), reinterpret_cast(ArrayList::Get), reinterpret_cast(ArrayList::Set), reinterpret_cast(ArrayList::GetSize), reinterpret_cast(JSAPIArrayListIterator::Next), reinterpret_cast(HashMap::HashMapConstructor), reinterpret_cast(HashMap::HasKey), reinterpret_cast(HashMap::HasValue), reinterpret_cast(HashMap::Replace), reinterpret_cast(HashMap::Keys), reinterpret_cast(HashMap::Values), reinterpret_cast(HashMap::Entries), reinterpret_cast(HashMap::ForEach), reinterpret_cast(HashMap::Set), reinterpret_cast(HashMap::SetAll), reinterpret_cast(HashMap::Remove), reinterpret_cast(HashMap::Get), reinterpret_cast(HashMap::Clear), reinterpret_cast(HashMap::GetLength), reinterpret_cast(HashMap::IsEmpty), reinterpret_cast(HashSet::HashSetConstructor), reinterpret_cast(HashSet::IsEmpty), reinterpret_cast(HashSet::Has), reinterpret_cast(HashSet::Add), reinterpret_cast(HashSet::Remove), reinterpret_cast(HashSet::Clear), reinterpret_cast(HashSet::GetLength), reinterpret_cast(HashSet::Values), reinterpret_cast(HashSet::Entries), reinterpret_cast(JSAPIHashMapIterator::Next), reinterpret_cast(JSAPIHashSetIterator::Next), reinterpret_cast(LightWeightMap::HasAll), reinterpret_cast(LightWeightMap::HasKey), reinterpret_cast(LightWeightMap::HasValue), reinterpret_cast(LightWeightMap::IncreaseCapacityTo), reinterpret_cast(LightWeightMap::Entries), reinterpret_cast(LightWeightMap::Get), reinterpret_cast(LightWeightMap::GetIndexOfKey), reinterpret_cast(LightWeightMap::GetIndexOfValue), reinterpret_cast(LightWeightMap::IsEmpty), reinterpret_cast(LightWeightMap::GetKeyAt), reinterpret_cast(LightWeightMap::Keys), reinterpret_cast(LightWeightMap::SetAll), reinterpret_cast(LightWeightMap::Set), reinterpret_cast(LightWeightMap::Remove), reinterpret_cast(LightWeightMap::RemoveAt), reinterpret_cast(LightWeightMap::Clear), reinterpret_cast(LightWeightMap::SetValueAt), reinterpret_cast(LightWeightMap::ForEach), reinterpret_cast(LightWeightMap::ToString), reinterpret_cast(LightWeightMap::GetValueAt), reinterpret_cast(LightWeightMap::Values), reinterpret_cast(JSAPILightWeightMapIterator::Next), reinterpret_cast(LightWeightSet::LightWeightSetConstructor), reinterpret_cast(LightWeightSet::Add), reinterpret_cast(LightWeightSet::AddAll), reinterpret_cast(LightWeightSet::IsEmpty), reinterpret_cast(LightWeightSet::GetValueAt), reinterpret_cast(LightWeightSet::HasAll), reinterpret_cast(LightWeightSet::Has), reinterpret_cast(LightWeightSet::HasHash), reinterpret_cast(LightWeightSet::Equal), reinterpret_cast(LightWeightSet::IncreaseCapacityTo), reinterpret_cast(LightWeightSet::GetIteratorObj), reinterpret_cast(LightWeightSet::Values), reinterpret_cast(LightWeightSet::Entries), reinterpret_cast(LightWeightSet::ForEach), reinterpret_cast(LightWeightSet::GetIndexOf), reinterpret_cast(LightWeightSet::Remove), reinterpret_cast(LightWeightSet::RemoveAt), reinterpret_cast(LightWeightSet::Clear), reinterpret_cast(LightWeightSet::ToString), reinterpret_cast(LightWeightSet::ToArray), reinterpret_cast(LightWeightSet::GetSize), reinterpret_cast(JSAPILightWeightSetIterator::Next), reinterpret_cast(TreeMap::TreeMapConstructor), reinterpret_cast(TreeMap::Set), reinterpret_cast(TreeMap::Get), reinterpret_cast(TreeMap::Remove), reinterpret_cast(TreeMap::GetFirstKey), reinterpret_cast(TreeMap::GetLastKey), reinterpret_cast(TreeMap::GetLowerKey), reinterpret_cast(TreeMap::GetHigherKey), reinterpret_cast(TreeMap::HasKey), reinterpret_cast(TreeMap::HasValue), reinterpret_cast(TreeMap::SetAll), reinterpret_cast(TreeMap::Replace), reinterpret_cast(TreeMap::Keys), reinterpret_cast(TreeMap::Values), reinterpret_cast(TreeMap::Entries), reinterpret_cast(TreeMap::ForEach), reinterpret_cast(TreeMap::Clear), reinterpret_cast(TreeMap::IsEmpty), reinterpret_cast(TreeMap::GetLength), reinterpret_cast(TreeSet::TreeSetConstructor), reinterpret_cast(TreeSet::Add), reinterpret_cast(TreeSet::Has), reinterpret_cast(TreeSet::Remove), reinterpret_cast(TreeSet::GetFirstValue), reinterpret_cast(TreeSet::GetLastValue), reinterpret_cast(TreeSet::GetLowerValue), reinterpret_cast(TreeSet::GetHigherValue), reinterpret_cast(TreeSet::PopFirst), reinterpret_cast(TreeSet::PopLast), reinterpret_cast(TreeSet::IsEmpty), reinterpret_cast(TreeSet::Values), reinterpret_cast(TreeSet::Entries), reinterpret_cast(TreeSet::ForEach), reinterpret_cast(TreeSet::Clear), reinterpret_cast(TreeSet::GetLength), reinterpret_cast(JSAPITreeMapIterator::Next), reinterpret_cast(JSAPITreeSetIterator::Next), reinterpret_cast(Deque::DequeConstructor), reinterpret_cast(Deque::InsertFront), reinterpret_cast(Deque::InsertEnd), reinterpret_cast(Deque::GetFirst), reinterpret_cast(Deque::GetLast), reinterpret_cast(Deque::Has), reinterpret_cast(Deque::PopFirst), reinterpret_cast(Deque::PopLast), reinterpret_cast(Deque::ForEach), reinterpret_cast(Deque::GetIteratorObj), reinterpret_cast(Deque::GetSize), reinterpret_cast(JSAPIDequeIterator::Next), reinterpret_cast(Vector::VectorConstructor), reinterpret_cast(Vector::Add), reinterpret_cast(Vector::Insert), reinterpret_cast(Vector::SetLength), reinterpret_cast(Vector::GetCapacity), reinterpret_cast(Vector::IncreaseCapacityTo), reinterpret_cast(Vector::Get), reinterpret_cast(Vector::GetIndexOf), reinterpret_cast(Vector::GetIndexFrom), reinterpret_cast(Vector::IsEmpty), reinterpret_cast(Vector::GetLastElement), reinterpret_cast(Vector::GetLastIndexOf), reinterpret_cast(Vector::GetLastIndexFrom), reinterpret_cast(Vector::Remove), reinterpret_cast(Vector::RemoveByIndex), reinterpret_cast(Vector::RemoveByRange), reinterpret_cast(Vector::Set), reinterpret_cast(Vector::SubVector), reinterpret_cast(Vector::ToString), reinterpret_cast(Vector::GetSize), reinterpret_cast(Vector::ForEach), reinterpret_cast(Vector::ReplaceAllElements), reinterpret_cast(Vector::TrimToCurrentLength), reinterpret_cast(Vector::Clear), reinterpret_cast(Vector::Clone), reinterpret_cast(Vector::Has), reinterpret_cast(Vector::GetFirstElement), reinterpret_cast(Vector::CopyToArray), reinterpret_cast(Vector::ConvertToArray), reinterpret_cast(Vector::Sort), reinterpret_cast(Vector::GetIteratorObj), reinterpret_cast(JSAPIVectorIterator::Next), reinterpret_cast(Queue::QueueConstructor), reinterpret_cast(Queue::Add), reinterpret_cast(Queue::GetFirst), reinterpret_cast(Queue::Pop), reinterpret_cast(Queue::ForEach), reinterpret_cast(Queue::GetIteratorObj), reinterpret_cast(Queue::GetSize), reinterpret_cast(JSAPIQueueIterator::Next), reinterpret_cast(PlainArray::PlainArrayConstructor), reinterpret_cast(PlainArray::Add), reinterpret_cast(PlainArray::Clear), reinterpret_cast(PlainArray::Clone), reinterpret_cast(PlainArray::Has), reinterpret_cast(PlainArray::Get), reinterpret_cast(PlainArray::GetIteratorObj), reinterpret_cast(PlainArray::ForEach), reinterpret_cast(PlainArray::ToString), reinterpret_cast(PlainArray::GetIndexOfKey), reinterpret_cast(PlainArray::GetIndexOfValue), reinterpret_cast(PlainArray::IsEmpty), reinterpret_cast(PlainArray::GetKeyAt), reinterpret_cast(PlainArray::Remove), reinterpret_cast(PlainArray::RemoveAt), reinterpret_cast(PlainArray::RemoveRangeFrom), reinterpret_cast(PlainArray::SetValueAt), reinterpret_cast(PlainArray::GetValueAt), reinterpret_cast(PlainArray::GetSize), reinterpret_cast(JSAPIPlainArrayIterator::Next), reinterpret_cast(ContainerStack::StackConstructor), reinterpret_cast(ContainerStack::Iterator), reinterpret_cast(ContainerStack::IsEmpty), reinterpret_cast(ContainerStack::Push), reinterpret_cast(ContainerStack::Peek), reinterpret_cast(ContainerStack::Pop), reinterpret_cast(ContainerStack::Locate), reinterpret_cast(ContainerStack::ForEach), reinterpret_cast(ContainerStack::GetLength), reinterpret_cast(JSAPIStackIterator::Next), reinterpret_cast(List::ListConstructor), reinterpret_cast(List::Add), reinterpret_cast(List::GetFirst), reinterpret_cast(List::GetLast), reinterpret_cast(List::Insert), reinterpret_cast(List::Clear), reinterpret_cast(List::RemoveByIndex), reinterpret_cast(List::Remove), reinterpret_cast(List::Has), reinterpret_cast(List::IsEmpty), reinterpret_cast(List::Get), reinterpret_cast(List::GetIndexOf), reinterpret_cast(List::GetLastIndexOf), reinterpret_cast(List::Set), reinterpret_cast(List::ForEach), reinterpret_cast(List::ReplaceAllElements), reinterpret_cast(List::GetIteratorObj), reinterpret_cast(List::Equal), reinterpret_cast(List::Sort), reinterpret_cast(List::ConvertToArray), reinterpret_cast(List::GetSubList), reinterpret_cast(List::Length), reinterpret_cast(JSAPIListIterator::Next), reinterpret_cast(LinkedList::LinkedListConstructor), reinterpret_cast(LinkedList::Add), reinterpret_cast(LinkedList::GetFirst), reinterpret_cast(LinkedList::GetLast), reinterpret_cast(LinkedList::Insert), reinterpret_cast(LinkedList::AddFirst), reinterpret_cast(LinkedList::Clear), reinterpret_cast(LinkedList::Clone), reinterpret_cast(LinkedList::Has), reinterpret_cast(LinkedList::Get), reinterpret_cast(LinkedList::GetIndexOf), reinterpret_cast(LinkedList::GetLastIndexOf), reinterpret_cast(LinkedList::RemoveByIndex), reinterpret_cast(LinkedList::Remove), reinterpret_cast(LinkedList::RemoveFirst), reinterpret_cast(LinkedList::RemoveLast), reinterpret_cast(LinkedList::RemoveFirstFound), reinterpret_cast(LinkedList::RemoveLastFound), reinterpret_cast(LinkedList::Set), reinterpret_cast(LinkedList::ConvertToArray), reinterpret_cast(LinkedList::ForEach), reinterpret_cast(JSAPILinkedListIterator::Next), // not builtins method reinterpret_cast(JSFunction::PrototypeSetter), reinterpret_cast(JSFunction::PrototypeGetter), reinterpret_cast(JSFunction::NameGetter), reinterpret_cast(JSArray::LengthSetter), reinterpret_cast(JSArray::LengthGetter), reinterpret_cast(JSPandaFileManager::GetInstance) }; void SnapshotProcessor::Initialize() { auto heap = const_cast(vm_->GetHeap()); size_t oldSpaceCapacity = heap->GetOldSpace()->GetInitialCapacity(); oldLocalSpace_ = new LocalSpace(heap, oldSpaceCapacity, oldSpaceCapacity); size_t nonMovableCapacity = heap->GetNonMovableSpace()->GetInitialCapacity(); nonMovableLocalSpace_ = new LocalSpace(heap, nonMovableCapacity, nonMovableCapacity); size_t machineCodeCapacity = heap->GetMachineCodeSpace()->GetInitialCapacity(); machineCodeLocalSpace_ = new LocalSpace(heap, machineCodeCapacity, machineCodeCapacity); size_t snapshotSpaceCapacity = heap->GetSnapshotSpace()->GetMaximumCapacity(); snapshotLocalSpace_ = new SnapshotSpace(heap, snapshotSpaceCapacity, snapshotSpaceCapacity); hugeObjectLocalSpace_ = new HugeObjectSpace(heap, heap->GetHeapRegionAllocator(), oldSpaceCapacity, oldSpaceCapacity); } SnapshotProcessor::~SnapshotProcessor() { pandaMethod_.clear(); stringVector_.clear(); regionIndexMap_.clear(); if (oldLocalSpace_ != nullptr) { oldLocalSpace_->Reset(); delete oldLocalSpace_; oldLocalSpace_ = nullptr; } if (nonMovableLocalSpace_ != nullptr) { nonMovableLocalSpace_->Reset(); delete nonMovableLocalSpace_; nonMovableLocalSpace_ = nullptr; } if (machineCodeLocalSpace_ != nullptr) { machineCodeLocalSpace_->Reset(); delete machineCodeLocalSpace_; machineCodeLocalSpace_ = nullptr; } if (snapshotLocalSpace_ != nullptr) { snapshotLocalSpace_->Destroy(); delete snapshotLocalSpace_; snapshotLocalSpace_ = nullptr; } if (hugeObjectLocalSpace_ != nullptr) { hugeObjectLocalSpace_->Destroy(); delete hugeObjectLocalSpace_; hugeObjectLocalSpace_ = nullptr; } } void SnapshotProcessor::StopAllocate() { oldLocalSpace_->Stop(); nonMovableLocalSpace_->Stop(); machineCodeLocalSpace_->Stop(); snapshotLocalSpace_->Stop(); } void SnapshotProcessor::WriteObjectToFile(std::fstream &writer) { WriteSpaceObjectToFile(oldLocalSpace_, writer); WriteSpaceObjectToFile(nonMovableLocalSpace_, writer); WriteSpaceObjectToFile(machineCodeLocalSpace_, writer); WriteSpaceObjectToFile(snapshotLocalSpace_, writer); WriteHugeObjectToFile(hugeObjectLocalSpace_, writer); } void SnapshotProcessor::WriteSpaceObjectToFile(Space* space, std::fstream &writer) { size_t regionCount = space->GetRegionCount(); if (regionCount > 0) { size_t alignedRegionObjSize = AlignUp(sizeof(Region), static_cast(MemAlignment::MEM_ALIGN_REGION)); auto lastRegion = space->GetCurrentRegion(); space->EnumerateRegions([&writer, lastRegion, alignedRegionObjSize](Region *current) { if (current != lastRegion) { // fixme: Except for the last region of a space, // currently the snapshot feature assumes that every serialized region must have fixed size. // The original region size plus the aligned region object size should not exceed DEFAULT_REGION_SIZE. // Currently we even harden it to make them exactly equal to avoid writing dirty / invalid data to the // file. Because in the snapshot file the region object and the associated region will be serialized // together to an area which has the fixed size of DEFAULT_REGION_SIZE. // Need to relax this assumption / limitation. ASSERT(alignedRegionObjSize + (current->end_ - ToUintPtr(current->packedData_.markGCBitset_)) == DEFAULT_REGION_SIZE); // Firstly, serialize the region head into the file; writer.write(reinterpret_cast(current), alignedRegionObjSize); // Secondly, write the valid region memory (exclude region head and GC bit set). writer.write(reinterpret_cast(current->packedData_.begin_), ToUintPtr(current) + DEFAULT_REGION_SIZE - current->packedData_.begin_); writer.flush(); } }); // Firstly, serialize the region object into the file; writer.write(reinterpret_cast(lastRegion), alignedRegionObjSize); // Secondly, write the valid region memory (exclude region head and GC bit set). writer.write(reinterpret_cast(lastRegion->packedData_.begin_), lastRegion->highWaterMark_ - lastRegion->packedData_.begin_); writer.flush(); } } void SnapshotProcessor::WriteHugeObjectToFile(HugeObjectSpace* space, std::fstream &writer) { size_t alignedRegionObjSize = AlignUp(sizeof(Region), static_cast(MemAlignment::MEM_ALIGN_REGION)); size_t hugeRegionHeadSize = AlignUp(alignedRegionObjSize + GCBitset::BYTE_PER_WORD, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); space->EnumerateRegions([&hugeRegionHeadSize, &writer](Region *region) { size_t objSize = hugeRegionHeadSize; uint64_t snapshotData = region->GetSnapshotData(); // huge object size is storaged in region param snapshotMark_ high 32 bits objSize += SnapshotHelper::GetHugeObjectSize(snapshotData); writer.write(reinterpret_cast(region), objSize); writer.flush(); }); } std::vector SnapshotProcessor::StatisticsObjectSize() { std::vector objSizeVector; objSizeVector.emplace_back(StatisticsSpaceObjectSize(oldLocalSpace_)); objSizeVector.emplace_back(StatisticsSpaceObjectSize(nonMovableLocalSpace_)); objSizeVector.emplace_back(StatisticsSpaceObjectSize(machineCodeLocalSpace_)); objSizeVector.emplace_back(StatisticsSpaceObjectSize(snapshotLocalSpace_)); objSizeVector.emplace_back(StatisticsHugeObjectSize(hugeObjectLocalSpace_)); return objSizeVector; } uint32_t SnapshotProcessor::StatisticsSpaceObjectSize(Space* space) { size_t regionCount = space->GetRegionCount(); size_t objSize = 0U; if (regionCount > 0) { auto lastRegion = space->GetCurrentRegion(); size_t alignedRegionObjSize = AlignUp(sizeof(Region), static_cast(MemAlignment::MEM_ALIGN_REGION)); size_t lastRegionSize = lastRegion->highWaterMark_ - lastRegion->packedData_.begin_; // fixme: Except for the last region of a space, // currently the snapshot feature assumes that every serialized region must have fixed size. // The original region size plus the aligned region object size should not exceed DEFAULT_REGION_SIZE. // Because in the snapshot file the region object and the associated region will be serialized // together to an area which has the fixed size of DEFAULT_REGION_SIZE. // Need to relax this assumption / limitation. objSize = (regionCount - 1) * (DEFAULT_REGION_SIZE - GetMarkGCBitSetSize()) + alignedRegionObjSize + lastRegionSize; } ASSERT(objSize <= Constants::MAX_UINT_32); return static_cast(objSize); } uint32_t SnapshotProcessor::StatisticsHugeObjectSize(HugeObjectSpace* space) { size_t objSize = 0U; size_t alignedRegionObjSize = AlignUp(sizeof(Region), static_cast(MemAlignment::MEM_ALIGN_REGION)); size_t hugeRegionHeadSize = AlignUp(alignedRegionObjSize + GCBitset::BYTE_PER_WORD, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); space->EnumerateRegions([&objSize, &hugeRegionHeadSize](Region *region) { objSize += hugeRegionHeadSize; uint64_t snapshotData = region->GetSnapshotData(); // huge object size is storaged in region param snapshotData_ high 32 bits objSize += SnapshotHelper::GetHugeObjectSize(snapshotData); }); return static_cast(objSize); } void SnapshotProcessor::ProcessObjectQueue(CQueue *queue, std::unordered_map *data) { while (!queue->empty()) { auto taggedObject = queue->front(); if (taggedObject == nullptr) { break; } queue->pop(); SerializeObject(taggedObject, queue, data); } StopAllocate(); } uintptr_t SnapshotProcessor::AllocateObjectToLocalSpace(Space *space, size_t objectSize) { uintptr_t newObj = 0; if (space->GetSpaceType() == MemSpaceType::HUGE_OBJECT_SPACE) { newObj = reinterpret_cast(space)->Allocate(objectSize, vm_->GetAssociatedJSThread()); } else if (space->GetSpaceType() == MemSpaceType::SNAPSHOT_SPACE) { newObj = reinterpret_cast(space)->Allocate(objectSize); } else { newObj = reinterpret_cast(space)->Allocate(objectSize); } auto current = space->GetCurrentRegion(); if (newObj == current->GetBegin()) { // region param snapshotData_ low 32 bits is reused to record regionIndex uint64_t snapshotData = regionIndex_; if (current->InHugeObjectSpace()) { // region param snapshotData_ high 32 bits is reused to record huge object size snapshotData += SnapshotHelper::EncodeHugeObjectSize(objectSize); } current->SetSnapshotData(snapshotData); regionIndex_++; } return newObj; } void SnapshotProcessor::SetObjectEncodeField(uintptr_t obj, size_t offset, uint64_t value) { *reinterpret_cast(obj + offset) = value; } void SnapshotProcessor::DeserializeObjectExcludeString(uintptr_t oldSpaceBegin, size_t oldSpaceObjSize, size_t nonMovableObjSize, size_t machineCodeObjSize, size_t snapshotObjSize, size_t hugeSpaceObjSize) { uintptr_t nonMovableBegin = oldSpaceBegin + oldSpaceObjSize; uintptr_t machineCodeBegin = nonMovableBegin + nonMovableObjSize; uintptr_t snapshotBegin = machineCodeBegin + machineCodeObjSize; uintptr_t hugeObjBegin = snapshotBegin + snapshotObjSize; auto heap = vm_->GetHeap(); auto oldSpace = heap->GetOldSpace(); auto nonMovableSpace = heap->GetNonMovableSpace(); auto machineCodeSpace = heap->GetMachineCodeSpace(); auto snapshotSpace = heap->GetSnapshotSpace(); auto hugeObjectSpace = heap->GetHugeObjectSpace(); DeserializeSpaceObject(oldSpaceBegin, oldSpace, oldSpaceObjSize); DeserializeSpaceObject(nonMovableBegin, nonMovableSpace, nonMovableObjSize); DeserializeSpaceObject(machineCodeBegin, machineCodeSpace, machineCodeObjSize); DeserializeSpaceObject(snapshotBegin, snapshotSpace, snapshotObjSize); DeserializeHugeSpaceObject(hugeObjBegin, hugeObjectSpace, hugeSpaceObjSize); snapshotSpace->ResetAllocator(); } void SnapshotProcessor::DeserializeSpaceObject(uintptr_t beginAddr, Space* space, size_t spaceObjSize) { size_t numberOfRegions = 0U; if (spaceObjSize != 0) { numberOfRegions = (spaceObjSize - 1) / (DEFAULT_REGION_SIZE - GetMarkGCBitSetSize()) + 1; // round up } for (size_t i = 0; i < numberOfRegions; i++) { Region *region = vm_->GetHeapRegionAllocator()->AllocateAlignedRegion( space, DEFAULT_REGION_SIZE, vm_->GetAssociatedJSThread()); auto fileRegion = ToNativePtr(beginAddr + i * (DEFAULT_REGION_SIZE - GetMarkGCBitSetSize())); uintptr_t objectBeginAddr = ToUintPtr(fileRegion) + AlignUp(sizeof(Region), static_cast(MemAlignment::MEM_ALIGN_REGION)); // region snapshotData_ is used to record region index for snapshot size_t regionIndex = fileRegion->GetSnapshotData(); size_t liveObjectSize = 0; if (space->GetSpaceType() == MemSpaceType::SNAPSHOT_SPACE) { liveObjectSize = fileRegion->highWaterMark_ - fileRegion->packedData_.begin_; ASSERT(liveObjectSize <= region->end_ - region->packedData_.begin_); } else { liveObjectSize = fileRegion->AliveObject(); } regionIndexMap_.emplace(regionIndex, region); ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast(region->packedData_.begin_), liveObjectSize); if (memcpy_s(ToVoidPtr(region->packedData_.begin_), liveObjectSize, ToVoidPtr(objectBeginAddr), liveObjectSize) != EOK) { LOG_FULL(FATAL) << "memcpy_s failed"; UNREACHABLE(); } // Other information like aliveObject size, highWaterMark etc. in the region object to restore. region->aliveObject_ = liveObjectSize; region->highWaterMark_ = region->packedData_.begin_ + liveObjectSize; region->SetGCFlag(RegionGCFlags::NEED_RELOCATE); if (space->GetSpaceType() != MemSpaceType::SNAPSHOT_SPACE) { auto sparseSpace = reinterpret_cast(space); region->InitializeFreeObjectSets(); sparseSpace->FreeLiveRange(region, region->GetHighWaterMark(), region->GetEnd(), true); sparseSpace->IncreaseLiveObjectSize(liveObjectSize); sparseSpace->IncreaseAllocatedSize(liveObjectSize); sparseSpace->AddRegion(region); } else { auto snapshotSpace = reinterpret_cast(space); snapshotSpace->IncreaseLiveObjectSize(liveObjectSize); snapshotSpace->AddRegion(region); } } } void SnapshotProcessor::DeserializeHugeSpaceObject(uintptr_t beginAddr, HugeObjectSpace* space, size_t hugeSpaceObjSize) { uintptr_t currentAddr = beginAddr; uintptr_t endAddr = beginAddr + hugeSpaceObjSize; while (currentAddr < endAddr) { auto fileRegion = ToNativePtr(currentAddr); uintptr_t oldMarkGCBitsetAddr = ToUintPtr(fileRegion) + AlignUp(sizeof(Region), static_cast(MemAlignment::MEM_ALIGN_REGION)); // Retrieve the data beginning address based on the serialized data format. uintptr_t copyFrom = oldMarkGCBitsetAddr + (fileRegion->packedData_.begin_ - ToUintPtr(fileRegion->packedData_.markGCBitset_)); // region snapshotData_ is used to record region index for snapshot uint64_t snapshotData = fileRegion->GetSnapshotData(); // high 32 bits storage huge object size size_t objSize = SnapshotHelper::GetHugeObjectSize(snapshotData); size_t alignedHugeRegionSize = AlignUp(objSize + sizeof(Region), PANDA_POOL_ALIGNMENT_IN_BYTES); Region *region = vm_->GetHeapRegionAllocator()->AllocateAlignedRegion( space, alignedHugeRegionSize, vm_->GetAssociatedJSThread()); // low 32 bits storage regionIndex size_t regionIndex = SnapshotHelper::GetHugeObjectRegionIndex(snapshotData); regionIndexMap_.emplace(regionIndex, region); ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast(region->packedData_.begin_), objSize); if (memcpy_s(ToVoidPtr(region->packedData_.begin_), objSize, ToVoidPtr(copyFrom), objSize) != EOK) { LOG_FULL(FATAL) << "memcpy_s failed"; UNREACHABLE(); } // Other information like aliveObject size, highWaterMark etc. in the region object to restore. region->aliveObject_ = objSize; region->highWaterMark_ = region->packedData_.begin_ + objSize; region->SetGCFlag(RegionGCFlags::NEED_RELOCATE); space->AddRegion(region); currentAddr += (fileRegion->packedData_.begin_ - fileRegion->allocateBase_); currentAddr += objSize; } } void SnapshotProcessor::DeserializeString(uintptr_t stringBegin, uintptr_t stringEnd) { EcmaStringTable *stringTable = vm_->GetEcmaStringTable(); ASSERT(stringVector_.empty()); auto oldSpace = const_cast(vm_->GetHeap())->GetOldSpace(); auto hugeSpace = const_cast(vm_->GetHeap())->GetHugeObjectSpace(); auto globalConst = const_cast(vm_->GetJSThread()->GlobalConstants()); auto stringClass = globalConst->GetStringClass(); while (stringBegin < stringEnd) { EcmaString *str = reinterpret_cast(stringBegin); size_t strSize = EcmaStringAccessor(str).ObjectSize(); strSize = AlignUp(strSize, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); auto strFromTable = stringTable->GetString(str); if (strFromTable) { stringVector_.emplace_back(ToUintPtr(strFromTable)); } else { uintptr_t newObj = 0; if (UNLIKELY(strSize > MAX_REGULAR_HEAP_OBJECT_SIZE)) { newObj = hugeSpace->Allocate(strSize, vm_->GetJSThread()); } else { newObj = oldSpace->Allocate(strSize, false); } if (newObj == 0) { LOG_ECMA_MEM(FATAL) << "Snapshot Allocate OldLocalSpace OOM"; UNREACHABLE(); } if (memcpy_s(ToVoidPtr(newObj), strSize, str, strSize) != EOK) { LOG_FULL(FATAL) << "memcpy_s failed"; UNREACHABLE(); } str = reinterpret_cast(newObj); str->SetClass(reinterpret_cast(stringClass.GetTaggedObject())); EcmaStringAccessor(str).ClearInternString(); stringTable->GetOrInternString(str); stringVector_.emplace_back(newObj); } stringBegin += strSize; } } void SnapshotProcessor::DeserializePandaMethod(uintptr_t begin, uintptr_t end, MethodLiteral *methods, size_t &methodNums, size_t &others) { for (size_t i = 0; i < others; i++) { pandaMethod_.emplace_back(begin); auto method = reinterpret_cast(begin); if (memcpy_s(methods + (--methodNums), Method::Size(), method, Method::Size()) != EOK) { LOG_FULL(FATAL) << "memcpy_s failed"; UNREACHABLE(); } begin += Method::Size(); if (begin >= end) { others = others - i - 1; } } } void SnapshotProcessor::HandleRootObject(SnapshotType type, uintptr_t rootObjectAddr, size_t objType, size_t &constSpecialIndex) { switch (type) { case SnapshotType::VM_ROOT: { if (JSType(objType) == JSType::GLOBAL_ENV) { vm_->SetGlobalEnv(reinterpret_cast(rootObjectAddr)); } else if (JSType(objType) == JSType::MICRO_JOB_QUEUE) { vm_->SetMicroJobQueue(reinterpret_cast(rootObjectAddr)); } break; } case SnapshotType::BUILTINS: { JSTaggedValue result(static_cast(rootObjectAddr)); auto constants = const_cast(vm_->GetJSThread()->GlobalConstants()); size_t constCount = constants->GetConstantCount(); while (constants->IsSpecialOrUndefined(constSpecialIndex)) { constSpecialIndex++; // Skip special or undefined value } if (constSpecialIndex < constCount) { constants->SetConstant(ConstantIndex(constSpecialIndex), result); } else { vm_->SetGlobalEnv(reinterpret_cast(rootObjectAddr)); } constSpecialIndex++; break; } case SnapshotType::AI: { JSTaggedValue item = JSTaggedValue(static_cast(rootObjectAddr)); if (!isRootObjRelocate_ && item.IsTaggedArray()) { vm_->GetAOTFileManager()->AddConstantPool(fileName_, item); isRootObjRelocate_ = true; } break; } default: break; } } void SnapshotProcessor::SerializeObject(TaggedObject *objectHeader, CQueue *queue, std::unordered_map *data) { auto hclass = objectHeader->GetClass(); JSType objectType = hclass->GetObjectType(); uintptr_t snapshotObj = 0; if (UNLIKELY(data->find(ToUintPtr(objectHeader)) == data->end())) { LOG_FULL(FATAL) << "Data map can not find object"; UNREACHABLE(); } else { snapshotObj = data->find(ToUintPtr(objectHeader))->second.first; } // header EncodeBit encodeBit = SerializeObjectHeader(objectHeader, static_cast(objectType), queue, data); SetObjectEncodeField(snapshotObj, 0, encodeBit.GetValue()); auto visitor = [this, snapshotObj, queue, data](TaggedObject *root, ObjectSlot start, ObjectSlot end, bool isNative) { for (ObjectSlot slot = start; slot < end; slot++) { if (isNative) { auto nativePointer = *reinterpret_cast(slot.SlotAddress()); SetObjectEncodeField(snapshotObj, slot.SlotAddress() - ToUintPtr(root), NativePointerToEncodeBit(nativePointer).GetValue()); } else { auto fieldAddr = reinterpret_cast(slot.SlotAddress()); SetObjectEncodeField(snapshotObj, slot.SlotAddress() - ToUintPtr(root), SerializeTaggedField(fieldAddr, queue, data)); } } }; objXRay_.VisitObjectBody(objectHeader, objectHeader->GetClass(), visitor); } void SnapshotProcessor::Relocate(SnapshotType type, const JSPandaFile *jsPandaFile, uint64_t rootObjSize) { size_t methodNums = 0; MethodLiteral *methods = nullptr; if (jsPandaFile) { methodNums = jsPandaFile->GetNumMethods(); methods = jsPandaFile->GetMethodLiterals(); } auto heap = vm_->GetHeap(); auto oldSpace = heap->GetOldSpace(); auto nonMovableSpace = heap->GetNonMovableSpace(); auto machineCodeSpace = heap->GetMachineCodeSpace(); auto snapshotSpace = heap->GetSnapshotSpace(); auto hugeObjectSpace = heap->GetHugeObjectSpace(); RelocateSpaceObject(oldSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(nonMovableSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(machineCodeSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(snapshotSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(hugeObjectSpace, type, methods, methodNums, rootObjSize); } void SnapshotProcessor::RelocateSpaceObject(Space* space, SnapshotType type, MethodLiteral* methods, size_t methodNums, size_t rootObjSize) { size_t others = 0; size_t objIndex = 0; size_t constSpecialIndex = 0; EcmaStringTable *stringTable = vm_->GetEcmaStringTable(); space->EnumerateRegions([stringTable, &others, &objIndex, &rootObjSize, &constSpecialIndex, &type, this, methods, &methodNums](Region *current) { if (!current->NeedRelocate()) { return; } current->ClearGCFlag(RegionGCFlags::NEED_RELOCATE); size_t allocated = current->GetAllocatedBytes(); uintptr_t begin = current->GetBegin(); uintptr_t end = begin + allocated; while (begin < end) { if (others != 0) { DeserializePandaMethod(begin, end, methods, methodNums, others); break; } EncodeBit encodeBit(*reinterpret_cast(begin)); auto objType = encodeBit.GetObjectType(); if (objType == Constants::MASK_METHOD_SPACE_BEGIN) { begin += sizeof(uint64_t); others = encodeBit.GetNativePointerOrObjectIndex(); DeserializePandaMethod(begin, end, methods, methodNums, others); break; } TaggedObject *objectHeader = reinterpret_cast(begin); DeserializeClassWord(objectHeader); DeserializeField(objectHeader); if (builtinsDeserialize_ && JSType(objType) == JSType::STRING) { auto str = reinterpret_cast(begin); EcmaStringAccessor(str).ClearInternString(); stringTable->InsertStringIfNotExist(str); } if (objIndex < rootObjSize) { HandleRootObject(type, begin, objType, constSpecialIndex); } begin = begin + AlignUp(objectHeader->GetClass()->SizeFromJSHClass(objectHeader), static_cast(MemAlignment::MEM_ALIGN_OBJECT)); objIndex++; } }); } EncodeBit SnapshotProcessor::SerializeObjectHeader(TaggedObject *objectHeader, size_t objectType, CQueue *queue, std::unordered_map *data) { auto hclass = objectHeader->GetClass(); ASSERT(hclass != nullptr); EncodeBit encodeBit(0); if (data->find(ToUintPtr(hclass)) == data->end()) { encodeBit = EncodeTaggedObject(hclass, queue, data); } else { ObjectEncode objectEncodePair = data->find(ToUintPtr(hclass))->second; encodeBit = objectEncodePair.second; } encodeBit.SetObjectType(objectType); return encodeBit; } uint64_t SnapshotProcessor::SerializeTaggedField(JSTaggedType *tagged, CQueue *queue, std::unordered_map *data) { JSTaggedValue taggedValue(*tagged); if (taggedValue.IsWeak()) { EncodeBit special(JSTaggedValue::Undefined().GetRawData()); special.SetObjectSpecial(); return special.GetValue(); } if (taggedValue.IsSpecial()) { EncodeBit special(taggedValue.GetRawData()); special.SetObjectSpecial(); return special.GetValue(); // special encode bit } if (!taggedValue.IsHeapObject()) { return taggedValue.GetRawData(); // not object } EncodeBit encodeBit(0); if (data->find(*tagged) == data->end()) { encodeBit = EncodeTaggedObject(taggedValue.GetTaggedObject(), queue, data); } else { ObjectEncode objectEncodePair = data->find(taggedValue.GetRawData())->second; encodeBit = objectEncodePair.second; } if (taggedValue.IsString()) { encodeBit.SetReferenceToString(true); } return encodeBit.GetValue(); // object } void SnapshotProcessor::DeserializeTaggedField(uint64_t *value, TaggedObject *root) { EncodeBit encodeBit(*value); if (!builtinsDeserialize_ && encodeBit.IsReference() && encodeBit.IsGlobalConstOrBuiltins()) { size_t index = encodeBit.GetNativePointerOrObjectIndex(); *value = vm_->GetSnapshotEnv()->FindEnvObjectByIndex(index); return; } if (!encodeBit.IsReference()) { return; } if (encodeBit.IsReference() && !encodeBit.IsSpecial()) { Region *rootRegion = Region::ObjectAddressToRange(ToUintPtr(root)); uintptr_t taggedObjectAddr = TaggedObjectEncodeBitToAddr(encodeBit); Region *valueRegion = Region::ObjectAddressToRange(taggedObjectAddr); if (!rootRegion->InYoungSpace() && valueRegion->InYoungSpace()) { // Should align with '8' in 64 and 32 bit platform ASSERT((ToUintPtr(value) % static_cast(MemAlignment::MEM_ALIGN_OBJECT)) == 0); rootRegion->InsertOldToNewRSet((uintptr_t)value); } *value = taggedObjectAddr; return; } if (encodeBit.IsSpecial()) { encodeBit.ClearObjectSpecialFlag(); *value = encodeBit.GetValue(); } } void SnapshotProcessor::DeserializeClassWord(TaggedObject *object) { EncodeBit encodeBit(*reinterpret_cast(object)); if (!builtinsDeserialize_ && encodeBit.IsGlobalConstOrBuiltins()) { size_t hclassIndex = encodeBit.GetNativePointerOrObjectIndex(); auto globalConst = const_cast(vm_->GetJSThread()->GlobalConstants()); JSTaggedValue hclassValue = globalConst->GetGlobalConstantObject(hclassIndex); ASSERT(hclassValue.IsJSHClass()); object->SetClass(JSHClass::Cast(hclassValue.GetTaggedObject())); return; } uintptr_t hclassAddr = TaggedObjectEncodeBitToAddr(encodeBit); object->SetClass(reinterpret_cast(hclassAddr)); } void SnapshotProcessor::DeserializeField(TaggedObject *objectHeader) { auto visitor = [this]([[maybe_unused]] TaggedObject *root, ObjectSlot start, ObjectSlot end, bool isNative) { for (ObjectSlot slot = start; slot < end; slot++) { auto encodeBitAddr = reinterpret_cast(slot.SlotAddress()); if (isNative) { DeserializeNativePointer(encodeBitAddr); } else { DeserializeTaggedField(encodeBitAddr, root); } } }; objXRay_.VisitObjectBody(objectHeader, objectHeader->GetClass(), visitor); } EncodeBit SnapshotProcessor::NativePointerToEncodeBit(void *nativePointer) { EncodeBit native(0); if (nativePointer != nullptr) { // nativePointer size_t index = Constants::MAX_C_POINTER_INDEX; if (programSerialize_) { pandaMethod_.emplace_back(ToUintPtr(nativePointer)); ASSERT(pandaMethod_.size() + GetNativeTableSize() <= Constants::MAX_UINT_16); // NOLINTNEXTLINE(bugprone-narrowing-conversions, cppcoreguidelines-narrowing-conversions) index = pandaMethod_.size() + GetNativeTableSize() - 1; } else { index = SearchNativeMethodIndex(nativePointer); } LOG_ECMA_IF(index > Constants::MAX_C_POINTER_INDEX, FATAL) << "MAX_C_POINTER_INDEX: " << index; native.SetNativePointerOrObjectIndex(index); } return native; } size_t SnapshotProcessor::SearchNativeMethodIndex(void *nativePointer) { for (size_t i = 0; i < GetNativeTableSize(); i++) { if (nativePointer == reinterpret_cast(g_nativeTable[i])) { return i; } } // not found LOG_FULL(FATAL) << "native method did not register in g_table, please register it first"; UNREACHABLE(); } uintptr_t SnapshotProcessor::TaggedObjectEncodeBitToAddr(EncodeBit taggedBit) { ASSERT(taggedBit.IsReference()); if (!builtinsDeserialize_ && taggedBit.IsReferenceToString()) { size_t stringIndex = taggedBit.GetNativePointerOrObjectIndex(); return stringVector_[stringIndex]; } size_t regionIndex = taggedBit.GetRegionIndex(); if (UNLIKELY(regionIndexMap_.find(regionIndex) == regionIndexMap_.end())) { LOG_FULL(FATAL) << "Snapshot deserialize can not find region by index"; } Region *region = regionIndexMap_.find(regionIndex)->second; size_t objectOffset = taggedBit.GetObjectOffsetInRegion(); return ToUintPtr(region) + objectOffset; } void SnapshotProcessor::DeserializeNativePointer(uint64_t *value) { EncodeBit native(*value); size_t index = native.GetNativePointerOrObjectIndex(); uintptr_t addr = 0U; size_t nativeTableSize = GetNativeTableSize(); if (index < nativeTableSize) { addr = g_nativeTable[index]; } else { addr = pandaMethod_.at(index - nativeTableSize); } *value = addr; } void SnapshotProcessor::SerializePandaFileMethod() { EncodeBit encodeBit(pandaMethod_.size()); encodeBit.SetObjectType(Constants::MASK_METHOD_SPACE_BEGIN); ObjectFactory *factory = vm_->GetFactory(); // panda method space begin uintptr_t snapshotObj = factory->NewSpaceBySnapshotAllocator(sizeof(uint64_t)); if (snapshotObj == 0) { LOG_ECMA(ERROR) << "SnapshotAllocator OOM"; return; } SetObjectEncodeField(snapshotObj, 0, encodeBit.GetValue()); // methods // panda methods for (auto &it : pandaMethod_) { // write method size_t methodObjSize = Method::Size(); uintptr_t methodObj = factory->NewSpaceBySnapshotAllocator(methodObjSize); if (methodObj == 0) { LOG_ECMA(ERROR) << "SnapshotAllocator OOM"; return; } if (memcpy_s(ToVoidPtr(methodObj), methodObjSize, ToVoidPtr(it), Method::Size()) != EOK) { LOG_FULL(FATAL) << "memcpy_s failed"; UNREACHABLE(); } } } EncodeBit SnapshotProcessor::EncodeTaggedObject(TaggedObject *objectHeader, CQueue *queue, std::unordered_map *data) { if (!builtinsSerialize_) { // String duplicate if (objectHeader->GetClass()->GetObjectType() == JSType::STRING) { ASSERT(stringVector_.size() < Constants::MAX_OBJECT_INDEX); EncodeBit encodeBit(stringVector_.size()); stringVector_.emplace_back(ToUintPtr(objectHeader)); data->emplace(ToUintPtr(objectHeader), std::make_pair(0U, encodeBit)); return encodeBit; } // builtins object reuse if (objectHeader->GetClass()->IsGlobalConstOrBuiltinsObject()) { size_t index = vm_->GetSnapshotEnv()->GetEnvObjectIndex(ToUintPtr(objectHeader)); if (index != SnapshotEnv::MAX_UINT_32) { EncodeBit encodeBit(index); encodeBit.SetGlobalConstOrBuiltins(); data->emplace(ToUintPtr(objectHeader), std::make_pair(0U, encodeBit)); return encodeBit; } } } queue->emplace(objectHeader); size_t objectSize = objectHeader->GetClass()->SizeFromJSHClass(objectHeader); if (objectSize == 0) { LOG_ECMA_MEM(FATAL) << "It is a zero object. Not Support."; } uintptr_t newObj = 0; if (builtinsSerialize_) { newObj = AllocateObjectToLocalSpace(snapshotLocalSpace_, objectSize); } else { auto region = Region::ObjectAddressToRange(objectHeader); if (region->InYoungOrOldSpace()) { newObj = AllocateObjectToLocalSpace(oldLocalSpace_, objectSize); } else if (region->InMachineCodeSpace()) { newObj = AllocateObjectToLocalSpace(machineCodeLocalSpace_, objectSize); } else if (region->InNonMovableSpace() || region->InReadOnlySpace()) { newObj = AllocateObjectToLocalSpace(nonMovableLocalSpace_, objectSize); } else if (region->InHugeObjectSpace()) { newObj = AllocateObjectToLocalSpace(hugeObjectLocalSpace_, objectSize); } else { newObj = AllocateObjectToLocalSpace(snapshotLocalSpace_, objectSize); } } if (newObj == 0) { LOG_ECMA_MEM(FATAL) << "Snapshot Allocate OOM"; } if (memcpy_s(ToVoidPtr(newObj), objectSize, objectHeader, objectSize) != EOK) { LOG_FULL(FATAL) << "memcpy_s failed"; UNREACHABLE(); } auto currentRegion = Region::ObjectAddressToRange(newObj); // region snapshotData_ low 32 bits is used to record region index for snapshot uint64_t snapshotData = currentRegion->GetSnapshotData(); size_t regionIndex = SnapshotHelper::GetHugeObjectRegionIndex(snapshotData); size_t objOffset = newObj - ToUintPtr(currentRegion); EncodeBit encodeBit(static_cast(regionIndex)); encodeBit.SetObjectOffsetInRegion(objOffset); data->emplace(ToUintPtr(objectHeader), std::make_pair(newObj, encodeBit)); return encodeBit; } void SnapshotProcessor::EncodeTaggedObjectRange(ObjectSlot start, ObjectSlot end, CQueue *queue, std::unordered_map *data) { while (start < end) { JSTaggedValue object(start.GetTaggedType()); start++; if (object.IsHeapObject()) { EncodeBit encodeBit(0); if (data->find(object.GetRawData()) == data->end()) { encodeBit = EncodeTaggedObject(object.GetTaggedObject(), queue, data); } } } } size_t SnapshotProcessor::GetNativeTableSize() const { return sizeof(g_nativeTable) / sizeof(g_nativeTable[0]); } } // namespace panda::ecmascript