/* * 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/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_dataview.h" #include "ecmascript/builtins/builtins_date.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_iterator.h" #include "ecmascript/builtins/builtins_json.h" #include "ecmascript/builtins/builtins_map.h" #include "ecmascript/builtins/builtins_math.h" #include "ecmascript/builtins/builtins_number.h" #include "ecmascript/builtins/builtins_object.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_set.h" #include "ecmascript/builtins/builtins_sharedarraybuffer.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/containers/containers_bitvector.h" #include "ecmascript/runtime_lock.h" #ifdef ARK_SUPPORT_INTL #include "ecmascript/builtins/builtins_collator.h" #include "ecmascript/builtins/builtins_date_time_format.h" #include "ecmascript/builtins/builtins_displaynames.h" #include "ecmascript/builtins/builtins_intl.h" #include "ecmascript/builtins/builtins_list_format.h" #include "ecmascript/builtins/builtins_locale.h" #include "ecmascript/builtins/builtins_number_format.h" #include "ecmascript/builtins/builtins_plural_rules.h" #include "ecmascript/builtins/builtins_relative_time_format.h" #include "ecmascript/builtins/builtins_segmenter.h" #include "ecmascript/builtins/builtins_segments.h" #include "ecmascript/builtins/builtins_segment_iterator.h" #endif namespace panda::ecmascript { using Number = builtins::BuiltinsNumber; using BuiltinsBigInt = builtins::BuiltinsBigInt; using Object = builtins::BuiltinsObject; using Date = builtins::BuiltinsDate; 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 BuiltinsCjsExports = builtins::BuiltinsCjsExports; using BuiltinsCjsModule = builtins::BuiltinsCjsModule; using BuiltinsCjsRequire = builtins::BuiltinsCjsRequire; using ArkTools = builtins::BuiltinsArkTools; using ErrorType = base::ErrorType; using DataView = builtins::BuiltinsDataView; 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 BitVector = containers::ContainersBitVector; 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; #ifdef ARK_SUPPORT_INTL using DisplayNames = builtins::BuiltinsDisplayNames; using ListFormat = builtins::BuiltinsListFormat; 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 Segmenter = builtins::BuiltinsSegmenter; using Segments = builtins::BuiltinsSegments; #endif // 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(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(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::GetOwnPropertyDescriptors), 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(Object::HasOwn), 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::GetHasIndices), 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::FindLast), reinterpret_cast(BuiltinsArray::FindLastIndex), 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::Includes), reinterpret_cast(BuiltinsArray::Flat), reinterpret_cast(BuiltinsArray::FlatMap), reinterpret_cast(BuiltinsArray::At), reinterpret_cast(BuiltinsArray::ToReversed), reinterpret_cast(BuiltinsArray::With), reinterpret_cast(BuiltinsArray::ToSorted), reinterpret_cast(BuiltinsArray::ToSpliced), 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::FindLast), reinterpret_cast(BuiltinsTypedArray::FindLastIndex), 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::ToSorted), reinterpret_cast(BuiltinsTypedArray::Subarray), reinterpret_cast(BuiltinsTypedArray::ToLocaleString), reinterpret_cast(BuiltinsTypedArray::Values), reinterpret_cast(BuiltinsTypedArray::With), reinterpret_cast(BuiltinsTypedArray::GetBuffer), reinterpret_cast(BuiltinsTypedArray::GetByteLength), reinterpret_cast(BuiltinsTypedArray::GetByteOffset), reinterpret_cast(BuiltinsTypedArray::GetLength), reinterpret_cast(BuiltinsTypedArray::ToStringTag), reinterpret_cast(BuiltinsTypedArray::At), reinterpret_cast(BuiltinsTypedArray::ToReversed), 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::At), reinterpret_cast(BuiltinsString::CharAt), reinterpret_cast(BuiltinsString::CharCodeAt), reinterpret_cast(BuiltinsString::CodePointAt), reinterpret_cast(BuiltinsString::IsWellFormed), reinterpret_cast(BuiltinsString::ToWellFormed), 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(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), reinterpret_cast(BuiltinsBigInt::BigIntConstructor), reinterpret_cast(BuiltinsBigInt::AsUintN), reinterpret_cast(BuiltinsBigInt::AsIntN), reinterpret_cast(BuiltinsBigInt::ToLocaleString), reinterpret_cast(BuiltinsBigInt::ToString), reinterpret_cast(BuiltinsBigInt::ValueOf), #ifdef ARK_SUPPORT_INTL reinterpret_cast(DisplayNames::DisplayNamesConstructor), reinterpret_cast(DisplayNames::SupportedLocalesOf), reinterpret_cast(DisplayNames::Of), reinterpret_cast(DisplayNames::ResolvedOptions), 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(Segmenter::SegmenterConstructor), reinterpret_cast(Segmenter::SupportedLocalesOf), reinterpret_cast(Segmenter::ResolvedOptions), reinterpret_cast(Segmenter::Segment), reinterpret_cast(Segments::Containing), #endif // 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(BitVector::BitVectorConstructor), reinterpret_cast(BitVector::Push), reinterpret_cast(BitVector::Pop), reinterpret_cast(BitVector::Has), reinterpret_cast(BitVector::SetBitsByRange), reinterpret_cast(BitVector::GetBitsByRange), reinterpret_cast(BitVector::Resize), reinterpret_cast(BitVector::SetAllBits), reinterpret_cast(BitVector::GetBitCountByRange), reinterpret_cast(BitVector::GetIndexOf), reinterpret_cast(BitVector::GetLastIndexOf), reinterpret_cast(BitVector::FlipBitByIndex), reinterpret_cast(BitVector::FlipBitsByRange), reinterpret_cast(BitVector::GetSize), reinterpret_cast(BitVector::GetIteratorObj), reinterpret_cast(JSAPIBitVectorIterator::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(JSFunction::LengthGetter), 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(); deserializeStringVector_.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) { auto lastRegion = space->GetCurrentRegion(); space->EnumerateRegions([this, &writer, lastRegion](Region *current) { if (current != lastRegion) { ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast(ToUintPtr(current)), DEFAULT_REGION_SIZE); ResetRegionUnusedRange(current); SnapshotRegionHeadInfo info = GenerateRegionHeadInfo(current); // Firstly, serialize the region head information into the file; writer.write(reinterpret_cast(&info), SnapshotRegionHeadInfo::RegionHeadInfoSize()); // 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(); } }); SnapshotRegionHeadInfo info = GenerateRegionHeadInfo(lastRegion); // Firstly, serialize the region object into the file; writer.write(reinterpret_cast(&info), SnapshotRegionHeadInfo::RegionHeadInfoSize()); // 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) { space->EnumerateRegions([&writer](Region *region) { SnapshotRegionHeadInfo info; info.regionIndex_ = SnapshotHelper::GetHugeObjectRegionIndex(region->GetSnapshotData()); size_t objSize = SnapshotHelper::GetHugeObjectSize(region->GetSnapshotData()); info.aliveObjectSize_ = objSize; // Firstly, serialize the region head information into the file; writer.write(reinterpret_cast(&info), SnapshotRegionHeadInfo::RegionHeadInfoSize()); // Secondly, write the valid region memory (exclude region head and GC bit set). writer.write(reinterpret_cast(region->packedData_.begin_), 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 lastRegionSize = lastRegion->highWaterMark_ - lastRegion->packedData_.begin_; objSize = (regionCount - 1) * (SnapshotRegionHeadInfo::RegionHeadInfoSize() + Region::GetRegionAvailableSize()) + SnapshotRegionHeadInfo::RegionHeadInfoSize() + lastRegionSize; } ASSERT(objSize <= Constants::MAX_UINT_32); return static_cast(objSize); } uint32_t SnapshotProcessor::StatisticsHugeObjectSize(HugeObjectSpace* space) { size_t objSize = 0U; space->EnumerateRegions([&objSize](Region *region) { objSize += SnapshotRegionHeadInfo::RegionHeadInfoSize(); 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) / (Region::GetRegionAvailableSize() + SnapshotRegionHeadInfo::RegionHeadInfoSize()) + 1; } for (size_t i = 0; i < numberOfRegions; i++) { Region *region = vm_->GetHeapRegionAllocator()->AllocateAlignedRegion( space, DEFAULT_REGION_SIZE, vm_->GetAssociatedJSThread(), const_cast(vm_->GetHeap())); auto info = ToNativePtr(beginAddr + i * (Region::GetRegionAvailableSize() + SnapshotRegionHeadInfo::RegionHeadInfoSize())); uintptr_t objectBeginAddr = ToUintPtr(info) + SnapshotRegionHeadInfo::RegionHeadInfoSize(); size_t regionIndex = info->regionIndex_; size_t liveObjectSize = info->aliveObjectSize_; regionIndexMap_.emplace(regionIndex, region); ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast(region->packedData_.begin_), liveObjectSize); if (errno_t ret = memcpy_s(ToVoidPtr(region->packedData_.begin_), liveObjectSize, ToVoidPtr(objectBeginAddr), liveObjectSize); ret != EOK) { LOG_FULL(FATAL) << "memcpy_s failed: " << ret; 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); 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 info = ToNativePtr(currentAddr); // Retrieve the data beginning address based on the serialized data format. uintptr_t copyFrom = ToUintPtr(info) + SnapshotRegionHeadInfo::RegionHeadInfoSize(); size_t objSize = info->aliveObjectSize_; 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)); ASSERT(objSize > MAX_REGULAR_HEAP_OBJECT_SIZE); size_t alignedHugeRegionSize = AlignUp(objSize + hugeRegionHeadSize, PANDA_POOL_ALIGNMENT_IN_BYTES); Region *region = vm_->GetHeapRegionAllocator()->AllocateAlignedRegion( space, alignedHugeRegionSize, vm_->GetAssociatedJSThread(), const_cast(vm_->GetHeap())); size_t regionIndex = info->regionIndex_; 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 += SnapshotRegionHeadInfo::RegionHeadInfoSize(); currentAddr += objSize; } } void SnapshotProcessor::DeserializeString(uintptr_t stringBegin, uintptr_t stringEnd) { EcmaStringTable *stringTable = vm_->GetEcmaStringTable(); JSThread *thread = vm_->GetJSThread(); ASSERT(deserializeStringVector_.empty()); auto hugeSpace = sHeap_->GetHugeObjectSpace(); auto globalConst = const_cast(thread->GlobalConstants()); auto lineStringClass = globalConst->GetLineStringClass(); auto constantStringClass = globalConst->GetConstantStringClass(); while (stringBegin < stringEnd) { // str is from snapshot file, which is in native heap. EcmaString *str = reinterpret_cast(stringBegin); int index = JSTaggedValue(*(reinterpret_cast(str))).GetInt(); if (index == 1) { str->SetClassWithoutBarrier(reinterpret_cast(constantStringClass.GetTaggedObject())); std::shared_ptr jsPandaFile = JSPandaFileManager::GetInstance()->FindMergedJSPandaFile(); if (jsPandaFile != nullptr) { auto constantStr = ConstantString::Cast(str); uint32_t id = constantStr->GetEntityIdU32(); auto stringData = jsPandaFile->GetStringData(EntityId(id)).data; constantStr->SetConstantData(const_cast(stringData)); constantStr->SetRelocatedData(thread, JSTaggedValue::Undefined(), BarrierMode::SKIP_BARRIER); } else { LOG_ECMA_MEM(FATAL) << "JSPandaFile is nullptr"; } } else { ASSERT(index == 0); str->SetClassWithoutBarrier(reinterpret_cast(lineStringClass.GetTaggedObject())); } size_t strSize = EcmaStringAccessor(str).ObjectSize(); strSize = AlignUp(strSize, static_cast(MemAlignment::MEM_ALIGN_OBJECT)); { auto hashcode = EcmaStringAccessor(str).GetHashcode(); RuntimeLockHolder locker(thread, stringTable->stringTable_[EcmaStringTable::GetTableId(hashcode)].mutex_); auto strFromTable = stringTable->GetStringThreadUnsafe(str, hashcode); if (strFromTable) { deserializeStringVector_.emplace_back(thread, strFromTable); } else { uintptr_t newObj = 0; if (UNLIKELY(strSize > MAX_REGULAR_HEAP_OBJECT_SIZE)) { newObj = hugeSpace->Allocate(thread, strSize); } else { newObj = sHeap_->GetOldSpace()->TryAllocateAndExpand(thread, strSize, true); } if (newObj == 0) { LOG_ECMA_MEM(FATAL) << "Snapshot Allocate OldSharedSpace OOM"; UNREACHABLE(); } if (memcpy_s(ToVoidPtr(newObj), strSize, str, strSize) != EOK) { LOG_FULL(FATAL) << "memcpy_s failed"; UNREACHABLE(); } str = reinterpret_cast(newObj); stringTable->InsertStringToTableWithHashThreadUnsafe(str, hashcode); deserializeStringVector_.emplace_back(thread, str); } } 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_->GetJSThread()->GetCurrentEcmaContext()->SetGlobalEnv( reinterpret_cast(rootObjectAddr)); } else if (JSType(objType) == JSType::MICRO_JOB_QUEUE) { vm_->GetJSThread()->GetCurrentEcmaContext()->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_->GetJSThread()->GetCurrentEcmaContext()->SetGlobalEnv( reinterpret_cast(rootObjectAddr)); } constSpecialIndex++; break; } case SnapshotType::AI: { JSTaggedValue item = JSTaggedValue(static_cast(rootObjectAddr)); if (!isRootObjRelocate_ && item.IsTaggedArray()) { root_ = item; isRootObjRelocate_ = true; } break; } default: break; } } void SnapshotProcessor::AddRootObjectToAOTFileManager(SnapshotType type, const CString &fileName) { if (type == SnapshotType::AI) { ASSERT(!root_.IsHole()); AOTFileManager *aotFileManager = vm_->GetAOTFileManager(); aotFileManager->ParseDeserializedData(fileName, root_); } } SnapshotProcessor::SerializeObjectVisitor::SerializeObjectVisitor(SnapshotProcessor *processor, uintptr_t snapshotObj, CQueue *queue, std::unordered_map *data) : processor_(processor), snapshotObj_(snapshotObj), queue_(queue), data_(data) {} void SnapshotProcessor::SerializeObjectVisitor::VisitObjectRangeImpl(TaggedObject *root, ObjectSlot start, ObjectSlot end, VisitObjectArea area) { int index = 0; for (ObjectSlot slot = start; slot < end; slot++) { if (area == VisitObjectArea::NATIVE_POINTER) { auto nativePointer = *reinterpret_cast(slot.SlotAddress()); processor_->SetObjectEncodeField(snapshotObj_, slot.SlotAddress() - ToUintPtr(root), processor_->NativePointerToEncodeBit(nativePointer).GetValue()); } else { if (processor_->VisitObjectBodyWithRep(root, slot, snapshotObj_, index, area)) { continue; } auto fieldAddr = reinterpret_cast(slot.SlotAddress()); processor_->SetObjectEncodeField(snapshotObj_, slot.SlotAddress() - ToUintPtr(root), processor_->SerializeTaggedField(fieldAddr, queue_, data_)); } } } 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()); SerializeObjectVisitor visitor(this, snapshotObj, queue, data); ObjectXRay::VisitObjectBody(objectHeader, objectHeader->GetClass(), visitor); } bool SnapshotProcessor::VisitObjectBodyWithRep(TaggedObject *root, ObjectSlot slot, uintptr_t obj, int index, VisitObjectArea area) { if (area != VisitObjectArea::IN_OBJECT) { return false; } auto hclass = root->GetClass(); ASSERT(!hclass->IsAllTaggedProp()); auto layout = LayoutInfo::Cast(hclass->GetLayout().GetTaggedObject()); auto attr = layout->GetAttr(index++); if (attr.GetRepresentation() == Representation::DOUBLE) { auto fieldAddr = reinterpret_cast(slot.SlotAddress()); SetObjectEncodeField(obj, slot.SlotAddress() - ToUintPtr(root), JSTaggedValue(*fieldAddr).GetRawData()); return true; } else if (attr.GetRepresentation() == Representation::INT) { auto fieldAddr = reinterpret_cast(slot.SlotAddress()); SetObjectEncodeField(obj, slot.SlotAddress() - ToUintPtr(root), JSTaggedValue(static_cast(*fieldAddr)).GetRawData()); return true; } return false; } 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(jsPandaFile, oldSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(jsPandaFile, nonMovableSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(jsPandaFile, machineCodeSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(jsPandaFile, snapshotSpace, type, methods, methodNums, rootObjSize); RelocateSpaceObject(jsPandaFile, hugeObjectSpace, type, methods, methodNums, rootObjSize); } void SnapshotProcessor::RelocateSpaceObject(const JSPandaFile *jsPandaFile, 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([jsPandaFile, 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_FIRST && JSType(objType) <= JSType::STRING_LAST)) { EcmaString *str = reinterpret_cast(begin); EcmaStringAccessor(str).ClearInternString(); stringTable->GetOrInternFlattenString(vm_, str); if (JSType(objType) == JSType::CONSTANT_STRING) { auto constantStr = ConstantString::Cast(str); uint32_t id = constantStr->GetEntityIdU32(); auto stringData = jsPandaFile->GetStringData(EntityId(id)).data; constantStr->SetConstantData(const_cast(stringData)); } } 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()) { taggedValue.RemoveWeakTag(); if (taggedValue.IsJSHClass()) { EncodeBit encodeBit = GetObjectEncode(taggedValue, queue, data); encodeBit.SetTSWeakObject(); return encodeBit.GetValue(); } 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 = GetObjectEncode(taggedValue, queue, data); 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(); auto object = vm_->GetSnapshotEnv()->RelocateRootObjectAddr(index); *value = object; WriteBarrier(vm_->GetJSThread(), reinterpret_cast(value), 0, object); 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->InGeneralOldSpace() && 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); } if (valueRegion->InSharedSweepableSpace()) { if (!rootRegion->InSharedHeap()) { rootRegion->InsertLocalToShareRSet((uintptr_t)value); } // In deserializing can not use barriers, only mark the shared value to prevent markingbit being lost if (vm_->GetJSThread()->IsSharedConcurrentMarkingOrFinished()) { ASSERT(DaemonThread::GetInstance()->IsConcurrentMarkingOrFinished()); valueRegion->AtomicMark(reinterpret_cast(taggedObjectAddr)); } } *value = taggedObjectAddr; return; } if (encodeBit.IsSpecial()) { encodeBit.ClearObjectSpecialFlag(); *value = encodeBit.GetValue(); } } void SnapshotProcessor::DeserializeClassWord(TaggedObject *object) { // During AOT deserialization, setting the hclass on an object does not require atomic operations, but a write // barrier is still needed to track cross-generation references. 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->SetClassWithoutBarrier(JSHClass::Cast(hclassValue.GetTaggedObject())); WriteBarrier(vm_->GetJSThread(), object, JSHClass::HCLASS_OFFSET, hclassValue.GetRawData()); return; } uintptr_t hclassAddr = TaggedObjectEncodeBitToAddr(encodeBit); JSHClass *hclass = reinterpret_cast(hclassAddr); object->SetClassWithoutBarrier(hclass); WriteBarrier(vm_->GetJSThread(), object, JSHClass::HCLASS_OFFSET, JSTaggedValue(hclass).GetRawData()); } SnapshotProcessor::DeserializeFieldVisitor::DeserializeFieldVisitor(SnapshotProcessor *processor) : processor_(processor) {} void SnapshotProcessor::DeserializeFieldVisitor::VisitObjectRangeImpl(TaggedObject *root, ObjectSlot start, ObjectSlot end, VisitObjectArea area) { for (ObjectSlot slot = start; slot < end; slot++) { auto encodeBitAddr = reinterpret_cast(slot.SlotAddress()); if (area == VisitObjectArea::NATIVE_POINTER) { processor_->DeserializeNativePointer(encodeBitAddr); } else { processor_->DeserializeTaggedField(encodeBitAddr, root); } } } void SnapshotProcessor::DeserializeField(TaggedObject *objectHeader) { DeserializeFieldVisitor visitor(this); ObjectXRay::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); ASSERT(pandaMethod_.size() + GetNativeTableSize() > 0); // 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 reinterpret_cast(*deserializeStringVector_.at(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(); uintptr_t addr = ToUintPtr(region) + objectOffset; if (taggedBit.IsTSWeakObject()) { JSTaggedValue object(static_cast(addr)); object.CreateWeakRef(); addr = object.GetRawData(); } return addr; } 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(); } } } uintptr_t SnapshotProcessor::GetNewObj(size_t objectSize, TaggedObject *objectHeader) { if (builtinsSerialize_) { return AllocateObjectToLocalSpace(snapshotLocalSpace_, objectSize); } auto region = Region::ObjectAddressToRange(objectHeader); if (region->InYoungOrOldSpace() || region->InSharedOldSpace()) { return AllocateObjectToLocalSpace(oldLocalSpace_, objectSize); } if (region->InMachineCodeSpace()) { return AllocateObjectToLocalSpace(machineCodeLocalSpace_, objectSize); } if (region->InNonMovableSpace() || region->InReadOnlySpace() || region->InSharedNonMovableSpace() || region->InSharedReadOnlySpace()) { return AllocateObjectToLocalSpace(nonMovableLocalSpace_, objectSize); } if (region->InHugeObjectSpace() || region->InSharedHugeObjectSpace()) { return AllocateObjectToLocalSpace(hugeObjectLocalSpace_, objectSize); } return AllocateObjectToLocalSpace(snapshotLocalSpace_, objectSize); } EncodeBit SnapshotProcessor::EncodeTaggedObject(TaggedObject *objectHeader, CQueue *queue, std::unordered_map *data) { if (!builtinsSerialize_) { // String duplicate if (objectHeader->GetClass()->IsString()) { ASSERT(stringVector_.size() < Constants::MAX_OBJECT_INDEX); EncodeBit encodeBit(stringVector_.size()); if (EcmaStringAccessor(objectHeader).IsTreeString()) { data->emplace(ToUintPtr(objectHeader), std::make_pair(0U, encodeBit)); objectHeader = EcmaStringAccessor::FlattenNoGCForSnapshot(vm_, EcmaString::Cast(objectHeader)); } stringVector_.emplace_back(ToUintPtr(objectHeader)); data->emplace(ToUintPtr(objectHeader), std::make_pair(0U, encodeBit)); return encodeBit; } // builtins object reuse size_t index = vm_->GetSnapshotEnv()->FindEnvObjectIndex(ToUintPtr(objectHeader)); if (index != SnapshotEnv::MAX_UINT_32) { EncodeBit encodeBit(index); encodeBit.SetGlobalConstOrBuiltins(); data->emplace(ToUintPtr(objectHeader), std::make_pair(0U, encodeBit)); return encodeBit; } } auto oldObjHeader = objectHeader; if (objectHeader->GetClass()->IsString()) { if (EcmaStringAccessor(objectHeader).IsTreeString()) { objectHeader = EcmaStringAccessor::FlattenNoGCForSnapshot(vm_, EcmaString::Cast(objectHeader)); } } 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 = GetNewObj(objectSize, objectHeader); 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); if (oldObjHeader->GetClass()->IsString()) { if (EcmaStringAccessor(oldObjHeader).IsTreeString()) { data->emplace(ToUintPtr(oldObjHeader), std::make_pair(0U, encodeBit)); } } data->emplace(ToUintPtr(objectHeader), std::make_pair(newObj, encodeBit)); return encodeBit; } EncodeBit SnapshotProcessor::GetObjectEncode(JSTaggedValue object, CQueue *queue, std::unordered_map *data) { JSTaggedType addr = object.GetRawData(); EncodeBit encodeBit(0); if (data->find(addr) == data->end()) { encodeBit = EncodeTaggedObject(object.GetTaggedObject(), queue, data); } else { ObjectEncode objectEncodePair = data->find(object.GetRawData())->second; encodeBit = objectEncodePair.second; } 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]); } SnapshotRegionHeadInfo SnapshotProcessor::GenerateRegionHeadInfo(Region *region) { // Record region head information for deserialize SnapshotRegionHeadInfo info; info.regionIndex_ = region->GetSnapshotData(); if (region->InSnapshotSpace()) { info.aliveObjectSize_ = region->highWaterMark_ - region->packedData_.begin_; } else { info.aliveObjectSize_ = region->AliveObject(); } return info; } void SnapshotProcessor::ResetRegionUnusedRange(Region *region) { // memset unused memory to 0 if (region->AliveObject() < region->end_ - region->packedData_.begin_) { uintptr_t unusedAddrBegin = region->packedData_.begin_ + region->AliveObject(); size_t unusedSize = region->end_ - region->packedData_.begin_ - region->AliveObject(); if (memset_s(reinterpret_cast(unusedAddrBegin), unusedSize, 0, unusedSize)) { LOG_FULL(FATAL) << "memset_s failed"; UNREACHABLE(); } } } } // namespace panda::ecmascript