mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-10-08 00:24:00 +00:00
commit
d1ad59c7dc
11
BUILD.gn
11
BUILD.gn
@ -603,6 +603,7 @@ ecma_source = [
|
||||
"ecmascript/builtins/builtins_weak_map.cpp",
|
||||
"ecmascript/builtins/builtins_weak_ref.cpp",
|
||||
"ecmascript/builtins/builtins_weak_set.cpp",
|
||||
"ecmascript/builtins/shared_builtins.cpp",
|
||||
"ecmascript/byte_array.cpp",
|
||||
"ecmascript/ohos/code_decrypt.cpp",
|
||||
"ecmascript/ohos/enable_aot_list_helper.cpp",
|
||||
@ -779,6 +780,10 @@ ecma_source = [
|
||||
"ecmascript/mem/parallel_marker.cpp",
|
||||
"ecmascript/mem/partial_gc.cpp",
|
||||
"ecmascript/mem/regexp_cached_chunk.cpp",
|
||||
"ecmascript/mem/shared_heap/shared_concurrent_sweeper.cpp",
|
||||
"ecmascript/mem/shared_heap/shared_gc.cpp",
|
||||
"ecmascript/mem/shared_heap/shared_gc_marker.cpp",
|
||||
"ecmascript/mem/shared_heap/shared_space.cpp",
|
||||
"ecmascript/mem/stw_young_gc.cpp",
|
||||
"ecmascript/mem/space.cpp",
|
||||
"ecmascript/mem/sparse_space.cpp",
|
||||
@ -792,9 +797,12 @@ ecma_source = [
|
||||
"ecmascript/module/js_module_record.cpp",
|
||||
"ecmascript/module/js_module_source_text.cpp",
|
||||
"ecmascript/module/js_module_deregister.cpp",
|
||||
"ecmascript/module/js_shared_module.cpp",
|
||||
"ecmascript/module/js_shared_module_manager.cpp",
|
||||
"ecmascript/module/module_data_extractor.cpp",
|
||||
"ecmascript/module/module_path_helper.cpp",
|
||||
"ecmascript/module/napi_module_loader.cpp",
|
||||
"ecmascript/mutator_lock.cpp",
|
||||
"ecmascript/napi/jsnapi.cpp",
|
||||
"ecmascript/napi/jsnapi_expo.cpp",
|
||||
"ecmascript/object_factory.cpp",
|
||||
@ -815,6 +823,7 @@ ecma_source = [
|
||||
"ecmascript/serializer/base_deserializer.cpp",
|
||||
"ecmascript/serializer/base_serializer.cpp",
|
||||
"ecmascript/serializer/value_serializer.cpp",
|
||||
"ecmascript/shared_object_factory.cpp",
|
||||
"ecmascript/stackmap/ark_stackmap_builder.cpp",
|
||||
"ecmascript/stackmap/ark_stackmap_parser.cpp",
|
||||
"ecmascript/stackmap/litecg/litecg_stackmap_type.cpp",
|
||||
@ -829,6 +838,8 @@ ecma_source = [
|
||||
"ecmascript/regexp/regexp_opcode.cpp",
|
||||
"ecmascript/regexp/regexp_parser.cpp",
|
||||
"ecmascript/regexp/regexp_parser_cache.cpp",
|
||||
"ecmascript/runtime.cpp",
|
||||
"ecmascript/runtime_lock.cpp",
|
||||
"ecmascript/global_index_map.cpp",
|
||||
"ecmascript/shared_mm/shared_mm.cpp",
|
||||
"ecmascript/tagged_dictionary.cpp",
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -52,9 +52,7 @@
|
||||
#include "ecmascript/builtins/builtins_set.h"
|
||||
#include "ecmascript/builtins/builtins_sharedarraybuffer.h"
|
||||
#include "ecmascript/builtins/builtins_string.h"
|
||||
#include "ecmascript/builtins/builtins_shared_function.h"
|
||||
#include "ecmascript/builtins/builtins_string_iterator.h"
|
||||
#include "ecmascript/builtins/builtins_shared_object.h"
|
||||
#include "ecmascript/builtins/builtins_symbol.h"
|
||||
#include "ecmascript/builtins/builtins_typedarray.h"
|
||||
#include "ecmascript/builtins/builtins_weak_map.h"
|
||||
@ -98,6 +96,7 @@
|
||||
#include "ecmascript/marker_cell.h"
|
||||
#include "ecmascript/napi/include/jsnapi.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/runtime.h"
|
||||
#ifdef ARK_SUPPORT_INTL
|
||||
#include "ecmascript/builtins/builtins_collator.h"
|
||||
#include "ecmascript/builtins/builtins_date_time_format.h"
|
||||
@ -136,8 +135,6 @@ using Boolean = builtins::BuiltinsBoolean;
|
||||
using BuiltinsLazyCallback = builtins::BuiltinsLazyCallback;
|
||||
using BuiltinsMap = builtins::BuiltinsMap;
|
||||
using BuiltinsSet = builtins::BuiltinsSet;
|
||||
using BuiltinsSharedObject = builtins::BuiltinsSharedObject;
|
||||
using BuiltinsSharedFunction = builtins::BuiltinsSharedFunction;
|
||||
using BuiltinsWeakMap = builtins::BuiltinsWeakMap;
|
||||
using BuiltinsWeakSet = builtins::BuiltinsWeakSet;
|
||||
using BuiltinsWeakRef = builtins::BuiltinsWeakRef;
|
||||
@ -201,125 +198,12 @@ using SharedArrayBuffer = builtins::BuiltinsSharedArrayBuffer;
|
||||
using BuiltinsAsyncIterator = builtins::BuiltinsAsyncIterator;
|
||||
using AsyncGeneratorObject = builtins::BuiltinsAsyncGenerator;
|
||||
|
||||
void Builtins::InitializeSObjectAndSFunction(const JSHandle<GlobalEnv> &env)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
|
||||
JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull();
|
||||
// SharedObject.prototype[hclass]
|
||||
JSHandle<JSHClass> sobjPrototypeHClass = factory_->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT,
|
||||
nullHandle);
|
||||
// SharedObject.prototype
|
||||
JSHandle<JSObject> sObjFuncPrototype =
|
||||
factory_->NewJSObjectWithInit(sobjPrototypeHClass);
|
||||
JSHandle<JSTaggedValue> sObjFuncPrototypeVal(sObjFuncPrototype);
|
||||
// SharedObject.prototype_or_hclass
|
||||
JSHandle<JSHClass> sObjIHClass =
|
||||
factory_->NewEcmaHClass(JSSharedObject::SIZE, JSType::JS_SHARED_OBJECT, sObjFuncPrototypeVal);
|
||||
|
||||
// SharedFunction.prototype_or_hclass
|
||||
JSHandle<JSHClass> sFuncPrototypeHClass(
|
||||
factory_->NewEcmaHClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION, sObjFuncPrototypeVal));
|
||||
InitializeSFunciton(env, sFuncPrototypeHClass);
|
||||
InitializeSObject(env, sObjIHClass, sObjFuncPrototype);
|
||||
env->SetSObjectFunctionPrototype(thread_, sObjFuncPrototype);
|
||||
sObjFuncPrototype->GetJSHClass()->SetExtensible(false);
|
||||
}
|
||||
|
||||
void Builtins::InitializeSObject(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &sObjIHClass,
|
||||
const JSHandle<JSObject> &sObjFuncPrototype) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
// SharedObject constructor (forbidden use NewBuiltinConstructor)
|
||||
JSHandle<JSFunction> sObjectFunction =
|
||||
factory_->NewSFunction(env, reinterpret_cast<void *>(BuiltinsSharedObject::SharedObjectConstructor),
|
||||
FunctionKind::BUILTIN_CONSTRUCTOR);
|
||||
InitializeSCtor(sObjIHClass, sObjectFunction, "SharedObject", FunctionLength::ONE);
|
||||
env->SetSObjectFunction(thread_, sObjectFunction);
|
||||
// sObject method.
|
||||
for (const base::BuiltinFunctionEntry &entry : Object::GetObjectFunctions()) {
|
||||
SetSFunction(env, JSHandle<JSObject>(sObjectFunction), entry.GetName(), entry.GetEntrypoint(),
|
||||
entry.GetLength(), entry.GetBuiltinStubId());
|
||||
}
|
||||
// sObject.prototype method
|
||||
JSHandle<JSObject> sObjFuncPrototypeObj(sObjFuncPrototype);
|
||||
for (const base::BuiltinFunctionEntry &entry : Object::GetObjectPrototypeFunctions()) {
|
||||
SetSFunction(env, sObjFuncPrototypeObj, entry.GetName(), entry.GetEntrypoint(), entry.GetLength(),
|
||||
entry.GetBuiltinStubId());
|
||||
}
|
||||
|
||||
// B.2.2.1 sObject.prototype.__proto__
|
||||
JSHandle<JSTaggedValue> protoKey(factory_->NewFromASCII("__proto__"));
|
||||
JSHandle<JSTaggedValue> protoGetter =
|
||||
CreateSGetterSetter(env, Object::ProtoGetter, "__proto__", FunctionLength::ZERO);
|
||||
JSHandle<JSTaggedValue> protoSetter =
|
||||
CreateSGetterSetter(env, Object::ProtoSetter, "__proto__", FunctionLength::ONE);
|
||||
SetSAccessor(sObjFuncPrototypeObj, protoKey, protoGetter, protoSetter);
|
||||
sObjectFunction->GetJSHClass()->SetExtensible(false);
|
||||
}
|
||||
|
||||
void Builtins::InitializeSFunciton(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSHClass> &sFuncPrototypeHClass) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
// Initialize SharedFunction.prototype
|
||||
JSHandle<JSFunction> sFuncPrototype = factory_->NewJSFunctionByHClass(
|
||||
reinterpret_cast<void *>(Function::FunctionPrototypeInvokeSelf), sFuncPrototypeHClass);
|
||||
// SharedFunction.prototype.name = ""
|
||||
SetSFunctionName(sFuncPrototype, thread_->GlobalConstants()->GetHandledEmptyString());
|
||||
// SharedFunction.prototype.length = 0
|
||||
SetSFunctionLength(sFuncPrototype, FunctionLength::ZERO);
|
||||
|
||||
// SharedFunction.prototype_or_hclass
|
||||
JSHandle<JSHClass> sFuncIHClass = factory_->NewEcmaHClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
|
||||
JSHandle<JSTaggedValue>(sFuncPrototype));
|
||||
sFuncIHClass->SetCallable(true);
|
||||
sFuncIHClass->SetConstructor(true);
|
||||
|
||||
// new SharedFunction() (forbidden use NewBuiltinConstructor)
|
||||
JSHandle<JSFunction> sFuncFunction = factory_->NewSFunctionByHClass(
|
||||
reinterpret_cast<void *>(BuiltinsSharedFunction::SharedFunctionConstructor),
|
||||
sFuncIHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
|
||||
InitializeSCtor(sFuncIHClass, sFuncFunction, "SharedFunction", FunctionLength::ONE);
|
||||
env->SetSFunctionFunction(thread_, sFuncFunction);
|
||||
env->SetSFunctionPrototype(thread_, sFuncPrototype);
|
||||
|
||||
JSHandle<JSTaggedValue> sFuncPrototypeVal(sFuncPrototype);
|
||||
JSHandle<JSHClass> sConstructorClass =
|
||||
factory_->NewEcmaHClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION, sFuncPrototypeVal);
|
||||
sConstructorClass->SetConstructor(true);
|
||||
sConstructorClass->SetCallable(true);
|
||||
env->SetSConstructorClass(thread_, sConstructorClass);
|
||||
|
||||
JSHandle<JSHClass> sNormalFuncClass =
|
||||
factory_->NewEcmaHClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION, sFuncPrototypeVal);
|
||||
sNormalFuncClass->SetCallable(true);
|
||||
env->SetSNormalFunctionClass(thread_, sNormalFuncClass);
|
||||
|
||||
JSHandle<JSHClass> functionClass =
|
||||
factory_->CreateSFunctionClassWithoutProto(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
|
||||
env->GetSFunctionPrototype());
|
||||
env->SetSFunctionClassWithoutProto(thread_, functionClass);
|
||||
|
||||
JSHandle<JSObject> sFuncPrototypeObj(sFuncPrototype);
|
||||
SharedStrictModeForbiddenAccessCallerArguments(env, sFuncPrototypeObj);
|
||||
// Function.prototype method
|
||||
for (const base::BuiltinFunctionEntry &entry: Function::GetFunctionPrototypeFunctions()) {
|
||||
SetSFunction(env, sFuncPrototypeObj, entry.GetName(), entry.GetEntrypoint(),
|
||||
entry.GetLength(), entry.GetBuiltinStubId());
|
||||
}
|
||||
// 19.2.3.5 Function.prototype.toString ( )
|
||||
SetSFunction(env, sFuncPrototypeObj, thread_->GlobalConstants()->GetHandledToStringString(),
|
||||
Function::FunctionPrototypeToString, FunctionLength::ZERO);
|
||||
sFuncFunction->GetJSHClass()->SetExtensible(false);
|
||||
sFuncPrototype->GetJSHClass()->SetExtensible(false);
|
||||
}
|
||||
|
||||
void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread, bool lazyInit, bool isRealm)
|
||||
{
|
||||
thread_ = thread;
|
||||
vm_ = thread->GetEcmaVM();
|
||||
factory_ = vm_->GetFactory();
|
||||
sHeap_ = SharedHeap::GetInstance();
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
JSHandle<JSTaggedValue> nullHandle(thread, JSTaggedValue::Null());
|
||||
|
||||
@ -444,7 +328,12 @@ void Builtins::Initialize(const JSHandle<GlobalEnv> &env, JSThread *thread, bool
|
||||
InitializeBoolean(env, primRefObjHClass);
|
||||
InitializeRegExp(env);
|
||||
InitializeString(env, objFuncPrototypeVal);
|
||||
InitializeSObjectAndSFunction(env);
|
||||
auto runtimeGlobalEnv = Runtime::GetInstance()->GetGlobalEnv();
|
||||
if (runtimeGlobalEnv.IsHole()) {
|
||||
InitializeSObjectAndSFunction(env);
|
||||
} else {
|
||||
CopySObjectAndSFunction(env, runtimeGlobalEnv);
|
||||
}
|
||||
JSHandle<JSHClass> argumentsClass = factory_->CreateJSArguments(env);
|
||||
env->SetArgumentsClass(thread_, argumentsClass);
|
||||
SetArgumentsSharedAccessor(env);
|
||||
@ -712,7 +601,7 @@ void Builtins::InitializeSymbol(const JSHandle<GlobalEnv> &env, const JSHandle<J
|
||||
}
|
||||
|
||||
// Symbol attribute
|
||||
JSHandle<JSTaggedValue> hasInstanceSymbol(factory_->NewWellKnownSymbolWithChar("Symbol.hasInstance"));
|
||||
JSHandle<JSTaggedValue> hasInstanceSymbol(factory_->NewSWellKnownSymbolWithChar("Symbol.hasInstance"));
|
||||
SetNoneAttributeProperty(symbolFunction, "hasInstance", hasInstanceSymbol);
|
||||
JSHandle<JSTaggedValue> isConcatSpreadableSymbol(factory_->NewWellKnownSymbolWithChar("Symbol.isConcatSpreadable"));
|
||||
SetNoneAttributeProperty(symbolFunction, "isConcatSpreadable", isConcatSpreadableSymbol);
|
||||
@ -2689,8 +2578,9 @@ JSHandle<JSFunction> Builtins::NewFunction(const JSHandle<GlobalEnv> &env, const
|
||||
EcmaEntrypoint func, int length,
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId) const
|
||||
{
|
||||
MemSpaceType methodSpaceType = MemSpaceType::SHARED_NON_MOVABLE;
|
||||
JSHandle<JSFunction> function = factory_->NewJSFunction(env, reinterpret_cast<void *>(func),
|
||||
FunctionKind::NORMAL_FUNCTION, builtinId, MemSpaceType::NON_MOVABLE);
|
||||
FunctionKind::NORMAL_FUNCTION, builtinId, methodSpaceType);
|
||||
JSFunction::SetFunctionLength(thread_, function, JSTaggedValue(length));
|
||||
JSHandle<JSFunctionBase> baseFunction(function);
|
||||
auto globalConst = const_cast<GlobalEnvConstants *>(thread_->GlobalConstants());
|
||||
@ -3837,103 +3727,6 @@ void Builtins::InitializeDefaultExportOfScript(const JSHandle<GlobalEnv> &env) c
|
||||
return;
|
||||
}
|
||||
|
||||
void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, std::string_view name) const
|
||||
{
|
||||
JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8(name));
|
||||
SetSFunctionName(ctor, nameString);
|
||||
}
|
||||
|
||||
void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &name) const
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
|
||||
JSHandle<JSTaggedValue> nameKey = globalConst->GetHandledNameString();
|
||||
PropertyDescriptor nameDesc(thread_, name, false, false, false);
|
||||
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>(ctor), nameKey, nameDesc, SCheckMode::SKIP);
|
||||
}
|
||||
|
||||
void Builtins::SetSFunctionLength(const JSHandle<JSFunction> &ctor, int length) const
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
|
||||
JSHandle<JSTaggedValue> lengthKeyHandle = globalConst->GetHandledLengthString();
|
||||
JSTaggedValue taggedLength(length);
|
||||
PropertyDescriptor lengthDesc(thread_, JSHandle<JSTaggedValue>(thread_, taggedLength), false, false, false);
|
||||
JSObject::DefineOwnProperty(thread_, JSHandle<JSObject>(ctor), lengthKeyHandle, lengthDesc, SCheckMode::SKIP);
|
||||
}
|
||||
|
||||
void Builtins::InitializeSCtor(const JSHandle<JSHClass> &protoHClass, const JSHandle<JSFunction> &ctor,
|
||||
std::string_view name, int length) const
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
|
||||
SetSFunctionLength(ctor, length);
|
||||
SetSFunctionName(ctor, name);
|
||||
|
||||
JSHandle<JSTaggedValue> constructorKey = globalConst->GetHandledConstructorString();
|
||||
PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>::Cast(ctor), false, false, false);
|
||||
JSHandle<JSObject> prototype(thread_, protoHClass->GetProto());
|
||||
JSObject::DefineOwnProperty(thread_, prototype, constructorKey, descriptor, SCheckMode::SKIP);
|
||||
|
||||
JSFunction::SetFunctionPrototypeOrInstanceHClass(thread_, ctor, protoHClass.GetTaggedValue());
|
||||
}
|
||||
|
||||
JSHandle<JSFunction> Builtins::NewSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
|
||||
EcmaEntrypoint func, int length,
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId) const
|
||||
{
|
||||
JSHandle<JSFunction> function = factory_->NewSFunction(env, reinterpret_cast<void *>(func),
|
||||
FunctionKind::NORMAL_FUNCTION, builtinId, MemSpaceType::NON_MOVABLE);
|
||||
SetSFunctionLength(function, length);
|
||||
SetSFunctionName(function, key);
|
||||
function->GetJSHClass()->SetExtensible(false);
|
||||
return function;
|
||||
}
|
||||
|
||||
void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
|
||||
EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId) const
|
||||
{
|
||||
JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8(key));
|
||||
SetSFunction(env, obj, keyString, func, length, builtinId);
|
||||
}
|
||||
|
||||
void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
|
||||
const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, int length,
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId) const
|
||||
{
|
||||
JSHandle<JSFunction> function(NewSFunction(env, key, func, length, builtinId));
|
||||
PropertyDescriptor descriptor(thread_, JSHandle<JSTaggedValue>(function), false, false, false);
|
||||
JSObject::DefineOwnProperty(thread_, obj, key, descriptor, SCheckMode::SKIP);
|
||||
}
|
||||
|
||||
void Builtins::SetSAccessor(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
|
||||
const JSHandle<JSTaggedValue> &getter, const JSHandle<JSTaggedValue> &setter) const
|
||||
{
|
||||
JSHandle<AccessorData> accessor = factory_->NewAccessorData();
|
||||
accessor->SetGetter(thread_, getter);
|
||||
accessor->SetSetter(thread_, setter);
|
||||
PropertyAttributes attr = PropertyAttributes::DefaultAccessor(false, false, false);
|
||||
JSObject::AddAccessor(thread_, JSHandle<JSTaggedValue>::Cast(obj), key, accessor, attr);
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> Builtins::CreateSGetterSetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
|
||||
std::string_view name, int length) const
|
||||
{
|
||||
JSHandle<JSTaggedValue> funcName(factory_->NewFromUtf8(name));
|
||||
JSHandle<JSFunction> function = NewSFunction(env, funcName, func, length);
|
||||
return JSHandle<JSTaggedValue>(function);
|
||||
}
|
||||
|
||||
void Builtins::SharedStrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSObject> &prototype) const
|
||||
{
|
||||
JSHandle<JSFunction> func =
|
||||
factory_->NewSFunction(env, reinterpret_cast<void *>(JSFunction::AccessCallerArgumentsThrowTypeError),
|
||||
FunctionKind::NORMAL_FUNCTION, kungfu::BuiltinsStubCSigns::INVALID, MemSpaceType::NON_MOVABLE);
|
||||
|
||||
JSHandle<JSTaggedValue> caller(factory_->NewFromASCII("caller"));
|
||||
SetSAccessor(prototype, caller, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
|
||||
|
||||
JSHandle<JSTaggedValue> arguments(factory_->NewFromASCII("arguments"));
|
||||
SetSAccessor(prototype, arguments, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
|
||||
}
|
||||
JSHandle<JSTaggedValue> Builtins::CreateArrayUnscopables(JSThread *thread) const
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
@ -3981,13 +3774,13 @@ JSHandle<JSTaggedValue> Builtins::CreateArrayUnscopables(JSThread *thread) const
|
||||
|
||||
JSHandle<JSTaggedValue> valuesKey = globalConst->GetHandledValuesString();
|
||||
JSObject::CreateDataProperty(thread, unscopableList, valuesKey, trueVal);
|
||||
|
||||
|
||||
JSHandle<JSTaggedValue> toReversedKey((factory->NewFromASCII("toReversed")));
|
||||
JSObject::CreateDataProperty(thread, unscopableList, toReversedKey, trueVal);
|
||||
|
||||
|
||||
JSHandle<JSTaggedValue> toSortedKey((factory->NewFromASCII("toSorted")));
|
||||
JSObject::CreateDataProperty(thread, unscopableList, toSortedKey, trueVal);
|
||||
|
||||
|
||||
JSHandle<JSTaggedValue> toSplicedKey((factory->NewFromASCII("toSpliced")));
|
||||
JSObject::CreateDataProperty(thread, unscopableList, toSplicedKey, trueVal);
|
||||
return JSHandle<JSTaggedValue>::Cast(unscopableList);
|
||||
|
@ -50,6 +50,7 @@ private:
|
||||
JSThread *thread_{nullptr};
|
||||
ObjectFactory *factory_{nullptr};
|
||||
EcmaVM *vm_{nullptr};
|
||||
SharedHeap *sHeap_{nullptr};
|
||||
|
||||
JSHandle<JSFunction> NewBuiltinConstructor(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &prototype,
|
||||
EcmaEntrypoint ctorFunc, std::string_view name, int length,
|
||||
@ -344,17 +345,28 @@ private:
|
||||
EcmaEntrypoint func, int length) const;
|
||||
void SetNonConstantObject(const JSHandle<JSObject> &obj, std::string_view key,
|
||||
JSHandle<JSTaggedValue> &value) const;
|
||||
void InitializeSObjectAndSFunction(const JSHandle<GlobalEnv> &env);
|
||||
|
||||
// For SharedObject/SharedFunction
|
||||
void InitializeSObjectAndSFunction(const JSHandle<GlobalEnv> &env) const;
|
||||
void CopySObjectAndSFunction(const JSHandle<GlobalEnv> &env, const JSTaggedValue &srcEnv) const;
|
||||
void InitializeSObject(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &sObjIHClass,
|
||||
const JSHandle<JSObject> &sObjFuncPrototype) const;
|
||||
void InitializeSFunciton(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSHClass> &sFuncPrototypeHClass) const;
|
||||
const JSHandle<JSObject> &sObjFuncPrototype,
|
||||
const JSHandle<JSFunction> &sFuncPrototype) const;
|
||||
void InitializeSFunction(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSFunction> &sFuncPrototype) const;
|
||||
|
||||
JSHandle<JSHClass> CreateSObjectFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const;
|
||||
JSHandle<JSHClass> CreateSObjectPrototypeHClass() const;
|
||||
JSHandle<JSHClass> CreateSFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const;
|
||||
JSHandle<JSHClass> CreateSFunctionPrototypeHClass(const JSHandle<JSTaggedValue> &sObjFuncPrototypeVal) const;
|
||||
|
||||
void InitializeSCtor(const JSHandle<JSHClass> &protoHClass, const JSHandle<JSFunction> &ctor,
|
||||
std::string_view name, int length) const;
|
||||
|
||||
void SetSFunctionName(const JSHandle<JSFunction> &ctor, std::string_view name) const;
|
||||
void SetSFunctionName(const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &name) const;
|
||||
void SetSFunctionLength(const JSHandle<JSFunction> &ctor, int length) const;
|
||||
void SetSFunctionPrototype(const JSHandle<JSFunction> &ctor, const JSTaggedValue &prototype) const;
|
||||
|
||||
JSHandle<JSFunction> NewSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
|
||||
EcmaEntrypoint func, int length,
|
||||
@ -362,18 +374,18 @@ private:
|
||||
kungfu::BuiltinsStubCSigns::INVALID) const;
|
||||
|
||||
void SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
|
||||
EcmaEntrypoint func, int length, kungfu::BuiltinsStubCSigns::ID builtinId =
|
||||
EcmaEntrypoint func, uint32_t index, int length, kungfu::BuiltinsStubCSigns::ID builtinId =
|
||||
kungfu::BuiltinsStubCSigns::INVALID) const;
|
||||
|
||||
void SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
|
||||
const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, int length,
|
||||
const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, uint32_t index, int length,
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId = kungfu::BuiltinsStubCSigns::INVALID) const;
|
||||
void SetSAccessor(const JSHandle<JSObject> &obj, const JSHandle<JSTaggedValue> &key,
|
||||
void SetSAccessor(const JSHandle<JSObject> &obj, uint32_t index,
|
||||
const JSHandle<JSTaggedValue> &getter, const JSHandle<JSTaggedValue> &setter) const;
|
||||
|
||||
JSHandle<JSTaggedValue> CreateSGetterSetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
|
||||
std::string_view name, int length) const;
|
||||
void SharedStrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> &env,
|
||||
void SharedStrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> &env, uint32_t &index,
|
||||
const JSHandle<JSObject> &prototype) const;
|
||||
JSHandle<JSTaggedValue> CreateArrayUnscopables(JSThread *thread) const;
|
||||
friend class builtins::BuiltinsLazyCallback;
|
||||
|
@ -51,12 +51,40 @@ public:
|
||||
// ecma 19.2.3.6 Function.prototype[@@hasInstance] (V)
|
||||
static JSTaggedValue FunctionPrototypeHasInstance(EcmaRuntimeCallInfo *argv);
|
||||
|
||||
static Span<const std::pair<std::string_view, bool>> GetFunctionPrototypeProperties()
|
||||
{
|
||||
return Span<const std::pair<std::string_view, bool>>(FUNCTION_PROTOTYPE_PROPERTIES);
|
||||
}
|
||||
|
||||
static Span<const std::pair<std::string_view, bool>> GetFunctionProperties()
|
||||
{
|
||||
return Span<const std::pair<std::string_view, bool>>(FUNCTION_PROPERTIES);
|
||||
}
|
||||
|
||||
static Span<const base::BuiltinFunctionEntry> GetFunctionPrototypeFunctions()
|
||||
{
|
||||
return Span<const base::BuiltinFunctionEntry>(FUNCTION_PROTOTYPE_FUNCTIONS);
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr std::array FUNCTION_PROTOTYPE_PROPERTIES = {
|
||||
std::pair<std::string_view, bool>("length", false),
|
||||
std::pair<std::string_view, bool>("name", false),
|
||||
std::pair<std::string_view, bool>("constructor", false),
|
||||
std::pair<std::string_view, bool>("caller", true),
|
||||
std::pair<std::string_view, bool>("arguments", true),
|
||||
std::pair<std::string_view, bool>("apply", false),
|
||||
std::pair<std::string_view, bool>("bind", false),
|
||||
std::pair<std::string_view, bool>("call", false),
|
||||
std::pair<std::string_view, bool>("toString", false),
|
||||
std::pair<std::string_view, bool>("[Symbol.hasInstance]", false),
|
||||
};
|
||||
|
||||
static constexpr std::array FUNCTION_PROPERTIES = {
|
||||
std::pair<std::string_view, bool>("length", false),
|
||||
std::pair<std::string_view, bool>("name", false),
|
||||
std::pair<std::string_view, bool>("prototype", false),
|
||||
};
|
||||
|
||||
#define BUILTIN_FUNCTION_FUNCTION_ENTRY(name, func, length, id) \
|
||||
base::BuiltinFunctionEntry::Create(name, BuiltinsFunction::func, length, kungfu::BuiltinsStubCSigns::id),
|
||||
|
||||
|
@ -180,6 +180,17 @@ public:
|
||||
|
||||
static JSTaggedValue AssignTaggedValue(JSThread *thread, const JSHandle<JSTaggedValue> &source,
|
||||
const JSHandle<JSObject> &toAssign);
|
||||
|
||||
static Span<const std::pair<std::string_view, bool>> GetFunctionPrototypeProperties()
|
||||
{
|
||||
return Span<const std::pair<std::string_view, bool>>(OBJECT_PROTOTYPE_PROPERTIES);
|
||||
}
|
||||
|
||||
static Span<const std::pair<std::string_view, bool>> GetFunctionProperties()
|
||||
{
|
||||
return Span<const std::pair<std::string_view, bool>>(OBJECT_PROPERTIES);
|
||||
}
|
||||
|
||||
private:
|
||||
#define BUILTIN_OBJECT_FUNCTION_ENTRY(name, func, length, id) \
|
||||
base::BuiltinFunctionEntry::Create(name, BuiltinsObject::func, length, kungfu::BuiltinsStubCSigns::id),
|
||||
@ -192,6 +203,24 @@ private:
|
||||
};
|
||||
#undef BUILTIN_OBJECT_FUNCTION_ENTRY
|
||||
|
||||
#define OBJECT_PROPERTIES_PAIR(name, func, length, id) \
|
||||
std::pair<std::string_view, bool>(name, false),
|
||||
|
||||
static constexpr std::array OBJECT_PROTOTYPE_PROPERTIES = {
|
||||
std::pair<std::string_view, bool>("constructor", false),
|
||||
BUILTIN_OBJECT_PROTOTYPE_FUNCTIONS(OBJECT_PROPERTIES_PAIR)
|
||||
std::pair<std::string_view, bool>("__proto__", true),
|
||||
};
|
||||
|
||||
static constexpr std::array OBJECT_PROPERTIES = {
|
||||
std::pair<std::string_view, bool>("length", false),
|
||||
std::pair<std::string_view, bool>("name", false),
|
||||
std::pair<std::string_view, bool>("prototype", false),
|
||||
BUILTIN_OBJECT_FUNCTIONS(OBJECT_PROPERTIES_PAIR)
|
||||
|
||||
};
|
||||
#undef OBJECT_PROPERTIES_PAIR
|
||||
|
||||
static JSTaggedValue ObjectDefineProperties(JSThread *thread, const JSHandle<JSTaggedValue> &obj,
|
||||
const JSHandle<JSTaggedValue> &prop);
|
||||
static JSTaggedValue GetOwnPropertyKeys(JSThread *thread, const JSHandle<JSTaggedValue> &obj, const KeyType &type);
|
||||
|
343
ecmascript/builtins/shared_builtins.cpp
Normal file
343
ecmascript/builtins/shared_builtins.cpp
Normal file
@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Copyright (c) 2023 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/builtins/builtins.h"
|
||||
|
||||
#include "ecmascript/builtins/builtins_function.h"
|
||||
#include "ecmascript/builtins/builtins_object.h"
|
||||
#include "ecmascript/builtins/builtins_shared_function.h"
|
||||
#include "ecmascript/builtins/builtins_shared_object.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
using BuiltinsSharedObject = builtins::BuiltinsSharedObject;
|
||||
using BuiltinsSharedFunction = builtins::BuiltinsSharedFunction;
|
||||
using Function = builtins::BuiltinsFunction;
|
||||
using Object = builtins::BuiltinsObject;
|
||||
|
||||
void Builtins::InitializeSObjectAndSFunction(const JSHandle<GlobalEnv> &env) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
// SharedObject.prototype[hclass]
|
||||
JSHandle<JSHClass> sobjPrototypeHClass = CreateSObjectPrototypeHClass();
|
||||
// SharedObject.prototype
|
||||
JSHandle<JSObject> sObjFuncPrototype =
|
||||
factory_->NewSharedOldSpaceJSObject(sobjPrototypeHClass);
|
||||
JSHandle<JSTaggedValue> sObjFuncPrototypeVal(sObjFuncPrototype);
|
||||
// SharedObject.prototype_or_hclass
|
||||
auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
|
||||
JSHandle<JSHClass> sObjIHClass =
|
||||
factory_->NewSEcmaHClass(JSSharedObject::SIZE, 0, JSType::JS_SHARED_OBJECT, sObjFuncPrototypeVal,
|
||||
emptySLayout);
|
||||
// SharedFunction.prototype_or_hclass
|
||||
JSHandle<JSHClass> sFuncPrototypeHClass = CreateSFunctionPrototypeHClass(sObjFuncPrototypeVal);
|
||||
// SharedFunction.prototype
|
||||
JSHandle<JSFunction> sFuncPrototype = factory_->NewSFunctionByHClass(
|
||||
reinterpret_cast<void *>(Function::FunctionPrototypeInvokeSelf), sFuncPrototypeHClass,
|
||||
FunctionKind::NORMAL_FUNCTION);
|
||||
InitializeSFunction(env, sFuncPrototype);
|
||||
InitializeSObject(env, sObjIHClass, sObjFuncPrototype, sFuncPrototype);
|
||||
env->SetSObjectFunctionPrototype(thread_, sObjFuncPrototype);
|
||||
}
|
||||
|
||||
void Builtins::CopySObjectAndSFunction(const JSHandle<GlobalEnv> &env, const JSTaggedValue &srcEnv) const
|
||||
{
|
||||
// Copy shareds.
|
||||
ASSERT(srcEnv.IsJSGlobalEnv());
|
||||
auto sGlobalEnv = reinterpret_cast<GlobalEnv*>(srcEnv.GetTaggedObject());
|
||||
#define COPY_ENV_SHARED_FIELDS(Type, Name, INDEX) \
|
||||
env->Set##Name(thread_, sGlobalEnv->Get##Name());
|
||||
GLOBAL_ENV_SHARED_FIELDS(COPY_ENV_SHARED_FIELDS)
|
||||
#undef COPY_ENV_SHARED_FIELDS
|
||||
}
|
||||
|
||||
void Builtins::InitializeSObject(const JSHandle<GlobalEnv> &env, const JSHandle<JSHClass> &sObjIHClass,
|
||||
const JSHandle<JSObject> &sObjFuncPrototype,
|
||||
const JSHandle<JSFunction> &sFuncPrototype) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
// SharedObject constructor (forbidden use NewBuiltinConstructor)
|
||||
JSHandle<JSHClass> sObjectFunctionHClass = CreateSObjectFunctionHClass(sFuncPrototype);
|
||||
JSHandle<JSFunction> sObjectFunction =
|
||||
factory_->NewSFunctionByHClass(reinterpret_cast<void *>(BuiltinsSharedObject::SharedObjectConstructor),
|
||||
sObjectFunctionHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
|
||||
|
||||
InitializeSCtor(sObjIHClass, sObjectFunction, "SharedObject", FunctionLength::ONE);
|
||||
env->SetSObjectFunction(thread_, sObjectFunction);
|
||||
// sObject method.
|
||||
uint32_t fieldIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX + 1;
|
||||
for (const base::BuiltinFunctionEntry &entry : Object::GetObjectFunctions()) {
|
||||
SetSFunction(env, JSHandle<JSObject>(sObjectFunction), entry.GetName(), entry.GetEntrypoint(),
|
||||
fieldIndex++, entry.GetLength(), entry.GetBuiltinStubId());
|
||||
}
|
||||
// sObject.prototype method
|
||||
fieldIndex = 0; // constructor
|
||||
sObjFuncPrototype->SetPropertyInlinedProps(thread_, fieldIndex++, sObjectFunction.GetTaggedValue());
|
||||
for (const base::BuiltinFunctionEntry &entry : Object::GetObjectPrototypeFunctions()) {
|
||||
SetSFunction(env, sObjFuncPrototype, entry.GetName(), entry.GetEntrypoint(), fieldIndex++, entry.GetLength(),
|
||||
entry.GetBuiltinStubId());
|
||||
}
|
||||
// B.2.2.1 sObject.prototype.__proto__
|
||||
JSHandle<JSTaggedValue> protoGetter =
|
||||
CreateSGetterSetter(env, Object::ProtoGetter, "__proto__", FunctionLength::ZERO);
|
||||
JSHandle<JSTaggedValue> protoSetter =
|
||||
CreateSGetterSetter(env, Object::ProtoSetter, "__proto__", FunctionLength::ONE);
|
||||
SetSAccessor(sObjFuncPrototype, fieldIndex, protoGetter, protoSetter);
|
||||
}
|
||||
|
||||
void Builtins::InitializeSFunction(const JSHandle<GlobalEnv> &env,
|
||||
const JSHandle<JSFunction> &sFuncPrototype) const
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
SetSFunctionLength(sFuncPrototype, FunctionLength::ZERO);
|
||||
SetSFunctionName(sFuncPrototype, thread_->GlobalConstants()->GetHandledEmptyString());
|
||||
// SharedFunction.prototype_or_hclass
|
||||
auto emptySLayout = thread_->GlobalConstants()->GetHandledEmptySLayoutInfo();
|
||||
JSHandle<JSHClass> sFuncIHClass = factory_->NewSEcmaHClass(JSSharedFunction::SIZE, 0, JSType::JS_SHARED_FUNCTION,
|
||||
JSHandle<JSTaggedValue>(sFuncPrototype), emptySLayout);
|
||||
sFuncIHClass->SetCallable(true);
|
||||
sFuncIHClass->SetConstructor(true);
|
||||
// SharedFunction.hclass
|
||||
JSHandle<JSHClass> sFuncHClass = CreateSFunctionHClass(sFuncPrototype);
|
||||
// new SharedFunction() (forbidden use NewBuiltinConstructor)
|
||||
JSHandle<JSFunction> sFuncFunction = factory_->NewSFunctionByHClass(
|
||||
reinterpret_cast<void *>(BuiltinsSharedFunction::SharedFunctionConstructor),
|
||||
sFuncHClass, FunctionKind::BUILTIN_CONSTRUCTOR);
|
||||
InitializeSCtor(sFuncIHClass, sFuncFunction, "SharedFunction", FunctionLength::ONE);
|
||||
env->SetSFunctionFunction(thread_, sFuncFunction);
|
||||
env->SetSFunctionPrototype(thread_, sFuncPrototype);
|
||||
|
||||
JSHandle<JSTaggedValue> sFuncPrototypeVal(sFuncPrototype);
|
||||
JSHandle<JSHClass> functionClass =
|
||||
factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
|
||||
sFuncPrototypeVal);
|
||||
env->SetSFunctionClassWithoutProto(thread_, functionClass);
|
||||
|
||||
JSHandle<JSHClass> functionClassWithoutAccessor =
|
||||
factory_->CreateSFunctionClass(JSSharedFunction::SIZE, JSType::JS_SHARED_FUNCTION,
|
||||
sFuncPrototypeVal, false);
|
||||
env->SetSFunctionClassWithoutAccessor(thread_, functionClassWithoutAccessor);
|
||||
uint32_t fieldIndex = 2; // 2: length and name
|
||||
JSHandle<JSObject> sFuncPrototypeObj(sFuncPrototype);
|
||||
sFuncPrototypeObj->SetPropertyInlinedProps(thread_, fieldIndex++, sFuncFunction.GetTaggedValue()); // constructor
|
||||
SharedStrictModeForbiddenAccessCallerArguments(env, fieldIndex, sFuncPrototypeObj);
|
||||
// Function.prototype method
|
||||
// 19.2.3.1 Function.prototype.apply ( thisArg, argArray )
|
||||
SetSFunction(env, sFuncPrototypeObj, "apply", Function::FunctionPrototypeApply, fieldIndex++, FunctionLength::TWO,
|
||||
BUILTINS_STUB_ID(FunctionPrototypeApply));
|
||||
// 19.2.3.2 Function.prototype.bind ( thisArg , ...args)
|
||||
SetSFunction(env, sFuncPrototypeObj, "bind", Function::FunctionPrototypeBind, fieldIndex++, FunctionLength::ONE);
|
||||
// 19.2.3.3 Function.prototype.call (thisArg , ...args)
|
||||
SetSFunction(env, sFuncPrototypeObj, "call", Function::FunctionPrototypeCall, fieldIndex++, FunctionLength::ONE);
|
||||
// 19.2.3.5 Function.prototype.toString ( )
|
||||
SetSFunction(env, sFuncPrototypeObj, thread_->GlobalConstants()->GetHandledToStringString(),
|
||||
Function::FunctionPrototypeToString, fieldIndex++, FunctionLength::ZERO);
|
||||
SetSFunction(env, sFuncPrototypeObj, "[Symbol.hasInstance]",
|
||||
Function::FunctionPrototypeHasInstance, fieldIndex++, FunctionLength::ONE);
|
||||
}
|
||||
|
||||
|
||||
JSHandle<JSHClass> Builtins::CreateSObjectFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
|
||||
{
|
||||
uint32_t index = 0;
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
|
||||
attributes.SetIsInlinedProps(true);
|
||||
attributes.SetRepresentation(Representation::TAGGED);
|
||||
auto properties = Object::GetFunctionProperties();
|
||||
uint32_t length = properties.size();
|
||||
JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
|
||||
for (const std::pair<std::string_view, bool> &each : properties) {
|
||||
attributes.SetOffset(index);
|
||||
attributes.SetIsAccessor(each.second);
|
||||
JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8(each.first));
|
||||
layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
|
||||
}
|
||||
JSHandle<JSHClass> sobjPrototypeHClass =
|
||||
factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
|
||||
JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
|
||||
sobjPrototypeHClass->SetConstructor(true);
|
||||
sobjPrototypeHClass->SetCallable(true);
|
||||
return sobjPrototypeHClass;
|
||||
}
|
||||
|
||||
JSHandle<JSHClass> Builtins::CreateSObjectPrototypeHClass() const
|
||||
{
|
||||
const GlobalEnvConstants *globalConst = thread_->GlobalConstants();
|
||||
JSHandle<JSTaggedValue> nullHandle = globalConst->GetHandledNull();
|
||||
|
||||
uint32_t index = 0;
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
|
||||
attributes.SetIsInlinedProps(true);
|
||||
attributes.SetRepresentation(Representation::TAGGED);
|
||||
auto properties = Object::GetFunctionPrototypeProperties();
|
||||
uint32_t length = properties.size();
|
||||
JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
|
||||
for (const std::pair<std::string_view, bool> &each : properties) {
|
||||
attributes.SetOffset(index);
|
||||
attributes.SetIsAccessor(each.second);
|
||||
JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8(each.first));
|
||||
layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
|
||||
}
|
||||
|
||||
JSHandle<JSHClass> sobjPrototypeHClass =
|
||||
factory_->NewSEcmaHClass(JSSharedObject::SIZE, length, JSType::JS_SHARED_OBJECT, nullHandle,
|
||||
JSHandle<JSTaggedValue>(layout));
|
||||
return sobjPrototypeHClass;
|
||||
}
|
||||
|
||||
JSHandle<JSHClass> Builtins::CreateSFunctionHClass(const JSHandle<JSFunction> &sFuncPrototype) const
|
||||
{
|
||||
uint32_t index = 0;
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
|
||||
attributes.SetIsInlinedProps(true);
|
||||
attributes.SetRepresentation(Representation::TAGGED);
|
||||
auto properties = Function::GetFunctionProperties();
|
||||
uint32_t length = properties.size();
|
||||
JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
|
||||
for (const std::pair<std::string_view, bool> &each : properties) {
|
||||
attributes.SetOffset(index);
|
||||
attributes.SetIsAccessor(each.second);
|
||||
JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8(each.first));
|
||||
layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
|
||||
}
|
||||
JSHandle<JSHClass> sobjPrototypeHClass =
|
||||
factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION,
|
||||
JSHandle<JSTaggedValue>(sFuncPrototype), JSHandle<JSTaggedValue>(layout));
|
||||
sobjPrototypeHClass->SetConstructor(true);
|
||||
sobjPrototypeHClass->SetCallable(true);
|
||||
return sobjPrototypeHClass;
|
||||
}
|
||||
|
||||
JSHandle<JSHClass> Builtins::CreateSFunctionPrototypeHClass(const JSHandle<JSTaggedValue> &sObjFuncPrototypeVal) const
|
||||
{
|
||||
uint32_t index = 0;
|
||||
auto env = vm_->GetGlobalEnv();
|
||||
PropertyAttributes attributes = PropertyAttributes::Default(false, false, false);
|
||||
attributes.SetIsInlinedProps(true);
|
||||
attributes.SetRepresentation(Representation::TAGGED);
|
||||
auto properties = Function::GetFunctionPrototypeProperties();
|
||||
uint32_t length = properties.size();
|
||||
JSHandle<LayoutInfo> layout = factory_->CreateSLayoutInfo(length);
|
||||
JSHandle<JSTaggedValue> keyString;
|
||||
for (const std::pair<std::string_view, bool> &each : properties) {
|
||||
attributes.SetOffset(index);
|
||||
attributes.SetIsAccessor(each.second);
|
||||
if (each.first == "[Symbol.hasInstance]") {
|
||||
keyString = env->GetHasInstanceSymbol();
|
||||
} else {
|
||||
keyString = JSHandle<JSTaggedValue>(factory_->NewFromUtf8(each.first));
|
||||
}
|
||||
layout->AddKey(thread_, index++, keyString.GetTaggedValue(), attributes);
|
||||
}
|
||||
JSHandle<JSHClass> sobjPrototypeHClass =
|
||||
factory_->NewSEcmaHClass(JSSharedFunction::SIZE, length, JSType::JS_SHARED_FUNCTION, sObjFuncPrototypeVal,
|
||||
JSHandle<JSTaggedValue>(layout));
|
||||
sobjPrototypeHClass->SetCallable(true);
|
||||
return sobjPrototypeHClass;
|
||||
}
|
||||
|
||||
void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, std::string_view name) const
|
||||
{
|
||||
JSHandle<JSTaggedValue> nameString(factory_->NewFromUtf8(name));
|
||||
SetSFunctionName(ctor, nameString);
|
||||
}
|
||||
|
||||
void Builtins::SetSFunctionName(const JSHandle<JSFunction> &ctor, const JSHandle<JSTaggedValue> &name) const
|
||||
{
|
||||
auto nameIndex = JSFunction::NAME_INLINE_PROPERTY_INDEX;
|
||||
ctor->SetPropertyInlinedProps(thread_, nameIndex, name.GetTaggedValue());
|
||||
}
|
||||
|
||||
void Builtins::SetSFunctionLength(const JSHandle<JSFunction> &ctor, int length) const
|
||||
{
|
||||
JSTaggedValue taggedLength(length);
|
||||
auto lengthIndex = JSFunction::LENGTH_INLINE_PROPERTY_INDEX;
|
||||
ctor->SetPropertyInlinedProps(thread_, lengthIndex, taggedLength);
|
||||
}
|
||||
|
||||
void Builtins::SetSFunctionPrototype(const JSHandle<JSFunction> &ctor, const JSTaggedValue &prototype) const
|
||||
{
|
||||
auto prototypeIndex = JSFunction::PROTOTYPE_INLINE_PROPERTY_INDEX;
|
||||
ctor->SetPropertyInlinedProps(thread_, prototypeIndex, prototype);
|
||||
}
|
||||
|
||||
void Builtins::InitializeSCtor(const JSHandle<JSHClass> &protoHClass, const JSHandle<JSFunction> &ctor,
|
||||
std::string_view name, int length) const
|
||||
{
|
||||
SetSFunctionLength(ctor, length);
|
||||
SetSFunctionName(ctor, name);
|
||||
SetSFunctionPrototype(ctor, protoHClass->GetProto());
|
||||
ctor->SetProtoOrHClass(thread_, protoHClass);
|
||||
}
|
||||
|
||||
JSHandle<JSFunction> Builtins::NewSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSTaggedValue> &key,
|
||||
EcmaEntrypoint func, int length,
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId) const
|
||||
{
|
||||
JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutAccessor());
|
||||
JSHandle<JSFunction> function = factory_->NewSFunctionByHClass(reinterpret_cast<void *>(func),
|
||||
hclass, FunctionKind::NORMAL_FUNCTION, builtinId, MemSpaceType::SHARED_NON_MOVABLE);
|
||||
SetSFunctionLength(function, length);
|
||||
SetSFunctionName(function, key);
|
||||
function->GetJSHClass()->SetExtensible(false);
|
||||
return function;
|
||||
}
|
||||
|
||||
void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj, std::string_view key,
|
||||
EcmaEntrypoint func, uint32_t index, int length,
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId) const
|
||||
{
|
||||
JSHandle<JSTaggedValue> keyString(factory_->NewFromUtf8(key));
|
||||
SetSFunction(env, obj, keyString, func, index, length, builtinId);
|
||||
}
|
||||
|
||||
void Builtins::SetSFunction(const JSHandle<GlobalEnv> &env, const JSHandle<JSObject> &obj,
|
||||
const JSHandle<JSTaggedValue> &key, EcmaEntrypoint func, uint32_t index, int length,
|
||||
kungfu::BuiltinsStubCSigns::ID builtinId) const
|
||||
{
|
||||
JSHandle<JSFunction> function(NewSFunction(env, key, func, length, builtinId));
|
||||
obj->SetPropertyInlinedProps(thread_, index, function.GetTaggedValue());
|
||||
}
|
||||
|
||||
void Builtins::SetSAccessor(const JSHandle<JSObject> &obj, uint32_t index,
|
||||
const JSHandle<JSTaggedValue> &getter, const JSHandle<JSTaggedValue> &setter) const
|
||||
{
|
||||
JSHandle<AccessorData> accessor = factory_->NewSAccessorData();
|
||||
accessor->SetGetter(thread_, getter);
|
||||
accessor->SetSetter(thread_, setter);
|
||||
obj->SetPropertyInlinedProps(thread_, index, accessor.GetTaggedValue());
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> Builtins::CreateSGetterSetter(const JSHandle<GlobalEnv> &env, EcmaEntrypoint func,
|
||||
std::string_view name, int length) const
|
||||
{
|
||||
JSHandle<JSTaggedValue> funcName(factory_->NewFromUtf8(name));
|
||||
JSHandle<JSFunction> function = NewSFunction(env, funcName, func, length);
|
||||
return JSHandle<JSTaggedValue>(function);
|
||||
}
|
||||
|
||||
void Builtins::SharedStrictModeForbiddenAccessCallerArguments(const JSHandle<GlobalEnv> &env, uint32_t &index,
|
||||
const JSHandle<JSObject> &prototype) const
|
||||
{
|
||||
JSHandle<JSHClass> hclass = JSHandle<JSHClass>::Cast(env->GetSFunctionClassWithoutProto());
|
||||
JSHandle<JSFunction> func =
|
||||
factory_->NewSFunctionWithAccessor(
|
||||
reinterpret_cast<void *>(JSFunction::AccessCallerArgumentsThrowTypeError), hclass,
|
||||
FunctionKind::NORMAL_FUNCTION);
|
||||
// "caller"
|
||||
SetSAccessor(prototype, index++, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
|
||||
// "arguments"
|
||||
SetSAccessor(prototype, index++, JSHandle<JSTaggedValue>(func), JSHandle<JSTaggedValue>(func));
|
||||
}
|
||||
} // namespace panda::ecmascript
|
@ -49,6 +49,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -49,6 +49,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -46,6 +46,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -47,6 +47,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -48,6 +48,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,7 @@ public:
|
||||
instance->SetEnableForceGC(true);
|
||||
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
|
||||
thread = instance->GetJSThread();
|
||||
thread->ManagedCodeBegin();
|
||||
scope = new EcmaHandleScope(thread);
|
||||
}
|
||||
|
||||
|
106
ecmascript/checkpoint/thread_state_transition.h
Normal file
106
ecmascript/checkpoint/thread_state_transition.h
Normal file
@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 2024 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.
|
||||
*/
|
||||
|
||||
#ifndef ECMASCRIPT_CHECKPOINT_THREAD_STATE_TRANSITION_H
|
||||
#define ECMASCRIPT_CHECKPOINT_THREAD_STATE_TRANSITION_H
|
||||
|
||||
#include "ecmascript/runtime.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
class ThreadStateTransitionScope final {
|
||||
public:
|
||||
explicit ThreadStateTransitionScope(JSThread* self, ThreadState newState)
|
||||
: self_(self)
|
||||
{
|
||||
ASSERT(self_ != nullptr);
|
||||
oldState_ = self_->GetState();
|
||||
if (oldState_ != newState) {
|
||||
self_->UpdateState(newState);
|
||||
}
|
||||
}
|
||||
|
||||
~ThreadStateTransitionScope()
|
||||
{
|
||||
if (oldState_ != self_->GetState()) {
|
||||
self_->UpdateState(oldState_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
JSThread* self_;
|
||||
ThreadState oldState_;
|
||||
NO_COPY_SEMANTIC(ThreadStateTransitionScope);
|
||||
};
|
||||
|
||||
class ThreadSuspensionScope final {
|
||||
public:
|
||||
explicit ThreadSuspensionScope(JSThread* self) : scope_(self, ThreadState::IS_SUSPENDED)
|
||||
{
|
||||
ASSERT(self->GetState() == ThreadState::IS_SUSPENDED);
|
||||
}
|
||||
|
||||
~ThreadSuspensionScope() = default;
|
||||
|
||||
private:
|
||||
ThreadStateTransitionScope scope_;
|
||||
NO_COPY_SEMANTIC(ThreadSuspensionScope);
|
||||
};
|
||||
|
||||
class ThreadNativeScope final {
|
||||
public:
|
||||
explicit ThreadNativeScope(JSThread* self) : scope_(self, ThreadState::NATIVE)
|
||||
{
|
||||
ASSERT(self->GetState() == ThreadState::NATIVE);
|
||||
}
|
||||
|
||||
~ThreadNativeScope() = default;
|
||||
|
||||
private:
|
||||
ThreadStateTransitionScope scope_;
|
||||
NO_COPY_SEMANTIC(ThreadNativeScope);
|
||||
};
|
||||
|
||||
class ThreadManagedScope final {
|
||||
public:
|
||||
explicit ThreadManagedScope(JSThread* self) : scope_(self, ThreadState::RUNNING) {}
|
||||
|
||||
~ThreadManagedScope() = default;
|
||||
|
||||
private:
|
||||
ThreadStateTransitionScope scope_;
|
||||
NO_COPY_SEMANTIC(ThreadManagedScope);
|
||||
};
|
||||
|
||||
class SuspendAllScope final {
|
||||
public:
|
||||
explicit SuspendAllScope(JSThread* self)
|
||||
: self_(self), scope_(self, ThreadState::IS_SUSPENDED)
|
||||
{
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "SuspendAll");
|
||||
Runtime::GetInstance()->SuspendAll(self_);
|
||||
}
|
||||
~SuspendAllScope()
|
||||
{
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "ResumeAll");
|
||||
Runtime::GetInstance()->ResumeAll(self_);
|
||||
}
|
||||
private:
|
||||
JSThread* self_;
|
||||
ThreadStateTransitionScope scope_;
|
||||
NO_COPY_SEMANTIC(SuspendAllScope);
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
#endif // ECMASCRIPT_CHECKPOINT_THREAD_STATE_TRANSITION_H
|
@ -38,6 +38,7 @@ enum TriggerGCType {
|
||||
FULL_GC,
|
||||
// GC is expected to compress objects into appspawn space;
|
||||
APPSPAWN_FULL_GC,
|
||||
SHARED_GC,
|
||||
GC_TYPE_LAST
|
||||
};
|
||||
|
||||
@ -90,7 +91,8 @@ enum class RequestAotMode : uint8_t {
|
||||
V(COLLECT_REGION_SET_SIZE) \
|
||||
SEMI_RECORD_DATA(V) \
|
||||
PARTIAL_RECORD_DATA(V) \
|
||||
FULL_RECORD_DATA(V)
|
||||
FULL_RECORD_DATA(V) \
|
||||
SHARED_RECORD_DATA(V)
|
||||
|
||||
#define RECORD_DURATION(V) \
|
||||
V(SEMI_MIN_PAUSE) \
|
||||
@ -104,7 +106,10 @@ enum class RequestAotMode : uint8_t {
|
||||
V(OLD_TOTAL_PAUSE) \
|
||||
V(COMPRESS_MIN_PAUSE) \
|
||||
V(COMPRESS_MAX_PAUSE) \
|
||||
V(COMPRESS_TOTAL_PAUSE)
|
||||
V(COMPRESS_TOTAL_PAUSE) \
|
||||
V(SHARED_MIN_PAUSE) \
|
||||
V(SHARED_MAX_PAUSE) \
|
||||
V(SHARED_TOTAL_PAUSE)
|
||||
|
||||
#define SEMI_RECORD_DATA(V) \
|
||||
V(SEMI_COUNT) \
|
||||
@ -126,6 +131,13 @@ enum class RequestAotMode : uint8_t {
|
||||
V(COMPRESS_TOTAL_ALIVE) \
|
||||
V(COMPRESS_TOTAL_COMMIT)
|
||||
|
||||
#define SHARED_RECORD_DATA(V) \
|
||||
V(SHARED_COUNT) \
|
||||
V(SHARED_ALIVE_SIZE) \
|
||||
V(SHARED_TOTAL_ALIVE) \
|
||||
V(SHARED_COMMIT_SIZE) \
|
||||
V(SHARED_TOTAL_COMMIT)
|
||||
|
||||
#define TRACE_GC_SPEED(V) \
|
||||
V(UPDATE_REFERENCE_SPEED) \
|
||||
V(OLD_CLEAR_NATIVE_OBJ_SPEED) \
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "ecmascript/base/string_helper.h"
|
||||
#include "ecmascript/checkpoint/thread_state_transition.h"
|
||||
#include "ecmascript/compiler/aot_compiler_preprocessor.h"
|
||||
#include "ecmascript/compiler/aot_file/aot_file_manager.h"
|
||||
#include "ecmascript/compiler/pass_manager.h"
|
||||
@ -90,6 +91,7 @@ int Main(const int argc, const char **argv)
|
||||
}
|
||||
|
||||
{
|
||||
ecmascript::ThreadManagedScope managedScope(vm->GetJSThread());
|
||||
LocalScope scope(vm);
|
||||
arg_list_t pandaFileNames {};
|
||||
std::map<std::string, std::shared_ptr<OhosPkgArgs>> pkgArgsMap;
|
||||
|
@ -221,14 +221,16 @@ void AotCompilerPreprocessor::GenerateGlobalTypes(const CompilationOptions &cOpt
|
||||
typeRecorder.BindPgoTypeToGateType(jsPandaFile, tsManager, methodLiteral);
|
||||
|
||||
bcInfo->IterateInfoByType(methodOffset, PGOBCInfo::Type::ARRAY_LITERAL,
|
||||
[this, tsManager, ptManager,
|
||||
&recordName]([[maybe_unused]] const uint32_t bcIdx,
|
||||
[[maybe_unused]] const uint32_t bcOffset, const uint32_t cpIdx) {
|
||||
[this, tsManager, ptManager, &recordName]([[maybe_unused]] const uint32_t bcIdx,
|
||||
[[maybe_unused]] const uint32_t bcOffset, const uint32_t cpIdx) {
|
||||
JSHandle<ConstantPool> constpoolHandle(tsManager->GetConstantPool());
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
JSTaggedValue unsharedCp = thread->GetCurrentEcmaContext()
|
||||
->FindUnsharedConstpool(constpoolHandle.GetTaggedValue());
|
||||
ASSERT(ConstantPool::CheckUnsharedConstpool(unsharedCp));
|
||||
JSTaggedValue arr =
|
||||
ConstantPool::GetLiteralFromCache<ConstPoolType::ARRAY_LITERAL>(
|
||||
thread, constpoolHandle.GetTaggedValue(), cpIdx, recordName);
|
||||
thread, unsharedCp, cpIdx, recordName);
|
||||
JSHandle<JSArray> arrayHandle(thread, arr);
|
||||
panda_file::File::EntityId id =
|
||||
ConstantPool::GetIdFromCache(constpoolHandle.GetTaggedValue(), cpIdx);
|
||||
@ -260,4 +262,4 @@ std::string AotCompilerPreprocessor::GetMainPkgArgsAppSignature() const
|
||||
{
|
||||
return GetMainPkgArgs() == nullptr ? "" : GetMainPkgArgs()->GetAppSignature();
|
||||
}
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
} // namespace panda::ecmascript::kungfu
|
||||
|
@ -282,6 +282,7 @@ void AOTFileManager::SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JS
|
||||
Method *method = mainFunc->GetCallTarget();
|
||||
method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
||||
method->SetCodeEntryAndMarkAOTWhenBinding(static_cast<uintptr_t>(mainEntry));
|
||||
mainFunc->SetCodeEntry(static_cast<uintptr_t>(mainEntry));
|
||||
method->SetIsFastCall(isFastCall);
|
||||
#ifndef NDEBUG
|
||||
PrintAOTEntry(jsPandaFile, method, mainEntry);
|
||||
@ -292,9 +293,14 @@ void AOTFileManager::SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JS
|
||||
methodLiteral->SetIsFastCall(isFastCall);
|
||||
}
|
||||
|
||||
void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method,
|
||||
uint32_t entryIndex, bool *canFastCall)
|
||||
void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, JSFunction *function,
|
||||
Method *method, uint32_t entryIndex, bool *canFastCall)
|
||||
{
|
||||
uint64_t methodCodeEntry = method->GetCodeEntryOrLiteral();
|
||||
if (function != nullptr && methodCodeEntry != reinterpret_cast<uintptr_t>(nullptr)) {
|
||||
function->SetCodeEntry(methodCodeEntry);
|
||||
return;
|
||||
}
|
||||
AnFileDataManager *anFileDataManager = AnFileDataManager::GetInstance();
|
||||
uint32_t anFileInfoIndex = jsPandaFile->GetAOTFileInfoIndex();
|
||||
const std::shared_ptr<AnFileInfo> anFileInfo = anFileDataManager->SafeGetAnFileInfo(anFileInfoIndex);
|
||||
|
@ -60,7 +60,11 @@ public:
|
||||
static constexpr size_t AOT_IHC_INDEX = 2;
|
||||
static constexpr size_t AOT_ELEMENT_INDEX = 3;
|
||||
static constexpr size_t AOT_ELEMENTS_KIND_INDEX = 4;
|
||||
static constexpr size_t RESERVED_LENGTH = AOT_ELEMENTS_KIND_INDEX;
|
||||
static constexpr size_t LITERAL_TYPE_INDEX = 5;
|
||||
static constexpr size_t RESERVED_LENGTH = LITERAL_TYPE_INDEX;
|
||||
|
||||
static constexpr int32_t METHOD_LITERAL_TYPE = 1;
|
||||
static constexpr int32_t INVALID_LITERAL_TYPE = 0;
|
||||
|
||||
static AOTLiteralInfo *Cast(TaggedObject *object)
|
||||
{
|
||||
@ -80,6 +84,7 @@ public:
|
||||
SetChc(JSTaggedValue::Undefined());
|
||||
SetElementIndex(JSTaggedValue(kungfu::BaseSnapshotInfo::AOT_ELEMENT_INDEX_DEFAULT_VALUE));
|
||||
SetElementsKind(ElementsKind::GENERIC);
|
||||
SetLiteralType(JSTaggedValue(INVALID_LITERAL_TYPE));
|
||||
}
|
||||
|
||||
inline uint32_t GetCacheLength() const
|
||||
@ -130,6 +135,16 @@ public:
|
||||
return kind;
|
||||
}
|
||||
|
||||
inline void SetLiteralType(JSTaggedValue value)
|
||||
{
|
||||
Barriers::SetPrimitive(GetData(), GetLiteralTypeOffset(), value.GetRawData());
|
||||
}
|
||||
|
||||
inline int GetLiteralType() const
|
||||
{
|
||||
return JSTaggedValue(Barriers::GetValue<JSTaggedType>(GetData(), GetLiteralTypeOffset())).GetInt();
|
||||
}
|
||||
|
||||
inline void SetObjectToCache(JSThread *thread, uint32_t index, JSTaggedValue value)
|
||||
{
|
||||
Set(thread, index, value);
|
||||
@ -160,6 +175,11 @@ private:
|
||||
{
|
||||
return JSTaggedValue::TaggedTypeSize() * (GetLength() - AOT_ELEMENTS_KIND_INDEX);
|
||||
}
|
||||
|
||||
inline size_t GetLiteralTypeOffset() const
|
||||
{
|
||||
return JSTaggedValue::TaggedTypeSize() * (GetLength() - LITERAL_TYPE_INDEX);
|
||||
}
|
||||
};
|
||||
|
||||
class AOTFileManager {
|
||||
@ -187,8 +207,8 @@ public:
|
||||
void BindPandaFilesInAotFile(const std::string &aotFileBaseName, const std::string &moduleName);
|
||||
void SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JSPandaFile *jsPandaFile,
|
||||
std::string_view entryPoint);
|
||||
void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *method,
|
||||
uint32_t entryIndex, bool *canFastCall = nullptr);
|
||||
void SetAOTFuncEntry(const JSPandaFile *jsPandaFile, JSFunction *function,
|
||||
Method *method, uint32_t entryIndex = 0, bool *canFastCall = nullptr);
|
||||
bool LoadAiFile([[maybe_unused]] const std::string &filename);
|
||||
bool LoadAiFile(const JSPandaFile *jsPandaFile);
|
||||
kungfu::ArkStackMapParser* GetStackMapParser() const;
|
||||
|
@ -68,8 +68,8 @@ public:
|
||||
private:
|
||||
JSHandle<ConstantPool> NewSnapshotConstantPool(uint32_t cacheSize);
|
||||
|
||||
void GenerateSnapshotConstantPools(const CMap<int32_t, JSTaggedValue> &allConstantPools, const CString &fileName,
|
||||
uint32_t fileIndex);
|
||||
void GenerateSnapshotConstantPools(
|
||||
const CMap<int32_t, JSTaggedValue> &allConstantPools, const CString &fileName, uint32_t fileIndex);
|
||||
|
||||
EcmaVM *vm_ {nullptr};
|
||||
ObjectFactory *factory_ {nullptr};
|
||||
|
@ -141,6 +141,7 @@ void MethodSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalData,
|
||||
JSHandle<AOTLiteralInfo> aotLiteralInfo = factory->NewAOTLiteralInfo(1); // 1: only one method
|
||||
int initValue = static_cast<int>(AOTLiteralInfo::NO_FUNC_ENTRY_VALUE);
|
||||
aotLiteralInfo->SetObjectToCache(thread_, 0, JSTaggedValue(initValue));
|
||||
aotLiteralInfo->SetLiteralType(JSTaggedValue(AOTLiteralInfo::METHOD_LITERAL_TYPE));
|
||||
if (!ihc->IsUndefined()) {
|
||||
aotLiteralInfo->SetIhc(ihc.GetTaggedValue());
|
||||
}
|
||||
@ -160,8 +161,7 @@ void ClassLiteralSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalD
|
||||
bool hasAbcId = TryGetABCId(abcId);
|
||||
for (auto item : info_) {
|
||||
const ItemData &data = item.second;
|
||||
JSHandle<ConstantPool> cp(thread_,
|
||||
thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, data.constantPoolId_));
|
||||
JSHandle<ConstantPool> cp = GetUnsharedConstpool(data);
|
||||
auto literalObj = ConstantPool::GetClassLiteralFromCache(thread_, cp, data.constantPoolIdx_, data.recordName_);
|
||||
JSHandle<ClassLiteral> classLiteral(thread_, literalObj);
|
||||
JSHandle<TaggedArray> arrayHandle(thread_, classLiteral->GetArray());
|
||||
@ -195,8 +195,7 @@ void ObjectLiteralSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &global
|
||||
bool hasAbcId = TryGetABCId(abcId);
|
||||
for (auto item : info_) {
|
||||
const ItemData &data = item.second;
|
||||
JSHandle<ConstantPool> cp(thread_,
|
||||
thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, data.constantPoolId_));
|
||||
JSHandle<ConstantPool> cp = GetUnsharedConstpool(data);
|
||||
panda_file::File::EntityId id = cp->GetEntityId(data.constantPoolIdx_);
|
||||
JSMutableHandle<TaggedArray> elements(thread_, JSTaggedValue::Undefined());
|
||||
JSMutableHandle<TaggedArray> properties(thread_, JSTaggedValue::Undefined());
|
||||
@ -233,8 +232,7 @@ void ArrayLiteralSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalD
|
||||
PGOTypeManager *ptManager = thread_->GetCurrentEcmaContext()->GetPTManager();
|
||||
for (auto item : info_) {
|
||||
const ItemData &data = item.second;
|
||||
JSHandle<ConstantPool> cp(thread_,
|
||||
thread_->GetCurrentEcmaContext()->FindConstpool(jsPandaFile_, data.constantPoolId_));
|
||||
JSHandle<ConstantPool> cp = GetUnsharedConstpool(data);
|
||||
panda_file::File::EntityId id = cp->GetEntityId(data.constantPoolIdx_);
|
||||
JSHandle<TaggedArray> literal = LiteralDataExtractor::GetDatasIgnoreType(
|
||||
thread_, jsPandaFile_, id, cp, data.recordName_);
|
||||
@ -253,6 +251,14 @@ void ArrayLiteralSnapshotInfo::StoreDataToGlobalData(SnapshotGlobalData &globalD
|
||||
}
|
||||
}
|
||||
|
||||
JSHandle<ConstantPool> BaseSnapshotInfo::GetUnsharedConstpool(const ItemData &data)
|
||||
{
|
||||
EcmaContext *context = thread_->GetCurrentEcmaContext();
|
||||
JSTaggedValue shareCp = context->FindConstpool(jsPandaFile_, data.constantPoolId_);
|
||||
JSHandle<ConstantPool> cp(thread_, context->FindUnsharedConstpool(shareCp));
|
||||
return cp;
|
||||
}
|
||||
|
||||
void SnapshotConstantPoolData::Record(const BytecodeInstruction &bcIns, int32_t bcIndex,
|
||||
const CString &recordName, const MethodLiteral *method)
|
||||
{
|
||||
|
@ -77,6 +77,7 @@ protected:
|
||||
JSHandle<JSTaggedValue> ihc, JSHandle<JSTaggedValue> chc,
|
||||
int32_t elementIndex = AOT_ELEMENT_INDEX_DEFAULT_VALUE,
|
||||
ElementsKind kind = ElementsKind::GENERIC);
|
||||
JSHandle<ConstantPool> GetUnsharedConstpool(const ItemData &data);
|
||||
|
||||
CUnorderedMap<ItemKey, ItemData> info_ {};
|
||||
EcmaVM *vm_ {nullptr};
|
||||
|
@ -380,7 +380,9 @@ namespace panda::ecmascript::kungfu {
|
||||
T(HandleCallRuntimeDefinePrivatePropertyPrefImm8Imm16Imm16V8) \
|
||||
T(HandleCallRuntimeCallInitPrefImm8V8) \
|
||||
T(HandleCallRuntimeDefineSendableClassPrefImm16Id16Id16Imm16V8) \
|
||||
T(HandleCallRuntimeLdSendableClassPrefImm16)
|
||||
T(HandleCallRuntimeLdSendableClassPrefImm16) \
|
||||
T(HandleCallRuntimeLdsendableexternalmodulevarImm8) \
|
||||
T(HandleCallRuntimeWideLdsendableexternalmodulevarPrefImm16)
|
||||
|
||||
#define ASM_INTERPRETER_BC_HELPER_STUB_LIST(V) \
|
||||
V(SingleStepDebugging) \
|
||||
|
@ -442,7 +442,7 @@ void BuiltinsObjectStubBuilder::LayoutInfoAssignAllEnumProperty(Variable *result
|
||||
Bind(&next);
|
||||
|
||||
GateRef key = GetKeyFromLayoutInfo(layout, *idx);
|
||||
GateRef attr = TruncInt64ToInt32(GetPropAttrFromLayoutInfo(layout, *idx));
|
||||
GateRef attr = GetPropAttrFromLayoutInfo(layout, *idx);
|
||||
Label stringKey(env);
|
||||
BRANCH(TaggedIsString(key), &stringKey, &loopEnd);
|
||||
Bind(&stringKey);
|
||||
@ -727,7 +727,7 @@ void BuiltinsObjectStubBuilder::HasOwnProperty(Variable *result, Label *exit, La
|
||||
BRANCH(TaggedIsString(prop), &keyIsString, slowPath); // 2 : two args
|
||||
Bind(&keyIsString);
|
||||
{
|
||||
GateRef res = CallNGCRuntime(glue_, RTSTUB_ID(TryToElementsIndexOrFindInStringTable), { glue_, prop });
|
||||
GateRef res = CallRuntime(glue_, RTSTUB_ID(TryToElementsIndexOrFindInStringTable), { prop });
|
||||
BRANCH(TaggedIsNumber(res), &isIndex, ¬Index);
|
||||
Bind(&isIndex);
|
||||
{
|
||||
|
@ -447,6 +447,8 @@ BytecodeMetaData BytecodeMetaData::InitBytecodeMetaData(const uint8_t *pc)
|
||||
case EcmaOpcode::CALLRUNTIME_DEFINEPRIVATEPROPERTY_PREF_IMM8_IMM16_IMM16_V8:
|
||||
case EcmaOpcode::CALLRUNTIME_CALLINIT_PREF_IMM8_V8:
|
||||
case EcmaOpcode::CALLRUNTIME_DEFINESENDABLECLASS_PREF_IMM16_ID16_ID16_IMM16_V8:
|
||||
case EcmaOpcode::CALLRUNTIME_LDSENDABLEEXTERNALMODULEVAR_PREF_IMM8:
|
||||
case EcmaOpcode::CALLRUNTIME_WIDELDSENDABLEEXTERNALMODULEVAR_PREF_IMM16:
|
||||
flags |= BytecodeFlags::READ_FUNC;
|
||||
break;
|
||||
case EcmaOpcode::SUPERCALLTHISRANGE_IMM8_IMM8_V8:
|
||||
@ -1126,6 +1128,16 @@ void BytecodeInfo::InitBytecodeInfo(BytecodeCircuitBuilder *builder,
|
||||
info.inputs.emplace_back(Immediate(index));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::CALLRUNTIME_LDSENDABLEEXTERNALMODULEVAR_PREF_IMM8: {
|
||||
int32_t index = READ_INST_8_1();
|
||||
info.inputs.emplace_back(Immediate(index));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::CALLRUNTIME_WIDELDSENDABLEEXTERNALMODULEVAR_PREF_IMM16: {
|
||||
int32_t index = READ_INST_16_1();
|
||||
info.inputs.emplace_back(Immediate(index));
|
||||
break;
|
||||
}
|
||||
case EcmaOpcode::STCONSTTOGLOBALRECORD_IMM16_ID16: {
|
||||
uint16_t stringId = READ_INST_16_2();
|
||||
info.inputs.emplace_back(ConstDataId(ConstDataIDType::StringIDType, stringId));
|
||||
|
@ -1850,6 +1850,22 @@ DEF_CALL_SIGNATURE(InsertOldToNewRSet)
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(InsertLocalToShareRSet)
|
||||
{
|
||||
// 3 : 3 input parameters
|
||||
CallSignature index("InsertLocalToShareRSet", 0, 3, ArgumentsOrder::DEFAULT_ORDER, VariableType::VOID());
|
||||
*callSign = index;
|
||||
// 3 : 3 input parameters
|
||||
std::array<VariableType, 3> params = {
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_POINTER(),
|
||||
VariableType::NATIVE_POINTER(),
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetGCLeafFunction(true);
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(FloatSqrt)
|
||||
{
|
||||
// 1 : 1 input parameters
|
||||
@ -2144,38 +2160,6 @@ DEF_CALL_SIGNATURE(JsBoundCallInternal)
|
||||
callSign->SetCallConv(CallSignature::CallConv::CCallConv);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(TryToElementsIndexOrFindInStringTable)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature tryToElementsIndexOrFindInStringTable("TryToElementsIndexOrFindInStringTable", 0, 2,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = tryToElementsIndexOrFindInStringTable;
|
||||
// 2 : 2 input parameters
|
||||
std::array<VariableType, 2> params = {
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_POINTER(),
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetGCLeafFunction(true);
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(TryGetInternString)
|
||||
{
|
||||
// 2 : 2 input parameters
|
||||
CallSignature tryGetInternString("TryGetInternString", 0, 2,
|
||||
ArgumentsOrder::DEFAULT_ORDER, VariableType::JS_ANY());
|
||||
*callSign = tryGetInternString;
|
||||
// 2 : 2 input parameters
|
||||
std::array<VariableType, 2> params = {
|
||||
VariableType::NATIVE_POINTER(),
|
||||
VariableType::JS_POINTER(),
|
||||
};
|
||||
callSign->SetParameters(params.data());
|
||||
callSign->SetGCLeafFunction(true);
|
||||
callSign->SetTargetKind(CallSignature::TargetKind::RUNTIME_STUB_NO_GC);
|
||||
}
|
||||
|
||||
DEF_CALL_SIGNATURE(CreateArrayFromList)
|
||||
{
|
||||
// 3 : 3 input parameters
|
||||
|
@ -437,6 +437,7 @@ private:
|
||||
V(FatalPrintCustom) \
|
||||
V(GetActualArgvNoGC) \
|
||||
V(InsertOldToNewRSet) \
|
||||
V(InsertLocalToShareRSet) \
|
||||
V(DoubleToInt) \
|
||||
V(DoubleToLength) \
|
||||
V(FloatMod) \
|
||||
@ -475,8 +476,6 @@ private:
|
||||
V(JSFunctionEntry) \
|
||||
V(OptimizedFastCallEntry) \
|
||||
V(JSProxyCallInternalWithArgV) \
|
||||
V(TryToElementsIndexOrFindInStringTable) \
|
||||
V(TryGetInternString) \
|
||||
V(CreateArrayFromList) \
|
||||
V(JSObjectGetMethod) \
|
||||
V(JsProxyCallInternal) \
|
||||
|
@ -441,6 +441,17 @@ void CircuitBuilder::AppendFrameArgs(std::vector<GateRef> &args, GateRef hirGate
|
||||
}
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetUnsharedConstpool(GateRef constpool)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto newGate = GetCircuit()->NewGate(circuit_->GetUnsharedConstpool(), MachineType::I64,
|
||||
{ currentDepend, constpool },
|
||||
GateType::AnyType());
|
||||
currentLabel->SetDepend(newGate);
|
||||
return newGate;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetGlobalEnv()
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
@ -523,9 +534,8 @@ GateRef CircuitBuilder::GetMethodFromFunction(GateRef function)
|
||||
|
||||
GateRef CircuitBuilder::GetModuleFromFunction(GateRef function)
|
||||
{
|
||||
GateRef method = GetMethodFromFunction(function);
|
||||
GateRef offset = IntPtr(Method::ECMA_MODULE_OFFSET);
|
||||
return Load(VariableType::JS_POINTER(), method, offset);
|
||||
GateRef offset = IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
||||
return Load(VariableType::JS_POINTER(), function, offset);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetHomeObjectFromFunction(GateRef function)
|
||||
@ -540,6 +550,28 @@ GateRef CircuitBuilder::GetConstPoolFromFunction(GateRef jsFunc)
|
||||
return Load(VariableType::JS_ANY(), method, IntPtr(Method::CONSTANT_POOL_OFFSET));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool)
|
||||
{
|
||||
GateRef unshareIdx = GetUnsharedConstpoolIndex(constpool);
|
||||
GateRef unshareCpOffset = JSThread::GlueData::GetUnSharedConstpoolsOffset(env_->Is32Bit());
|
||||
GateRef unshareCpAddr = Load(VariableType::NATIVE_POINTER(), glue, IntPtr(unshareCpOffset));
|
||||
return GetUnsharedConstpool(unshareCpAddr, unshareIdx);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetUnsharedConstpoolIndex(GateRef constpool)
|
||||
{
|
||||
GateRef constPoolSize = GetLengthOfTaggedArray(constpool);
|
||||
GateRef unshareIdx = Int32Sub(constPoolSize, Int32(ConstantPool::UNSHARED_CONSTPOOL_INDEX));
|
||||
return GetValueFromTaggedArray(constpool, unshareIdx);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetUnsharedConstpool(GateRef arrayAddr, GateRef index)
|
||||
{
|
||||
GateRef dataOffset = PtrAdd(arrayAddr,
|
||||
PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), ZExtInt32ToPtr(TaggedGetInt(index))));
|
||||
return Load(VariableType::JS_ANY(), dataOffset, IntPtr(0));
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetEmptyArray(GateRef glue)
|
||||
{
|
||||
GateRef gConstAddr = Load(VariableType::JS_ANY(), glue,
|
||||
@ -734,7 +766,7 @@ GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef hirGate, Ga
|
||||
{ constPool, Int32ToTaggedInt(index), module }, hirGate);
|
||||
} else {
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetMethodFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index), module }, hirGate);
|
||||
{ constPool, Int32ToTaggedInt(index) }, hirGate);
|
||||
}
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -746,7 +778,7 @@ GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef hirGate, Ga
|
||||
Bind(&isAOTLiteralInfo);
|
||||
{
|
||||
result = CallRuntime(glue, RTSTUB_ID(GetMethodFromCache), Gate::InvalidGateRef,
|
||||
{ constPool, Int32ToTaggedInt(index), module }, hirGate);
|
||||
{ constPool, Int32ToTaggedInt(index) }, hirGate);
|
||||
Jump(&exit);
|
||||
}
|
||||
} else if (type == ConstPoolType::ARRAY_LITERAL) {
|
||||
@ -800,23 +832,30 @@ void CircuitBuilder::SetHomeObjectToFunction(GateRef glue, GateRef function, Gat
|
||||
Store(VariableType::JS_ANY(), glue, function, offset, value);
|
||||
}
|
||||
|
||||
void CircuitBuilder::SetModuleToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
{
|
||||
GateRef offset = IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
||||
Store(VariableType::JS_POINTER(), glue, function, offset, value);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetGlobalEnvValue(VariableType type, GateRef env, size_t index)
|
||||
{
|
||||
auto valueIndex = IntPtr(GlobalEnv::HEADER_SIZE + JSTaggedValue::TaggedTypeSize() * index);
|
||||
return Load(type, env, valueIndex);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetCodeAddr(GateRef method)
|
||||
GateRef CircuitBuilder::GetCodeAddr(GateRef jsFunc)
|
||||
{
|
||||
auto codeAddOffset = IntPtr(Method::CODE_ENTRY_OFFSET);
|
||||
return Load(VariableType::NATIVE_POINTER(), method, codeAddOffset);
|
||||
auto codeAddOffset = IntPtr(JSFunction::CODE_ENTRY_OFFSET);
|
||||
return Load(VariableType::NATIVE_POINTER(), jsFunc, codeAddOffset);
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::GetHClassGateFromIndex(GateRef gate, int32_t index)
|
||||
{
|
||||
ArgumentAccessor argAcc(circuit_);
|
||||
GateRef constPool = argAcc.GetFrameArgsIn(gate, FrameArgIdx::CONST_POOL);
|
||||
return LoadHClassFromConstpool(constPool, index);
|
||||
GateRef unsharedConstpool = GetUnsharedConstpool(constPool);
|
||||
return LoadHClassFromUnsharedConstpool(unsharedConstpool, index);
|
||||
}
|
||||
|
||||
GateRef Variable::AddPhiOperand(GateRef val)
|
||||
|
@ -258,8 +258,12 @@ public:
|
||||
GateRef LoadBuiltinObject(size_t offset);
|
||||
|
||||
// Get
|
||||
GateRef GetUnsharedConstpool(GateRef constpool);
|
||||
GateRef GetConstPoolFromFunction(GateRef jsFunc);
|
||||
GateRef GetCodeAddr(GateRef method);
|
||||
GateRef GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool);
|
||||
GateRef GetUnsharedConstpoolIndex(GateRef constpool);
|
||||
GateRef GetUnsharedConstpool(GateRef arrayAddr, GateRef index);
|
||||
GateRef GetCodeAddr(GateRef jsFunc);
|
||||
GateRef GetObjectFromConstPool(GateRef glue, GateRef hirGate, GateRef constPool, GateRef module, GateRef index,
|
||||
ConstPoolType type);
|
||||
GateRef GetFunctionLexicalEnv(GateRef function);
|
||||
@ -303,6 +307,7 @@ public:
|
||||
void SetLengthToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetLexicalEnvToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetModuleToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
|
||||
inline GateRef LogicAnd(GateRef x, GateRef y);
|
||||
inline GateRef LogicOr(GateRef x, GateRef y);
|
||||
@ -593,7 +598,7 @@ public:
|
||||
GateRef LoadStringLength(GateRef string);
|
||||
GateRef LoadConstOffset(VariableType type, GateRef receiver, size_t offset,
|
||||
MemoryOrder order = MemoryOrder::Default());
|
||||
GateRef LoadHClassFromConstpool(GateRef constpool, size_t index);
|
||||
GateRef LoadHClassFromUnsharedConstpool(GateRef constpool, size_t index);
|
||||
GateRef TypedCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC);
|
||||
GateRef TypedFastCall(GateRef hirGate, std::vector<GateRef> args, bool isNoGC);
|
||||
inline void SetValueToTaggedArray(VariableType valType, GateRef glue, GateRef array, GateRef index, GateRef val);
|
||||
|
@ -991,7 +991,7 @@ void JsProxyCallInternalStubBuilder::GenerateCircuit()
|
||||
BRANCH(IsClassConstructor(method), &slowPath1, ¬CallConstructor1);
|
||||
Bind(¬CallConstructor1);
|
||||
GateRef meth = GetMethodFromFunction(method);
|
||||
GateRef code = GetAotCodeAddr(meth);
|
||||
GateRef code = GetAotCodeAddr(method);
|
||||
BRANCH(JudgeAotAndFastCallWithMethod(meth, CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL),
|
||||
&fastCall1, ¬FastCall1);
|
||||
Bind(&fastCall1);
|
||||
|
@ -327,6 +327,8 @@ namespace panda::ecmascript::kungfu {
|
||||
V(CALLRUNTIME_CALLINIT_PREF_IMM8_V8) \
|
||||
V(CALLRUNTIME_DEFINESENDABLECLASS_PREF_IMM16_ID16_ID16_IMM16_V8) \
|
||||
V(CALLRUNTIME_LDSENDABLECLASS_PREF_IMM16) \
|
||||
V(CALLRUNTIME_LDSENDABLEEXTERNALMODULEVAR_PREF_IMM8) \
|
||||
V(CALLRUNTIME_WIDELDSENDABLEEXTERNALMODULEVAR_PREF_IMM16) \
|
||||
|
||||
inline std::string GetEcmaOpcodeStr(EcmaOpcode opcode)
|
||||
{
|
||||
|
@ -270,15 +270,14 @@ GateRef InterpreterStubBuilder::GetEnvFromFunction(GateRef function)
|
||||
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::LEXICAL_ENV_OFFSET));
|
||||
}
|
||||
|
||||
GateRef InterpreterStubBuilder::GetProfileTypeInfoFromMethod(GateRef method)
|
||||
GateRef InterpreterStubBuilder::GetProfileTypeInfoFromFunction(GateRef function)
|
||||
{
|
||||
return Load(VariableType::JS_POINTER(), method, IntPtr(Method::PROFILE_TYPE_INFO_OFFSET));
|
||||
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::PROFILE_TYPE_INFO_OFFSET));
|
||||
}
|
||||
|
||||
GateRef InterpreterStubBuilder::GetModuleFromFunction(GateRef function)
|
||||
{
|
||||
GateRef method = GetMethodFromFunction(function);
|
||||
return Load(VariableType::JS_POINTER(), method, IntPtr(Method::ECMA_MODULE_OFFSET));
|
||||
return Load(VariableType::JS_POINTER(), function, IntPtr(JSFunction::ECMA_MODULE_OFFSET));
|
||||
}
|
||||
|
||||
GateRef InterpreterStubBuilder::GetHomeObjectFromFunction(GateRef function)
|
||||
@ -315,6 +314,12 @@ GateRef InterpreterStubBuilder::GetResumeModeFromAsyncGeneratorObject(GateRef ob
|
||||
Int32((1LU << JSAsyncGeneratorObject::ResumeModeBits::SIZE) - 1));
|
||||
}
|
||||
|
||||
void InterpreterStubBuilder::SetModuleToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
{
|
||||
GateRef offset = IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
||||
Store(VariableType::JS_POINTER(), glue, function, offset, value);
|
||||
}
|
||||
|
||||
void InterpreterStubBuilder::SetPcToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
{
|
||||
Store(VariableType::INT64(), glue, frame,
|
||||
|
@ -2533,7 +2533,7 @@ DECLARE_ASM_HANDLER(HandleReturn)
|
||||
GateRef function = GetFunctionFromFrame(prevState);
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
CallNGCRuntime(glue, RTSTUB_ID(ResumeRspAndDispatch),
|
||||
@ -2605,7 +2605,7 @@ DECLARE_ASM_HANDLER(HandleReturnundefined)
|
||||
GateRef function = GetFunctionFromFrame(prevState);
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
CallNGCRuntime(glue, RTSTUB_ID(ResumeRspAndDispatch),
|
||||
@ -2687,7 +2687,7 @@ DECLARE_ASM_HANDLER(HandleSuspendgeneratorV8)
|
||||
GateRef function = GetFunctionFromFrame(prevState);
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
CallNGCRuntime(glue, RTSTUB_ID(ResumeRspAndDispatch),
|
||||
@ -2768,7 +2768,7 @@ DECLARE_ASM_HANDLER(HandleDeprecatedSuspendgeneratorPrefV8V8)
|
||||
GateRef function = GetFunctionFromFrame(prevState);
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
CallNGCRuntime(glue, RTSTUB_ID(ResumeRspAndDispatch),
|
||||
@ -3112,7 +3112,7 @@ DECLARE_ASM_HANDLER(HandleAsyncgeneratorresolveV8V8V8)
|
||||
GateRef function = GetFunctionFromFrame(prevState);
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
CallNGCRuntime(glue, RTSTUB_ID(ResumeRspAndDispatch),
|
||||
@ -4388,7 +4388,7 @@ DECLARE_ASM_HANDLER(HandleDefinefuncImm8Id16Imm8)
|
||||
GateRef methodId = ReadInst16_1(pc);
|
||||
GateRef length = ReadInst8_3(pc);
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
GateRef result = newBuilder.NewJSFunction(glue, constpool, GetModule(sp), ZExtInt16ToInt32(methodId));
|
||||
GateRef result = newBuilder.NewJSFunction(glue, constpool, ZExtInt16ToInt32(methodId));
|
||||
Label notException(env);
|
||||
CHECK_EXCEPTION_WITH_JUMP(result, ¬Exception);
|
||||
Bind(¬Exception);
|
||||
@ -4398,6 +4398,7 @@ DECLARE_ASM_HANDLER(HandleDefinefuncImm8Id16Imm8)
|
||||
GateRef envHandle = GetEnvFromFrame(frame);
|
||||
SetLexicalEnvToFunction(glue, result, envHandle);
|
||||
GateRef currentFunc = GetFunctionFromFrame(frame);
|
||||
SetModuleToFunction(glue, result, GetModuleFromFunction(currentFunc));
|
||||
SetHomeObjectToFunction(glue, result, GetHomeObjectFromFunction(currentFunc));
|
||||
callback.ProfileDefineClass(result);
|
||||
varAcc = result;
|
||||
@ -4412,7 +4413,7 @@ DECLARE_ASM_HANDLER(HandleDefinefuncImm16Id16Imm8)
|
||||
GateRef methodId = ReadInst16_2(pc);
|
||||
GateRef length = ReadInst8_4(pc);
|
||||
NewObjectStubBuilder newBuilder(this);
|
||||
GateRef result = newBuilder.NewJSFunction(glue, constpool, GetModule(sp), ZExtInt16ToInt32(methodId));
|
||||
GateRef result = newBuilder.NewJSFunction(glue, constpool, ZExtInt16ToInt32(methodId));
|
||||
Label notException(env);
|
||||
CHECK_EXCEPTION_WITH_JUMP(result, ¬Exception);
|
||||
Bind(¬Exception);
|
||||
@ -4423,6 +4424,7 @@ DECLARE_ASM_HANDLER(HandleDefinefuncImm16Id16Imm8)
|
||||
SetLexicalEnvToFunction(glue, result, envHandle);
|
||||
GateRef currentFunc = GetFunctionFromFrame(frame);
|
||||
SetHomeObjectToFunction(glue, result, GetHomeObjectFromFunction(currentFunc));
|
||||
SetModuleToFunction(glue, result, GetModuleFromFunction(currentFunc));
|
||||
varAcc = result;
|
||||
callback.ProfileDefineClass(result);
|
||||
DISPATCH_WITH_ACC(DEFINEFUNC_IMM16_ID16_IMM8);
|
||||
@ -4437,8 +4439,9 @@ DECLARE_ASM_HANDLER(HandleDefinemethodImm8Id16Imm8)
|
||||
GateRef length = ReadInst8_3(pc);
|
||||
GateRef lexEnv = GetEnvFromFrame(GetFrame(sp));
|
||||
DEFVARIABLE(result, VariableType::JS_POINTER(),
|
||||
GetMethodFromConstPool(glue, constpool, GetModule(sp), ZExtInt16ToInt32(methodId)));
|
||||
result = CallRuntime(glue, RTSTUB_ID(DefineMethod), { *result, acc, Int8ToTaggedInt(length), lexEnv });
|
||||
GetMethodFromConstPool(glue, constpool, ZExtInt16ToInt32(methodId)));
|
||||
result = CallRuntime(glue, RTSTUB_ID(DefineMethod), { *result, acc, Int8ToTaggedInt(length),
|
||||
lexEnv, GetModule(sp) });
|
||||
Label notException(env);
|
||||
CHECK_EXCEPTION_WITH_JUMP(*result, ¬Exception);
|
||||
Bind(¬Exception);
|
||||
@ -4456,8 +4459,9 @@ DECLARE_ASM_HANDLER(HandleDefinemethodImm16Id16Imm8)
|
||||
GateRef length = ReadInst8_4(pc);
|
||||
GateRef lexEnv = GetEnvFromFrame(GetFrame(sp));
|
||||
DEFVARIABLE(result, VariableType::JS_POINTER(),
|
||||
GetMethodFromConstPool(glue, constpool, GetModule(sp), ZExtInt16ToInt32(methodId)));
|
||||
result = CallRuntime(glue, RTSTUB_ID(DefineMethod), { *result, acc, Int8ToTaggedInt(length), lexEnv });
|
||||
GetMethodFromConstPool(glue, constpool, ZExtInt16ToInt32(methodId)));
|
||||
result = CallRuntime(glue, RTSTUB_ID(DefineMethod), { *result, acc, Int8ToTaggedInt(length),
|
||||
lexEnv, GetModule(sp) });
|
||||
Label notException(env);
|
||||
CHECK_EXCEPTION_WITH_JUMP(*result, ¬Exception);
|
||||
Bind(¬Exception);
|
||||
@ -4800,7 +4804,7 @@ DECLARE_ASM_HANDLER_NOPRINT(ExceptionHandler)
|
||||
GateRef function = GetFunctionFromFrame(GetFrame(*varSp));
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
CallNGCRuntime(glue, RTSTUB_ID(ResumeCaughtFrameAndDispatch), {
|
||||
glue, *varSp, *varPc, *varConstpool,
|
||||
@ -4842,7 +4846,7 @@ DECLARE_ASM_HANDLER(SingleStepDebugging)
|
||||
varAcc = GetAccFromFrame(frameAfter);
|
||||
GateRef function = GetFunctionFromFrame(frameAfter);
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
}
|
||||
@ -4921,7 +4925,7 @@ DECLARE_ASM_HANDLER(BCDebuggerEntry)
|
||||
GateRef function = GetFunctionFromFrame(prevState);
|
||||
GateRef method = Load(VariableType::JS_ANY(), function, IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varConstpool = GetConstpoolFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromMethod(method);
|
||||
varProfileTypeInfo = GetProfileTypeInfoFromFunction(function);
|
||||
varHotnessCounter = GetHotnessCounterFromMethod(method);
|
||||
GateRef jumpSize = IntPtr(0);
|
||||
CallNGCRuntime(glue, RTSTUB_ID(ResumeRspAndRollback),
|
||||
@ -5165,6 +5169,48 @@ DECLARE_ASM_HANDLER(HandleCallRuntimeLdSendableClassPrefImm16)
|
||||
DISPATCH_WITH_ACC(CALLRUNTIME_LDSENDABLECLASS_PREF_IMM16);
|
||||
}
|
||||
|
||||
DECLARE_ASM_HANDLER(HandleCallRuntimeLdsendableexternalmodulevarImm8)
|
||||
{
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
|
||||
DEFVARIABLE(moduleRef, VariableType::JS_ANY(), Undefined());
|
||||
GateRef index = ReadInst8_1(pc);
|
||||
|
||||
// LdSendableExternalModuleVarByIndex may load uninitialized module lazy. Exception could happened.
|
||||
GateRef currentFunc = GetFunctionFromFrame(GetFrame(sp));
|
||||
moduleRef = CallRuntime(glue, RTSTUB_ID(LdSendableExternalModuleVarByIndex), {Int8ToTaggedInt(index), currentFunc});
|
||||
|
||||
auto env = GetEnvironment();
|
||||
Label notException(env);
|
||||
CHECK_EXCEPTION_WITH_JUMP(*moduleRef, ¬Exception);
|
||||
Bind(¬Exception);
|
||||
{
|
||||
varAcc = *moduleRef;
|
||||
DISPATCH_WITH_ACC(CALLRUNTIME_LDSENDABLEEXTERNALMODULEVAR_PREF_IMM8);
|
||||
}
|
||||
}
|
||||
|
||||
DECLARE_ASM_HANDLER(HandleCallRuntimeWideLdsendableexternalmodulevarPrefImm16)
|
||||
{
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), acc);
|
||||
DEFVARIABLE(moduleRef, VariableType::JS_ANY(), Undefined());
|
||||
|
||||
GateRef index = ReadInst16_1(pc);
|
||||
|
||||
// LdSendableExternalModuleVarByIndex may load uninitialized module lazy. Exception could happened.
|
||||
GateRef currentFunc = GetFunctionFromFrame(GetFrame(sp));
|
||||
moduleRef =
|
||||
CallRuntime(glue, RTSTUB_ID(LdSendableExternalModuleVarByIndex), {Int16ToTaggedInt(index), currentFunc});
|
||||
|
||||
auto env = GetEnvironment();
|
||||
Label notException(env);
|
||||
CHECK_EXCEPTION_WITH_JUMP(*moduleRef, ¬Exception);
|
||||
Bind(¬Exception);
|
||||
{
|
||||
varAcc = *moduleRef;
|
||||
DISPATCH_WITH_ACC(CALLRUNTIME_WIDELDSENDABLEEXTERNALMODULEVAR_PREF_IMM16);
|
||||
}
|
||||
}
|
||||
|
||||
ASM_INTERPRETER_BC_TYPE_PROFILER_STUB_LIST(DECLARE_ASM_HANDLER_PROFILE)
|
||||
ASM_INTERPRETER_BC_LAYOUT_PROFILER_STUB_LIST(DECLARE_ASM_HANDLER_PROFILE)
|
||||
ASM_INTERPRETER_BC_FUNC_HOT_PROFILER_STUB_LIST(DECLARE_ASM_HANDLER_PROFILE)
|
||||
|
@ -102,7 +102,7 @@ public:
|
||||
inline GateRef GetEnvFromFunction(GateRef frame);
|
||||
inline GateRef GetConstpoolFromMethod(GateRef function);
|
||||
inline GateRef GetModule(GateRef sp);
|
||||
inline GateRef GetProfileTypeInfoFromMethod(GateRef function);
|
||||
inline GateRef GetProfileTypeInfoFromFunction(GateRef function);
|
||||
inline GateRef GetModuleFromFunction(GateRef function);
|
||||
inline GateRef GetHomeObjectFromFunction(GateRef function);
|
||||
inline GateRef GetResumeModeFromGeneratorObject(GateRef obj);
|
||||
@ -117,6 +117,7 @@ public:
|
||||
inline void SetAccToFrame(GateRef glue, GateRef frame, GateRef value);
|
||||
inline void SetEnvToFrame(GateRef glue, GateRef frame, GateRef value);
|
||||
inline void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
inline void SetModuleToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
inline void SetFrameState(GateRef glue, GateRef sp, GateRef function, GateRef acc,
|
||||
GateRef env, GateRef pc, GateRef prev, GateRef type);
|
||||
|
||||
|
@ -33,6 +33,7 @@ GateRef LaterElimination::VisitGate(GateRef gate)
|
||||
{
|
||||
auto opcode = acc_.GetOpCode(gate);
|
||||
switch (opcode) {
|
||||
case OpCode::GET_UNSHARED_CONSTPOOL:
|
||||
case OpCode::GET_GLOBAL_ENV:
|
||||
case OpCode::GET_GLOBAL_ENV_OBJ:
|
||||
case OpCode::GET_GLOBAL_ENV_OBJ_HCLASS:
|
||||
|
@ -851,11 +851,11 @@ GateRef CircuitBuilder::LoadConstOffset(VariableType type, GateRef receiver, siz
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef CircuitBuilder::LoadHClassFromConstpool(GateRef constpool, size_t index)
|
||||
GateRef CircuitBuilder::LoadHClassFromUnsharedConstpool(GateRef constpool, size_t index)
|
||||
{
|
||||
auto currentLabel = env_->GetCurrentLabel();
|
||||
auto currentDepend = currentLabel->GetDepend();
|
||||
auto ret = GetCircuit()->NewGate(circuit_->LoadHClassFromConstpool(index), MachineType::I64,
|
||||
auto ret = GetCircuit()->NewGate(circuit_->LoadHClassFromUnsharedConstpool(index), MachineType::I64,
|
||||
{ currentDepend, constpool }, GateType::AnyType());
|
||||
currentLabel->SetDepend(ret);
|
||||
return ret;
|
||||
|
@ -28,6 +28,9 @@ GateRef MCRLowering::VisitGate(GateRef gate)
|
||||
{
|
||||
auto op = acc_.GetOpCode(gate);
|
||||
switch (op) {
|
||||
case OpCode::GET_UNSHARED_CONSTPOOL:
|
||||
LowerGetUnsharedConstpool(gate);
|
||||
break;
|
||||
case OpCode::STATE_SPLIT:
|
||||
DeleteStateSplit(gate);
|
||||
break;
|
||||
@ -50,7 +53,7 @@ GateRef MCRLowering::VisitGate(GateRef gate)
|
||||
LowerLoadConstOffset(gate);
|
||||
break;
|
||||
case OpCode::LOAD_HCLASS_FROM_CONSTPOOL:
|
||||
LowerLoadHClassFromConstpool(gate);
|
||||
LowerLoadHClassFromUnsharedConstpool(gate);
|
||||
break;
|
||||
case OpCode::STORE_CONST_OFFSET:
|
||||
LowerStoreConstOffset(gate);
|
||||
@ -163,7 +166,7 @@ void MCRLowering::LowerLoadConstOffset(GateRef gate)
|
||||
acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void MCRLowering::LowerLoadHClassFromConstpool(GateRef gate)
|
||||
void MCRLowering::LowerLoadHClassFromUnsharedConstpool(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef constpool = acc_.GetValueIn(gate, 0);
|
||||
@ -261,6 +264,18 @@ void MCRLowering::LowerIsSpecificObjectType(GateRef gate)
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void MCRLowering::LowerGetUnsharedConstpool(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef constpool = acc_.GetValueIn(gate, 0); // 0: this object
|
||||
GateRef newGate = builder_.GetUnsharedConstpoolFromGlue(glue_, constpool);
|
||||
|
||||
acc_.UpdateAllUses(gate, newGate);
|
||||
|
||||
// delete old gate
|
||||
acc_.DeleteGate(gate);
|
||||
}
|
||||
|
||||
void MCRLowering::DeleteStateSplit(GateRef gate)
|
||||
{
|
||||
auto depend = acc_.GetDep(gate);
|
||||
@ -825,6 +840,15 @@ void MCRLowering::LowerGetGlobalConstantValue(GateRef gate)
|
||||
acc_.ReplaceGate(gate, Circuit::NullGate(), builder_.GetDepend(), result);
|
||||
}
|
||||
|
||||
void MCRLowering::HeapAllocateInSOld(GateRef gate)
|
||||
{
|
||||
GateRef size = acc_.GetValueIn(gate, 0);
|
||||
GateRef ret = builder_.CallRuntime(glue_, RTSTUB_ID(AllocateInSOld), Gate::InvalidGateRef,
|
||||
{builder_.ToTaggedInt(size)}, gate);
|
||||
|
||||
acc_.ReplaceGate(gate, builder_.GetState(), builder_.GetDepend(), ret);
|
||||
}
|
||||
|
||||
void MCRLowering::LowerInt32CheckRightIsZero(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
|
@ -46,8 +46,9 @@ private:
|
||||
void LowerHClassStableArrayCheck(GateRef gate);
|
||||
void LowerElementskindCheck(GateRef gate);
|
||||
void LowerGetConstPool(GateRef gate);
|
||||
void LowerGetUnsharedConstpool(GateRef gate);
|
||||
void LowerLoadConstOffset(GateRef gate);
|
||||
void LowerLoadHClassFromConstpool(GateRef gate);
|
||||
void LowerLoadHClassFromUnsharedConstpool(GateRef gate);
|
||||
void LowerStoreConstOffset(GateRef gate);
|
||||
void LowerConvertHoleAsUndefined(GateRef gate);
|
||||
void LowerCheckAndConvert(GateRef gate);
|
||||
@ -98,6 +99,7 @@ private:
|
||||
GateRef ConvertTaggedNumberToInt32(GateRef gate, Label *exit);
|
||||
GateRef ConvertTaggedNumberToFloat64(GateRef gate, Label *exit);
|
||||
GateRef ConvertTaggedBooleanToBool(GateRef gate);
|
||||
void HeapAllocateInSOld(GateRef gate);
|
||||
void InitializeWithSpeicalValue(Label *exit, GateRef object, GateRef glue, GateRef value,
|
||||
GateRef start, GateRef end);
|
||||
|
||||
|
@ -91,7 +91,7 @@ namespace panda::ecmascript::kungfu {
|
||||
|
||||
#define MCR_GATE_META_DATA_LIST_WITH_VALUE(V) \
|
||||
V(LoadConstOffset, LOAD_CONST_OFFSET, GateFlags::NO_WRITE, 0, 1, 1) \
|
||||
V(LoadHClassFromConstpool, LOAD_HCLASS_FROM_CONSTPOOL, GateFlags::NO_WRITE, 0, 1, 1) \
|
||||
V(LoadHClassFromUnsharedConstpool, LOAD_HCLASS_FROM_CONSTPOOL, GateFlags::NO_WRITE, 0, 1, 1) \
|
||||
V(StoreConstOffset, STORE_CONST_OFFSET, GateFlags::NONE_FLAG, 0, 1, 2) \
|
||||
V(LoadElement, LOAD_ELEMENT, GateFlags::NO_WRITE, 1, 1, 2) \
|
||||
V(StoreElement, STORE_ELEMENT, GateFlags::NONE_FLAG, 1, 1, 3) \
|
||||
|
@ -599,30 +599,39 @@ GateRef NewObjectStubBuilder::LoadHClassFromMethod(GateRef glue, GateRef method)
|
||||
return ret;
|
||||
}
|
||||
|
||||
GateRef NewObjectStubBuilder::NewJSFunction(GateRef glue, GateRef constpool, GateRef module, GateRef index)
|
||||
GateRef NewObjectStubBuilder::NewJSFunction(GateRef glue, GateRef constpool, GateRef index)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
Label subentry(env);
|
||||
env->SubCfgEntry(&subentry);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(ihc, VariableType::JS_ANY(), Undefined());
|
||||
DEFVARIABLE(val, VariableType::JS_ANY(), Undefined());
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
auto val = GetValueFromTaggedArray(constpool, index);
|
||||
|
||||
val = GetValueFromTaggedArray(constpool, index);
|
||||
|
||||
Label isHeapObject(env);
|
||||
Label afterAOTLiteral(env);
|
||||
BRANCH(TaggedIsHeapObject(val), &isHeapObject, &afterAOTLiteral);
|
||||
BRANCH(TaggedIsHeapObject(*val), &isHeapObject, &afterAOTLiteral);
|
||||
{
|
||||
Bind(&isHeapObject);
|
||||
Label isAOTLiteral(env);
|
||||
BRANCH(IsAOTLiteralInfo(val), &isAOTLiteral, &afterAOTLiteral);
|
||||
BRANCH(IsAOTLiteralInfo(*val), &isAOTLiteral, &afterAOTLiteral);
|
||||
{
|
||||
Bind(&isAOTLiteral);
|
||||
ihc = GetIhcFromAOTLiteralInfo(val);
|
||||
// Avoiding shareobj references to unshareobj.
|
||||
GateRef unshareIdx = GetUnsharedConstpoolIndex(constpool);
|
||||
GateRef unshareCpOffset = JSThread::GlueData::GetUnSharedConstpoolsOffset(env->Is32Bit());
|
||||
GateRef unshareCpAddr = Load(VariableType::NATIVE_POINTER(), glue, IntPtr(unshareCpOffset));
|
||||
GateRef unshareCp = GetUnsharedConstpool(unshareCpAddr, unshareIdx);
|
||||
val = GetValueFromTaggedArray(unshareCp, index);
|
||||
ihc = GetIhcFromAOTLiteralInfo(*val);
|
||||
Jump(&afterAOTLiteral);
|
||||
}
|
||||
}
|
||||
Bind(&afterAOTLiteral);
|
||||
GateRef method = GetMethodFromConstPool(glue, constpool, module, index);
|
||||
GateRef method = GetMethodFromConstPool(glue, constpool, index);
|
||||
GateRef hclass = LoadHClassFromMethod(glue, method);
|
||||
result = NewJSObject(glue, hclass);
|
||||
SetExtensibleToBitfield(glue, hclass, true);
|
||||
@ -631,6 +640,16 @@ GateRef NewObjectStubBuilder::NewJSFunction(GateRef glue, GateRef constpool, Gat
|
||||
InitializeJSFunction(glue, *result, kind);
|
||||
SetMethodToFunction(glue, *result, method);
|
||||
|
||||
Label isAotWithCallField(env);
|
||||
Label afterAotWithCallField(env);
|
||||
BRANCH(IsAotWithCallField(method), &isAotWithCallField, &afterAotWithCallField);
|
||||
{
|
||||
Bind(&isAotWithCallField);
|
||||
SetCodeEntryToFunction(glue, *result, method);
|
||||
Jump(&afterAotWithCallField);
|
||||
}
|
||||
Bind(&afterAotWithCallField);
|
||||
|
||||
Label ihcNotUndefined(env);
|
||||
BRANCH(TaggedIsUndefined(*ihc), &exit, &ihcNotUndefined);
|
||||
Bind(&ihcNotUndefined);
|
||||
@ -651,8 +670,7 @@ void NewObjectStubBuilder::NewJSFunction(GateRef glue, GateRef jsFunc, GateRef i
|
||||
Label hasException(env);
|
||||
Label notException(env);
|
||||
GateRef constPool = GetConstPoolFromFunction(jsFunc);
|
||||
GateRef module = GetModuleFromFunction(jsFunc);
|
||||
result->WriteVariable(NewJSFunction(glue, constPool, module, index));
|
||||
result->WriteVariable(NewJSFunction(glue, constPool, index));
|
||||
BRANCH(HasPendingException(glue), &hasException, ¬Exception);
|
||||
Bind(&hasException);
|
||||
{
|
||||
@ -662,6 +680,7 @@ void NewObjectStubBuilder::NewJSFunction(GateRef glue, GateRef jsFunc, GateRef i
|
||||
{
|
||||
SetLengthToFunction(glue_, result->ReadVariable(), length);
|
||||
SetLexicalEnvToFunction(glue_, result->ReadVariable(), lexEnv);
|
||||
SetModuleToFunction(glue_, result->ReadVariable(), GetModuleFromFunction(jsFunc));
|
||||
SetHomeObjectToFunction(glue_, result->ReadVariable(), GetHomeObjectFromFunction(jsFunc));
|
||||
Jump(success);
|
||||
}
|
||||
@ -916,6 +935,14 @@ void NewObjectStubBuilder::HeapAlloc(Variable *result, Label *exit, RegionSpaceF
|
||||
}
|
||||
}
|
||||
|
||||
void NewObjectStubBuilder::AllocateInSOld(Variable *result, Label *exit)
|
||||
{
|
||||
DEFVARIABLE(ret, VariableType::JS_ANY(), Undefined());
|
||||
ret = CallRuntime(glue_, RTSTUB_ID(AllocateInSOld), {IntToTaggedInt(size_)});
|
||||
result->WriteVariable(*ret);
|
||||
Jump(exit);
|
||||
}
|
||||
|
||||
void NewObjectStubBuilder::AllocateInYoungPrologue(Variable *result, Label *callRuntime, Label *exit)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
@ -1057,7 +1084,7 @@ void NewObjectStubBuilder::AllocLineStringObject(Variable *result, Label *exit,
|
||||
IntPtr(static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT)));
|
||||
}
|
||||
Label afterAllocate(env);
|
||||
AllocateInYoung(result, &afterAllocate);
|
||||
AllocateInSOld(result, &afterAllocate);
|
||||
|
||||
Bind(&afterAllocate);
|
||||
GateRef stringClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue_,
|
||||
@ -1075,7 +1102,7 @@ void NewObjectStubBuilder::AllocSlicedStringObject(Variable *result, Label *exit
|
||||
|
||||
size_ = AlignUp(IntPtr(SlicedString::SIZE), IntPtr(static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT)));
|
||||
Label afterAllocate(env);
|
||||
AllocateInYoung(result, &afterAllocate);
|
||||
AllocateInSOld(result, &afterAllocate);
|
||||
|
||||
Bind(&afterAllocate);
|
||||
GateRef stringClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue_,
|
||||
@ -1100,7 +1127,7 @@ void NewObjectStubBuilder::AllocTreeStringObject(Variable *result, Label *exit,
|
||||
|
||||
size_ = AlignUp(IntPtr(TreeEcmaString::SIZE), IntPtr(static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT)));
|
||||
Label afterAllocate(env);
|
||||
AllocateInYoung(result, &afterAllocate);
|
||||
AllocateInSOld(result, &afterAllocate);
|
||||
|
||||
Bind(&afterAllocate);
|
||||
GateRef stringClass = GetGlobalConstantValue(VariableType::JS_POINTER(), glue_,
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
GateRef NewJSArrayWithSize(GateRef hclass, GateRef size);
|
||||
GateRef NewJSForinIterator(GateRef glue, GateRef receiver, GateRef keys, GateRef cachedHclass);
|
||||
GateRef LoadHClassFromMethod(GateRef glue, GateRef method);
|
||||
GateRef NewJSFunction(GateRef glue, GateRef constpool, GateRef module, GateRef index);
|
||||
GateRef NewJSFunction(GateRef glue, GateRef constpool, GateRef index);
|
||||
void NewJSFunction(GateRef glue, GateRef jsFunc, GateRef index, GateRef length, GateRef lexEnv,
|
||||
Variable *result, Label *success, Label *failed);
|
||||
void InitializeJSFunction(GateRef glue, GateRef func, GateRef kind);
|
||||
@ -98,6 +98,7 @@ private:
|
||||
void AllocateInYoungPrologue(Variable *result, Label *callRuntime, Label *exit);
|
||||
void AllocateInYoung(Variable *result, Label *exit);
|
||||
void AllocateInYoung(Variable *result, Label *error, Label *noError);
|
||||
void AllocateInSOld(Variable *result, Label *exit);
|
||||
void InitializeTaggedArrayWithSpeicalValue(Label *exit,
|
||||
GateRef array, GateRef value, GateRef start, GateRef length);
|
||||
GateRef glue_ {Circuit::NullGate()};
|
||||
|
@ -145,8 +145,9 @@ void NTypeHCRLowering::LowerCreateArguments(GateRef gate, GateRef glue)
|
||||
}
|
||||
}
|
||||
|
||||
GateRef NTypeHCRLowering::LoadFromConstPool(GateRef constPool, size_t index, size_t valVecType)
|
||||
GateRef NTypeHCRLowering::LoadFromConstPool(GateRef constpool, size_t index, size_t valVecType)
|
||||
{
|
||||
GateRef constPool = builder_.GetUnsharedConstpool(constpool);
|
||||
GateRef constPoolSize = builder_.GetLengthOfTaggedArray(constPool);
|
||||
GateRef valVecIndex = builder_.Int32Sub(constPoolSize, builder_.Int32(valVecType));
|
||||
GateRef valVec = builder_.GetValueFromTaggedArray(constPool, valVecIndex);
|
||||
@ -254,9 +255,8 @@ void NTypeHCRLowering::LowerStoreModuleVar(GateRef gate, GateRef glue)
|
||||
GateRef jsFunc = acc_.GetValueIn(gate, 0);
|
||||
GateRef index = acc_.GetValueIn(gate, 1);
|
||||
GateRef value = acc_.GetValueIn(gate, 2);
|
||||
GateRef method = builder_.GetMethodFromFunction(jsFunc);
|
||||
GateRef moduleOffset = builder_.IntPtr(Method::ECMA_MODULE_OFFSET);
|
||||
GateRef module = builder_.Load(VariableType::JS_ANY(), method, moduleOffset);
|
||||
GateRef moduleOffset = builder_.IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
||||
GateRef module = builder_.Load(VariableType::JS_ANY(), jsFunc, moduleOffset);
|
||||
GateRef localExportEntriesOffset = builder_.IntPtr(SourceTextModule::LOCAL_EXPORT_ENTTRIES_OFFSET);
|
||||
GateRef localExportEntries = builder_.Load(VariableType::JS_ANY(), module, localExportEntriesOffset);
|
||||
GateRef nameDictionaryOffset = builder_.IntPtr(SourceTextModule::NAME_DICTIONARY_OFFSET);
|
||||
@ -286,9 +286,8 @@ void NTypeHCRLowering::LowerLdLocalModuleVar(GateRef gate)
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef jsFunc = acc_.GetValueIn(gate, 0);
|
||||
GateRef index = acc_.GetValueIn(gate, 1);
|
||||
GateRef method = builder_.GetMethodFromFunction(jsFunc);
|
||||
GateRef moduleOffset = builder_.IntPtr(Method::ECMA_MODULE_OFFSET);
|
||||
GateRef module = builder_.Load(VariableType::JS_ANY(), method, moduleOffset);
|
||||
GateRef moduleOffset = builder_.IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
||||
GateRef module = builder_.Load(VariableType::JS_ANY(), jsFunc, moduleOffset);
|
||||
GateRef nameDictionaryOffset = builder_.IntPtr(SourceTextModule::NAME_DICTIONARY_OFFSET);
|
||||
GateRef dictionary = builder_.Load(VariableType::JS_ANY(), module, nameDictionaryOffset);
|
||||
DEFVALUE(result, (&builder_), VariableType::JS_ANY(), builder_.Hole());
|
||||
|
@ -74,7 +74,9 @@ private:
|
||||
JSTaggedValue GetArrayLiteralValue(uint32_t cpId, uint32_t cpIdx)
|
||||
{
|
||||
JSTaggedValue cp = GetConstantpoolValue(cpId);
|
||||
return ConstantPool::GetLiteralFromCache<ConstPoolType::ARRAY_LITERAL>(thread_, cp, cpIdx, recordName_);
|
||||
JSTaggedValue unsharedCp = thread_->GetCurrentEcmaContext()->FindUnsharedConstpool(cp);
|
||||
return ConstantPool::GetLiteralFromCache<ConstPoolType::ARRAY_LITERAL>(
|
||||
thread_, unsharedCp, cpIdx, recordName_);
|
||||
}
|
||||
|
||||
Circuit *circuit_ {nullptr};
|
||||
|
@ -1007,7 +1007,8 @@ void NumberSpeculativeLowering::VisitLoadPropertyOnProto(GateRef gate)
|
||||
auto receiverHC = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, TaggedObject::HCLASS_OFFSET);
|
||||
auto prototype = builder_.LoadConstOffset(VariableType::JS_ANY(), receiverHC, JSHClass::PROTOTYPE_OFFSET);
|
||||
|
||||
auto holderHC = builder_.LoadHClassFromConstpool(constpool, acc_.GetConstantValue(hclassIndex));
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constpool);
|
||||
auto holderHC = builder_.LoadHClassFromUnsharedConstpool(unsharedConstpool, acc_.GetConstantValue(hclassIndex));
|
||||
DEFVALUE(current, (&builder_), VariableType::JS_ANY(), prototype);
|
||||
Label exit(&builder_);
|
||||
Label loopHead(&builder_);
|
||||
|
@ -72,7 +72,8 @@ void PostSchedule::GenerateExtraBB(ControlFlowGraph &cfg)
|
||||
|
||||
bool PostSchedule::VisitHeapAlloc(GateRef gate, ControlFlowGraph &cfg, size_t bbIdx, size_t instIdx)
|
||||
{
|
||||
ASSERT(acc_.TryGetValue(gate) == RegionSpaceFlag::IN_YOUNG_SPACE);
|
||||
ASSERT(acc_.TryGetValue(gate) == RegionSpaceFlag::IN_YOUNG_SPACE ||
|
||||
acc_.TryGetValue(gate) == RegionSpaceFlag::IN_SHARED_OLD_SPACE);
|
||||
std::vector<GateRef> currentBBGates;
|
||||
std::vector<GateRef> successBBGates;
|
||||
std::vector<GateRef> failBBGates;
|
||||
|
@ -407,7 +407,7 @@ GateRef ProfilerStubBuilder::UpdateTrackTypeInPropAttr(GateRef attr, GateRef val
|
||||
|
||||
GateRef oldTrackType = GetTrackTypeInPropAttr(attr);
|
||||
DEFVARIABLE(newTrackType, VariableType::INT32(), Int32(static_cast<int32_t>(TrackType::TAGGED)));
|
||||
DEFVARIABLE(result, VariableType::INT32(), attr);
|
||||
DEFVARIABLE(result, VariableType::INT64(), attr);
|
||||
|
||||
Label exit(env);
|
||||
Label judgeValue(env);
|
||||
@ -451,8 +451,7 @@ void ProfilerStubBuilder::UpdatePropAttrIC(
|
||||
GateRef attrIndex = HandlerBaseGetAttrIndex(handler);
|
||||
GateRef hclass = LoadHClass(receiver);
|
||||
GateRef layout = GetLayoutFromHClass(hclass);
|
||||
GateRef propAttr = GetPropAttrFromLayoutInfo(layout, attrIndex);
|
||||
GateRef attr = GetInt32OfTInt(propAttr);
|
||||
GateRef attr = GetPropAttrFromLayoutInfo(layout, attrIndex);
|
||||
GateRef newAttr = UpdateTrackTypeInPropAttr(attr, value, callback);
|
||||
BRANCH(IsJSShared(receiver), &exit, &handleUnShared);
|
||||
Bind(&handleUnShared);
|
||||
|
@ -45,6 +45,7 @@ namespace panda::ecmascript::kungfu {
|
||||
V(IfSuccess, IF_SUCCESS, GateFlags::CONTROL, 1, 0, 0) \
|
||||
V(IfException, IF_EXCEPTION, GateFlags::CONTROL, 1, 1, 0) \
|
||||
V(GetException, GET_EXCEPTION, GateFlags::NONE_FLAG, 1, 1, 0) \
|
||||
V(GetUnsharedConstpool, GET_UNSHARED_CONSTPOOL, GateFlags::NO_WRITE, 0, 1, 1) \
|
||||
V(GetGlobalEnv, GET_GLOBAL_ENV, GateFlags::NO_WRITE, 0, 1, 0) \
|
||||
V(GetSuperConstructor, GET_SUPER_CONSTRUCTOR, GateFlags::NO_WRITE, 1, 1, 1) \
|
||||
V(CheckSafePointAndStackOver, CHECK_SAFEPOINT_AND_STACKOVER, GateFlags::NO_WRITE, 1, 1, 0) \
|
||||
|
@ -745,6 +745,10 @@ void SlowPathLowering::Lower(GateRef gate)
|
||||
case EcmaOpcode::CALLRUNTIME_LDSENDABLECLASS_PREF_IMM16:
|
||||
LowerLdSendableClass(gate);
|
||||
break;
|
||||
case EcmaOpcode::CALLRUNTIME_LDSENDABLEEXTERNALMODULEVAR_PREF_IMM8:
|
||||
case EcmaOpcode::CALLRUNTIME_WIDELDSENDABLEEXTERNALMODULEVAR_PREF_IMM16:
|
||||
LowerSendableExternalModule(gate);
|
||||
break;
|
||||
case EcmaOpcode::LDA_STR_ID16:
|
||||
LowerLdStr(gate);
|
||||
break;
|
||||
@ -2674,7 +2678,7 @@ void SlowPathLowering::LowerDefineMethod(GateRef gate)
|
||||
Label successExit(&builder_);
|
||||
Label exceptionExit(&builder_);
|
||||
GateRef result = LowerCallRuntime(gate, RTSTUB_ID(DefineMethod),
|
||||
{method, homeObject, builder_.ToTaggedInt(length), env}, true);
|
||||
{method, homeObject, builder_.ToTaggedInt(length), env, builder_.GetModuleFromFunction(jsFunc)}, true);
|
||||
BRANCH_CIR(builder_.IsSpecial(result, JSTaggedValue::VALUE_EXCEPTION),
|
||||
&exceptionExit, &successExit);
|
||||
CREATE_DOUBLE_EXIT(successExit, exceptionExit)
|
||||
@ -2967,7 +2971,7 @@ void SlowPathLowering::LowerFastCall(GateRef gate, GateRef glue, GateRef func, G
|
||||
builder_.Bind(&call);
|
||||
{
|
||||
builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true);
|
||||
GateRef code = builder_.GetCodeAddr(method);
|
||||
GateRef code = builder_.GetCodeAddr(func);
|
||||
auto depend = builder_.GetDepend();
|
||||
const CallSignature *cs = RuntimeStubCSigns::GetOptimizedFastCallSign();
|
||||
result->WriteVariable(builder_.Call(cs, glue, code, depend, argsFastCall, gate, "callFastAOT"));
|
||||
@ -2997,7 +3001,7 @@ void SlowPathLowering::LowerFastCall(GateRef gate, GateRef glue, GateRef func, G
|
||||
builder_.Bind(&call1);
|
||||
{
|
||||
builder_.StartCallTimer(glue_, gate, {glue_, func, builder_.True()}, true);
|
||||
GateRef code = builder_.GetCodeAddr(method);
|
||||
GateRef code = builder_.GetCodeAddr(func);
|
||||
auto depend = builder_.GetDepend();
|
||||
const CallSignature *cs = RuntimeStubCSigns::GetOptimizedCallSign();
|
||||
result->WriteVariable(builder_.Call(cs, glue, code, depend, args, gate, "callAOT"));
|
||||
@ -3043,8 +3047,7 @@ void SlowPathLowering::LowerTypedCall(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef func = acc_.GetValueIn(gate, static_cast<size_t>(CommonArgIdx::FUNC));
|
||||
GateRef method = builder_.GetMethodFromFunction(func);
|
||||
GateRef code = builder_.GetCodeAddr(method);
|
||||
GateRef code = builder_.GetCodeAddr(func);
|
||||
size_t num = acc_.GetNumValueIn(gate);
|
||||
std::vector<GateRef> args(num);
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
@ -3061,8 +3064,7 @@ void SlowPathLowering::LowerTypedFastCall(GateRef gate)
|
||||
{
|
||||
Environment env(gate, circuit_, &builder_);
|
||||
GateRef func = acc_.GetValueIn(gate, static_cast<size_t>(FastCallArgIdx::FUNC));
|
||||
GateRef method = builder_.GetMethodFromFunction(func);
|
||||
GateRef code = builder_.GetCodeAddr(method);
|
||||
GateRef code = builder_.GetCodeAddr(func);
|
||||
size_t num = acc_.GetNumValueIn(gate);
|
||||
std::vector<GateRef> args(num);
|
||||
for (size_t i = 0; i < num; ++i) {
|
||||
@ -3278,6 +3280,16 @@ void SlowPathLowering::LowerLdSendableClass(GateRef gate)
|
||||
ReplaceHirWithValue(gate, newGate);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerSendableExternalModule(GateRef gate)
|
||||
{
|
||||
ASSERT(acc_.GetNumValueIn(gate) == 1);
|
||||
GateRef jsFunc = argAcc_.GetFrameArgsIn(gate, FrameArgIdx::FUNC);
|
||||
GateRef index = builder_.ToTaggedInt(acc_.GetValueIn(gate, 0));
|
||||
GateRef result = LowerCallRuntime(gate,
|
||||
RTSTUB_ID(LdSendableExternalModuleVarByIndex), {index, jsFunc}, true);
|
||||
ReplaceHirWithValue(gate, result);
|
||||
}
|
||||
|
||||
void SlowPathLowering::LowerCallInit(GateRef gate)
|
||||
{
|
||||
// same as callthis0
|
||||
|
@ -237,6 +237,7 @@ private:
|
||||
void LowerLdLocalModuleVarByIndex(GateRef gate);
|
||||
void LowerExternalModule(GateRef gate);
|
||||
void LowerGetModuleNamespace(GateRef gate);
|
||||
void LowerSendableExternalModule(GateRef gate);
|
||||
void LowerSuperCall(GateRef gate);
|
||||
void LowerSuperCallArrow(GateRef gate);
|
||||
void LowerSuperCallSpread(GateRef gate);
|
||||
|
@ -243,9 +243,9 @@ inline GateRef StubBuilder::CallOptimized(GateRef glue, GateRef code, const std:
|
||||
return result;
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetAotCodeAddr(GateRef method)
|
||||
inline GateRef StubBuilder::GetAotCodeAddr(GateRef jsFunc)
|
||||
{
|
||||
return env_->GetBuilder()->GetCodeAddr(method);
|
||||
return env_->GetBuilder()->GetCodeAddr(jsFunc);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::CallStub(GateRef glue, int index, const std::initializer_list<GateRef>& args)
|
||||
@ -1435,7 +1435,7 @@ inline GateRef StubBuilder::IsWritable(GateRef attr)
|
||||
{
|
||||
return Int32NotEqual(
|
||||
Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::WritableField::START_BIT)),
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::WritableField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::WritableField::SIZE) - 1)),
|
||||
Int32(0));
|
||||
}
|
||||
@ -1444,7 +1444,7 @@ inline GateRef StubBuilder::IsDefaultAttribute(GateRef attr)
|
||||
{
|
||||
return Int32NotEqual(
|
||||
Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::DefaultAttributesField::START_BIT)),
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::DefaultAttributesField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::DefaultAttributesField::SIZE) - 1)),
|
||||
Int32(0));
|
||||
}
|
||||
@ -1453,7 +1453,7 @@ inline GateRef StubBuilder::IsConfigable(GateRef attr)
|
||||
{
|
||||
return Int32NotEqual(
|
||||
Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::ConfigurableField::START_BIT)),
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::ConfigurableField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::ConfigurableField::SIZE) - 1)),
|
||||
Int32(0));
|
||||
}
|
||||
@ -1461,8 +1461,8 @@ inline GateRef StubBuilder::IsConfigable(GateRef attr)
|
||||
inline GateRef StubBuilder::IsAccessor(GateRef attr)
|
||||
{
|
||||
return Int32NotEqual(
|
||||
Int32And(Int32LSR(attr,
|
||||
Int32(PropertyAttributes::IsAccessorField::START_BIT)),
|
||||
Int32And(
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::IsAccessorField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::IsAccessorField::SIZE) - 1)),
|
||||
Int32(0));
|
||||
}
|
||||
@ -1470,8 +1470,8 @@ inline GateRef StubBuilder::IsAccessor(GateRef attr)
|
||||
inline GateRef StubBuilder::IsEnumerable(GateRef attr)
|
||||
{
|
||||
return Int32NotEqual(
|
||||
Int32And(Int32LSR(attr,
|
||||
Int32(PropertyAttributes::EnumerableField::START_BIT)),
|
||||
Int32And(
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::EnumerableField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::EnumerableField::SIZE) - 1)),
|
||||
Int32(0));
|
||||
}
|
||||
@ -1479,8 +1479,8 @@ inline GateRef StubBuilder::IsEnumerable(GateRef attr)
|
||||
inline GateRef StubBuilder::IsInlinedProperty(GateRef attr)
|
||||
{
|
||||
return Int32NotEqual(
|
||||
Int32And(Int32LSR(attr,
|
||||
Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)),
|
||||
Int32And(
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::IsInlinedPropsField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1)),
|
||||
Int32(0));
|
||||
}
|
||||
@ -1800,18 +1800,18 @@ inline GateRef StubBuilder::GetTransWithProtoHandlerInfo(GateRef obj)
|
||||
inline GateRef StubBuilder::PropAttrGetOffset(GateRef attr)
|
||||
{
|
||||
return Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::OffsetField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
|
||||
}
|
||||
|
||||
// SetDictionaryOrder func in property_attribute.h
|
||||
inline GateRef StubBuilder::SetDictionaryOrderFieldInPropAttr(GateRef attr, GateRef value)
|
||||
{
|
||||
GateRef mask = Int32LSL(
|
||||
Int32((1LLU << PropertyAttributes::DictionaryOrderField::SIZE) - 1),
|
||||
Int32(PropertyAttributes::DictionaryOrderField::START_BIT));
|
||||
GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
|
||||
Int32LSL(value, Int32(PropertyAttributes::DictionaryOrderField::START_BIT)));
|
||||
GateRef mask = Int64LSL(
|
||||
Int64((1LLU << PropertyAttributes::DictionaryOrderField::SIZE) - 1),
|
||||
Int64(PropertyAttributes::DictionaryOrderField::START_BIT));
|
||||
GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
|
||||
Int64LSL(value, Int64(PropertyAttributes::DictionaryOrderField::START_BIT)));
|
||||
return newVal;
|
||||
}
|
||||
|
||||
@ -2106,6 +2106,20 @@ inline GateRef StubBuilder::GetValueFromTaggedArray(GateRef array, GateRef index
|
||||
return Load(VariableType::JS_ANY(), array, dataOffset);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetUnsharedConstpoolIndex(GateRef constpool)
|
||||
{
|
||||
GateRef constPoolSize = GetLengthOfTaggedArray(constpool);
|
||||
GateRef unshareIdx = Int32Sub(constPoolSize, Int32(ConstantPool::UNSHARED_CONSTPOOL_INDEX));
|
||||
return GetValueFromTaggedArray(constpool, unshareIdx);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetUnsharedConstpool(GateRef arrayAddr, GateRef index)
|
||||
{
|
||||
GateRef dataOffset =
|
||||
PtrAdd(arrayAddr, PtrMul(IntPtr(JSTaggedValue::TaggedTypeSize()), ZExtInt32ToPtr(TaggedGetInt(index))));
|
||||
return Load(VariableType::JS_ANY(), dataOffset);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetValueFromMutantTaggedArray(GateRef elements, GateRef index)
|
||||
{
|
||||
GateRef offset = PtrMul(ZExtInt32ToPtr(index), IntPtr(sizeof(int64_t)));
|
||||
@ -2127,8 +2141,8 @@ inline void StubBuilder::CheckUpdateSharedType(bool isDicMode, Variable *result,
|
||||
Bind(&isSharedObj);
|
||||
{
|
||||
Label typeMismatch(env);
|
||||
GateRef trackType = isDicMode ? GetDictTrackTypeInPropAttr(attr) : GetTrackTypeInPropAttr(attr);
|
||||
MatchTrackType(trackType, value, executeSetProp, &typeMismatch);
|
||||
GateRef fieldType = isDicMode ? GetDictSharedFieldTypeInPropAttr(attr) : GetSharedFieldTypeInPropAttr(attr);
|
||||
MatchFieldType(fieldType, value, executeSetProp, &typeMismatch);
|
||||
Bind(&typeMismatch);
|
||||
{
|
||||
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty));
|
||||
@ -2139,12 +2153,12 @@ inline void StubBuilder::CheckUpdateSharedType(bool isDicMode, Variable *result,
|
||||
}
|
||||
}
|
||||
|
||||
inline void StubBuilder::MatchTrackType(Variable *result, GateRef glue, GateRef trackType, GateRef value,
|
||||
inline void StubBuilder::MatchFieldType(Variable *result, GateRef glue, GateRef fieldType, GateRef value,
|
||||
Label *executeSetProp, Label *exit)
|
||||
{
|
||||
auto *env = GetEnvironment();
|
||||
Label typeMismatch(env);
|
||||
MatchTrackType(trackType, value, executeSetProp, &typeMismatch);
|
||||
MatchFieldType(fieldType, value, executeSetProp, &typeMismatch);
|
||||
Bind(&typeMismatch);
|
||||
{
|
||||
GateRef taggedId = Int32(GET_MESSAGE_STRING_ID(SetTypeMismatchedSharedProperty));
|
||||
@ -2154,11 +2168,11 @@ inline void StubBuilder::MatchTrackType(Variable *result, GateRef glue, GateRef
|
||||
}
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetTrackTypeFromHandler(GateRef attr)
|
||||
inline GateRef StubBuilder::GetFieldTypeFromHandler(GateRef attr)
|
||||
{
|
||||
return Int32And(Int32LSR(attr,
|
||||
Int32(HandlerBase::STrackTypeBit::START_BIT)),
|
||||
Int32((1LLU << HandlerBase::STrackTypeBit::SIZE) - 1));
|
||||
Int32(HandlerBase::SFieldTypeBit::START_BIT)),
|
||||
Int32((1LLU << HandlerBase::SFieldTypeBit::SIZE) - 1));
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::ClearSharedStoreKind(GateRef handlerInfo)
|
||||
@ -2213,13 +2227,14 @@ inline void StubBuilder::SetPropAttrToLayoutInfo(GateRef glue, GateRef layout, G
|
||||
{
|
||||
GateRef index = Int32Add(Int32LSL(entry, Int32(LayoutInfo::ELEMENTS_INDEX_LOG2)),
|
||||
Int32(LayoutInfo::ATTR_INDEX_OFFSET));
|
||||
GateRef taggedAttr = Int64ToTaggedInt(ZExtInt32ToInt64(attr));
|
||||
GateRef taggedAttr = Int64ToTaggedInt(attr);
|
||||
SetValueToTaggedArray(VariableType::JS_ANY(), glue, layout, index, taggedAttr);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetPropertyMetaDataFromAttr(GateRef attr)
|
||||
{
|
||||
return Int32And(Int32LSR(attr, Int32(PropertyAttributes::PropertyMetaDataField::START_BIT)),
|
||||
return Int32And(
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::PropertyMetaDataField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::PropertyMetaDataField::SIZE) - 1));
|
||||
}
|
||||
|
||||
@ -2462,61 +2477,68 @@ inline GateRef StubBuilder::IsCallable(GateRef obj)
|
||||
inline GateRef StubBuilder::GetOffsetFieldInPropAttr(GateRef attr)
|
||||
{
|
||||
return Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::OffsetField::START_BIT)),
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::OffsetField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1));
|
||||
}
|
||||
|
||||
// SetOffset func in property_attribute.h
|
||||
inline GateRef StubBuilder::SetOffsetFieldInPropAttr(GateRef attr, GateRef value)
|
||||
{
|
||||
GateRef mask = Int32LSL(
|
||||
Int32((1LLU << PropertyAttributes::OffsetField::SIZE) - 1),
|
||||
Int32(PropertyAttributes::OffsetField::START_BIT));
|
||||
GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
|
||||
Int32LSL(value, Int32(PropertyAttributes::OffsetField::START_BIT)));
|
||||
GateRef mask = Int64LSL(
|
||||
Int64((1LLU << PropertyAttributes::OffsetField::SIZE) - 1),
|
||||
Int64(PropertyAttributes::OffsetField::START_BIT));
|
||||
GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
|
||||
Int64LSL(ZExtInt32ToInt64(value), Int64(PropertyAttributes::OffsetField::START_BIT)));
|
||||
return newVal;
|
||||
}
|
||||
|
||||
// SetIsInlinedProps func in property_attribute.h
|
||||
inline GateRef StubBuilder::SetIsInlinePropsFieldInPropAttr(GateRef attr, GateRef value)
|
||||
{
|
||||
GateRef mask = Int32LSL(
|
||||
Int32((1LU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1),
|
||||
Int32(PropertyAttributes::IsInlinedPropsField::START_BIT));
|
||||
GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
|
||||
Int32LSL(value, Int32(PropertyAttributes::IsInlinedPropsField::START_BIT)));
|
||||
GateRef mask = Int64LSL(
|
||||
Int64((1LU << PropertyAttributes::IsInlinedPropsField::SIZE) - 1),
|
||||
Int64(PropertyAttributes::IsInlinedPropsField::START_BIT));
|
||||
GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
|
||||
Int64LSL(ZExtInt32ToInt64(value), Int64(PropertyAttributes::IsInlinedPropsField::START_BIT)));
|
||||
return newVal;
|
||||
}
|
||||
|
||||
|
||||
inline GateRef StubBuilder::SetTrackTypeInPropAttr(GateRef attr, GateRef type)
|
||||
{
|
||||
GateRef mask = Int32LSL(
|
||||
Int32((1LU << PropertyAttributes::TrackTypeField::SIZE) - 1),
|
||||
Int32(PropertyAttributes::TrackTypeField::START_BIT));
|
||||
GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
|
||||
Int32LSL(type, Int32(PropertyAttributes::TrackTypeField::START_BIT)));
|
||||
GateRef mask = Int64LSL(
|
||||
Int64((1LU << PropertyAttributes::TrackTypeField::SIZE) - 1),
|
||||
Int64(PropertyAttributes::TrackTypeField::START_BIT));
|
||||
GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
|
||||
Int64LSL(ZExtInt32ToInt64(type), Int64(PropertyAttributes::TrackTypeField::START_BIT)));
|
||||
return newVal;
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetSharedFieldTypeInPropAttr(GateRef attr)
|
||||
{
|
||||
return Int32And(
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::SharedFieldTypeField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::SharedFieldTypeField::SIZE) - 1));
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetTrackTypeInPropAttr(GateRef attr)
|
||||
{
|
||||
return Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::TrackTypeField::START_BIT)),
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::TrackTypeField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::TrackTypeField::SIZE) - 1));
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetDictTrackTypeInPropAttr(GateRef attr)
|
||||
inline GateRef StubBuilder::GetDictSharedFieldTypeInPropAttr(GateRef attr)
|
||||
{
|
||||
return Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::DictTrackTypeField::START_BIT)),
|
||||
Int32((1LLU << PropertyAttributes::DictTrackTypeField::SIZE) - 1));
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::DictSharedFieldTypeField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::DictSharedFieldTypeField::SIZE) - 1));
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetRepInPropAttr(GateRef attr)
|
||||
{
|
||||
return Int32And(
|
||||
Int32LSR(attr, Int32(PropertyAttributes::RepresentationField::START_BIT)),
|
||||
TruncInt64ToInt32(Int64LSR(attr, Int64(PropertyAttributes::RepresentationField::START_BIT))),
|
||||
Int32((1LLU << PropertyAttributes::RepresentationField::SIZE) - 1));
|
||||
}
|
||||
|
||||
@ -2532,12 +2554,12 @@ inline GateRef StubBuilder::IsDoubleRepInPropAttr(GateRef rep)
|
||||
|
||||
inline GateRef StubBuilder::SetTaggedRepInPropAttr(GateRef attr)
|
||||
{
|
||||
GateRef mask = Int32LSL(
|
||||
Int32((1LU << PropertyAttributes::RepresentationField::SIZE) - 1),
|
||||
Int32(PropertyAttributes::RepresentationField::START_BIT));
|
||||
GateRef targetType = Int32(static_cast<int32_t>(Representation::TAGGED));
|
||||
GateRef newVal = Int32Or(Int32And(attr, Int32Not(mask)),
|
||||
Int32LSL(targetType, Int32(PropertyAttributes::RepresentationField::START_BIT)));
|
||||
GateRef mask = Int64LSL(
|
||||
Int64((1LU << PropertyAttributes::RepresentationField::SIZE) - 1),
|
||||
Int64(PropertyAttributes::RepresentationField::START_BIT));
|
||||
GateRef targetType = Int32(static_cast<uint32_t>(Representation::TAGGED));
|
||||
GateRef newVal = Int64Or(Int64And(attr, Int64Not(mask)),
|
||||
Int64LSL(ZExtInt32ToInt64(targetType), Int64(PropertyAttributes::RepresentationField::START_BIT)));
|
||||
return newVal;
|
||||
}
|
||||
|
||||
@ -2587,6 +2609,42 @@ inline GateRef StubBuilder::InYoungGeneration(GateRef region)
|
||||
}
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::InSharedHeap(GateRef region)
|
||||
{
|
||||
auto offset = Region::PackedData::GetFlagOffset(env_->Is32Bit());
|
||||
GateRef x = Load(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
|
||||
IntPtr(0));
|
||||
if (env_->Is32Bit()) {
|
||||
GateRef spaceType = Int32And(x, Int32(RegionSpaceFlag::VALID_SPACE_MASK));
|
||||
GateRef greater = Int32GreaterThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SPACE_BEGIN));
|
||||
GateRef less = Int32LessThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SPACE_END));
|
||||
return BoolAnd(greater, less);
|
||||
} else {
|
||||
GateRef spaceType = Int64And(x, Int64(RegionSpaceFlag::VALID_SPACE_MASK));
|
||||
GateRef greater = Int64GreaterThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SPACE_BEGIN));
|
||||
GateRef less = Int64LessThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SPACE_END));
|
||||
return BoolAnd(greater, less);
|
||||
}
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::InSharedSweepableSpace(GateRef region)
|
||||
{
|
||||
auto offset = Region::PackedData::GetFlagOffset(env_->Is32Bit());
|
||||
GateRef x = Load(VariableType::NATIVE_POINTER(), PtrAdd(IntPtr(offset), region),
|
||||
IntPtr(0));
|
||||
if (env_->Is32Bit()) {
|
||||
GateRef spaceType = Int32And(x, Int32(RegionSpaceFlag::VALID_SPACE_MASK));
|
||||
GateRef greater = Int32GreaterThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_BEGIN));
|
||||
GateRef less = Int32LessThanOrEqual(spaceType, Int32(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_END));
|
||||
return BoolAnd(greater, less);
|
||||
} else {
|
||||
GateRef spaceType = Int64And(x, Int64(RegionSpaceFlag::VALID_SPACE_MASK));
|
||||
GateRef greater = Int64GreaterThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_BEGIN));
|
||||
GateRef less = Int64LessThanOrEqual(spaceType, Int64(RegionSpaceFlag::SHARED_SWEEPABLE_SPACE_END));
|
||||
return BoolAnd(greater, less);
|
||||
}
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetParentEnv(GateRef object)
|
||||
{
|
||||
GateRef index = Int32(LexicalEnv::PARENT_ENV_INDEX);
|
||||
@ -2663,6 +2721,12 @@ inline void StubBuilder::SetHomeObjectToFunction(GateRef glue, GateRef function,
|
||||
Store(VariableType::JS_ANY(), glue, function, offset, value);
|
||||
}
|
||||
|
||||
inline void StubBuilder::SetModuleToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
{
|
||||
GateRef offset = IntPtr(JSFunction::ECMA_MODULE_OFFSET);
|
||||
Store(VariableType::JS_POINTER(), glue, function, offset, value);
|
||||
}
|
||||
|
||||
inline void StubBuilder::SetWorkNodePointerToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
{
|
||||
GateRef offset = IntPtr(JSFunction::WORK_NODE_POINTER_OFFSET);
|
||||
@ -2675,6 +2739,14 @@ inline void StubBuilder::SetMethodToFunction(GateRef glue, GateRef function, Gat
|
||||
Store(VariableType::JS_ANY(), glue, function, offset, value);
|
||||
}
|
||||
|
||||
inline void StubBuilder::SetCodeEntryToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
{
|
||||
GateRef methodOffset = IntPtr(Method::CODEENTRY_LITERAL_OFFSET);
|
||||
GateRef codeEntry = Load(VariableType::NATIVE_POINTER(), value, methodOffset);
|
||||
GateRef funcOffset = IntPtr(JSFunctionBase::CODE_ENTRY_OFFSET);
|
||||
Store(VariableType::NATIVE_POINTER(), glue, function, funcOffset, codeEntry);
|
||||
}
|
||||
|
||||
inline void StubBuilder::SetLengthToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
{
|
||||
GateRef offset = IntPtr(JSFunctionBase::LENGTH_OFFSET);
|
||||
@ -2870,8 +2942,8 @@ inline GateRef StubBuilder::GetGlobalConstantValue(VariableType type, GateRef gl
|
||||
|
||||
inline GateRef StubBuilder::GetSingleCharTable(GateRef glue)
|
||||
{
|
||||
return Load(VariableType::JS_ANY(), glue,
|
||||
IntPtr(JSThread::GlueData::GetSingleCharTableOffset(env_->Is32Bit())));
|
||||
return GetGlobalConstantValue(
|
||||
VariableType::JS_POINTER(), glue, ConstantIndex::SINGLE_CHAR_TABLE_INDEX);
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetGlobalEnvValue(VariableType type, GateRef env, size_t index)
|
||||
@ -3034,8 +3106,7 @@ inline GateRef StubBuilder::IsTypedArray(GateRef obj)
|
||||
|
||||
inline GateRef StubBuilder::GetProfileTypeInfo(GateRef jsFunc)
|
||||
{
|
||||
GateRef method = GetMethodFromFunction(jsFunc);
|
||||
return Load(VariableType::JS_POINTER(), method, IntPtr(Method::PROFILE_TYPE_INFO_OFFSET));
|
||||
return Load(VariableType::JS_POINTER(), jsFunc, IntPtr(JSFunction::PROFILE_TYPE_INFO_OFFSET));
|
||||
}
|
||||
|
||||
inline void StubBuilder::CheckDetectorName(GateRef glue, GateRef key, Label *fallthrough, Label *slow)
|
||||
@ -3128,7 +3199,7 @@ inline GateRef StubBuilder::GetKeyIndex(GateRef index)
|
||||
inline GateRef StubBuilder::GetAttr(GateRef layoutInfo, GateRef index)
|
||||
{
|
||||
GateRef fixedIdx = GetAttrIndex(index);
|
||||
return GetInt32OfTInt(GetValueFromTaggedArray(layoutInfo, fixedIdx));
|
||||
return GetInt64OfTInt(GetValueFromTaggedArray(layoutInfo, fixedIdx));
|
||||
}
|
||||
|
||||
inline GateRef StubBuilder::GetKey(GateRef layoutInfo, GateRef index)
|
||||
|
@ -114,7 +114,7 @@ void StubBuilder::LoopEnd(Label *loopHead)
|
||||
env_->SetCurrentLabel(nullptr);
|
||||
}
|
||||
|
||||
void StubBuilder::MatchTrackType(GateRef trackType, GateRef value, Label *executeSetProp, Label *typeMismatch)
|
||||
void StubBuilder::MatchFieldType(GateRef fieldType, GateRef value, Label *executeSetProp, Label *typeMismatch)
|
||||
{
|
||||
auto *env = GetEnvironment();
|
||||
Label isNumber(env);
|
||||
@ -124,11 +124,13 @@ void StubBuilder::MatchTrackType(GateRef trackType, GateRef value, Label *execut
|
||||
Label isString(env);
|
||||
Label checkJSShared(env);
|
||||
Label isJSShared(env);
|
||||
Label checkBigInt(env);
|
||||
Label isBigInt(env);
|
||||
Label checkJSNone(env);
|
||||
Label isJSNone(env);
|
||||
Label exit(env);
|
||||
DEFVARIABLE(result, VariableType::BOOL(), False());
|
||||
BRANCH(Equal(trackType, Int32(static_cast<int32_t>(TrackType::NUMBER))), &isNumber, &checkBoolean);
|
||||
BRANCH(Equal(fieldType, Int32(static_cast<int32_t>(SharedFieldType::NUMBER))), &isNumber, &checkBoolean);
|
||||
Bind(&isNumber);
|
||||
{
|
||||
result = TaggedIsNumber(value);
|
||||
@ -136,7 +138,7 @@ void StubBuilder::MatchTrackType(GateRef trackType, GateRef value, Label *execut
|
||||
}
|
||||
Bind(&checkBoolean);
|
||||
{
|
||||
BRANCH(Equal(trackType, Int32(static_cast<int32_t>(TrackType::BOOLEAN))), &isBoolean, &checkString);
|
||||
BRANCH(Equal(fieldType, Int32(static_cast<int32_t>(SharedFieldType::BOOLEAN))), &isBoolean, &checkString);
|
||||
Bind(&isBoolean);
|
||||
{
|
||||
result = TaggedIsBoolean(value);
|
||||
@ -145,7 +147,7 @@ void StubBuilder::MatchTrackType(GateRef trackType, GateRef value, Label *execut
|
||||
}
|
||||
Bind(&checkString);
|
||||
{
|
||||
BRANCH(Equal(trackType, Int32(static_cast<int32_t>(TrackType::STRING))), &isString, &checkJSShared);
|
||||
BRANCH(Equal(fieldType, Int32(static_cast<int32_t>(SharedFieldType::STRING))), &isString, &checkJSShared);
|
||||
Bind(&isString);
|
||||
{
|
||||
result = BoolOr(TaggedIsString(value), TaggedIsNull(value));
|
||||
@ -154,16 +156,25 @@ void StubBuilder::MatchTrackType(GateRef trackType, GateRef value, Label *execut
|
||||
}
|
||||
Bind(&checkJSShared);
|
||||
{
|
||||
BRANCH(Equal(trackType, Int32(static_cast<int32_t>(TrackType::SENDABLE))), &isJSShared, &checkJSNone);
|
||||
BRANCH(Equal(fieldType, Int32(static_cast<int32_t>(SharedFieldType::SENDABLE))), &isJSShared, &checkBigInt);
|
||||
Bind(&isJSShared);
|
||||
{
|
||||
result = BoolOr(TaggedIsShared(value), TaggedIsNull(value));
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&checkBigInt);
|
||||
{
|
||||
BRANCH(Equal(fieldType, Int32(static_cast<int32_t>(SharedFieldType::BIG_INT))), &isBigInt, &checkJSNone);
|
||||
Bind(&isBigInt);
|
||||
{
|
||||
result = TaggedIsBigInt(value);
|
||||
Jump(&exit);
|
||||
}
|
||||
}
|
||||
Bind(&checkJSNone);
|
||||
{
|
||||
BRANCH(Equal(trackType, Int32(static_cast<int32_t>(TrackType::NONE))), &isJSNone, &exit);
|
||||
BRANCH(Equal(fieldType, Int32(static_cast<int32_t>(SharedFieldType::NONE))), &isJSNone, &exit);
|
||||
Bind(&isJSNone);
|
||||
{
|
||||
// bypass none type
|
||||
@ -399,7 +410,6 @@ GateRef StubBuilder::IsMatchInTransitionDictionary(GateRef element, GateRef key,
|
||||
return BoolAnd(Equal(element, key), Int32Equal(metaData, attr));
|
||||
}
|
||||
|
||||
// metaData is int32 type
|
||||
GateRef StubBuilder::FindEntryFromTransitionDictionary(GateRef glue, GateRef elements, GateRef key, GateRef metaData)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
@ -475,9 +485,9 @@ GateRef StubBuilder::FindEntryFromTransitionDictionary(GateRef glue, GateRef ele
|
||||
{
|
||||
Label isMatch(env);
|
||||
Label notMatch(env);
|
||||
BRANCH(
|
||||
IsMatchInTransitionDictionary(element, key, metaData,
|
||||
GetAttributesFromDictionary<TransitionsDictionary>(elements, *entry)),
|
||||
BRANCH(IsMatchInTransitionDictionary(element, key, metaData,
|
||||
// metaData is int32 type
|
||||
TruncInt64ToInt32(GetAttributesFromDictionary<TransitionsDictionary>(elements, *entry))),
|
||||
&isMatch, ¬Match);
|
||||
{
|
||||
Bind(&isMatch);
|
||||
@ -837,7 +847,7 @@ void StubBuilder::JSHClassAddProperty(GateRef glue, GateRef receiver, GateRef ke
|
||||
IntToTaggedInt(inlineProps) });
|
||||
CopyAllHClass(glue, newJshclass, hclass);
|
||||
CallRuntime(glue, RTSTUB_ID(UpdateLayOutAndAddTransition),
|
||||
{ hclass, newJshclass, key, IntToTaggedInt(attr) });
|
||||
{ hclass, newJshclass, key, Int64ToTaggedInt(attr) });
|
||||
#if ECMASCRIPT_ENABLE_IC
|
||||
NotifyHClassChanged(glue, hclass, newJshclass);
|
||||
#endif
|
||||
@ -889,7 +899,7 @@ GateRef StubBuilder::AddPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
}
|
||||
Bind(&afterCtorCon);
|
||||
// 0x111 : default attribute for property: writable, enumerable, configurable
|
||||
DEFVARIABLE(attr, VariableType::INT32(), propertyAttributes);
|
||||
DEFVARIABLE(attr, VariableType::INT64(), propertyAttributes);
|
||||
GateRef numberOfProps = GetNumberOfPropsFromHClass(hclass);
|
||||
GateRef inlinedProperties = GetInlinedPropertiesFromHClass(hclass);
|
||||
Label hasUnusedInProps(env);
|
||||
@ -909,7 +919,7 @@ GateRef StubBuilder::AddPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
GateRef newHclass = LoadHClass(receiver);
|
||||
GateRef newLayoutInfo = GetLayoutFromHClass(newHclass);
|
||||
GateRef offset = GetInlinedPropOffsetFromHClass(hclass, numberOfProps);
|
||||
attr = GetInt32OfTInt(GetPropAttrFromLayoutInfo(newLayoutInfo, numberOfProps));
|
||||
attr = GetPropAttrFromLayoutInfo(newLayoutInfo, numberOfProps);
|
||||
SetValueWithAttr(glue, receiver, offset, key, value, *attr);
|
||||
result = Undefined();
|
||||
Jump(&exit);
|
||||
@ -941,7 +951,7 @@ GateRef StubBuilder::AddPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Bind(&isDictMode);
|
||||
{
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(NameDictPutIfAbsent),
|
||||
{receiver, *array, key, value, IntToTaggedInt(*attr), TaggedFalse()});
|
||||
{receiver, *array, key, value, Int64ToTaggedInt(*attr), TaggedFalse()});
|
||||
SetPropertiesArray(VariableType::JS_POINTER(), glue, receiver, res);
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -960,7 +970,7 @@ GateRef StubBuilder::AddPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
attr = SetDictionaryOrderFieldInPropAttr(*attr,
|
||||
Int32(PropertyAttributes::MAX_FAST_PROPS_CAPACITY));
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(NameDictPutIfAbsent),
|
||||
{ receiver, *array, key, value, IntToTaggedInt(*attr), TaggedTrue() });
|
||||
{ receiver, *array, key, value, Int64ToTaggedInt(*attr), TaggedTrue() });
|
||||
SetPropertiesArray(VariableType::JS_POINTER(), glue, receiver, res);
|
||||
result = Undefined();
|
||||
Jump(&exit);
|
||||
@ -1234,11 +1244,22 @@ void StubBuilder::SetValueWithBarrier(GateRef glue, GateRef obj, GateRef offset,
|
||||
Label exit(env);
|
||||
Label isVailedIndex(env);
|
||||
Label notValidIndex(env);
|
||||
|
||||
Label shareBarrier(env);
|
||||
Label shareBarrierExit(env);
|
||||
// ObjectAddressToRange function may cause obj is not an object. GC may not mark this obj.
|
||||
GateRef objectRegion = ObjectAddressToRange(obj);
|
||||
GateRef valueRegion = ObjectAddressToRange(value);
|
||||
GateRef slotAddr = PtrAdd(TaggedCastToIntPtr(obj), offset);
|
||||
GateRef objectNotInShare = BoolNot(InSharedHeap(objectRegion));
|
||||
GateRef valueRegionInShare = InSharedSweepableSpace(valueRegion);
|
||||
BRANCH(BoolAnd(objectNotInShare, valueRegionInShare), &shareBarrier, &shareBarrierExit);
|
||||
Bind(&shareBarrier);
|
||||
{
|
||||
// todo(lukai) fastpath
|
||||
CallNGCRuntime(glue, RTSTUB_ID(InsertLocalToShareRSet), { glue, obj, offset });
|
||||
Jump(&shareBarrierExit);
|
||||
}
|
||||
Bind(&shareBarrierExit);
|
||||
GateRef objectNotInYoung = BoolNot(InYoungGeneration(objectRegion));
|
||||
GateRef valueRegionInYoung = InYoungGeneration(valueRegion);
|
||||
BRANCH(BoolAnd(objectNotInYoung, valueRegionInYoung), &isVailedIndex, ¬ValidIndex);
|
||||
@ -1719,6 +1740,7 @@ GateRef StubBuilder::LoadICWithHandler(
|
||||
Label handlerIsPrototypeHandler(env);
|
||||
Label handlerNotPrototypeHandler(env);
|
||||
Label cellHasChanged(env);
|
||||
Label cellNotUndefined(env);
|
||||
Label loopHead(env);
|
||||
Label loopEnd(env);
|
||||
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
|
||||
@ -1775,6 +1797,8 @@ GateRef StubBuilder::LoadICWithHandler(
|
||||
Bind(&handlerIsPrototypeHandler);
|
||||
{
|
||||
GateRef cellValue = GetProtoCell(*handler);
|
||||
BRANCH(TaggedIsUndefined(cellValue), &loopEnd, &cellNotUndefined);
|
||||
Bind(&cellNotUndefined);
|
||||
BRANCH(GetHasChanged(cellValue), &cellHasChanged, &loopEnd);
|
||||
Bind(&cellHasChanged);
|
||||
{
|
||||
@ -2073,6 +2097,7 @@ GateRef StubBuilder::StoreICWithHandler(GateRef glue, GateRef receiver, GateRef
|
||||
Label aotHandlerInfoNotField(env);
|
||||
Label cellHasChanged(env);
|
||||
Label cellNotChanged(env);
|
||||
Label cellNotUndefined(env);
|
||||
Label aotCellNotChanged(env);
|
||||
Label loopHead(env);
|
||||
Label loopEnd(env);
|
||||
@ -2099,8 +2124,8 @@ GateRef StubBuilder::StoreICWithHandler(GateRef glue, GateRef receiver, GateRef
|
||||
BRANCH(IsStoreShared(handlerInfo), &isShared, ¬Shared);
|
||||
Bind(&isShared);
|
||||
{
|
||||
GateRef trackType = GetTrackTypeFromHandler(handlerInfo);
|
||||
MatchTrackType(&result, glue, trackType, value, &prepareIntHandlerLoop, &exit);
|
||||
GateRef field = GetFieldTypeFromHandler(handlerInfo);
|
||||
MatchFieldType(&result, glue, field, value, &prepareIntHandlerLoop, &exit);
|
||||
Bind(&prepareIntHandlerLoop);
|
||||
{
|
||||
handler = IntToTaggedPtr(ClearSharedStoreKind(handlerInfo));
|
||||
@ -2151,6 +2176,8 @@ GateRef StubBuilder::StoreICWithHandler(GateRef glue, GateRef receiver, GateRef
|
||||
Bind(&handlerIsPrototypeHandler);
|
||||
{
|
||||
GateRef cellValue = GetProtoCell(*handler);
|
||||
BRANCH(TaggedIsUndefined(cellValue), &loopEnd, &cellNotUndefined);
|
||||
Bind(&cellNotUndefined);
|
||||
BRANCH(TaggedIsNull(cellValue), &cellHasChanged, &cellNotNull);
|
||||
Bind(&cellNotNull);
|
||||
{
|
||||
@ -2378,7 +2405,7 @@ GateRef StubBuilder::GetAttributesFromDictionary(GateRef elements, GateRef entry
|
||||
GateRef attributesIndex =
|
||||
Int32Add(arrayIndex, Int32(DictionaryT::ENTRY_DETAILS_INDEX));
|
||||
auto attrValue = GetValueFromTaggedArray(elements, attributesIndex);
|
||||
return GetInt32OfTInt(attrValue);
|
||||
return GetInt64OfTInt(attrValue);
|
||||
}
|
||||
|
||||
template<typename DictionaryT>
|
||||
@ -2439,7 +2466,7 @@ inline void StubBuilder::UpdateValueAndAttributes(GateRef glue, GateRef elements
|
||||
GateRef attroffset =
|
||||
PtrMul(ZExtInt32ToPtr(attributesIndex), IntPtr(JSTaggedValue::TaggedTypeSize()));
|
||||
GateRef dataOffset = PtrAdd(attroffset, IntPtr(TaggedArray::DATA_OFFSET));
|
||||
Store(VariableType::INT64(), glue, elements, dataOffset, IntToTaggedInt(attr));
|
||||
Store(VariableType::INT64(), glue, elements, dataOffset, Int64ToTaggedInt(attr));
|
||||
}
|
||||
|
||||
template<typename DictionaryT>
|
||||
@ -2650,7 +2677,7 @@ GateRef StubBuilder::GetPropertyByValue(GateRef glue, GateRef receiver, GateRef
|
||||
Label notFind(env);
|
||||
Label find(env);
|
||||
// if key can't find in stringtabele, key is not propertyname for a object
|
||||
GateRef res = CallNGCRuntime(glue, RTSTUB_ID(TryGetInternString), { glue, *key });
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(TryGetInternString), { *key });
|
||||
BRANCH(TaggedIsHole(res), ¬Find, &find);
|
||||
Bind(¬Find);
|
||||
{
|
||||
@ -2754,8 +2781,7 @@ GateRef StubBuilder::GetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Bind(&hasEntry);
|
||||
{
|
||||
// PropertyAttributes attr(layoutInfo->GetAttr(entry))
|
||||
GateRef propAttr = GetPropAttrFromLayoutInfo(layOutInfo, entryA);
|
||||
GateRef attr = GetInt32OfTInt(propAttr);
|
||||
GateRef attr = GetPropAttrFromLayoutInfo(layOutInfo, entryA);
|
||||
GateRef value = JSObjectGetProperty(*holder, hclass, attr);
|
||||
Label isAccessor(env);
|
||||
Label notAccessor(env);
|
||||
@ -2880,7 +2906,7 @@ void StubBuilder::TransitionForRepChange(GateRef glue, GateRef receiver, GateRef
|
||||
IntToTaggedInt(inlineProps) });
|
||||
CopyAllHClass(glue, newJshclass, hclass);
|
||||
CallRuntime(glue, RTSTUB_ID(CopyAndUpdateObjLayout),
|
||||
{ hclass, newJshclass, key, IntToTaggedInt(attr) });
|
||||
{ hclass, newJshclass, key, Int64ToTaggedInt(attr) });
|
||||
#if ECMASCRIPT_ENABLE_IC
|
||||
NotifyHClassChanged(glue, hclass, newJshclass);
|
||||
#endif
|
||||
@ -2967,7 +2993,7 @@ GateRef StubBuilder::AddElementInternal(GateRef glue, GateRef receiver, GateRef
|
||||
Bind(&isDicMode);
|
||||
{
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(NumberDictionaryPut),
|
||||
{ receiver, elements, IntToTaggedInt(index), value, IntToTaggedInt(attr), TaggedFalse() });
|
||||
{ receiver, elements, IntToTaggedInt(index), value, Int64ToTaggedInt(attr), TaggedFalse() });
|
||||
SetElementsArray(VariableType::JS_POINTER(), glue, receiver, res);
|
||||
result = True();
|
||||
Jump(&exit);
|
||||
@ -2987,7 +3013,7 @@ GateRef StubBuilder::AddElementInternal(GateRef glue, GateRef receiver, GateRef
|
||||
Bind(&isTransToDict);
|
||||
{
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(NumberDictionaryPut),
|
||||
{ receiver, elements, IntToTaggedInt(index), value, IntToTaggedInt(attr), TaggedTrue() });
|
||||
{ receiver, elements, IntToTaggedInt(index), value, Int64ToTaggedInt(attr), TaggedTrue() });
|
||||
SetElementsArray(VariableType::JS_POINTER(), glue, receiver, res);
|
||||
result = True();
|
||||
Jump(&exit);
|
||||
@ -3155,7 +3181,7 @@ GateRef StubBuilder::IsArrayLengthWritable(GateRef glue, GateRef receiver)
|
||||
}
|
||||
Bind(&isNegtiveOne);
|
||||
{
|
||||
GateRef attr1 = Int32(PropertyAttributes::GetDefaultAttributes());
|
||||
GateRef attr1 = Int64(PropertyAttributes::GetDefaultAttributes());
|
||||
result = IsWritable(attr1);
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -3163,8 +3189,7 @@ GateRef StubBuilder::IsArrayLengthWritable(GateRef glue, GateRef receiver)
|
||||
Bind(¬DicMode);
|
||||
{
|
||||
GateRef layoutInfo = GetLayoutFromHClass(hclass);
|
||||
GateRef propAttr = GetPropAttrFromLayoutInfo(layoutInfo, Int32(JSArray::LENGTH_INLINE_PROPERTY_INDEX));
|
||||
GateRef attr = GetInt32OfTInt(propAttr);
|
||||
GateRef attr = GetPropAttrFromLayoutInfo(layoutInfo, Int32(JSArray::LENGTH_INLINE_PROPERTY_INDEX));
|
||||
result = IsWritable(attr);
|
||||
Jump(&exit);
|
||||
}
|
||||
@ -3198,7 +3223,7 @@ GateRef StubBuilder::FindTransitions(GateRef glue, GateRef receiver, GateRef hcl
|
||||
GateRef last = Int32Sub(propNums, Int32(1));
|
||||
GateRef layoutInfo = GetLayoutFromHClass(transitionHClass);
|
||||
GateRef cachedKey = GetKeyFromLayoutInfo(layoutInfo, last);
|
||||
GateRef cachedAttr = GetInt32OfTInt(GetPropAttrFromLayoutInfo(layoutInfo, last));
|
||||
GateRef cachedAttr = GetPropAttrFromLayoutInfo(layoutInfo, last);
|
||||
GateRef cachedMetaData = GetPropertyMetaDataFromAttr(cachedAttr);
|
||||
Label keyMatch(env);
|
||||
Label isMatch(env);
|
||||
@ -3455,8 +3480,8 @@ GateRef StubBuilder::SetPropertyByIndex(GateRef glue, GateRef receiver, GateRef
|
||||
{
|
||||
Label success(env);
|
||||
Label failed(env);
|
||||
BRANCH(AddElementInternal(glue, receiver, index, value,
|
||||
Int32(PropertyAttributes::GetDefaultAttributes())), &success, &failed);
|
||||
BRANCH(AddElementInternal(glue, receiver, index, value, Int64(PropertyAttributes::GetDefaultAttributes())),
|
||||
&success, &failed);
|
||||
Bind(&success);
|
||||
{
|
||||
returnValue = Undefined();
|
||||
@ -3582,8 +3607,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Bind(&hasEntry);
|
||||
{
|
||||
// PropertyAttributes attr(layoutInfo->GetAttr(entry))
|
||||
GateRef propAttr = GetPropAttrFromLayoutInfo(layOutInfo, entry);
|
||||
GateRef attr = GetInt32OfTInt(propAttr);
|
||||
GateRef attr = GetPropAttrFromLayoutInfo(layOutInfo, entry);
|
||||
Label isAccessor(env);
|
||||
Label notAccessor(env);
|
||||
BRANCH(IsAccessor(attr), &isAccessor, ¬Accessor);
|
||||
@ -3764,8 +3788,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
{
|
||||
GateRef receiverHClass = LoadHClass(receiver);
|
||||
GateRef receiverLayoutInfo = GetLayoutFromHClass(receiverHClass);
|
||||
GateRef holePropAttr = GetPropAttrFromLayoutInfo(receiverLayoutInfo, *receiverHoleEntry);
|
||||
GateRef holeAttr = GetInt32OfTInt(holePropAttr);
|
||||
GateRef holeAttr = GetPropAttrFromLayoutInfo(receiverLayoutInfo, *receiverHoleEntry);
|
||||
JSObjectSetProperty(glue, receiver, receiverHClass, holeAttr, key, value);
|
||||
ProfilerStubBuilder(env).UpdatePropAttrWithValue(
|
||||
glue, jsType, receiverLayoutInfo, holeAttr, *receiverHoleEntry, value, callback);
|
||||
@ -3787,7 +3810,7 @@ GateRef StubBuilder::SetPropertyByName(GateRef glue, GateRef receiver, GateRef k
|
||||
Bind(&extensible);
|
||||
{
|
||||
result = AddPropertyByName(glue, receiver, key, value,
|
||||
Int32(PropertyAttributes::GetDefaultAttributes()), callback);
|
||||
Int64(PropertyAttributes::GetDefaultAttributes()), callback);
|
||||
Jump(&exit);
|
||||
}
|
||||
Bind(&exit);
|
||||
@ -3864,7 +3887,7 @@ GateRef StubBuilder::SetPropertyByValue(GateRef glue, GateRef receiver, GateRef
|
||||
{
|
||||
Label notFind(env);
|
||||
Label find(env);
|
||||
GateRef res = CallNGCRuntime(glue, RTSTUB_ID(TryGetInternString), { glue, *varKey });
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(TryGetInternString), { *varKey });
|
||||
BRANCH(TaggedIsHole(res), ¬Find, &find);
|
||||
Bind(¬Find);
|
||||
{
|
||||
@ -4335,7 +4358,7 @@ void StubBuilder::FastSetPropertyByName(GateRef glue, GateRef obj, GateRef key,
|
||||
{
|
||||
Label notFind(env);
|
||||
Label find(env);
|
||||
GateRef res = CallNGCRuntime(glue, RTSTUB_ID(TryGetInternString), { glue, *keyVar });
|
||||
GateRef res = CallRuntime(glue, RTSTUB_ID(TryGetInternString), { *keyVar });
|
||||
BRANCH(TaggedIsHole(res), ¬Find, &find);
|
||||
Bind(¬Find);
|
||||
{
|
||||
@ -5964,8 +5987,9 @@ GateRef StubBuilder::GetStringFromConstPool(GateRef glue, GateRef constpool, Gat
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, hirGate, constpool, module, index, ConstPoolType::STRING);
|
||||
}
|
||||
|
||||
GateRef StubBuilder::GetMethodFromConstPool(GateRef glue, GateRef constpool, GateRef module, GateRef index)
|
||||
GateRef StubBuilder::GetMethodFromConstPool(GateRef glue, GateRef constpool, GateRef index)
|
||||
{
|
||||
GateRef module = Circuit::NullGate();
|
||||
GateRef hirGate = Circuit::NullGate();
|
||||
return env_->GetBuilder()->GetObjectFromConstPool(glue, hirGate, constpool, module, index, ConstPoolType::METHOD);
|
||||
}
|
||||
@ -6975,7 +6999,7 @@ GateRef StubBuilder::JSCallDispatch(GateRef glue, GateRef func, GateRef actualNu
|
||||
BRANCH(Int64LessThanOrEqual(expectedArgc, realNumArgs), &fastCall, &fastCallBridge);
|
||||
Bind(&fastCall);
|
||||
{
|
||||
GateRef code = GetAotCodeAddr(method);
|
||||
GateRef code = GetAotCodeAddr(func);
|
||||
switch (mode) {
|
||||
case JSCallMode::CALL_THIS_ARG0:
|
||||
thisValue = data[0];
|
||||
@ -7151,7 +7175,7 @@ GateRef StubBuilder::JSCallDispatch(GateRef glue, GateRef func, GateRef actualNu
|
||||
BRANCH(Int64LessThanOrEqual(expectedArgc, realNumArgs), &slowCall, &slowCallBridge);
|
||||
Bind(&slowCall);
|
||||
{
|
||||
GateRef code = GetAotCodeAddr(method);
|
||||
GateRef code = GetAotCodeAddr(func);
|
||||
switch (mode) {
|
||||
case JSCallMode::CALL_THIS_ARG0:
|
||||
thisValue = data[0];
|
||||
|
@ -152,7 +152,7 @@ public:
|
||||
GateRef CallNGCRuntime(GateRef glue, int index, const std::initializer_list<GateRef>& args);
|
||||
GateRef FastCallOptimized(GateRef glue, GateRef code, const std::initializer_list<GateRef>& args);
|
||||
GateRef CallOptimized(GateRef glue, GateRef code, const std::initializer_list<GateRef>& args);
|
||||
GateRef GetAotCodeAddr(GateRef method);
|
||||
GateRef GetAotCodeAddr(GateRef jsFunc);
|
||||
GateRef CallStub(GateRef glue, int index, const std::initializer_list<GateRef>& args);
|
||||
GateRef CallBuiltinRuntime(GateRef glue, const std::initializer_list<GateRef>& args,
|
||||
bool isNew = false, const char* comment = nullptr);
|
||||
@ -234,6 +234,8 @@ public:
|
||||
GateRef TaggedIsAccessor(GateRef x);
|
||||
GateRef ObjectAddressToRange(GateRef x);
|
||||
GateRef InYoungGeneration(GateRef region);
|
||||
GateRef InSharedHeap(GateRef region);
|
||||
GateRef InSharedSweepableSpace(GateRef region);
|
||||
GateRef TaggedIsGeneratorObject(GateRef x);
|
||||
GateRef TaggedIsJSArray(GateRef x);
|
||||
GateRef TaggedIsAsyncGeneratorObject(GateRef x);
|
||||
@ -487,12 +489,14 @@ public:
|
||||
GateRef GetInlinedPropertiesFromHClass(GateRef hClass);
|
||||
void ThrowTypeAndReturn(GateRef glue, int messageId, GateRef val);
|
||||
GateRef GetValueFromTaggedArray(GateRef elements, GateRef index);
|
||||
GateRef GetUnsharedConstpoolIndex(GateRef constpool);
|
||||
GateRef GetUnsharedConstpool(GateRef array, GateRef index);
|
||||
GateRef GetValueFromMutantTaggedArray(GateRef elements, GateRef index);
|
||||
void CheckUpdateSharedType(bool isDicMode, Variable *result, GateRef glue, GateRef jsType, GateRef attr,
|
||||
GateRef value, Label *executeSetProp, Label *exit);
|
||||
void MatchTrackType(Variable *result, GateRef glue, GateRef trackType, GateRef value, Label *executeSetProp,
|
||||
void MatchFieldType(Variable *result, GateRef glue, GateRef fieldType, GateRef value, Label *executeSetProp,
|
||||
Label *exit);
|
||||
GateRef GetTrackTypeFromHandler(GateRef attr);
|
||||
GateRef GetFieldTypeFromHandler(GateRef attr);
|
||||
GateRef ClearSharedStoreKind(GateRef handlerInfo);
|
||||
GateRef GetTaggedValueWithElementsKind(GateRef receiver, GateRef index);
|
||||
GateRef SetValueWithElementsKind(GateRef glue, GateRef receiver, GateRef rawValue, GateRef index,
|
||||
@ -519,7 +523,7 @@ public:
|
||||
GateRef GetPropertiesAddrFromLayoutInfo(GateRef layout);
|
||||
GateRef GetPropertyMetaDataFromAttr(GateRef attr);
|
||||
GateRef GetKeyFromLayoutInfo(GateRef layout, GateRef entry);
|
||||
void MatchTrackType(GateRef trackType, GateRef value, Label *executeSetProp, Label *typeMismatch);
|
||||
void MatchFieldType(GateRef fieldType, GateRef value, Label *executeSetProp, Label *typeMismatch);
|
||||
GateRef FindElementWithCache(GateRef glue, GateRef layoutInfo, GateRef hClass,
|
||||
GateRef key, GateRef propsNum);
|
||||
GateRef FindElementFromNumberDictionary(GateRef glue, GateRef elements, GateRef index);
|
||||
@ -621,7 +625,8 @@ public:
|
||||
GateRef SetIsInlinePropsFieldInPropAttr(GateRef attr, GateRef value);
|
||||
GateRef SetTrackTypeInPropAttr(GateRef attr, GateRef type);
|
||||
GateRef GetTrackTypeInPropAttr(GateRef attr);
|
||||
GateRef GetDictTrackTypeInPropAttr(GateRef attr);
|
||||
GateRef GetSharedFieldTypeInPropAttr(GateRef attr);
|
||||
GateRef GetDictSharedFieldTypeInPropAttr(GateRef attr);
|
||||
GateRef GetRepInPropAttr(GateRef attr);
|
||||
GateRef IsIntRepInPropAttr(GateRef attr);
|
||||
GateRef IsDoubleRepInPropAttr(GateRef attr);
|
||||
@ -660,7 +665,9 @@ public:
|
||||
void SetProtoOrHClassToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetWorkNodePointerToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetHomeObjectToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetModuleToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetMethodToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetCodeEntryToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
void SetLengthToFunction(GateRef glue, GateRef function, GateRef value);
|
||||
GateRef GetGlobalObject(GateRef glue);
|
||||
GateRef GetMethodFromFunction(GateRef function);
|
||||
@ -683,7 +690,7 @@ public:
|
||||
inline GateRef GetObjectFromConstPool(GateRef constpool, GateRef index);
|
||||
GateRef GetConstPoolFromFunction(GateRef jsFunc);
|
||||
GateRef GetStringFromConstPool(GateRef glue, GateRef constpool, GateRef index);
|
||||
GateRef GetMethodFromConstPool(GateRef glue, GateRef constpool, GateRef index, GateRef module);
|
||||
GateRef GetMethodFromConstPool(GateRef glue, GateRef constpool, GateRef index);
|
||||
GateRef GetArrayLiteralFromConstPool(GateRef glue, GateRef constpool, GateRef index, GateRef module);
|
||||
GateRef GetObjectLiteralFromConstPool(GateRef glue, GateRef constpool, GateRef index, GateRef module);
|
||||
void SetExtensibleToBitfield(GateRef glue, GateRef obj, bool isExtensible);
|
||||
|
@ -179,7 +179,7 @@ void AsmInterpreterCall::JSCallCommonEntry(ExtendedAssembler *assembler, JSCallM
|
||||
__ Mov(temp, callTargetRegister);
|
||||
__ Ldr(Register(X20), MemoryOperand(methodRegister, Method::NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET));
|
||||
// Reload constpool and profileInfo to make sure gc map work normally
|
||||
__ Ldr(Register(X22), MemoryOperand(methodRegister, Method::PROFILE_TYPE_INFO_OFFSET));
|
||||
__ Ldr(Register(X22), MemoryOperand(temp, JSFunction::PROFILE_TYPE_INFO_OFFSET));
|
||||
__ Ldr(Register(X21), MemoryOperand(methodRegister, Method::CONSTANT_POOL_OFFSET));
|
||||
|
||||
__ Mov(temp, kungfu::BytecodeStubCSigns::ID_ThrowStackOverflowException);
|
||||
@ -1038,7 +1038,7 @@ void AsmInterpreterCall::GeneratorReEnterAsmInterpDispatch(ExtendedAssembler *as
|
||||
__ Align16(currentSlotRegister);
|
||||
__ Mov(Register(SP), currentSlotRegister);
|
||||
// call bc stub
|
||||
CallBCStub(assembler, newSp, glue, method, pc, temp);
|
||||
CallBCStub(assembler, newSp, glue, callTarget, method, pc, temp);
|
||||
|
||||
__ Bind(&stackOverflow);
|
||||
{
|
||||
@ -1147,6 +1147,7 @@ void AsmInterpreterCall::DispatchCall(ExtendedAssembler *assembler, Register pcR
|
||||
Register newSpRegister, Register accRegister)
|
||||
{
|
||||
Register glueRegister = __ GlueRegister();
|
||||
Register callTargetRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::CALL_TARGET);
|
||||
Register methodRegister = __ CallDispatcherArgument(kungfu::CallDispatchInputs::METHOD);
|
||||
|
||||
if (glueRegister.GetId() != X19) {
|
||||
@ -1158,7 +1159,7 @@ void AsmInterpreterCall::DispatchCall(ExtendedAssembler *assembler, Register pcR
|
||||
} else {
|
||||
ASSERT(accRegister == Register(X23));
|
||||
}
|
||||
__ Ldr(Register(X22), MemoryOperand(methodRegister, Method::PROFILE_TYPE_INFO_OFFSET));
|
||||
__ Ldr(Register(X22), MemoryOperand(callTargetRegister, JSFunction::PROFILE_TYPE_INFO_OFFSET));
|
||||
__ Ldr(Register(X21), MemoryOperand(methodRegister, Method::CONSTANT_POOL_OFFSET));
|
||||
__ Mov(Register(X20), pcRegister);
|
||||
__ Mov(Register(FP), newSpRegister);
|
||||
@ -1292,14 +1293,14 @@ void AsmInterpreterCall::PushGeneratorFrameState(ExtendedAssembler *assembler, R
|
||||
}
|
||||
|
||||
void AsmInterpreterCall::CallBCStub(ExtendedAssembler *assembler, Register &newSp, Register &glue,
|
||||
Register &method, Register &pc, Register &temp)
|
||||
Register &callTarget, Register &method, Register &pc, Register &temp)
|
||||
{
|
||||
// prepare call entry
|
||||
__ Mov(Register(X19), glue); // X19 - glue
|
||||
__ Mov(Register(FP), newSp); // FP - sp
|
||||
__ Mov(Register(X20), pc); // X20 - pc
|
||||
__ Ldr(Register(X21), MemoryOperand(method, Method::CONSTANT_POOL_OFFSET)); // X21 - constantpool
|
||||
__ Ldr(Register(X22), MemoryOperand(method, Method::PROFILE_TYPE_INFO_OFFSET)); // X22 - profileTypeInfo
|
||||
__ Ldr(Register(X22), MemoryOperand(callTarget, JSFunction::PROFILE_TYPE_INFO_OFFSET)); // X22 - profileTypeInfo
|
||||
__ Mov(Register(X23), Immediate(JSTaggedValue::Hole().GetRawData())); // X23 - acc
|
||||
__ Ldr(Register(X24), MemoryOperand(method, Method::LITERAL_INFO_OFFSET)); // X24 - hotnessCounter
|
||||
|
||||
|
@ -235,7 +235,7 @@ private:
|
||||
Register &contextRegister, Register &pcRegister, Register &operatorRegister);
|
||||
|
||||
static void CallBCStub(ExtendedAssembler *assembler, Register &newSp, Register &glue,
|
||||
Register &method, Register &pc, Register &temp);
|
||||
Register &callTarget, Register &method, Register &pc, Register &temp);
|
||||
|
||||
static void CallNativeEntry(ExtendedAssembler *assembler);
|
||||
|
||||
|
@ -209,7 +209,7 @@ void OptimizedCall::OptimizedCallAndPushUndefined(ExtendedAssembler *assembler)
|
||||
Register argV(X4);
|
||||
__ Ldr(jsfunc, MemoryOperand(sp, FRAME_SLOT_SIZE));
|
||||
__ Ldr(method, MemoryOperand(jsfunc, JSFunction::METHOD_OFFSET));
|
||||
__ Ldr(codeAddr, MemoryOperand(method, Method::CODE_ENTRY_OFFSET));
|
||||
__ Ldr(codeAddr, MemoryOperand(jsfunc, JSFunction::CODE_ENTRY_OFFSET));
|
||||
__ Ldr(expectedNumArgs, MemoryOperand(method, Method::CALL_FIELD_OFFSET));
|
||||
__ Lsr(expectedNumArgs, expectedNumArgs, MethodLiteral::NumArgsBits::START_BIT);
|
||||
__ And(expectedNumArgs, expectedNumArgs,
|
||||
@ -1035,7 +1035,7 @@ void OptimizedCall::CallOptimized(ExtendedAssembler *assembler)
|
||||
Register codeAddr(X5);
|
||||
__ Ldr(jsfunc, MemoryOperand(sp, FRAME_SLOT_SIZE));
|
||||
__ Ldr(method, MemoryOperand(jsfunc, JSFunction::METHOD_OFFSET));
|
||||
__ Ldr(codeAddr, MemoryOperand(method, Method::CODE_ENTRY_OFFSET));
|
||||
__ Ldr(codeAddr, MemoryOperand(jsfunc, JSFunction::CODE_ENTRY_OFFSET));
|
||||
__ Br(codeAddr);
|
||||
}
|
||||
|
||||
|
@ -227,7 +227,7 @@ void OptimizedFastCall::OptimizedFastCallAndPushUndefined(ExtendedAssembler *ass
|
||||
TempRegister1Scope scope1(assembler);
|
||||
Register method1 = __ TempRegister1();
|
||||
__ Ldr(method1, MemoryOperand(jsfunc, JSFunction::METHOD_OFFSET));
|
||||
__ Ldr(X11, MemoryOperand(method1, Method::CODE_ENTRY_OFFSET));
|
||||
__ Ldr(X11, MemoryOperand(jsfunc, JSFunction::CODE_ENTRY_OFFSET));
|
||||
__ Blr(X11);
|
||||
|
||||
__ Mov(Register(SP), Register(FP));
|
||||
@ -308,7 +308,7 @@ void OptimizedFastCall::JSFastCallWithArgV(ExtendedAssembler *assembler)
|
||||
TempRegister1Scope scope1(assembler);
|
||||
Register method = __ TempRegister1();
|
||||
__ Ldr(method, MemoryOperand(jsfunc, JSFunction::METHOD_OFFSET));
|
||||
__ Ldr(X11, MemoryOperand(method, Method::CODE_ENTRY_OFFSET));
|
||||
__ Ldr(X11, MemoryOperand(jsfunc, JSFunctionBase::CODE_ENTRY_OFFSET));
|
||||
__ Blr(X11);
|
||||
|
||||
__ Mov(Register(SP), Register(FP));
|
||||
@ -450,7 +450,7 @@ void OptimizedFastCall::JSFastCallWithArgVAndPushUndefined(ExtendedAssembler *as
|
||||
TempRegister1Scope scope1(assembler);
|
||||
Register method = __ TempRegister1();
|
||||
__ Ldr(method, MemoryOperand(X1, JSFunction::METHOD_OFFSET));
|
||||
__ Ldr(X11, MemoryOperand(method, Method::CODE_ENTRY_OFFSET));
|
||||
__ Ldr(X11, MemoryOperand(X1, JSFunction::CODE_ENTRY_OFFSET));
|
||||
__ Blr(X11);
|
||||
|
||||
__ Mov(Register(SP), Register(FP));
|
||||
|
@ -118,7 +118,7 @@ void AsmInterpreterCall::GeneratorReEnterAsmInterpDispatch(ExtendedAssembler *as
|
||||
contextRegister, pcRegister, tempRegister);
|
||||
|
||||
// call bc stub
|
||||
DispatchCall(assembler, pcRegister, newSpRegister, methodRegister);
|
||||
DispatchCall(assembler, pcRegister, newSpRegister, callTargetRegister, methodRegister);
|
||||
__ Bind(&stackOverflow);
|
||||
{
|
||||
ThrowStackOverflowExceptionAndReturn(assembler, glueRegister, fpRegister, tempRegister);
|
||||
@ -329,7 +329,7 @@ void AsmInterpreterCall::JSCallCommonEntry(ExtendedAssembler *assembler, JSCallM
|
||||
__ Movq(callTargetRegister, tempRegister);
|
||||
__ Movq(Operand(methodRegister, Method::NATIVE_POINTER_OR_BYTECODE_ARRAY_OFFSET), r12); // pc: r12
|
||||
// Reload constpool and profileInfo to make sure gc map work normally
|
||||
__ Movq(Operand(methodRegister, Method::PROFILE_TYPE_INFO_OFFSET), r14); // profileTypeInfo: r14
|
||||
__ Movq(Operand(tempRegister, JSFunction::PROFILE_TYPE_INFO_OFFSET), r14); // profileTypeInfo: r14
|
||||
__ Movq(Operand(methodRegister, Method::CONSTANT_POOL_OFFSET), rbx); // constantPool: rbx
|
||||
|
||||
__ Movq(kungfu::BytecodeStubCSigns::ID_ThrowStackOverflowException, tempRegister);
|
||||
@ -709,7 +709,7 @@ void AsmInterpreterCall::PushVregs(ExtendedAssembler *assembler, Label *stackOve
|
||||
PushFrameState(assembler, prevSpRegister, fpRegister,
|
||||
callTargetRegister, thisRegister, methodRegister, pcRegister, tempRegister);
|
||||
}
|
||||
DispatchCall(assembler, pcRegister, newSpRegister, methodRegister);
|
||||
DispatchCall(assembler, pcRegister, newSpRegister, callTargetRegister, methodRegister);
|
||||
}
|
||||
|
||||
// Input: %r13 - glue
|
||||
@ -717,7 +717,7 @@ void AsmInterpreterCall::PushVregs(ExtendedAssembler *assembler, Label *stackOve
|
||||
// %r12 - callTarget
|
||||
// %rbx - method
|
||||
void AsmInterpreterCall::DispatchCall(ExtendedAssembler *assembler, Register pcRegister,
|
||||
Register newSpRegister, Register methodRegister, Register accRegister)
|
||||
Register newSpRegister, Register callTargetRegister, Register methodRegister, Register accRegister)
|
||||
{
|
||||
Register glueRegister = __ GlueRegister();
|
||||
Label dispatchCall;
|
||||
@ -727,7 +727,7 @@ void AsmInterpreterCall::DispatchCall(ExtendedAssembler *assembler, Register pcR
|
||||
__ PushAlignBytes();
|
||||
__ Bind(&dispatchCall);
|
||||
// profileTypeInfo: r14
|
||||
__ Movq(Operand(methodRegister, Method::PROFILE_TYPE_INFO_OFFSET), r14);
|
||||
__ Movq(Operand(callTargetRegister, JSFunction::PROFILE_TYPE_INFO_OFFSET), r14);
|
||||
// glue may rdi
|
||||
if (glueRegister != r13) {
|
||||
__ Movq(glueRegister, r13);
|
||||
|
@ -184,7 +184,7 @@ private:
|
||||
static Register GetNewTargetRegsiter(ExtendedAssembler *assembler, JSCallMode mode, Register defaultRegister);
|
||||
static void PushVregs(ExtendedAssembler *assembler, Label *stackOverflow);
|
||||
static void DispatchCall(ExtendedAssembler *assembler, Register pcRegister, Register newSpRegister,
|
||||
Register methodRegister, Register accRegister = rInvalid);
|
||||
Register callTargetRegister, Register methodRegister, Register accRegister = rInvalid);
|
||||
static void CallNativeEntry(ExtendedAssembler *assemblSer);
|
||||
static void CallNativeWithArgv(ExtendedAssembler *assembler, bool callNew, bool hasNewTarget = false);
|
||||
static void CallNativeInternal(ExtendedAssembler *assembler, Register nativeCode);
|
||||
|
@ -123,7 +123,7 @@ void OptimizedCall::OptimizedCallAndPushUndefined(ExtendedAssembler *assembler)
|
||||
Register codeAddrReg = rsi;
|
||||
__ Movq(Operand(rsp, DOUBLE_SLOT_SIZE), jsFuncReg); // sp + 16 get jsFunc
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::METHOD_OFFSET), method); // get method
|
||||
__ Mov(Operand(method, Method::CODE_ENTRY_OFFSET), codeAddrReg);
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::CODE_ENTRY_OFFSET), codeAddrReg);
|
||||
|
||||
Register methodCallField = rcx;
|
||||
__ Mov(Operand(method, Method::CALL_FIELD_OFFSET), methodCallField); // get call field
|
||||
@ -1047,7 +1047,7 @@ void OptimizedCall::CallOptimized(ExtendedAssembler *assembler)
|
||||
Register codeAddrReg = rsi;
|
||||
__ Movq(Operand(rsp, DOUBLE_SLOT_SIZE), jsFuncReg); // sp + 16 get jsFunc
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::METHOD_OFFSET), method); // get method
|
||||
__ Mov(Operand(method, Method::CODE_ENTRY_OFFSET), codeAddrReg);
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::CODE_ENTRY_OFFSET), codeAddrReg);
|
||||
__ Jmp(codeAddrReg);
|
||||
}
|
||||
|
||||
@ -1102,7 +1102,7 @@ void OptimizedCall::DeoptEnterAsmInterp(ExtendedAssembler *assembler)
|
||||
__ Movq(Operand(callTargetRegister, JSFunctionBase::METHOD_OFFSET), methodRegister);
|
||||
|
||||
__ Leaq(Operand(rsp, AsmInterpretedFrame::GetSize(false)), opRegister);
|
||||
AsmInterpreterCall::DispatchCall(assembler, r12, opRegister, methodRegister, rsi);
|
||||
AsmInterpreterCall::DispatchCall(assembler, r12, opRegister, callTargetRegister, methodRegister, rsi);
|
||||
}
|
||||
|
||||
__ Bind(&stackOverflow);
|
||||
|
@ -116,7 +116,7 @@ void OptimizedFastCall::OptimizedFastCallAndPushUndefined(ExtendedAssembler *ass
|
||||
Register argvReg = r12;
|
||||
__ Leaq(Operand(rsp, 8 * FRAME_SLOT_SIZE), argvReg); // 8: skip 8 frames to get argv
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::METHOD_OFFSET), method); // get method
|
||||
__ Mov(Operand(method, Method::CODE_ENTRY_OFFSET), codeAddrReg); // get codeAddress
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::CODE_ENTRY_OFFSET), codeAddrReg); // get codeAddress
|
||||
__ Mov(Operand(method, Method::CALL_FIELD_OFFSET), methodCallField); // get call field
|
||||
__ Shr(MethodLiteral::NumArgsBits::START_BIT, methodCallField);
|
||||
__ Andl(((1LU << MethodLiteral::NumArgsBits::SIZE) - 1), methodCallField);
|
||||
@ -262,7 +262,7 @@ void OptimizedFastCall::JSFastCallWithArgV(ExtendedAssembler *assembler)
|
||||
Register method = r12;
|
||||
Register jsFuncReg = rsi;
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::METHOD_OFFSET), method); // get method
|
||||
__ Mov(Operand(method, Method::CODE_ENTRY_OFFSET), rbx); // get codeAddress
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::CODE_ENTRY_OFFSET), rbx); // get codeAddress
|
||||
__ Callq(rbx);
|
||||
}
|
||||
|
||||
@ -377,7 +377,7 @@ void OptimizedFastCall::JSFastCallWithArgVAndPushUndefined(ExtendedAssembler *as
|
||||
Register method = r12;
|
||||
Register jsFuncReg = rsi;
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::METHOD_OFFSET), method); // get method
|
||||
__ Mov(Operand(method, Method::CODE_ENTRY_OFFSET), rbx); // get codeAddress
|
||||
__ Mov(Operand(jsFuncReg, JSFunctionBase::CODE_ENTRY_OFFSET), rbx); // get codeAddress
|
||||
__ Callq(rbx);
|
||||
}
|
||||
#undef __
|
||||
|
@ -770,8 +770,9 @@ void CreateObjWithBufferTypeInfoAccessor::Init()
|
||||
auto imm = acc_.GetConstantValue(index_);
|
||||
auto methodOffset = acc_.TryGetMethodOffset(GetGate());
|
||||
JSTaggedValue cp = tsManager_->GetConstantPool(methodOffset);
|
||||
JSTaggedValue unsharedCp = thread_->GetCurrentEcmaContext()->FindUnsharedConstpool(cp);
|
||||
JSTaggedValue obj = ConstantPool::GetLiteralFromCache<ConstPoolType::OBJECT_LITERAL>(
|
||||
tsManager_->GetEcmaVM()->GetJSThread(), cp, imm, recordName_);
|
||||
tsManager_->GetEcmaVM()->GetJSThread(), unsharedCp, imm, recordName_);
|
||||
objHandle_ = JSHandle<JSObject>(thread_, obj);
|
||||
}
|
||||
|
||||
|
@ -657,11 +657,12 @@ void TypedHCRLowering::LowerPrimitiveToNumber(GateRef dst, GateRef src, GateType
|
||||
acc_.ReplaceGate(dst, builder_.GetState(), builder_.GetDepend(), *result);
|
||||
}
|
||||
|
||||
GateRef TypedHCRLowering::LoadFromConstPool(GateRef constPool, size_t index, size_t valVecType)
|
||||
GateRef TypedHCRLowering::LoadFromConstPool(GateRef constpool, size_t index, size_t valVecType)
|
||||
{
|
||||
GateRef constPoolSize = builder_.GetLengthOfTaggedArray(constPool);
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constpool);
|
||||
GateRef constPoolSize = builder_.GetLengthOfTaggedArray(unsharedConstpool);
|
||||
GateRef valVecIndex = builder_.Int32Sub(constPoolSize, builder_.Int32(valVecType));
|
||||
GateRef valVec = builder_.GetValueFromTaggedArray(constPool, valVecIndex);
|
||||
GateRef valVec = builder_.GetValueFromTaggedArray(unsharedConstpool, valVecIndex);
|
||||
return builder_.LoadFromTaggedArray(valVec, index);
|
||||
}
|
||||
|
||||
@ -1630,7 +1631,9 @@ void TypedHCRLowering::LowerLookupHolder(GateRef gate)
|
||||
GateRef receiver = acc_.GetValueIn(gate, 0);
|
||||
GateRef holderHCIndex = acc_.GetValueIn(gate, 1);
|
||||
GateRef constPool = acc_.GetValueIn(gate, 2); // 2: constpool
|
||||
GateRef holderHC = builder_.LoadHClassFromConstpool(constPool, acc_.GetConstantValue(holderHCIndex));
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constPool);
|
||||
GateRef holderHC = builder_.LoadHClassFromUnsharedConstpool(unsharedConstpool,
|
||||
acc_.GetConstantValue(holderHCIndex));
|
||||
DEFVALUE(holder, (&builder_), VariableType::JS_ANY(), receiver);
|
||||
Label loopHead(&builder_);
|
||||
Label exit(&builder_);
|
||||
@ -1698,7 +1701,8 @@ void TypedHCRLowering::LowerPrototypeCheck(GateRef gate)
|
||||
GateRef frameState = acc_.GetFrameState(gate);
|
||||
|
||||
uint32_t hclassIndex = acc_.GetHClassIndex(gate);
|
||||
auto expectedReceiverHC = builder_.LoadHClassFromConstpool(constPool, hclassIndex);
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constPool);
|
||||
auto expectedReceiverHC = builder_.LoadHClassFromUnsharedConstpool(unsharedConstpool, hclassIndex);
|
||||
|
||||
auto prototype = builder_.LoadConstOffset(VariableType::JS_ANY(), expectedReceiverHC, JSHClass::PROTOTYPE_OFFSET);
|
||||
auto protoHClass = builder_.LoadHClass(prototype);
|
||||
@ -2042,7 +2046,7 @@ GateRef TypedHCRLowering::AllocateLineString(GateRef glue, GateRef length, GateR
|
||||
GateRef stringClass = builder_.GetGlobalConstantValue(ConstantIndex::LINE_STRING_CLASS_INDEX);
|
||||
|
||||
builder_.StartAllocate();
|
||||
GateRef lineString = builder_.HeapAlloc(glue, *size, GateType::TaggedValue(), RegionSpaceFlag::IN_YOUNG_SPACE);
|
||||
GateRef lineString = builder_.HeapAlloc(glue, *size, GateType::TaggedValue(), RegionSpaceFlag::IN_SHARED_OLD_SPACE);
|
||||
builder_.StoreConstOffset(VariableType::JS_POINTER(), lineString, 0, stringClass,
|
||||
MemoryOrder::NeedBarrierAndAtomic());
|
||||
builder_.StoreConstOffset(VariableType::INT32(), lineString, EcmaString::MIX_LENGTH_OFFSET, *mixLength);
|
||||
@ -2081,7 +2085,8 @@ GateRef TypedHCRLowering::AllocateSlicedString(GateRef glue, GateRef flatString,
|
||||
GateRef size = builder_.IntPtr(AlignUp(SlicedString::SIZE, static_cast<size_t>(MemAlignment::MEM_ALIGN_OBJECT)));
|
||||
|
||||
builder_.StartAllocate();
|
||||
GateRef slicedString = builder_.HeapAlloc(glue, size, GateType::TaggedValue(), RegionSpaceFlag::IN_YOUNG_SPACE);
|
||||
GateRef slicedString = builder_.HeapAlloc(glue, size, GateType::TaggedValue(),
|
||||
RegionSpaceFlag::IN_SHARED_OLD_SPACE);
|
||||
builder_.StoreConstOffset(VariableType::JS_POINTER(), slicedString, 0, stringClass,
|
||||
MemoryOrder::NeedBarrierAndAtomic());
|
||||
builder_.StoreConstOffset(VariableType::INT32(), slicedString, EcmaString::MIX_LENGTH_OFFSET, *mixLength);
|
||||
@ -2694,7 +2699,8 @@ void TypedHCRLowering::LowerMonoLoadPropertyOnProto(GateRef gate)
|
||||
auto prototype = builder_.LoadConstOffset(VariableType::JS_ANY(), receiverHC, JSHClass::PROTOTYPE_OFFSET);
|
||||
|
||||
// lookup from receiver for holder
|
||||
auto holderHC = builder_.LoadHClassFromConstpool(constPool, acc_.GetConstantValue(hclassIndex));
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constPool);
|
||||
auto holderHC = builder_.LoadHClassFromUnsharedConstpool(unsharedConstpool, acc_.GetConstantValue(hclassIndex));
|
||||
DEFVALUE(current, (&builder_), VariableType::JS_ANY(), prototype);
|
||||
Label exit(&builder_);
|
||||
Label loopHead(&builder_);
|
||||
@ -2734,7 +2740,8 @@ void TypedHCRLowering::LowerMonoCallGetterOnProto(GateRef gate, GateRef glue)
|
||||
auto prototype = builder_.LoadConstOffset(VariableType::JS_ANY(), receiverHC, JSHClass::PROTOTYPE_OFFSET);
|
||||
|
||||
// lookup from receiver for holder
|
||||
auto holderHC = builder_.LoadHClassFromConstpool(constPool, acc_.GetConstantValue(hclassIndex));
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constPool);
|
||||
auto holderHC = builder_.LoadHClassFromUnsharedConstpool(unsharedConstpool, acc_.GetConstantValue(hclassIndex));
|
||||
DEFVALUE(current, (&builder_), VariableType::JS_ANY(), prototype);
|
||||
Label exitLoad(&builder_);
|
||||
Label loopHead(&builder_);
|
||||
@ -2824,7 +2831,8 @@ void TypedHCRLowering::LowerMonoStorePropertyLookUpProto(GateRef gate, GateRef g
|
||||
auto receiverHC = builder_.LoadConstOffset(VariableType::JS_POINTER(), receiver, TaggedObject::HCLASS_OFFSET);
|
||||
auto prototype = builder_.LoadConstOffset(VariableType::JS_ANY(), receiverHC, JSHClass::PROTOTYPE_OFFSET);
|
||||
// lookup from receiver for holder
|
||||
auto holderHC = builder_.LoadHClassFromConstpool(constpool, acc_.GetConstantValue(hclassIndex));
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constpool);
|
||||
auto holderHC = builder_.LoadHClassFromUnsharedConstpool(unsharedConstpool, acc_.GetConstantValue(hclassIndex));
|
||||
DEFVALUE(current, (&builder_), VariableType::JS_ANY(), prototype);
|
||||
Label exit(&builder_);
|
||||
Label loopHead(&builder_);
|
||||
@ -2893,7 +2901,8 @@ void TypedHCRLowering::LowerMonoStoreProperty(GateRef gate, GateRef glue)
|
||||
Label exit(&builder_);
|
||||
Label notProto(&builder_);
|
||||
Label isProto(&builder_);
|
||||
auto newHolderHC = builder_.LoadHClassFromConstpool(constPool, acc_.GetConstantValue(hclassIndex));
|
||||
GateRef unsharedConstpool = builder_.GetUnsharedConstpool(constPool);
|
||||
auto newHolderHC = builder_.LoadHClassFromUnsharedConstpool(unsharedConstpool, acc_.GetConstantValue(hclassIndex));
|
||||
builder_.StoreConstOffset(VariableType::JS_ANY(), newHolderHC, JSHClass::PROTOTYPE_OFFSET, prototype);
|
||||
builder_.Branch(builder_.IsProtoTypeHClass(receiverHC), &isProto, ¬Proto,
|
||||
BranchWeight::ONE_WEIGHT, BranchWeight::DEOPT_WEIGHT, "isProtoTypeHClass");
|
||||
@ -3114,8 +3123,7 @@ void TypedHCRLowering::LowerStringFromSingleCharCode(GateRef gate, GateRef glue)
|
||||
newBuilder.SetParameters(glue, 0);
|
||||
builder_.Bind(&canBeCompress);
|
||||
{
|
||||
GateRef singleCharTable = builder_.Load(VariableType::JS_ANY(), glue,
|
||||
builder_.IntPtr(JSThread::GlueData::GetSingleCharTableOffset(env.Is32Bit())));
|
||||
GateRef singleCharTable = builder_.GetGlobalConstantValue(ConstantIndex::SINGLE_CHAR_TABLE_INDEX);
|
||||
res = builder_.GetValueFromTaggedArray(singleCharTable, builder_.ZExtInt16ToInt32(*value));
|
||||
builder_.Jump(&exit);
|
||||
}
|
||||
|
@ -441,7 +441,8 @@ JSTaggedValue DebuggerApi::GetCurrentModule(const EcmaVM *ecmaVm)
|
||||
if (method->IsNativeWithCallField()) {
|
||||
continue;
|
||||
}
|
||||
JSTaggedValue module = method->GetModule();
|
||||
JSTaggedValue func = frameHandler.GetFunction();
|
||||
JSTaggedValue module = JSFunction::Cast(func.GetTaggedObject())->GetModule();
|
||||
if (module.IsUndefined()) {
|
||||
continue;
|
||||
}
|
||||
|
@ -411,12 +411,13 @@ bool Deoptimizier::CollectVirtualRegisters(Method* method, FrameWriter *frameWri
|
||||
return true;
|
||||
}
|
||||
|
||||
void Deoptimizier::Dump(Method* method, kungfu::DeoptType type, size_t depth)
|
||||
void Deoptimizier::Dump(JSTaggedValue callTarget, kungfu::DeoptType type, size_t depth)
|
||||
{
|
||||
if (thread_->IsPGOProfilerEnable()) {
|
||||
auto profileTypeInfo = method->GetProfileTypeInfo();
|
||||
JSFunction *function = JSFunction::Cast(callTarget);
|
||||
auto profileTypeInfo = function->GetProfileTypeInfo();
|
||||
if (profileTypeInfo.IsUndefined()) {
|
||||
SlowRuntimeStub::NotifyInlineCache(thread_, method);
|
||||
SlowRuntimeStub::NotifyInlineCache(thread_, function);
|
||||
}
|
||||
}
|
||||
if (traceDeopt_) {
|
||||
@ -424,7 +425,7 @@ void Deoptimizier::Dump(Method* method, kungfu::DeoptType type, size_t depth)
|
||||
LOG_TRACE(INFO) << "Check Type: " << checkType;
|
||||
std::string data = JsStackInfo::BuildJsStackTrace(thread_, true);
|
||||
LOG_COMPILER(INFO) << "Deoptimize" << data;
|
||||
const uint8_t *pc = method->GetBytecodeArray() + pc_.at(depth);
|
||||
const uint8_t *pc = GetMethod(callTarget)->GetBytecodeArray() + pc_.at(depth);
|
||||
BytecodeInstruction inst(pc);
|
||||
LOG_COMPILER(INFO) << inst;
|
||||
}
|
||||
@ -523,10 +524,10 @@ void Deoptimizier::UpdateAndDumpDeoptInfo(kungfu::DeoptType type)
|
||||
{
|
||||
// depth records the number of layers of nested calls when deopt occurs
|
||||
for (size_t i = 0; i <= inlineDepth_; i++) {
|
||||
JSTaggedValue CallTarget = GetDeoptValue(i, static_cast<int32_t>(SpecVregIndex::FUNC_INDEX));
|
||||
auto method = GetMethod(CallTarget);
|
||||
JSTaggedValue callTarget = GetDeoptValue(i, static_cast<int32_t>(SpecVregIndex::FUNC_INDEX));
|
||||
auto method = GetMethod(callTarget);
|
||||
if (i == inlineDepth_) {
|
||||
Dump(method, type, i);
|
||||
Dump(callTarget, type, i);
|
||||
}
|
||||
ASSERT(thread_ != nullptr);
|
||||
uint8_t deoptThreshold = method->GetDeoptThreshold();
|
||||
@ -535,9 +536,11 @@ void Deoptimizier::UpdateAndDumpDeoptInfo(kungfu::DeoptType type)
|
||||
method->SetDeoptThreshold(--deoptThreshold);
|
||||
} else {
|
||||
method->ClearAOTStatusWhenDeopt();
|
||||
if (method->GetMachineCode() != JSTaggedValue::Undefined()) {
|
||||
method->SetMachineCode(thread_, JSTaggedValue::Undefined());
|
||||
auto func = JSFunction::Cast(callTarget.GetTaggedObject());
|
||||
if (func->GetMachineCode() != JSTaggedValue::Undefined()) {
|
||||
func->SetMachineCode(thread_, JSTaggedValue::Undefined());
|
||||
}
|
||||
func->SetCodeEntry(reinterpret_cast<uintptr_t>(nullptr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -174,7 +174,7 @@ private:
|
||||
}
|
||||
Method* GetMethod(JSTaggedValue &target);
|
||||
void RelocateCalleeSave();
|
||||
void Dump(Method* method, kungfu::DeoptType type, size_t depth);
|
||||
void Dump(JSTaggedValue callTarget, kungfu::DeoptType type, size_t depth);
|
||||
size_t GetCallSize(size_t curDepth, const uint8_t *resumePc);
|
||||
JSThread *thread_ {nullptr};
|
||||
uintptr_t *calleeRegAddr_ {nullptr};
|
||||
|
@ -15,6 +15,7 @@
|
||||
|
||||
#include "ecmascript/dfx/hprof/heap_profiler.h"
|
||||
|
||||
#include "ecmascript/checkpoint/thread_state_transition.h"
|
||||
#include "ecmascript/dfx/hprof/file_stream.h"
|
||||
#include "ecmascript/dfx/hprof/heap_snapshot.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
@ -23,6 +24,7 @@
|
||||
#include "ecmascript/mem/assert_scope.h"
|
||||
#include "ecmascript/mem/concurrent_sweeper.h"
|
||||
#include "ecmascript/mem/heap-inl.h"
|
||||
#include "ecmascript/mem/shared_heap/shared_concurrent_sweeper.h"
|
||||
|
||||
#if defined(ENABLE_DUMP_IN_FAULTLOG)
|
||||
#include "faultloggerd_client.h"
|
||||
@ -127,8 +129,7 @@ void HeapProfiler::MoveEvent(uintptr_t address, TaggedObject *forwardAddress, si
|
||||
|
||||
void HeapProfiler::UpdateHeapObjects(HeapSnapshot *snapshot)
|
||||
{
|
||||
vm_->CollectGarbage(TriggerGCType::OLD_GC);
|
||||
vm_->GetHeap()->GetSweeper()->EnsureAllTaskFinished();
|
||||
ForceSharedGC();
|
||||
snapshot->UpdateNodes();
|
||||
}
|
||||
|
||||
@ -151,23 +152,28 @@ void HeapProfiler::DumpHeapSnapshot([[maybe_unused]] DumpFormat dumpFormat, [[ma
|
||||
bool HeapProfiler::DumpHeapSnapshot(DumpFormat dumpFormat, Stream *stream, Progress *progress,
|
||||
bool isVmMode, bool isPrivate, bool captureNumericValue, bool isFullGC)
|
||||
{
|
||||
if (isFullGC) {
|
||||
[[maybe_unused]] bool heapClean = ForceFullGC(vm_);
|
||||
ASSERT(heapClean);
|
||||
}
|
||||
LOG_ECMA(INFO) << "HeapProfiler DumpSnapshot start";
|
||||
int32_t heapCount = 0;
|
||||
if (isFullGC) {
|
||||
size_t heapSize = vm_->GetHeap()->GetLiveObjectSize();
|
||||
LOG_ECMA(INFO) << "HeapProfiler DumpSnapshot heap size " << heapSize;
|
||||
heapCount = static_cast<int32_t>(vm_->GetHeap()->GetHeapObjectCount());
|
||||
if (progress != nullptr) {
|
||||
progress->ReportProgress(0, heapCount);
|
||||
HeapSnapshot *snapshot = nullptr;
|
||||
{
|
||||
if (isFullGC) {
|
||||
[[maybe_unused]] bool heapClean = ForceFullGC(vm_);
|
||||
ASSERT(heapClean);
|
||||
}
|
||||
SuspendAllScope suspendScope(vm_->GetAssociatedJSThread());
|
||||
ForceSharedGC();
|
||||
LOG_ECMA(INFO) << "HeapProfiler DumpSnapshot start";
|
||||
if (isFullGC) {
|
||||
size_t heapSize = vm_->GetHeap()->GetLiveObjectSize();
|
||||
LOG_ECMA(INFO) << "HeapProfiler DumpSnapshot heap size " << heapSize;
|
||||
heapCount = static_cast<int32_t>(vm_->GetHeap()->GetHeapObjectCount());
|
||||
if (progress != nullptr) {
|
||||
progress->ReportProgress(0, heapCount);
|
||||
}
|
||||
}
|
||||
snapshot = MakeHeapSnapshot(SampleType::ONE_SHOT, isVmMode, isPrivate, captureNumericValue,
|
||||
false, isFullGC);
|
||||
ASSERT(snapshot != nullptr);
|
||||
}
|
||||
HeapSnapshot *snapshot = MakeHeapSnapshot(SampleType::ONE_SHOT, isVmMode, isPrivate, captureNumericValue,
|
||||
false, isFullGC);
|
||||
ASSERT(snapshot != nullptr);
|
||||
entryIdMap_->UpdateEntryIdMap(snapshot);
|
||||
isProfiling_ = true;
|
||||
if (progress != nullptr) {
|
||||
@ -187,6 +193,8 @@ bool HeapProfiler::DumpHeapSnapshot(DumpFormat dumpFormat, Stream *stream, Progr
|
||||
bool HeapProfiler::StartHeapTracking(double timeInterval, bool isVmMode, Stream *stream,
|
||||
bool traceAllocation, bool newThread)
|
||||
{
|
||||
vm_->CollectGarbage(TriggerGCType::OLD_GC);
|
||||
SuspendAllScope suspendScope(vm_->GetAssociatedJSThread());
|
||||
HeapSnapshot *snapshot = MakeHeapSnapshot(SampleType::REAL_TIME, isVmMode, false, false, traceAllocation);
|
||||
if (snapshot == nullptr) {
|
||||
return false;
|
||||
@ -211,8 +219,13 @@ bool HeapProfiler::UpdateHeapTracking(Stream *stream)
|
||||
if (snapshot == nullptr) {
|
||||
return false;
|
||||
}
|
||||
snapshot->RecordSampleTime();
|
||||
UpdateHeapObjects(snapshot);
|
||||
|
||||
{
|
||||
vm_->CollectGarbage(TriggerGCType::OLD_GC);
|
||||
SuspendAllScope suspendScope(vm_->GetAssociatedJSThread());
|
||||
snapshot->RecordSampleTime();
|
||||
UpdateHeapObjects(snapshot);
|
||||
}
|
||||
|
||||
if (stream != nullptr) {
|
||||
snapshot->PushHeapStat(stream);
|
||||
@ -241,7 +254,11 @@ bool HeapProfiler::StopHeapTracking(Stream *stream, Progress *progress, bool new
|
||||
if (progress != nullptr) {
|
||||
progress->ReportProgress(0, heapCount);
|
||||
}
|
||||
snapshot->FinishSnapshot();
|
||||
{
|
||||
SuspendAllScope suspendScope(vm_->GetAssociatedJSThread());
|
||||
snapshot->FinishSnapshot();
|
||||
}
|
||||
|
||||
isProfiling_ = false;
|
||||
if (progress != nullptr) {
|
||||
progress->ReportProgress(heapCount, heapCount);
|
||||
@ -305,6 +322,13 @@ bool HeapProfiler::ForceFullGC(const EcmaVM *vm)
|
||||
return false;
|
||||
}
|
||||
|
||||
void HeapProfiler::ForceSharedGC()
|
||||
{
|
||||
SharedHeap *sHeap = SharedHeap::GetInstance();
|
||||
sHeap->CollectGarbageImpl(TriggerGCType::SHARED_GC, GCReason::OTHER);
|
||||
sHeap->GetSweeper()->WaitAllTaskFinished();
|
||||
}
|
||||
|
||||
HeapSnapshot *HeapProfiler::MakeHeapSnapshot(SampleType sampleType, bool isVmMode, bool isPrivate,
|
||||
bool captureNumericValue, bool traceAllocation, bool isFullGC)
|
||||
{
|
||||
|
@ -112,6 +112,7 @@ private:
|
||||
* trigger full gc to make sure no unreachable objects in heap
|
||||
*/
|
||||
bool ForceFullGC(const EcmaVM *vm);
|
||||
void ForceSharedGC();
|
||||
|
||||
/**
|
||||
* make a new heap snapshot and put it into a container eg, vector
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/runtime.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
void HeapRootVisitor::VisitHeapRoots(JSThread *thread, const RootVisitor &visitor,
|
||||
@ -26,6 +27,9 @@ void HeapRootVisitor::VisitHeapRoots(JSThread *thread, const RootVisitor &visito
|
||||
auto ecmaVm = GetVMInstance(thread);
|
||||
ecmaVm->Iterate(visitor, rangeVisitor);
|
||||
thread->Iterate(visitor, rangeVisitor, derivedVisitor);
|
||||
|
||||
// SerializeRoot from shared heap
|
||||
Runtime::GetInstance()->IterateSerializeRoot(visitor);
|
||||
}
|
||||
|
||||
EcmaVM *HeapRootVisitor::GetVMInstance(JSThread *thread) const
|
||||
|
@ -534,6 +534,8 @@ CString *HeapSnapshot::GenerateNodeName(TaggedObject *entry)
|
||||
return GetString("ResolvedBinding");
|
||||
case JSType::RESOLVEDINDEXBINDING_RECORD:
|
||||
return GetString("ResolvedIndexBinding");
|
||||
case JSType::RESOLVEDRECORDBINDING_RECORD:
|
||||
return GetString("ResolvedRecordBinding");
|
||||
case JSType::JS_MODULE_NAMESPACE:
|
||||
return GetString("ModuleNamespace");
|
||||
case JSType::JS_API_PLAIN_ARRAY:
|
||||
@ -641,6 +643,12 @@ NodeType HeapSnapshot::GenerateNodeType(TaggedObject *entry)
|
||||
|
||||
void HeapSnapshot::FillNodes(bool isInFinish)
|
||||
{
|
||||
SharedHeap *sHeap = SharedHeap::GetInstance();
|
||||
if (sHeap != nullptr) {
|
||||
sHeap->IterateOverObjects([this, isInFinish](TaggedObject *obj) {
|
||||
GenerateNode(JSTaggedValue(obj), 0, isInFinish);
|
||||
});
|
||||
}
|
||||
// Iterate Heap Object
|
||||
auto heap = vm_->GetHeap();
|
||||
if (heap != nullptr) {
|
||||
|
@ -40,8 +40,8 @@ public:
|
||||
{
|
||||
return runtimeStatEnabled_;
|
||||
}
|
||||
void StartCount(PandaRuntimeTimer *timer, int callerId);
|
||||
void StopCount(const PandaRuntimeTimer *timer);
|
||||
void PUBLIC_API StartCount(PandaRuntimeTimer *timer, int callerId);
|
||||
void PUBLIC_API StopCount(const PandaRuntimeTimer *timer);
|
||||
void PrintAllStats() const;
|
||||
void ResetAllCount();
|
||||
void Print() const;
|
||||
|
@ -479,9 +479,11 @@ CString JSHClass::DumpJSType(JSType type)
|
||||
case JSType::SOURCE_TEXT_MODULE_RECORD:
|
||||
return "SourceTextModuleRecord";
|
||||
case JSType::RESOLVEDBINDING_RECORD:
|
||||
return "ResolvedBingingRecord";
|
||||
return "ResolvedBindingRecord";
|
||||
case JSType::RESOLVEDINDEXBINDING_RECORD:
|
||||
return "ResolvedIndexBingingRecord";
|
||||
return "ResolvedIndexBindingRecord";
|
||||
case JSType::RESOLVEDRECORDBINDING_RECORD:
|
||||
return "ResolvedRecordBindingRecord";
|
||||
case JSType::IMPORTENTRY_RECORD:
|
||||
return "ImportEntry";
|
||||
case JSType::LOCAL_EXPORTENTRY_RECORD:
|
||||
@ -1215,6 +1217,9 @@ static void DumpObject(TaggedObject *obj, std::ostream &os)
|
||||
case JSType::RESOLVEDINDEXBINDING_RECORD:
|
||||
ResolvedIndexBinding::Cast(obj)->Dump(os);
|
||||
break;
|
||||
case JSType::RESOLVEDRECORDBINDING_RECORD:
|
||||
ResolvedRecordBinding::Cast(obj)->Dump(os);
|
||||
break;
|
||||
case JSType::JS_MODULE_NAMESPACE:
|
||||
ModuleNamespace::Cast(obj)->Dump(os);
|
||||
break;
|
||||
@ -1678,11 +1683,14 @@ void JSFunction::Dump(std::ostream &os) const
|
||||
os << "\n";
|
||||
os << " - LexicalEnv: ";
|
||||
if (GetClass()->IsJSSharedFunction()) {
|
||||
os << GetLexicalEnv().GetTaggedObject()<< "\n";
|
||||
os << GetLexicalEnv().GetRawData()<< "\n";
|
||||
} else {
|
||||
GetLexicalEnv().Dump(os);
|
||||
os << "\n";
|
||||
}
|
||||
os << " - ProfileTypeInfo: ";
|
||||
GetProfileTypeInfo().Dump(os);
|
||||
os << "\n";
|
||||
os << " - HomeObject: ";
|
||||
GetHomeObject().Dump(os);
|
||||
os << "\n";
|
||||
@ -1692,6 +1700,9 @@ void JSFunction::Dump(std::ostream &os) const
|
||||
os << " - Method: ";
|
||||
GetMethod().Dump(os);
|
||||
os << "\n";
|
||||
os << " - Module: ";
|
||||
GetModule().Dump(os);
|
||||
os << "\n";
|
||||
JSObject::Dump(os);
|
||||
}
|
||||
|
||||
@ -3814,6 +3825,16 @@ void ResolvedIndexBinding::Dump(std::ostream &os) const
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void ResolvedRecordBinding::Dump(std::ostream &os) const
|
||||
{
|
||||
os << " - Module: ";
|
||||
GetModuleRecord().Dump(os);
|
||||
os << "\n";
|
||||
os << " - Index: ";
|
||||
GetIndex();
|
||||
os << "\n";
|
||||
}
|
||||
|
||||
void ModuleNamespace::Dump(std::ostream &os) const
|
||||
{
|
||||
os << " - Exports: ";
|
||||
@ -3898,12 +3919,6 @@ void Method::Dump(std::ostream &os) const
|
||||
os << " - ConstantPool: ";
|
||||
GetConstantPool().Dump(os);
|
||||
os << "\n";
|
||||
os << " - ProfileTypeInfo: ";
|
||||
GetProfileTypeInfo().Dump(os);
|
||||
os << "\n";
|
||||
os << " - Module: ";
|
||||
GetModule().Dump(os);
|
||||
os << "\n";
|
||||
os << " - FunctionKind: " << static_cast<int>(GetFunctionKind());
|
||||
os << "\n";
|
||||
os << " - CodeEntryOrLiteral: " << std::hex << GetCodeEntryOrLiteral() << "\n";
|
||||
@ -4400,6 +4415,9 @@ static void DumpObject(TaggedObject *obj, std::vector<Reference> &vec, bool isVm
|
||||
case JSType::RESOLVEDINDEXBINDING_RECORD:
|
||||
ResolvedIndexBinding::Cast(obj)->DumpForSnapshot(vec);
|
||||
return;
|
||||
case JSType::RESOLVEDRECORDBINDING_RECORD:
|
||||
ResolvedRecordBinding::Cast(obj)->DumpForSnapshot(vec);
|
||||
return;
|
||||
case JSType::JS_MODULE_NAMESPACE:
|
||||
ModuleNamespace::Cast(obj)->DumpForSnapshot(vec);
|
||||
return;
|
||||
@ -4815,7 +4833,10 @@ void JSFunction::DumpForSnapshot(std::vector<Reference> &vec) const
|
||||
{
|
||||
vec.emplace_back(CString("ProtoOrHClass"), GetProtoOrHClass());
|
||||
vec.emplace_back(CString("LexicalEnv"), GetLexicalEnv());
|
||||
vec.emplace_back(CString("ProfileTypeInfo"), GetProfileTypeInfo());
|
||||
vec.emplace_back(CString("HomeObject"), GetHomeObject());
|
||||
vec.emplace_back(CString("Module"), GetModule());
|
||||
vec.emplace_back(CString("Method"), GetMethod());
|
||||
if ((!GetMethod().IsNull()) && (!GetMethod().IsUndefined())) {
|
||||
vec.emplace_back(CString("FunctionKind"), JSTaggedValue(static_cast<int>(GetFunctionKind())));
|
||||
}
|
||||
@ -4828,9 +4849,6 @@ void Method::DumpForSnapshot(std::vector<Reference> &vec) const
|
||||
{
|
||||
vec.emplace_back(CString("MethodName"), JSTaggedValue(GetMethodName()));
|
||||
vec.emplace_back(CString("ConstantPool"), GetConstantPool());
|
||||
vec.emplace_back(CString("ProfileTypeInfo"), GetProfileTypeInfo());
|
||||
vec.emplace_back(CString("Module"), GetModule());
|
||||
vec.emplace_back(CString("MachineCode"), GetMachineCode());
|
||||
}
|
||||
|
||||
void Program::DumpForSnapshot(std::vector<Reference> &vec) const
|
||||
@ -5990,6 +6008,12 @@ void ResolvedIndexBinding::DumpForSnapshot(std::vector<Reference> &vec) const
|
||||
vec.emplace_back(CString("Index"), JSTaggedValue(GetIndex()));
|
||||
}
|
||||
|
||||
void ResolvedRecordBinding::DumpForSnapshot(std::vector<Reference> &vec) const
|
||||
{
|
||||
vec.emplace_back(CString("ModuleRecord"), GetModuleRecord());
|
||||
vec.emplace_back(CString("Index"), JSTaggedValue(GetIndex()));
|
||||
}
|
||||
|
||||
void ModuleNamespace::DumpForSnapshot(std::vector<Reference> &vec) const
|
||||
{
|
||||
vec.emplace_back(CString("Module"), GetModule());
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "ecmascript/builtins/builtins_string.h"
|
||||
#include "ecmascript/compiler/aot_file/an_file_data_manager.h"
|
||||
#include "ecmascript/compiler/common_stubs.h"
|
||||
#include "ecmascript/ecma_string.h"
|
||||
#include "ecmascript/ecma_string_table.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
@ -36,7 +37,9 @@
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/log.h"
|
||||
#include "ecmascript/module/module_path_helper.h"
|
||||
#include "ecmascript/module/js_shared_module.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/patch/patch_loader.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
||||
#include "ecmascript/require/js_cjs_module_cache.h"
|
||||
#include "ecmascript/require/js_require_manager.h"
|
||||
@ -47,6 +50,8 @@
|
||||
namespace panda::ecmascript {
|
||||
using PathHelper = base::PathHelper;
|
||||
|
||||
int32_t EcmaContext::unsharedConstpoolCount_ = 0;
|
||||
|
||||
EcmaContext::EcmaContext(JSThread *thread)
|
||||
: thread_(thread),
|
||||
vm_(thread->GetEcmaVM()),
|
||||
@ -93,18 +98,19 @@ bool EcmaContext::Initialize()
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
propertiesCache_ = new PropertiesCache();
|
||||
regExpParserCache_ = new RegExpParserCache();
|
||||
unsharedConstpools_ = new std::array<JSTaggedValue, UNSHARED_CONSTANTPOOL_COUNT>();
|
||||
unsharedConstpools_->fill(JSTaggedValue::Hole());
|
||||
thread_->SetUnsharedConstpools(reinterpret_cast<uintptr_t>(unsharedConstpools_->data()));
|
||||
|
||||
JSHandle<JSHClass> hClassHandle = factory_->InitClassClass();
|
||||
|
||||
thread_->SetGlobalConst(&globalConst_);
|
||||
globalConst_.Init(thread_);
|
||||
JSHandle<JSHClass> hClassHandle = JSHandle<JSHClass>(thread_, globalConst_.GetHClassClass());
|
||||
JSHandle<JSHClass> globalEnvClass = factory_->NewEcmaHClass(
|
||||
*hClassHandle,
|
||||
GlobalEnv::SIZE,
|
||||
JSType::GLOBAL_ENV);
|
||||
thread_->SetGlobalConst(&globalConst_);
|
||||
globalConst_.Init(thread_, *hClassHandle);
|
||||
auto arrayHClassIndexMaps = Elements::InitializeHClassMap();
|
||||
thread_->SetArrayHClassIndexMap(arrayHClassIndexMaps);
|
||||
|
||||
JSHandle<GlobalEnv> globalEnv = factory_->NewGlobalEnv(*globalEnvClass);
|
||||
globalEnv->Init(thread_);
|
||||
globalEnv_ = globalEnv.GetTaggedValue();
|
||||
@ -260,6 +266,7 @@ JSTaggedValue EcmaContext::ExecuteAot(size_t actualNumArgs, JSTaggedType *args,
|
||||
const JSTaggedType *prevFp, bool needPushUndefined)
|
||||
{
|
||||
INTERPRETER_TRACE(thread_, ExecuteAot);
|
||||
ASSERT(thread_->IsInManagedState());
|
||||
auto entry = thread_->GetRTInterface(kungfu::RuntimeStubCSigns::ID_JSFunctionEntry);
|
||||
// do not modify this log to INFO, this will call many times
|
||||
LOG_ECMA(DEBUG) << "start to execute aot entry: " << (void*)entry;
|
||||
@ -274,7 +281,7 @@ JSTaggedValue EcmaContext::ExecuteAot(size_t actualNumArgs, JSTaggedType *args,
|
||||
Expected<JSTaggedValue, bool> EcmaContext::CommonInvokeEcmaEntrypoint(const JSPandaFile *jsPandaFile,
|
||||
std::string_view entryPoint, JSHandle<JSFunction> &func, bool executeFromJob)
|
||||
{
|
||||
JSHandle<Method> method(thread_, func->GetMethod());
|
||||
ASSERT(thread_->IsInManagedState());
|
||||
JSHandle<JSTaggedValue> global = GlobalEnv::Cast(globalEnv_.GetTaggedObject())->GetJSGlobalObject();
|
||||
JSHandle<JSTaggedValue> undefined = thread_->GlobalConstants()->GetHandledUndefined();
|
||||
CString entry = entryPoint.data();
|
||||
@ -290,13 +297,14 @@ Expected<JSTaggedValue, bool> EcmaContext::CommonInvokeEcmaEntrypoint(const JSPa
|
||||
if (!jsPandaFile->IsBundlePack()) {
|
||||
moduleName = entry;
|
||||
}
|
||||
JSHandle<SourceTextModule> module = moduleManager_->HostGetImportedModule(moduleName);
|
||||
method->SetModule(thread_, module);
|
||||
JSHandle<JSTaggedValue> module(moduleManager_->HostGetImportedModule(moduleName));
|
||||
// esm -> SourceTextModule; cjs or script -> string of recordName
|
||||
func->SetModule(thread_, module);
|
||||
} else {
|
||||
// if it is Cjs at present, the module slot of the function is not used. We borrow it to store the recordName,
|
||||
// which can avoid the problem of larger memory caused by the new slot
|
||||
JSHandle<EcmaString> recordName = factory_->NewFromUtf8(entry);
|
||||
method->SetModule(thread_, recordName);
|
||||
func->SetModule(thread_, recordName);
|
||||
}
|
||||
vm_->CheckStartCpuProfiler();
|
||||
|
||||
@ -436,13 +444,13 @@ void EcmaContext::CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValu
|
||||
|
||||
bool EcmaContext::HasCachedConstpool(const JSPandaFile *jsPandaFile) const
|
||||
{
|
||||
return cachedConstpools_.find(jsPandaFile) != cachedConstpools_.end();
|
||||
return cachedSharedConstpools_.find(jsPandaFile) != cachedSharedConstpools_.end();
|
||||
}
|
||||
|
||||
JSTaggedValue EcmaContext::FindConstpool(const JSPandaFile *jsPandaFile, int32_t index)
|
||||
{
|
||||
auto iter = cachedConstpools_.find(jsPandaFile);
|
||||
if (iter == cachedConstpools_.end()) {
|
||||
auto iter = cachedSharedConstpools_.find(jsPandaFile);
|
||||
if (iter == cachedSharedConstpools_.end()) {
|
||||
return JSTaggedValue::Hole();
|
||||
}
|
||||
auto constpoolIter = iter->second.find(index);
|
||||
@ -452,11 +460,57 @@ JSTaggedValue EcmaContext::FindConstpool(const JSPandaFile *jsPandaFile, int32_t
|
||||
return constpoolIter->second;
|
||||
}
|
||||
|
||||
JSTaggedValue EcmaContext::FindUnsharedConstpool(JSTaggedValue sharedConstpool)
|
||||
{
|
||||
ConstantPool *shareCp = ConstantPool::Cast(sharedConstpool.GetTaggedObject());
|
||||
int32_t index = shareCp->GetUnsharedConstpoolIndex().GetInt();
|
||||
// unshared constpool index is default INT32_MAX.
|
||||
ASSERT(0 <= index && index != ConstantPool::CONSTPOOL_TYPE_FLAG && index < UNSHARED_CONSTANTPOOL_COUNT);
|
||||
JSTaggedValue unsharedConstpool = (*unsharedConstpools_)[index];
|
||||
if (unsharedConstpool.IsHole()) {
|
||||
ASSERT(index != INT32_MAX);
|
||||
JSHandle<ConstantPool> unshareCp =
|
||||
ConstantPool::CreateUnSharedConstPoolBySharedConstpool(vm_, shareCp->GetJSPandaFile(), shareCp);
|
||||
unsharedConstpool = unshareCp.GetTaggedValue();
|
||||
CheckUnsharedConstpoolArrayLimit(index);
|
||||
SetUnsharedConstpool(index, unsharedConstpool);
|
||||
}
|
||||
return unsharedConstpool;
|
||||
}
|
||||
|
||||
JSHandle<ConstantPool> EcmaContext::CreateConstpoolPair(JSPandaFile *jsPandaFile, EntityId methodId)
|
||||
{
|
||||
panda_file::IndexAccessor indexAccessor(*jsPandaFile->GetPandaFile(), methodId);
|
||||
int32_t index = static_cast<int32_t>(indexAccessor.GetHeaderIndex());
|
||||
JSHandle<ConstantPool> constpool =
|
||||
ConstantPool::CreateUnSharedConstPool(thread_->GetEcmaVM(), jsPandaFile, methodId);
|
||||
JSHandle<ConstantPool> sconstpool;
|
||||
int32_t count = GetAndIncreaseUnsharedConstpoolCount();
|
||||
if (jsPandaFile->IsLoadedAOT()) {
|
||||
sconstpool = ConstantPool::CreateSharedConstPoolForAOT(vm_, constpool, count, index);
|
||||
} else {
|
||||
sconstpool = ConstantPool::CreateSharedConstPool(
|
||||
thread_->GetEcmaVM(), jsPandaFile, methodId, count, index);
|
||||
}
|
||||
AddConstpool(jsPandaFile, sconstpool.GetTaggedValue(), index);
|
||||
CheckUnsharedConstpoolArrayLimit(count);
|
||||
SetUnsharedConstpool(count, constpool.GetTaggedValue());
|
||||
return sconstpool;
|
||||
}
|
||||
|
||||
void EcmaContext::EraseUnsharedConstpool(JSTaggedValue sharedConstpool)
|
||||
{
|
||||
int32_t index = ConstantPool::Cast(sharedConstpool.GetTaggedObject())->GetUnsharedConstpoolIndex().GetInt();
|
||||
// unshared constpool index is default INT32_MAX.
|
||||
ASSERT(0 <= index && index != ConstantPool::CONSTPOOL_TYPE_FLAG && index < UNSHARED_CONSTANTPOOL_COUNT);
|
||||
(*unsharedConstpools_)[index] = JSTaggedValue::Hole();
|
||||
}
|
||||
|
||||
std::optional<std::reference_wrapper<CMap<int32_t, JSTaggedValue>>> EcmaContext::FindConstpools(
|
||||
const JSPandaFile *jsPandaFile)
|
||||
{
|
||||
auto iter = cachedConstpools_.find(jsPandaFile);
|
||||
if (iter == cachedConstpools_.end()) {
|
||||
auto iter = cachedSharedConstpools_.find(jsPandaFile);
|
||||
if (iter == cachedSharedConstpools_.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return iter->second;
|
||||
@ -491,9 +545,18 @@ JSHandle<ConstantPool> EcmaContext::FindOrCreateConstPool(const JSPandaFile *jsP
|
||||
int32_t index = static_cast<int32_t>(indexAccessor.GetHeaderIndex());
|
||||
JSTaggedValue constpool = FindConstpoolWithAOT(jsPandaFile, index);
|
||||
if (constpool.IsHole()) {
|
||||
JSHandle<ConstantPool> newConstpool = ConstantPool::CreateConstPool(vm_, jsPandaFile, id);
|
||||
AddConstpool(jsPandaFile, newConstpool.GetTaggedValue(), index);
|
||||
return newConstpool;
|
||||
JSHandle<ConstantPool> newConstpool = ConstantPool::CreateUnSharedConstPool(vm_, jsPandaFile, id);
|
||||
JSHandle<ConstantPool> newSConstpool;
|
||||
int32_t count = GetAndIncreaseUnsharedConstpoolCount();
|
||||
if (jsPandaFile->IsLoadedAOT()) {
|
||||
newSConstpool = ConstantPool::CreateSharedConstPoolForAOT(vm_, newConstpool, count, index);
|
||||
} else {
|
||||
newSConstpool = ConstantPool::CreateSharedConstPool(vm_, jsPandaFile, id, count, index);
|
||||
}
|
||||
AddConstpool(jsPandaFile, newSConstpool.GetTaggedValue(), index);
|
||||
CheckUnsharedConstpoolArrayLimit(count);
|
||||
SetUnsharedConstpool(count, newConstpool.GetTaggedValue());
|
||||
return newSConstpool;
|
||||
}
|
||||
return JSHandle<ConstantPool>(thread_, constpool);
|
||||
}
|
||||
@ -504,20 +567,30 @@ void EcmaContext::CreateAllConstpool(const JSPandaFile *jsPandaFile)
|
||||
uint32_t index = 0;
|
||||
for (const auto &header : headers) {
|
||||
auto constpoolSize = header.method_idx_size;
|
||||
JSHandle<ConstantPool> sconstpool = factory_->NewSConstantPool(constpoolSize);
|
||||
int32_t count = GetAndIncreaseUnsharedConstpoolCount();
|
||||
sconstpool->SetJSPandaFile(jsPandaFile);
|
||||
sconstpool->SetIndexHeader(&header);
|
||||
sconstpool->SetUnsharedConstpoolIndex(JSTaggedValue(count));
|
||||
sconstpool->SetSharedConstpoolId(JSTaggedValue(index));
|
||||
AddConstpool(jsPandaFile, sconstpool.GetTaggedValue(), index);
|
||||
index++;
|
||||
|
||||
JSHandle<ConstantPool> constpool = factory_->NewConstantPool(constpoolSize);
|
||||
constpool->SetJSPandaFile(jsPandaFile);
|
||||
constpool->SetIndexHeader(&header);
|
||||
AddConstpool(jsPandaFile, constpool.GetTaggedValue(), index++);
|
||||
CheckUnsharedConstpoolArrayLimit(count);
|
||||
SetUnsharedConstpool(count, constpool.GetTaggedValue());
|
||||
}
|
||||
}
|
||||
|
||||
void EcmaContext::AddConstpool(const JSPandaFile *jsPandaFile, JSTaggedValue constpool, int32_t index)
|
||||
{
|
||||
ASSERT(constpool.IsConstantPool());
|
||||
if (cachedConstpools_.find(jsPandaFile) == cachedConstpools_.end()) {
|
||||
cachedConstpools_[jsPandaFile] = CMap<int32_t, JSTaggedValue>();
|
||||
if (cachedSharedConstpools_.find(jsPandaFile) == cachedSharedConstpools_.end()) {
|
||||
cachedSharedConstpools_[jsPandaFile] = CMap<int32_t, JSTaggedValue>();
|
||||
}
|
||||
auto &constpoolMap = cachedConstpools_[jsPandaFile];
|
||||
auto &constpoolMap = cachedSharedConstpools_[jsPandaFile];
|
||||
ASSERT(constpoolMap.find(index) == constpoolMap.end());
|
||||
constpoolMap.insert({index, constpool});
|
||||
}
|
||||
@ -531,9 +604,9 @@ JSHandle<JSTaggedValue> EcmaContext::GetAndClearEcmaUncaughtException() const
|
||||
|
||||
void EcmaContext::ProcessNativeDelete(const WeakRootVisitor &visitor)
|
||||
{
|
||||
auto iterator = cachedConstpools_.begin();
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "Constpools:" + std::to_string(cachedConstpools_.size()));
|
||||
while (iterator != cachedConstpools_.end()) {
|
||||
auto iterator = cachedSharedConstpools_.begin();
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "Constpools:" + std::to_string(cachedSharedConstpools_.size()));
|
||||
while (iterator != cachedSharedConstpools_.end()) {
|
||||
auto &constpools = iterator->second;
|
||||
auto constpoolIter = constpools.begin();
|
||||
while (constpoolIter != constpools.end()) {
|
||||
@ -543,6 +616,7 @@ void EcmaContext::ProcessNativeDelete(const WeakRootVisitor &visitor)
|
||||
auto fwd = visitor(obj);
|
||||
if (fwd == nullptr) {
|
||||
constpoolIter = constpools.erase(constpoolIter);
|
||||
EraseUnsharedConstpool(constpoolVal);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@ -552,7 +626,7 @@ void EcmaContext::ProcessNativeDelete(const WeakRootVisitor &visitor)
|
||||
LOG_ECMA(INFO) << "remove js pandafile by gc, file:" << iterator->first->GetJSPandaFileDesc();
|
||||
RelocateConstantString(iterator->first);
|
||||
JSPandaFileManager::GetInstance()->RemoveJSPandaFileVm(vm_, iterator->first);
|
||||
iterator = cachedConstpools_.erase(iterator);
|
||||
iterator = cachedSharedConstpools_.erase(iterator);
|
||||
} else {
|
||||
++iterator;
|
||||
}
|
||||
@ -561,8 +635,8 @@ void EcmaContext::ProcessNativeDelete(const WeakRootVisitor &visitor)
|
||||
|
||||
void EcmaContext::ProcessReferences(const WeakRootVisitor &visitor)
|
||||
{
|
||||
auto iterator = cachedConstpools_.begin();
|
||||
while (iterator != cachedConstpools_.end()) {
|
||||
auto iterator = cachedSharedConstpools_.begin();
|
||||
while (iterator != cachedSharedConstpools_.end()) {
|
||||
auto &constpools = iterator->second;
|
||||
auto constpoolIter = constpools.begin();
|
||||
while (constpoolIter != constpools.end()) {
|
||||
@ -583,7 +657,7 @@ void EcmaContext::ProcessReferences(const WeakRootVisitor &visitor)
|
||||
LOG_ECMA(INFO) << "remove js pandafile by gc, file:" << iterator->first->GetJSPandaFileDesc();
|
||||
RelocateConstantString(iterator->first);
|
||||
JSPandaFileManager::GetInstance()->RemoveJSPandaFileVm(vm_, iterator->first);
|
||||
iterator = cachedConstpools_.erase(iterator);
|
||||
iterator = cachedSharedConstpools_.erase(iterator);
|
||||
} else {
|
||||
++iterator;
|
||||
}
|
||||
@ -595,7 +669,7 @@ void EcmaContext::RelocateConstantString(const JSPandaFile *jsPandaFile)
|
||||
if (!jsPandaFile->IsFirstMergedAbc()) {
|
||||
return;
|
||||
}
|
||||
vm_->GetEcmaStringTable()->RelocateConstantData(jsPandaFile);
|
||||
vm_->GetEcmaStringTable()->RelocateConstantData(vm_, jsPandaFile);
|
||||
}
|
||||
|
||||
JSHandle<JSTaggedValue> EcmaContext::GetEcmaUncaughtException() const
|
||||
@ -705,19 +779,27 @@ bool EcmaContext::ExecutePromisePendingJob()
|
||||
|
||||
void EcmaContext::ClearBufferData()
|
||||
{
|
||||
auto iter = cachedConstpools_.begin();
|
||||
while (iter != cachedConstpools_.end()) {
|
||||
auto iter = cachedSharedConstpools_.begin();
|
||||
while (iter != cachedSharedConstpools_.end()) {
|
||||
LOG_ECMA(INFO) << "remove js pandafile by vm destruct, file:" << iter->first->GetJSPandaFileDesc();
|
||||
JSPandaFileManager::GetInstance()->RemoveJSPandaFileVm(vm_, iter->first);
|
||||
iter++;
|
||||
}
|
||||
cachedConstpools_.clear();
|
||||
cachedSharedConstpools_.clear();
|
||||
if (unsharedConstpools_ != nullptr) {
|
||||
delete unsharedConstpools_;
|
||||
unsharedConstpools_ = nullptr;
|
||||
thread_->SetUnsharedConstpools(reinterpret_cast<uintptr_t>(nullptr));
|
||||
}
|
||||
}
|
||||
|
||||
void EcmaContext::SetGlobalEnv(GlobalEnv *global)
|
||||
{
|
||||
ASSERT(global != nullptr);
|
||||
globalEnv_ = JSTaggedValue(global);
|
||||
// In jsthread iteration, SwitchCurrentContext is called to iterate each context.
|
||||
// If the target context is not fully initialized, the variable "global" will be nullptr.
|
||||
if (global != nullptr) {
|
||||
globalEnv_ = JSTaggedValue(global);
|
||||
}
|
||||
}
|
||||
|
||||
void EcmaContext::SetMicroJobQueue(job::MicroJobQueue *queue)
|
||||
@ -797,13 +879,27 @@ void EcmaContext::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
globalConst_.VisitRangeSlot(rv);
|
||||
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&globalEnv_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(®expCache_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(®expGlobal_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&numberToStringResultCache_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&stringSplitResultCache_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&stringToListResultCache_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(µJobQueue_)));
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&pointerToIndexDictionary_)));
|
||||
if (!regexpCache_.IsHole()) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(®expCache_)));
|
||||
}
|
||||
if (!regexpGlobal_.IsHole()) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(®expGlobal_)));
|
||||
}
|
||||
if (!numberToStringResultCache_.IsHole()) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&numberToStringResultCache_)));
|
||||
}
|
||||
if (!stringSplitResultCache_.IsHole()) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&stringSplitResultCache_)));
|
||||
}
|
||||
if (!stringToListResultCache_.IsHole()) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&stringToListResultCache_)));
|
||||
}
|
||||
if (!microJobQueue_.IsHole()) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(µJobQueue_)));
|
||||
}
|
||||
if (!pointerToIndexDictionary_.IsHole()) {
|
||||
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&pointerToIndexDictionary_)));
|
||||
}
|
||||
|
||||
if (moduleManager_) {
|
||||
moduleManager_->Iterate(v);
|
||||
@ -835,6 +931,11 @@ void EcmaContext::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
rv(Root::ROOT_VM, ObjectSlot(ToUintPtr(&joinStack_.front())),
|
||||
ObjectSlot(ToUintPtr(&joinStack_.back()) + JSTaggedValue::TaggedTypeSize()));
|
||||
}
|
||||
|
||||
auto start = ObjectSlot(ToUintPtr(unsharedConstpools_->data()));
|
||||
auto end = ObjectSlot(ToUintPtr(&unsharedConstpools_->data()[UNSHARED_CONSTANTPOOL_COUNT - 1]) +
|
||||
JSTaggedValue::TaggedTypeSize());
|
||||
rv(Root::ROOT_VM, start, end);
|
||||
}
|
||||
|
||||
size_t EcmaContext::IterateHandle(const RootRangeVisitor &rangeVisitor)
|
||||
|
@ -15,6 +15,7 @@
|
||||
#ifndef ECMASCRIPT_ECMA_CONTEXT_H
|
||||
#define ECMASCRIPT_ECMA_CONTEXT_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include "ecmascript/base/config.h"
|
||||
#include "ecmascript/common.h"
|
||||
@ -260,7 +261,10 @@ public:
|
||||
JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, int32_t index);
|
||||
// For new version instruction.
|
||||
JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, panda_file::File::EntityId id);
|
||||
JSTaggedValue PUBLIC_API FindUnsharedConstpool(JSTaggedValue sharedConstpool);
|
||||
JSHandle<ConstantPool> CreateConstpoolPair(JSPandaFile *jsPandaFile, EntityId methodId);
|
||||
JSTaggedValue FindConstpoolWithAOT(const JSPandaFile *jsPandaFile, int32_t index);
|
||||
void EraseUnsharedConstpool(JSTaggedValue sharedConstpool);
|
||||
std::optional<std::reference_wrapper<CMap<int32_t, JSTaggedValue>>> FindConstpools(
|
||||
const JSPandaFile *jsPandaFile);
|
||||
|
||||
@ -496,6 +500,27 @@ public:
|
||||
return isAotEntry_;
|
||||
}
|
||||
|
||||
void SetUnsharedConstpool(int32_t unsharedConstpoolIndex, JSTaggedValue constpool)
|
||||
{
|
||||
ASSERT(0 <= unsharedConstpoolIndex && unsharedConstpoolIndex < UNSHARED_CONSTANTPOOL_COUNT);
|
||||
unsharedConstpools_->data()[unsharedConstpoolIndex] = constpool;
|
||||
}
|
||||
|
||||
int32_t GetAndIncreaseUnsharedConstpoolCount()
|
||||
{
|
||||
static std::mutex unsharedConstpoolCountMutex_;
|
||||
std::lock_guard<std::mutex> guard(unsharedConstpoolCountMutex_);
|
||||
return unsharedConstpoolCount_++;
|
||||
}
|
||||
|
||||
void CheckUnsharedConstpoolArrayLimit(int32_t index)
|
||||
{
|
||||
if (index >= UNSHARED_CONSTANTPOOL_COUNT) {
|
||||
LOG_ECMA(FATAL) << "the unshared constpool array need to expanding capacity";
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
|
||||
private:
|
||||
void CJSExecution(JSHandle<JSFunction> &func, JSHandle<JSTaggedValue> &thisArg,
|
||||
@ -535,7 +560,12 @@ private:
|
||||
JSTaggedValue microJobQueue_ {JSTaggedValue::Hole()};
|
||||
EcmaRuntimeStat *runtimeStat_ {nullptr};
|
||||
|
||||
CMap<const JSPandaFile *, CMap<int32_t, JSTaggedValue>> cachedConstpools_ {};
|
||||
CMap<const JSPandaFile *, CMap<int32_t, JSTaggedValue>> cachedSharedConstpools_ {};
|
||||
// todo(lijiamin) Consider expanding capacity.
|
||||
static constexpr int32_t UNSHARED_CONSTANTPOOL_COUNT = 10240;
|
||||
std::array<JSTaggedValue, UNSHARED_CONSTANTPOOL_COUNT> *unsharedConstpools_ = nullptr;
|
||||
static int32_t unsharedConstpoolCount_; // unshared constpool index.
|
||||
static constexpr int32_t SHARED_CONSTPOOL_KEY_NOT_FOUND = INT32_MAX; // INT32_MAX :invalid value.
|
||||
|
||||
// for HotReload of module.
|
||||
CMap<CString, JSHandle<JSTaggedValue>> cachedPatchModules_ {};
|
||||
|
@ -196,13 +196,16 @@ public:
|
||||
return nativeFinalizeCallback_;
|
||||
}
|
||||
|
||||
bool CallFreeGlobalCallback()
|
||||
WeakClearCallback GetFreeGlobalCallback() const
|
||||
{
|
||||
return freeGlobalCallback_;
|
||||
}
|
||||
|
||||
void CallFreeGlobalCallback()
|
||||
{
|
||||
if (freeGlobalCallback_ != nullptr) {
|
||||
freeGlobalCallback_(reference_);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CallNativeFinalizeCallback()
|
||||
|
@ -25,19 +25,31 @@
|
||||
namespace panda::ecmascript {
|
||||
static constexpr size_t DEFAULT_HEAP_SIZE = 448_MB; // Recommended range: 128-448MB
|
||||
static constexpr size_t DEFAULT_WORKER_HEAP_SIZE = 768_MB; // Recommended range: 128_MB, LargeHeap: 768_MB
|
||||
static constexpr size_t DEFAULT_SHARED_HEAP_SIZE = 778_MB;
|
||||
|
||||
class EcmaParamConfiguration {
|
||||
public:
|
||||
EcmaParamConfiguration(bool isWorker, size_t poolSize)
|
||||
enum class HeapType : uint8_t {
|
||||
DEFAULT_HEAP,
|
||||
WORKER_HEAP,
|
||||
SHARED_HEAP
|
||||
};
|
||||
|
||||
EcmaParamConfiguration(HeapType heapType, size_t poolSize)
|
||||
{
|
||||
if (isWorker) {
|
||||
maxHeapSize_ = DEFAULT_WORKER_HEAP_SIZE;
|
||||
} else {
|
||||
if (poolSize >= DEFAULT_HEAP_SIZE) {
|
||||
maxHeapSize_ = DEFAULT_HEAP_SIZE;
|
||||
} else {
|
||||
maxHeapSize_ = poolSize; // pool is too small, no memory left for worker
|
||||
}
|
||||
switch (heapType) {
|
||||
case HeapType::WORKER_HEAP:
|
||||
maxHeapSize_ = DEFAULT_WORKER_HEAP_SIZE;
|
||||
break;
|
||||
case HeapType::SHARED_HEAP:
|
||||
maxHeapSize_ = DEFAULT_SHARED_HEAP_SIZE;
|
||||
break;
|
||||
default:
|
||||
if (poolSize >= DEFAULT_HEAP_SIZE) {
|
||||
maxHeapSize_ = DEFAULT_HEAP_SIZE;
|
||||
} else {
|
||||
maxHeapSize_ = poolSize; // pool is too small, no memory left for worker
|
||||
}
|
||||
}
|
||||
Initialize();
|
||||
}
|
||||
|
@ -21,6 +21,8 @@
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/js_handle.h"
|
||||
#include "ecmascript/js_tagged_value-inl.h"
|
||||
#include "ecmascript/mem/heap.h"
|
||||
#include "ecmascript/mem/space.h"
|
||||
#include "ecmascript/object_factory-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
@ -157,16 +159,14 @@ inline EcmaString *EcmaString::CreateLineStringNoGC(const EcmaVM *vm, size_t len
|
||||
inline EcmaString *EcmaString::CreateLineStringWithSpaceType(const EcmaVM *vm, size_t length, bool compressed,
|
||||
MemSpaceType type)
|
||||
{
|
||||
ASSERT(IsSMemSpace(type));
|
||||
size_t size = compressed ? LineEcmaString::ComputeSizeUtf8(length) : LineEcmaString::ComputeSizeUtf16(length);
|
||||
EcmaString *string = nullptr;
|
||||
switch (type) {
|
||||
case MemSpaceType::SEMI_SPACE:
|
||||
string = vm->GetFactory()->AllocLineStringObject(size);
|
||||
break;
|
||||
case MemSpaceType::OLD_SPACE:
|
||||
case MemSpaceType::SHARED_OLD_SPACE:
|
||||
string = vm->GetFactory()->AllocOldSpaceLineStringObject(size);
|
||||
break;
|
||||
case MemSpaceType::NON_MOVABLE:
|
||||
case MemSpaceType::SHARED_NON_MOVABLE:
|
||||
string = vm->GetFactory()->AllocNonMovableLineStringObject(size);
|
||||
break;
|
||||
default:
|
||||
@ -182,13 +182,14 @@ inline SlicedString *EcmaString::CreateSlicedString(const EcmaVM *vm, MemSpaceTy
|
||||
{
|
||||
auto slicedString = SlicedString::Cast(vm->GetFactory()->AllocSlicedStringObject(type));
|
||||
slicedString->SetRawHashcode(0);
|
||||
slicedString->SetParent(vm->GetJSThread(), JSTaggedValue::Undefined());
|
||||
slicedString->SetParent(vm->GetJSThread(), JSTaggedValue::Undefined(), BarrierMode::SKIP_BARRIER);
|
||||
return slicedString;
|
||||
}
|
||||
|
||||
inline EcmaString *EcmaString::CreateConstantString(const EcmaVM *vm, const uint8_t *utf8Data,
|
||||
size_t length, bool compressed, MemSpaceType type, uint32_t idOffset)
|
||||
{
|
||||
ASSERT(IsSMemSpace(type));
|
||||
auto string = ConstantString::Cast(vm->GetFactory()->AllocConstantStringObject(type));
|
||||
auto thread = vm->GetJSThread();
|
||||
string->SetLength(length, compressed);
|
||||
|
@ -18,12 +18,14 @@
|
||||
#include "ecmascript/ecma_string_table.h"
|
||||
#include "ecmascript/js_symbol.h"
|
||||
#include "ecmascript/mem/c_containers.h"
|
||||
#include "ecmascript/mem/space.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
|
||||
EcmaString *EcmaString::Concat(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right, MemSpaceType type)
|
||||
{
|
||||
ASSERT(IsSMemSpace(type));
|
||||
// allocator may trig gc and move src, need to hold it
|
||||
EcmaString *strLeft = *left;
|
||||
EcmaString *strRight = *right;
|
||||
@ -35,21 +37,9 @@ EcmaString *EcmaString::Concat(const EcmaVM *vm,
|
||||
}
|
||||
|
||||
if (leftLength == 0) {
|
||||
if (type == MemSpaceType::OLD_SPACE) {
|
||||
Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*right));
|
||||
if (objectRegion->InYoungSpace()) {
|
||||
return CopyStringToOldSpace(vm, right, rightLength, strRight->IsUtf8());
|
||||
}
|
||||
}
|
||||
return strRight;
|
||||
}
|
||||
if (rightLength == 0) {
|
||||
if (type == MemSpaceType::OLD_SPACE) {
|
||||
Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(*left));
|
||||
if (objectRegion->InYoungSpace()) {
|
||||
return CopyStringToOldSpace(vm, left, leftLength, strLeft->IsUtf8());
|
||||
}
|
||||
}
|
||||
return strLeft;
|
||||
}
|
||||
// if the result string is small, make a LineString
|
||||
@ -1130,6 +1120,7 @@ EcmaString *EcmaString::Trim(const JSThread *thread, const JSHandle<EcmaString>
|
||||
EcmaString *EcmaString::SlowFlatten(const EcmaVM *vm, const JSHandle<EcmaString> &string, MemSpaceType type)
|
||||
{
|
||||
ASSERT(string->IsTreeString() || string->IsSlicedString());
|
||||
ASSERT(IsSMemSpace(type));
|
||||
auto thread = vm->GetJSThread();
|
||||
uint32_t length = string->GetLength();
|
||||
EcmaString *result = nullptr;
|
||||
@ -1164,6 +1155,7 @@ EcmaString *EcmaString::Flatten(const EcmaVM *vm, const JSHandle<EcmaString> &st
|
||||
|
||||
FlatStringInfo EcmaString::FlattenAllString(const EcmaVM *vm, const JSHandle<EcmaString> &string, MemSpaceType type)
|
||||
{
|
||||
ASSERT(IsSMemSpace(type));
|
||||
EcmaString *s = *string;
|
||||
uint32_t startIndex = 0;
|
||||
if (s->IsLineOrConstantString()) {
|
||||
|
@ -110,15 +110,15 @@ private:
|
||||
|
||||
static EcmaString *CreateEmptyString(const EcmaVM *vm);
|
||||
static EcmaString *CreateFromUtf8(const EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
bool canBeCompress, MemSpaceType type = MemSpaceType::SEMI_SPACE, bool isConstantString = false,
|
||||
bool canBeCompress, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE, bool isConstantString = false,
|
||||
uint32_t idOffset = 0);
|
||||
static EcmaString *CreateFromUtf8CompressedSubString(const EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
uint32_t offset, uint32_t utf8Len, MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
static EcmaString *CreateUtf16StringFromUtf8(const EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE);
|
||||
static EcmaString *CreateFromUtf16(const EcmaVM *vm, const uint16_t *utf16Data, uint32_t utf16Len,
|
||||
bool canBeCompress, MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
static SlicedString *CreateSlicedString(const EcmaVM *vm, MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
bool canBeCompress, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE);
|
||||
static SlicedString *CreateSlicedString(const EcmaVM *vm, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE);
|
||||
static EcmaString *CreateLineString(const EcmaVM *vm, size_t length, bool compressed);
|
||||
static EcmaString *CreateLineStringNoGC(const EcmaVM *vm, size_t length, bool compressed);
|
||||
static EcmaString *CreateLineStringWithSpaceType(const EcmaVM *vm,
|
||||
@ -126,9 +126,9 @@ private:
|
||||
static EcmaString *CreateTreeString(const EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &left, const JSHandle<EcmaString> &right, uint32_t length, bool compressed);
|
||||
static EcmaString *CreateConstantString(const EcmaVM *vm, const uint8_t *utf8Data,
|
||||
size_t length, bool compressed, MemSpaceType type = MemSpaceType::SEMI_SPACE, uint32_t idOffset = 0);
|
||||
size_t length, bool compressed, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE, uint32_t idOffset = 0);
|
||||
static EcmaString *Concat(const EcmaVM *vm, const JSHandle<EcmaString> &left,
|
||||
const JSHandle<EcmaString> &right, MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
const JSHandle<EcmaString> &right, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE);
|
||||
static EcmaString *CopyStringToOldSpace(const EcmaVM *vm, const JSHandle<EcmaString> &original,
|
||||
uint32_t length, bool compressed);
|
||||
static EcmaString *FastSubString(const EcmaVM *vm,
|
||||
@ -719,10 +719,10 @@ private:
|
||||
static EcmaString *SlowFlatten(const EcmaVM *vm, const JSHandle<EcmaString> &string, MemSpaceType type);
|
||||
|
||||
static EcmaString *Flatten(const EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE);
|
||||
|
||||
static FlatStringInfo FlattenAllString(const EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE);
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE);
|
||||
|
||||
static EcmaString *FlattenNoGC(const EcmaVM *vm, EcmaString *string);
|
||||
|
||||
@ -1063,7 +1063,7 @@ public:
|
||||
}
|
||||
|
||||
static EcmaString *CreateFromUtf8(const EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE, bool isConstantString = false,
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE, bool isConstantString = false,
|
||||
uint32_t idOffset = 0)
|
||||
{
|
||||
return EcmaString::CreateFromUtf8(vm, utf8Data, utf8Len, canBeCompress, type, isConstantString, idOffset);
|
||||
@ -1071,31 +1071,31 @@ public:
|
||||
|
||||
static EcmaString *CreateFromUtf8CompressedSubString(const EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
uint32_t offset, uint32_t utf8Len,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE)
|
||||
{
|
||||
return EcmaString::CreateFromUtf8CompressedSubString(vm, string, offset, utf8Len, type);
|
||||
}
|
||||
|
||||
static EcmaString *CreateConstantString(const EcmaVM *vm, const uint8_t *utf8Data, size_t length,
|
||||
bool compressed, MemSpaceType type = MemSpaceType::SEMI_SPACE, uint32_t idOffset = 0)
|
||||
bool compressed, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE, uint32_t idOffset = 0)
|
||||
{
|
||||
return EcmaString::CreateConstantString(vm, utf8Data, length, compressed, type, idOffset);
|
||||
}
|
||||
|
||||
static EcmaString *CreateUtf16StringFromUtf8(const EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE)
|
||||
{
|
||||
return EcmaString::CreateUtf16StringFromUtf8(vm, utf8Data, utf8Len, type);
|
||||
}
|
||||
|
||||
static EcmaString *CreateFromUtf16(const EcmaVM *vm, const uint16_t *utf16Data, uint32_t utf16Len,
|
||||
bool canBeCompress, MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
bool canBeCompress, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE)
|
||||
{
|
||||
return EcmaString::CreateFromUtf16(vm, utf16Data, utf16Len, canBeCompress, type);
|
||||
}
|
||||
|
||||
static EcmaString *Concat(const EcmaVM *vm, const JSHandle<EcmaString> &str1Handle,
|
||||
const JSHandle<EcmaString> &str2Handle, MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
const JSHandle<EcmaString> &str2Handle, MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE)
|
||||
{
|
||||
return EcmaString::Concat(vm, str1Handle, str2Handle, type);
|
||||
}
|
||||
@ -1481,19 +1481,19 @@ public:
|
||||
}
|
||||
|
||||
static EcmaString *Flatten(const EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE)
|
||||
{
|
||||
return EcmaString::Flatten(vm, string, type);
|
||||
}
|
||||
|
||||
static FlatStringInfo FlattenAllString(const EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE)
|
||||
{
|
||||
return EcmaString::FlattenAllString(vm, string, type);
|
||||
}
|
||||
|
||||
static EcmaString *SlowFlatten(const EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
MemSpaceType type = MemSpaceType::SEMI_SPACE)
|
||||
MemSpaceType type = MemSpaceType::SHARED_OLD_SPACE)
|
||||
{
|
||||
return EcmaString::SlowFlatten(vm, string, type);
|
||||
}
|
||||
|
@ -17,17 +17,21 @@
|
||||
|
||||
#include "ecmascript/ecma_string-inl.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/jspandafile/js_pandafile.h"
|
||||
#include "ecmascript/log_wrapper.h"
|
||||
#include "ecmascript/mem/c_string.h"
|
||||
#include "ecmascript/mem/heap.h"
|
||||
#include "ecmascript/mem/space.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/platform/mutex.h"
|
||||
#include "ecmascript/runtime.h"
|
||||
#include "ecmascript/runtime_lock.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
EcmaStringTable::EcmaStringTable(const EcmaVM *vm) : vm_(vm) {}
|
||||
|
||||
std::pair<EcmaString *, uint32_t> EcmaStringTable::GetString(const JSHandle<EcmaString> &firstString,
|
||||
const JSHandle<EcmaString> &secondString) const
|
||||
std::pair<EcmaString *, uint32_t> EcmaStringTable::GetStringThreadUnsafe(const JSHandle<EcmaString> &firstString,
|
||||
const JSHandle<EcmaString> &secondString) const
|
||||
{
|
||||
ASSERT(EcmaStringAccessor(firstString).NotTreeString());
|
||||
ASSERT(EcmaStringAccessor(secondString).NotTreeString());
|
||||
@ -44,8 +48,8 @@ std::pair<EcmaString *, uint32_t> EcmaStringTable::GetString(const JSHandle<Ecma
|
||||
return std::make_pair(nullptr, hashCode);
|
||||
}
|
||||
|
||||
std::pair<EcmaString *, uint32_t> EcmaStringTable::GetString(const uint8_t *utf8Data,
|
||||
uint32_t utf8Len, bool canBeCompress) const
|
||||
std::pair<EcmaString *, uint32_t> EcmaStringTable::GetStringThreadUnsafe(const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
bool canBeCompress) const
|
||||
{
|
||||
uint32_t hashCode = EcmaStringAccessor::ComputeHashcodeUtf8(utf8Data, utf8Len, canBeCompress);
|
||||
auto range = table_.equal_range(hashCode);
|
||||
@ -58,7 +62,8 @@ std::pair<EcmaString *, uint32_t> EcmaStringTable::GetString(const uint8_t *utf8
|
||||
return std::make_pair(nullptr, hashCode);
|
||||
}
|
||||
|
||||
std::pair<EcmaString *, uint32_t> EcmaStringTable::GetString(const uint16_t *utf16Data, uint32_t utf16Len) const
|
||||
std::pair<EcmaString *, uint32_t> EcmaStringTable::GetStringThreadUnsafe(const uint16_t *utf16Data,
|
||||
uint32_t utf16Len) const
|
||||
{
|
||||
uint32_t hashCode = EcmaStringAccessor::ComputeHashcodeUtf16(const_cast<uint16_t *>(utf16Data), utf16Len);
|
||||
auto range = table_.equal_range(hashCode);
|
||||
@ -71,7 +76,7 @@ std::pair<EcmaString *, uint32_t> EcmaStringTable::GetString(const uint16_t *utf
|
||||
return std::make_pair(nullptr, hashCode);
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetString(EcmaString *string) const
|
||||
EcmaString *EcmaStringTable::GetStringThreadUnsafe(EcmaString *string) const
|
||||
{
|
||||
auto hashcode = EcmaStringAccessor(string).GetHashcode();
|
||||
auto range = table_.equal_range(hashcode);
|
||||
@ -84,68 +89,72 @@ EcmaString *EcmaStringTable::GetString(EcmaString *string) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void EcmaStringTable::InternString(EcmaString *string)
|
||||
void EcmaStringTable::InternStringThreadUnsafe(EcmaString *string)
|
||||
{
|
||||
if (EcmaStringAccessor(string).IsInternString()) {
|
||||
return;
|
||||
}
|
||||
// Strings in string table should not be in the young space.
|
||||
ASSERT(!Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(string))->InYoungSpace());
|
||||
ASSERT(Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(string))->InSharedHeap());
|
||||
ASSERT(EcmaStringAccessor(string).NotTreeString());
|
||||
auto hashcode = EcmaStringAccessor(string).GetHashcode();
|
||||
table_.emplace(hashcode, string);
|
||||
EcmaStringAccessor(string).SetInternString();
|
||||
}
|
||||
|
||||
void EcmaStringTable::InternEmptyString(EcmaString *emptyStr)
|
||||
void EcmaStringTable::InternEmptyString(JSThread *thread, EcmaString *emptyStr)
|
||||
{
|
||||
InternString(emptyStr);
|
||||
RuntimeLockHolder locker(thread, mutex_);
|
||||
InternStringThreadUnsafe(emptyStr);
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternString(const JSHandle<EcmaString> &firstString,
|
||||
EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, const JSHandle<EcmaString> &firstString,
|
||||
const JSHandle<EcmaString> &secondString)
|
||||
{
|
||||
auto firstFlat = JSHandle<EcmaString>(vm_->GetJSThread(), EcmaStringAccessor::Flatten(vm_, firstString));
|
||||
auto secondFlat = JSHandle<EcmaString>(vm_->GetJSThread(), EcmaStringAccessor::Flatten(vm_, secondString));
|
||||
std::pair<EcmaString *, uint32_t> result = GetString(firstFlat, secondFlat);
|
||||
auto firstFlat = JSHandle<EcmaString>(vm->GetJSThread(), EcmaStringAccessor::Flatten(vm, firstString));
|
||||
auto secondFlat = JSHandle<EcmaString>(vm->GetJSThread(), EcmaStringAccessor::Flatten(vm, secondString));
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(firstFlat, secondFlat);
|
||||
if (result.first != nullptr) {
|
||||
return result.first;
|
||||
}
|
||||
JSHandle<EcmaString> concatHandle(vm_->GetJSThread(),
|
||||
EcmaStringAccessor::Concat(vm_, firstFlat, secondFlat, MemSpaceType::OLD_SPACE));
|
||||
EcmaString *concatString = EcmaStringAccessor::Flatten(vm_, concatHandle, MemSpaceType::OLD_SPACE);
|
||||
JSHandle<EcmaString> concatHandle(vm->GetJSThread(),
|
||||
EcmaStringAccessor::Concat(vm, firstFlat, secondFlat, MemSpaceType::SHARED_OLD_SPACE));
|
||||
EcmaString *concatString = EcmaStringAccessor::Flatten(vm, concatHandle, MemSpaceType::SHARED_OLD_SPACE);
|
||||
concatString->SetMixHashcode(result.second);
|
||||
InternString(concatString);
|
||||
InternStringThreadUnsafe(concatString);
|
||||
return concatString;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternString(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress)
|
||||
EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
bool canBeCompress)
|
||||
{
|
||||
std::pair<EcmaString *, uint32_t> result = GetString(utf8Data, utf8Len, canBeCompress);
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, canBeCompress);
|
||||
if (result.first != nullptr) {
|
||||
return result.first;
|
||||
}
|
||||
|
||||
EcmaString *str =
|
||||
EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress, MemSpaceType::OLD_SPACE);
|
||||
EcmaStringAccessor::CreateFromUtf8(vm, utf8Data, utf8Len, canBeCompress, MemSpaceType::SHARED_OLD_SPACE);
|
||||
str->SetMixHashcode(result.second);
|
||||
InternString(str);
|
||||
InternStringThreadUnsafe(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternCompressedSubString(const JSHandle<EcmaString> &string,
|
||||
EcmaString *EcmaStringTable::GetOrInternCompressedSubString(EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
uint32_t offset, uint32_t utf8Len)
|
||||
{
|
||||
auto *utf8Data = EcmaStringAccessor(string).GetDataUtf8() + offset;
|
||||
std::pair<EcmaString *, uint32_t> result = GetString(utf8Data, utf8Len, true);
|
||||
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, true);
|
||||
if (result.first != nullptr) {
|
||||
return result.first;
|
||||
}
|
||||
|
||||
EcmaString *str = EcmaStringAccessor::CreateFromUtf8CompressedSubString(
|
||||
vm_, string, offset, utf8Len, MemSpaceType::OLD_SPACE);
|
||||
vm, string, offset, utf8Len);
|
||||
str->SetMixHashcode(result.second);
|
||||
InternString(str);
|
||||
InternStringThreadUnsafe(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -153,113 +162,129 @@ EcmaString *EcmaStringTable::GetOrInternCompressedSubString(const JSHandle<EcmaS
|
||||
This function is used to create global constant strings from non-movable sapce only.
|
||||
It only inserts string into string-table and provides no string-table validity check.
|
||||
*/
|
||||
EcmaString *EcmaStringTable::CreateAndInternStringNonMovable(const uint8_t *utf8Data, uint32_t utf8Len)
|
||||
EcmaString *EcmaStringTable::CreateAndInternStringNonMovable(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len)
|
||||
{
|
||||
std::pair<EcmaString *, uint32_t> result = GetString(utf8Data, utf8Len, true);
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, true);
|
||||
if (result.first != nullptr) {
|
||||
return result.first;
|
||||
}
|
||||
|
||||
EcmaString *str = EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, true, MemSpaceType::NON_MOVABLE);
|
||||
EcmaString *str = EcmaStringAccessor::CreateFromUtf8(vm, utf8Data, utf8Len, true, MemSpaceType::SHARED_NON_MOVABLE);
|
||||
str->SetMixHashcode(result.second);
|
||||
InternString(str);
|
||||
InternStringThreadUnsafe(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternString(const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress)
|
||||
EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, const uint16_t *utf16Data, uint32_t utf16Len,
|
||||
bool canBeCompress)
|
||||
{
|
||||
std::pair<EcmaString *, uint32_t> result = GetString(utf16Data, utf16Len);
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf16Data, utf16Len);
|
||||
if (result.first != nullptr) {
|
||||
return result.first;
|
||||
}
|
||||
|
||||
EcmaString *str =
|
||||
EcmaStringAccessor::CreateFromUtf16(vm_, utf16Data, utf16Len, canBeCompress, MemSpaceType::OLD_SPACE);
|
||||
EcmaStringAccessor::CreateFromUtf16(vm, utf16Data, utf16Len, canBeCompress, MemSpaceType::SHARED_OLD_SPACE);
|
||||
str->SetMixHashcode(result.second);
|
||||
InternString(str);
|
||||
InternStringThreadUnsafe(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternString(EcmaString *string)
|
||||
EcmaString *EcmaStringTable::GetOrInternString(EcmaVM *vm, EcmaString *string)
|
||||
{
|
||||
if (EcmaStringAccessor(string).IsInternString()) {
|
||||
return string;
|
||||
}
|
||||
JSHandle<EcmaString> strHandle(vm_->GetJSThread(), string);
|
||||
auto thread = vm->GetJSThread();
|
||||
JSHandle<EcmaString> strHandle(thread, string);
|
||||
// may gc
|
||||
auto strFlat = EcmaStringAccessor::Flatten(vm_, strHandle, MemSpaceType::OLD_SPACE);
|
||||
auto strFlat = EcmaStringAccessor::Flatten(vm, strHandle, MemSpaceType::SHARED_OLD_SPACE);
|
||||
if (EcmaStringAccessor(strFlat).IsInternString()) {
|
||||
return strFlat;
|
||||
}
|
||||
EcmaString *result = GetString(strFlat);
|
||||
JSHandle<EcmaString> strFlatHandle(thread, strFlat);
|
||||
// may gc
|
||||
RuntimeLockHolder locker(thread, mutex_);
|
||||
strFlat = *strFlatHandle;
|
||||
EcmaString *result = GetStringThreadUnsafe(strFlat);
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
if (EcmaStringAccessor(strFlat).NotTreeString()) {
|
||||
Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(strFlat));
|
||||
if (objectRegion->InYoungSpace()) {
|
||||
JSHandle<EcmaString> resultHandle(vm_->GetJSThread(), strFlat);
|
||||
strFlat = EcmaStringAccessor::CopyStringToOldSpace(vm_,
|
||||
resultHandle, EcmaStringAccessor(strFlat).GetLength(), EcmaStringAccessor(strFlat).IsUtf8());
|
||||
}
|
||||
}
|
||||
InternString(strFlat);
|
||||
InternStringThreadUnsafe(strFlat);
|
||||
return strFlat;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::InsertStringToTable(const JSHandle<EcmaString> &strHandle)
|
||||
EcmaString *EcmaStringTable::GetOrInternStringThreadUnsafe(EcmaVM *vm, EcmaString *string)
|
||||
{
|
||||
auto strFlat = EcmaStringAccessor::Flatten(vm_, strHandle, MemSpaceType::OLD_SPACE);
|
||||
if (EcmaStringAccessor(strFlat).NotTreeString()) {
|
||||
Region *objectRegion = Region::ObjectAddressToRange(reinterpret_cast<TaggedObject *>(strFlat));
|
||||
if (objectRegion->InYoungSpace()) {
|
||||
JSHandle<EcmaString> resultHandle(vm_->GetJSThread(), strFlat);
|
||||
strFlat = EcmaStringAccessor::CopyStringToOldSpace(vm_,
|
||||
resultHandle, EcmaStringAccessor(strFlat).GetLength(), EcmaStringAccessor(strFlat).IsUtf8());
|
||||
}
|
||||
if (EcmaStringAccessor(string).IsInternString()) {
|
||||
return string;
|
||||
}
|
||||
InternString(strFlat);
|
||||
JSHandle<EcmaString> strHandle(vm->GetJSThread(), string);
|
||||
EcmaString *strFlat = EcmaStringAccessor::Flatten(vm, strHandle, MemSpaceType::SHARED_OLD_SPACE);
|
||||
if (EcmaStringAccessor(strFlat).IsInternString()) {
|
||||
return strFlat;
|
||||
}
|
||||
EcmaString *result = GetStringThreadUnsafe(strFlat);
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
|
||||
InternStringThreadUnsafe(strFlat);
|
||||
return strFlat;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::TryGetInternString(EcmaString *string)
|
||||
EcmaString *EcmaStringTable::InsertStringToTable(EcmaVM *vm, const JSHandle<EcmaString> &strHandle)
|
||||
{
|
||||
return GetString(string);
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
auto strFlat = EcmaStringAccessor::Flatten(vm, strHandle, MemSpaceType::SHARED_OLD_SPACE);
|
||||
InternStringThreadUnsafe(strFlat);
|
||||
return strFlat;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
EcmaString *EcmaStringTable::TryGetInternString(JSThread *thread, const JSHandle<EcmaString> &string)
|
||||
{
|
||||
RuntimeLockHolder locker(thread, mutex_);
|
||||
return GetStringThreadUnsafe(*string);
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
bool canBeCompress, MemSpaceType type,
|
||||
bool isConstantString, uint32_t idOffset)
|
||||
{
|
||||
std::pair<EcmaString *, uint32_t> result = GetString(utf8Data, utf8Len, canBeCompress);
|
||||
ASSERT(IsSMemSpace(type));
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
std::pair<EcmaString *, uint32_t> result = GetStringThreadUnsafe(utf8Data, utf8Len, canBeCompress);
|
||||
if (result.first != nullptr) {
|
||||
return result.first;
|
||||
}
|
||||
type = type == MemSpaceType::NON_MOVABLE ? MemSpaceType::NON_MOVABLE : MemSpaceType::OLD_SPACE;
|
||||
EcmaString *str;
|
||||
type = (type == MemSpaceType::SHARED_NON_MOVABLE) ? type : MemSpaceType::SHARED_OLD_SPACE;
|
||||
EcmaString *str = nullptr;
|
||||
if (canBeCompress) {
|
||||
// Constant string will be created in this branch.
|
||||
str = EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress, type, isConstantString,
|
||||
str = EcmaStringAccessor::CreateFromUtf8(vm, utf8Data, utf8Len, canBeCompress, type, isConstantString,
|
||||
idOffset);
|
||||
} else {
|
||||
str = EcmaStringAccessor::CreateFromUtf8(vm_, utf8Data, utf8Len, canBeCompress, type);
|
||||
str = EcmaStringAccessor::CreateFromUtf8(vm, utf8Data, utf8Len, canBeCompress, type);
|
||||
}
|
||||
str->SetMixHashcode(result.second);
|
||||
InternString(str);
|
||||
InternStringThreadUnsafe(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(const uint8_t *utf8Data, uint32_t utf16Len,
|
||||
EcmaString *EcmaStringTable::GetOrInternStringWithSpaceType(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf16Len,
|
||||
MemSpaceType type)
|
||||
{
|
||||
type = type == MemSpaceType::NON_MOVABLE ? MemSpaceType::NON_MOVABLE : MemSpaceType::OLD_SPACE;
|
||||
EcmaString *str = EcmaStringAccessor::CreateUtf16StringFromUtf8(vm_, utf8Data, utf16Len, type);
|
||||
EcmaString *result = GetString(str);
|
||||
ASSERT(IsSMemSpace(type));
|
||||
type = (type == MemSpaceType::SHARED_NON_MOVABLE) ? type : MemSpaceType::SHARED_OLD_SPACE;
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
EcmaString *str = EcmaStringAccessor::CreateUtf16StringFromUtf8(vm, utf8Data, utf16Len, type);
|
||||
EcmaString *result = GetStringThreadUnsafe(str);
|
||||
if (result != nullptr) {
|
||||
return result;
|
||||
}
|
||||
InternString(str);
|
||||
InternStringThreadUnsafe(str);
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -269,6 +294,7 @@ void EcmaStringTable::SweepWeakReference(const WeakRootVisitor &visitor)
|
||||
// Strings in string table should not be in the young space. Only old gc will sweep string table.
|
||||
auto *object = it->second;
|
||||
auto fwd = visitor(object);
|
||||
// todo(hzzhouzebin) wait for shared-gc
|
||||
ASSERT(!Region::ObjectAddressToRange(object)->InYoungSpace());
|
||||
if (fwd == nullptr) {
|
||||
LOG_ECMA(VERBOSE) << "StringTable: delete string " << std::hex << object;
|
||||
@ -283,9 +309,10 @@ void EcmaStringTable::SweepWeakReference(const WeakRootVisitor &visitor)
|
||||
}
|
||||
}
|
||||
|
||||
void EcmaStringTable::RelocateConstantData(const JSPandaFile *jsPandaFile)
|
||||
void EcmaStringTable::RelocateConstantData(EcmaVM *vm, const JSPandaFile *jsPandaFile)
|
||||
{
|
||||
auto thread = vm_->GetJSThread();
|
||||
RuntimeLockHolder locker(vm->GetJSThread(), mutex_);
|
||||
auto thread = vm->GetJSThread();
|
||||
for (auto it = table_.begin(); it != table_.end();) {
|
||||
auto *object = it->second;
|
||||
if (!EcmaStringAccessor(object).IsConstantString()) {
|
||||
@ -303,12 +330,13 @@ void EcmaStringTable::RelocateConstantData(const JSPandaFile *jsPandaFile)
|
||||
if (constantStr->GetConstantData() == sd.data) {
|
||||
uint32_t strLen = sd.utf16_length;
|
||||
if (UNLIKELY(strLen == 0)) {
|
||||
it->second = *(vm_->GetFactory()->GetEmptyString());
|
||||
it->second = *(vm->GetFactory()->GetEmptyString());
|
||||
}
|
||||
size_t byteLength = sd.is_ascii ? 1 : sizeof(uint16_t);
|
||||
JSHandle<ByteArray> newData = vm_->GetFactory()->NewByteArray(
|
||||
JSMutableHandle<ByteArray> newData(vm->GetJSThread(), JSTaggedValue::Undefined());
|
||||
newData.Update(vm->GetFactory()->NewByteArray(
|
||||
strLen, byteLength, reinterpret_cast<void *>(const_cast<uint8_t *>(sd.data)),
|
||||
MemSpaceType::NON_MOVABLE);
|
||||
MemSpaceType::SHARED_NON_MOVABLE));
|
||||
constantStr->SetRelocatedData(thread, newData.GetTaggedValue());
|
||||
constantStr->SetConstantData(static_cast<uint8_t *>(newData->GetData()));
|
||||
constantStr->SetEntityId(-1);
|
||||
@ -319,8 +347,9 @@ void EcmaStringTable::RelocateConstantData(const JSPandaFile *jsPandaFile)
|
||||
}
|
||||
}
|
||||
|
||||
bool EcmaStringTable::CheckStringTableValidity()
|
||||
bool EcmaStringTable::CheckStringTableValidity(JSThread *thread)
|
||||
{
|
||||
RuntimeLockHolder locker(thread, mutex_);
|
||||
for (auto itemOuter = table_.begin(); itemOuter != table_.end(); ++itemOuter) {
|
||||
auto outerString = itemOuter->second;
|
||||
if (!EcmaStringAccessor(outerString).NotTreeString()) {
|
||||
@ -343,15 +372,15 @@ bool EcmaStringTable::CheckStringTableValidity()
|
||||
return true;
|
||||
}
|
||||
|
||||
void SingleCharTable::CreateSingleCharTable(JSThread *thread)
|
||||
JSTaggedValue SingleCharTable::CreateSingleCharTable(JSThread *thread)
|
||||
{
|
||||
auto table = thread->GetEcmaVM()->GetFactory()->NewTaggedArray(MAX_ONEBYTE_CHARCODE,
|
||||
JSTaggedValue::Undefined(), MemSpaceType::NON_MOVABLE);
|
||||
JSTaggedValue::Undefined(), MemSpaceType::SHARED_NON_MOVABLE);
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
for (uint32_t i = 1; i < MAX_ONEBYTE_CHARCODE; ++i) {
|
||||
std::string tmp(1, i + 0X00); // 1: size
|
||||
table->Set(thread, i, factory->NewFromASCIINonMovable(tmp).GetTaggedValue());
|
||||
}
|
||||
thread->SetSingleCharTable((table.GetTaggedValue()));
|
||||
return table.GetTaggedValue();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -16,9 +16,12 @@
|
||||
#ifndef ECMASCRIPT_STRING_TABLE_H
|
||||
#define ECMASCRIPT_STRING_TABLE_H
|
||||
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/js_thread.h"
|
||||
#include "ecmascript/mem/c_containers.h"
|
||||
#include "ecmascript/mem/space.h"
|
||||
#include "ecmascript/mem/visitor.h"
|
||||
#include "ecmascript/platform/mutex.h"
|
||||
#include "ecmascript/tagged_array-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
@ -28,51 +31,56 @@ class JSPandaFile;
|
||||
|
||||
class EcmaStringTable {
|
||||
public:
|
||||
explicit EcmaStringTable(const EcmaVM *vm);
|
||||
EcmaStringTable() = default;
|
||||
virtual ~EcmaStringTable()
|
||||
{
|
||||
table_.clear();
|
||||
}
|
||||
|
||||
void InternEmptyString(EcmaString *emptyStr);
|
||||
EcmaString *GetOrInternString(const JSHandle<EcmaString> &firstString, const JSHandle<EcmaString> &secondString);
|
||||
EcmaString *GetOrInternString(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress);
|
||||
EcmaString *CreateAndInternStringNonMovable(const uint8_t *utf8Data, uint32_t utf8Len);
|
||||
EcmaString *GetOrInternString(const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress);
|
||||
EcmaString *GetOrInternString(EcmaString *string);
|
||||
EcmaString *GetOrInternCompressedSubString(const JSHandle<EcmaString> &string, uint32_t offset, uint32_t utf8Len);
|
||||
EcmaString *GetOrInternStringWithSpaceType(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress,
|
||||
MemSpaceType type, bool isConstantString, uint32_t idOffset);
|
||||
EcmaString *GetOrInternStringWithSpaceType(const uint8_t *utf8Data, uint32_t utf16Len,
|
||||
void InternEmptyString(JSThread *thread, EcmaString *emptyStr);
|
||||
EcmaString *GetOrInternString(EcmaVM *vm,
|
||||
const JSHandle<EcmaString> &firstString,
|
||||
const JSHandle<EcmaString> &secondString);
|
||||
EcmaString *GetOrInternString(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress);
|
||||
EcmaString *CreateAndInternStringNonMovable(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len);
|
||||
EcmaString *GetOrInternString(EcmaVM *vm, const uint16_t *utf16Data, uint32_t utf16Len, bool canBeCompress);
|
||||
EcmaString *GetOrInternString(EcmaVM *vm, EcmaString *string);
|
||||
EcmaString *GetOrInternCompressedSubString(EcmaVM *vm, const JSHandle<EcmaString> &string,
|
||||
uint32_t offset, uint32_t utf8Len);
|
||||
EcmaString *GetOrInternStringWithSpaceType(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
bool canBeCompress, MemSpaceType type, bool isConstantString, uint32_t idOffset);
|
||||
EcmaString *GetOrInternStringWithSpaceType(EcmaVM *vm, const uint8_t *utf8Data, uint32_t utf16Len,
|
||||
MemSpaceType type);
|
||||
EcmaString *TryGetInternString(EcmaString *string);
|
||||
EcmaString *InsertStringToTable(const JSHandle<EcmaString> &strHandle);
|
||||
EcmaString *TryGetInternString(JSThread *thread, const JSHandle<EcmaString> &string);
|
||||
EcmaString *InsertStringToTable(EcmaVM *vm, const JSHandle<EcmaString> &strHandle);
|
||||
|
||||
void SweepWeakReference(const WeakRootVisitor &visitor);
|
||||
bool CheckStringTableValidity();
|
||||
void RelocateConstantData(const JSPandaFile *jsPandaFile);
|
||||
bool CheckStringTableValidity(JSThread *thread);
|
||||
void RelocateConstantData(EcmaVM *vm, const JSPandaFile *jsPandaFile);
|
||||
private:
|
||||
NO_COPY_SEMANTIC(EcmaStringTable);
|
||||
NO_MOVE_SEMANTIC(EcmaStringTable);
|
||||
|
||||
std::pair<EcmaString *, uint32_t> GetString(
|
||||
const JSHandle<EcmaString> &firstString, const JSHandle<EcmaString> &secondString) const;
|
||||
std::pair<EcmaString *, uint32_t> GetString(const uint8_t *utf8Data, uint32_t utf8Len, bool canBeCompress) const;
|
||||
std::pair<EcmaString *, uint32_t> GetString(const uint16_t *utf16Data, uint32_t utf16Len) const;
|
||||
EcmaString *GetString(EcmaString *string) const;
|
||||
std::pair<EcmaString *, uint32_t> GetStringThreadUnsafe(const JSHandle<EcmaString> &firstString,
|
||||
const JSHandle<EcmaString> &secondString) const;
|
||||
std::pair<EcmaString *, uint32_t> GetStringThreadUnsafe(const uint8_t *utf8Data, uint32_t utf8Len,
|
||||
bool canBeCompress) const;
|
||||
std::pair<EcmaString *, uint32_t> GetStringThreadUnsafe(const uint16_t *utf16Data, uint32_t utf16Len) const;
|
||||
EcmaString *GetStringThreadUnsafe(EcmaString *string) const;
|
||||
|
||||
void InternString(EcmaString *string);
|
||||
void InternStringThreadUnsafe(EcmaString *string);
|
||||
EcmaString *GetOrInternStringThreadUnsafe(EcmaVM *vm, EcmaString *string);
|
||||
|
||||
void InsertStringIfNotExist(EcmaString *string)
|
||||
void InsertStringIfNotExistThreadUnsafe(EcmaString *string)
|
||||
{
|
||||
EcmaString *str = GetString(string);
|
||||
EcmaString *str = GetStringThreadUnsafe(string);
|
||||
if (str == nullptr) {
|
||||
InternString(string);
|
||||
InternStringThreadUnsafe(string);
|
||||
}
|
||||
}
|
||||
|
||||
CUnorderedMultiMap<uint32_t, EcmaString *> table_;
|
||||
const EcmaVM *vm_{nullptr};
|
||||
RecursiveMutex mutex_;
|
||||
friend class SnapshotProcessor;
|
||||
friend class BaseDeserializer;
|
||||
};
|
||||
@ -83,12 +91,16 @@ public:
|
||||
{
|
||||
return reinterpret_cast<SingleCharTable*>(object);
|
||||
}
|
||||
static void CreateSingleCharTable(JSThread *thread);
|
||||
static JSTaggedValue CreateSingleCharTable(JSThread *thread);
|
||||
JSTaggedValue GetStringFromSingleCharTable(int32_t ch)
|
||||
{
|
||||
return Get(ch);
|
||||
}
|
||||
private:
|
||||
SingleCharTable() = default;
|
||||
~SingleCharTable() = default;
|
||||
NO_COPY_SEMANTIC(SingleCharTable);
|
||||
NO_MOVE_SEMANTIC(SingleCharTable);
|
||||
static constexpr uint32_t MAX_ONEBYTE_CHARCODE = 128; // 0X00-0X7F
|
||||
};
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include "ecmascript/base/string_helper.h"
|
||||
#include "ecmascript/builtins/builtins.h"
|
||||
#include "ecmascript/builtins/builtins_ark_tools.h"
|
||||
#include "ecmascript/checkpoint/thread_state_transition.h"
|
||||
#ifdef ARK_SUPPORT_INTL
|
||||
#include "ecmascript/builtins/builtins_collator.h"
|
||||
#include "ecmascript/builtins/builtins_date_time_format.h"
|
||||
@ -79,6 +80,7 @@
|
||||
#include "ecmascript/patch/quick_fix_manager.h"
|
||||
#include "ecmascript/pgo_profiler/pgo_profiler_manager.h"
|
||||
#include "ecmascript/regexp/regexp_parser_cache.h"
|
||||
#include "ecmascript/runtime.h"
|
||||
#include "ecmascript/runtime_call_id.h"
|
||||
#include "ecmascript/snapshot/mem/snapshot.h"
|
||||
#include "ecmascript/snapshot/mem/snapshot_env.h"
|
||||
@ -97,22 +99,24 @@ namespace panda::ecmascript {
|
||||
using RandomGenerator = base::RandomGenerator;
|
||||
using PGOProfilerManager = pgo::PGOProfilerManager;
|
||||
AOTFileManager *JsStackInfo::loader = nullptr;
|
||||
/* static */
|
||||
EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options, EcmaParamConfiguration &config)
|
||||
|
||||
EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options)
|
||||
{
|
||||
Runtime::CreateIfFirstVm(options);
|
||||
auto heapType = options.IsWorker() ? EcmaParamConfiguration::HeapType::WORKER_HEAP :
|
||||
EcmaParamConfiguration::HeapType::DEFAULT_HEAP;
|
||||
auto config = EcmaParamConfiguration(heapType,
|
||||
MemMapAllocator::GetInstance()->GetCapacity());
|
||||
MemMapAllocator::GetInstance()->IncreaseAndCheckReserved(config.GetMaxHeapSize());
|
||||
JSRuntimeOptions newOptions = options;
|
||||
// only define SUPPORT_ENABLE_ASM_INTERP can enable asm-interpreter
|
||||
#if !defined(SUPPORT_ENABLE_ASM_INTERP)
|
||||
newOptions.SetEnableAsmInterpreter(false);
|
||||
#endif
|
||||
auto vm = new EcmaVM(newOptions, config);
|
||||
if (UNLIKELY(vm == nullptr)) {
|
||||
LOG_ECMA(ERROR) << "Failed to create jsvm";
|
||||
return nullptr;
|
||||
}
|
||||
auto jsThread = JSThread::Create(vm);
|
||||
vm->thread_ = jsThread;
|
||||
vm->Initialize();
|
||||
Runtime::GetInstance()->InitializeIfFirstVm(vm);
|
||||
if (JsStackInfo::loader == nullptr) {
|
||||
JsStackInfo::loader = vm->GetAOTFileManager();
|
||||
}
|
||||
@ -127,12 +131,12 @@ EcmaVM *EcmaVM::Create(const JSRuntimeOptions &options, EcmaParamConfiguration &
|
||||
// static
|
||||
bool EcmaVM::Destroy(EcmaVM *vm)
|
||||
{
|
||||
if (vm != nullptr) {
|
||||
delete vm;
|
||||
vm = nullptr;
|
||||
return true;
|
||||
if (UNLIKELY(vm == nullptr)) {
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
delete vm;
|
||||
Runtime::DestroyIfLastVm();
|
||||
return true;
|
||||
}
|
||||
|
||||
void EcmaVM::PreFork()
|
||||
@ -140,6 +144,7 @@ void EcmaVM::PreFork()
|
||||
heap_->CompactHeapBeforeFork();
|
||||
heap_->AdjustSpaceSizeForAppSpawn();
|
||||
heap_->GetReadOnlySpace()->SetReadOnly();
|
||||
SharedHeap::GetInstance()->DisableParallelGC();
|
||||
heap_->DisableParallelGC();
|
||||
}
|
||||
|
||||
@ -147,7 +152,9 @@ void EcmaVM::PostFork()
|
||||
{
|
||||
RandomGenerator::InitRandom();
|
||||
heap_->SetHeapMode(HeapMode::SHARE);
|
||||
GetAssociatedJSThread()->SetThreadId();
|
||||
GetAssociatedJSThread()->PostFork();
|
||||
Taskpool::GetCurrentTaskpool()->Initialize();
|
||||
SharedHeap::GetInstance()->EnableParallelGC(GetJSOptions());
|
||||
heap_->EnableParallelGC();
|
||||
std::string bundleName = PGOProfilerManager::GetInstance()->GetBundleName();
|
||||
if (ohos::EnableAotListHelper::GetInstance()->IsDisableBlackList(bundleName)) {
|
||||
@ -164,8 +171,7 @@ void EcmaVM::PostFork()
|
||||
}
|
||||
|
||||
EcmaVM::EcmaVM(JSRuntimeOptions options, EcmaParamConfiguration config)
|
||||
: stringTable_(new EcmaStringTable(this)),
|
||||
nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
|
||||
: nativeAreaAllocator_(std::make_unique<NativeAreaAllocator>()),
|
||||
heapRegionAllocator_(std::make_unique<HeapRegionAllocator>()),
|
||||
chunk_(nativeAreaAllocator_.get()),
|
||||
ecmaParamConfiguration_(std::move(config))
|
||||
@ -233,6 +239,7 @@ Jit *EcmaVM::GetJit() const
|
||||
bool EcmaVM::Initialize()
|
||||
{
|
||||
ECMA_BYTRACE_NAME(HITRACE_TAG_ARK, "EcmaVM::Initialize");
|
||||
stringTable_ = Runtime::GetInstance()->GetEcmaStringTable();
|
||||
InitializePGOProfiler();
|
||||
Taskpool::GetCurrentTaskpool()->Initialize();
|
||||
#ifndef PANDA_TARGET_WINDOWS
|
||||
@ -241,7 +248,7 @@ bool EcmaVM::Initialize()
|
||||
heap_ = new Heap(this);
|
||||
heap_->Initialize();
|
||||
gcStats_ = chunk_.New<GCStats>(heap_, options_.GetLongPauseTime());
|
||||
factory_ = chunk_.New<ObjectFactory>(thread_, heap_);
|
||||
factory_ = chunk_.New<ObjectFactory>(thread_, heap_, SharedHeap::GetInstance());
|
||||
if (UNLIKELY(factory_ == nullptr)) {
|
||||
LOG_FULL(FATAL) << "alloc factory_ failed";
|
||||
UNREACHABLE();
|
||||
@ -251,13 +258,13 @@ bool EcmaVM::Initialize()
|
||||
auto context = new EcmaContext(thread_);
|
||||
thread_->PushContext(context);
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
thread_->SetReadyForGCIterating();
|
||||
snapshotEnv_ = new SnapshotEnv(this);
|
||||
context->Initialize();
|
||||
snapshotEnv_->AddGlobalConstToMap();
|
||||
thread_->SetGlueGlobalEnv(reinterpret_cast<GlobalEnv *>(context->GetGlobalEnv().GetTaggedType()));
|
||||
thread_->SetGlobalObject(GetGlobalEnv()->GetGlobalObject());
|
||||
thread_->SetCurrentEcmaContext(context);
|
||||
SingleCharTable::CreateSingleCharTable(thread_);
|
||||
GenerateInternalNativeMethods();
|
||||
quickFixManager_ = new QuickFixManager();
|
||||
if (options_.GetEnableAsmInterpreter()) {
|
||||
@ -275,6 +282,7 @@ bool EcmaVM::Initialize()
|
||||
|
||||
EcmaVM::~EcmaVM()
|
||||
{
|
||||
ASSERT(thread_->IsInRunningStateOrProfiling());
|
||||
initialized_ = false;
|
||||
#if defined(ECMASCRIPT_SUPPORT_CPUPROFILER)
|
||||
if (thread_->isProfiling_) {
|
||||
@ -349,7 +357,6 @@ EcmaVM::~EcmaVM()
|
||||
}
|
||||
|
||||
if (stringTable_ != nullptr) {
|
||||
delete stringTable_;
|
||||
stringTable_ = nullptr;
|
||||
}
|
||||
|
||||
@ -388,6 +395,7 @@ JSHandle<GlobalEnv> EcmaVM::GetGlobalEnv() const
|
||||
JSTaggedValue EcmaVM::FastCallAot(size_t actualNumArgs, JSTaggedType *args, const JSTaggedType *prevFp)
|
||||
{
|
||||
INTERPRETER_TRACE(thread_, ExecuteAot);
|
||||
ASSERT(thread_->IsInManagedState());
|
||||
auto entry = thread_->GetRTInterface(kungfu::RuntimeStubCSigns::ID_OptimizedFastCallEntry);
|
||||
// do not modify this log to INFO, this will call many times
|
||||
LOG_ECMA(DEBUG) << "start to execute aot entry: " << (void*)entry;
|
||||
@ -465,8 +473,6 @@ void EcmaVM::ProcessNativeDelete(const WeakRootVisitor &visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
thread_->GetCurrentEcmaContext()->ProcessNativeDelete(visitor);
|
||||
}
|
||||
|
||||
void EcmaVM::ProcessReferences(const WeakRootVisitor &visitor)
|
||||
@ -495,12 +501,12 @@ void EcmaVM::ProcessReferences(const WeakRootVisitor &visitor)
|
||||
++iter;
|
||||
}
|
||||
}
|
||||
thread_->GetCurrentEcmaContext()->ProcessReferences(visitor);
|
||||
GetPGOProfiler()->ProcessReferences(visitor);
|
||||
}
|
||||
|
||||
void EcmaVM::PushToNativePointerList(JSNativePointer *pointer)
|
||||
{
|
||||
ASSERT(!JSTaggedValue(pointer).IsInSharedHeap());
|
||||
nativePointerList_.emplace_back(pointer);
|
||||
}
|
||||
|
||||
@ -555,10 +561,12 @@ void EcmaVM::Iterate(const RootVisitor &v, const RootRangeVisitor &rv)
|
||||
{
|
||||
rv(Root::ROOT_VM, ObjectSlot(ToUintPtr(&internalNativeMethods_.front())),
|
||||
ObjectSlot(ToUintPtr(&internalNativeMethods_.back()) + JSTaggedValue::TaggedTypeSize()));
|
||||
if (!WIN_OR_MAC_OR_IOS_PLATFORM) {
|
||||
if (!WIN_OR_MAC_OR_IOS_PLATFORM && snapshotEnv_!= nullptr) {
|
||||
snapshotEnv_->Iterate(v);
|
||||
}
|
||||
pgoProfiler_->Iterate(v);
|
||||
if (pgoProfiler_ != nullptr) {
|
||||
pgoProfiler_->Iterate(v);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(ECMASCRIPT_SUPPORT_HEAPPROFILER)
|
||||
@ -636,7 +644,7 @@ void EcmaVM::GenerateInternalNativeMethods()
|
||||
size_t length = static_cast<size_t>(MethodIndex::METHOD_END);
|
||||
constexpr uint32_t numArgs = 2; // function object and this
|
||||
for (size_t i = 0; i < length; i++) {
|
||||
auto method = factory_->NewMethod(nullptr, MemSpaceType::NON_MOVABLE);
|
||||
auto method = factory_->NewSMethod(nullptr, MemSpaceType::SHARED_NON_MOVABLE);
|
||||
method->SetNativePointer(InternalMethodTable[i]);
|
||||
method->SetNativeBit(true);
|
||||
method->SetNumArgsWithCallField(numArgs);
|
||||
@ -830,4 +838,20 @@ bool EcmaVM::IsHmsModule(const CString &moduleStr) const
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Initialize IcuData Path
|
||||
void EcmaVM::InitializeIcuData(const JSRuntimeOptions &options)
|
||||
{
|
||||
std::string icuPath = options.GetIcuDataPath();
|
||||
if (icuPath == "default") {
|
||||
#if !WIN_OR_MAC_OR_IOS_PLATFORM && !defined(PANDA_TARGET_LINUX)
|
||||
SetHwIcuDirectory();
|
||||
#endif
|
||||
} else {
|
||||
std::string absPath;
|
||||
if (ecmascript::RealPath(icuPath, absPath)) {
|
||||
u_setDataDirectory(absPath.c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -102,7 +102,7 @@ using DeviceDisconnectCallback = std::function<bool()>;
|
||||
using UncatchableErrorHandler = std::function<void(panda::TryCatch&)>;
|
||||
class EcmaVM {
|
||||
public:
|
||||
static EcmaVM *Create(const JSRuntimeOptions &options, EcmaParamConfiguration &config);
|
||||
static EcmaVM *Create(const JSRuntimeOptions &options);
|
||||
|
||||
static bool Destroy(EcmaVM *vm);
|
||||
|
||||
@ -599,6 +599,8 @@ public:
|
||||
{
|
||||
return thread_->GetThreadId();
|
||||
}
|
||||
|
||||
static void InitializeIcuData(const JSRuntimeOptions &options);
|
||||
protected:
|
||||
|
||||
void PrintJSErrorInfo(const JSHandle<JSTaggedValue> &exceptionInfo) const;
|
||||
@ -618,7 +620,7 @@ private:
|
||||
bool icEnabled_ {true};
|
||||
bool initialized_ {false};
|
||||
GCStats *gcStats_ {nullptr};
|
||||
EcmaStringTable *stringTable_;
|
||||
EcmaStringTable *stringTable_ {nullptr};
|
||||
|
||||
// VM memory management.
|
||||
std::unique_ptr<NativeAreaAllocator> nativeAreaAllocator_;
|
||||
|
@ -14,14 +14,33 @@
|
||||
*/
|
||||
|
||||
#include "ecmascript/free_object.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/global_env_constants-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
FreeObject *FreeObject::FillFreeObject(EcmaVM *vm, uintptr_t address, size_t size)
|
||||
FreeObject *FreeObject::FillFreeObject(BaseHeap *heap, uintptr_t address, size_t size)
|
||||
{
|
||||
ASAN_UNPOISON_MEMORY_REGION(reinterpret_cast<void *>(address), size);
|
||||
FreeObject *freeObject = vm->GetFactory()->FillFreeObject(address, size);
|
||||
auto globalConst = heap->GetGlobalConst();
|
||||
FreeObject *object = nullptr;
|
||||
if (size >= FreeObject::SIZE_OFFSET && size < FreeObject::SIZE) {
|
||||
object = reinterpret_cast<FreeObject *>(address);
|
||||
object->SetClassWithoutBarrier(
|
||||
JSHClass::Cast(globalConst->GetFreeObjectWithOneFieldClass().GetTaggedObject()));
|
||||
object->SetNext(INVALID_OBJECT);
|
||||
} else if (size >= FreeObject::SIZE) {
|
||||
object = reinterpret_cast<FreeObject *>(address);
|
||||
object->SetClassWithoutBarrier(
|
||||
JSHClass::Cast(globalConst->GetFreeObjectWithTwoFieldClass().GetTaggedObject()));
|
||||
object->SetAvailable(size);
|
||||
object->SetNext(INVALID_OBJECT);
|
||||
} else if (size == FreeObject::NEXT_OFFSET) {
|
||||
object = reinterpret_cast<FreeObject *>(address);
|
||||
object->SetClassWithoutBarrier(
|
||||
JSHClass::Cast(globalConst->GetFreeObjectWithNoneFieldClass().GetTaggedObject()));
|
||||
} else {
|
||||
LOG_ECMA(DEBUG) << "Fill free object size is smaller";
|
||||
}
|
||||
ASAN_POISON_MEMORY_REGION(reinterpret_cast<void *>(address), size);
|
||||
return freeObject;
|
||||
return object;
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -16,7 +16,7 @@
|
||||
#ifndef ECMASCRIPT_FREE_OBJECT_H
|
||||
#define ECMASCRIPT_FREE_OBJECT_H
|
||||
|
||||
#include "ecmascript/js_hclass.h"
|
||||
#include "ecmascript/js_hclass-inl.h"
|
||||
#include "ecmascript/mem/barriers.h"
|
||||
#include "ecmascript/mem/tagged_object-inl.h"
|
||||
|
||||
@ -29,7 +29,7 @@ public:
|
||||
{
|
||||
return reinterpret_cast<FreeObject *>(object);
|
||||
}
|
||||
static FreeObject *FillFreeObject(EcmaVM *vm, uintptr_t address, size_t size);
|
||||
static FreeObject *FillFreeObject(BaseHeap *heap, uintptr_t address, size_t size);
|
||||
|
||||
inline bool IsEmpty() const
|
||||
{
|
||||
|
@ -61,7 +61,7 @@ JSTaggedValue GlobalDictionary::GetValue(int entry) const
|
||||
PropertyAttributes GlobalDictionary::GetAttributes(int entry) const
|
||||
{
|
||||
int index = GetEntryIndex(entry) + ENTRY_DETAILS_INDEX;
|
||||
return PropertyAttributes(Get(index).GetInt());
|
||||
return PropertyAttributes(Get(index));
|
||||
}
|
||||
|
||||
void GlobalDictionary::SetEntry(const JSThread *thread, int entry, const JSTaggedValue &key, const JSTaggedValue &value,
|
||||
|
@ -38,7 +38,7 @@ void GlobalEnv::Init(JSThread *thread)
|
||||
SetGlobalRecord(thread, GlobalDictionary::Create(thread));
|
||||
JSTaggedValue emptyStr = thread->GlobalConstants()->GetEmptyString();
|
||||
EcmaStringTable *stringTable = thread->GetEcmaVM()->GetEcmaStringTable();
|
||||
stringTable->InternEmptyString(EcmaString::Cast(emptyStr.GetTaggedObject()));
|
||||
stringTable->InternEmptyString(thread, EcmaString::Cast(emptyStr.GetTaggedObject()));
|
||||
SetTemplateMap(thread, TemplateMap::Create(thread));
|
||||
SetObjectLiteralHClassCache(thread, JSTaggedValue::Hole());
|
||||
SetJsonObjectHclassCache(thread, JSTaggedValue::Hole());
|
||||
|
@ -70,17 +70,18 @@ inline uintptr_t GlobalEnvConstants::GetGlobalConstantAddr(ConstantIndex index)
|
||||
* static_cast<int>(ConstantIndex::Index); \
|
||||
}
|
||||
|
||||
#define DECL_GET_IMPL_WITH_TYPE(Type, Name, Index, Desc) DECL_GET_IMPL_COMMON(Type, Name, Index)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_ACCESSOR(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CACHES(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
|
||||
#define DECL_GET_IMPL_STRING(Name, Index, Token) DECL_GET_IMPL_COMMON(JSTaggedValue, Name, Index)
|
||||
GLOBAL_ENV_CONSTANT_STRING(DECL_GET_IMPL_STRING) // NOLINT(readability-const-return-type)
|
||||
#define DECL_GET_IMPL_WITH_TYPE(Type, Name, Index, Desc) DECL_GET_IMPL_COMMON(Type, Name, Index)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_STRING(DECL_GET_IMPL_STRING) // NOLINT(readability-const-return-type)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_ACCESSOR(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_IMPL_WITH_TYPE); // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
GLOBAL_ENV_CACHES(DECL_GET_IMPL_WITH_TYPE) // NOLINT(readability-const-return-type)
|
||||
#undef DECL_GET_IMPL_WITH_TYPE
|
||||
#undef DECL_GET_IMPL_STRING
|
||||
|
||||
#undef DECL_GET_IMPL_COMMON
|
||||
// clang-format on
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include "ecmascript/builtins/builtins.h"
|
||||
#include "ecmascript/builtins/builtins_global.h"
|
||||
#include "ecmascript/ecma_string-inl.h"
|
||||
#include "ecmascript/ecma_string_table.h"
|
||||
#include "ecmascript/ecma_vm.h"
|
||||
#include "ecmascript/free_object.h"
|
||||
#include "ecmascript/global_env.h"
|
||||
@ -72,180 +73,225 @@
|
||||
#include "ecmascript/method.h"
|
||||
#include "ecmascript/module/js_module_source_text.h"
|
||||
#include "ecmascript/object_factory.h"
|
||||
#include "ecmascript/runtime.h"
|
||||
#include "ecmascript/subtyping_operator.h"
|
||||
#include "ecmascript/tagged_node.h"
|
||||
#include "ecmascript/ts_types/ts_type.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
void GlobalEnvConstants::Init(JSThread *thread, JSHClass *hClass)
|
||||
void GlobalEnvConstants::Init(JSThread *thread)
|
||||
{
|
||||
InitRootsClass(thread, hClass);
|
||||
InitGlobalConstant(thread);
|
||||
InitGlobalCaches();
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
auto *globalConst = Runtime::GetInstance()->GetGlobalEnvConstants();
|
||||
if (globalConst != nullptr) {
|
||||
// 1. Copy shareds.
|
||||
for (size_t i = static_cast<size_t>(ConstantIndex::SHARED_BEGIN);
|
||||
i <= static_cast<size_t>(ConstantIndex::SHARED_END); i++) {
|
||||
constants_[i] = globalConst->constants_[i];
|
||||
}
|
||||
} else {
|
||||
InitSharedRootsClasses(factory);
|
||||
InitSharedStrings(factory);
|
||||
InitSharedMiscellanious(thread, factory);
|
||||
}
|
||||
// 2. Init non-shareds.
|
||||
InitMiscellanious(thread, factory);
|
||||
InitRootsClasses(factory);
|
||||
}
|
||||
|
||||
void GlobalEnvConstants::InitRootsClass(JSThread *thread, JSHClass *hClass)
|
||||
void GlobalEnvConstants::InitSharedStrings(ObjectFactory *factory)
|
||||
{
|
||||
#define INIT_GLOBAL_ENV_CONSTANT_STRING(Name, Index, Token) \
|
||||
SetConstant(ConstantIndex::Index, factory->NewFromASCIINonMovable(Token));
|
||||
SHARED_GLOBAL_ENV_CONSTANT_STRING(INIT_GLOBAL_ENV_CONSTANT_STRING)
|
||||
#undef INIT_GLOBAL_ENV_CONSTANT_STRING
|
||||
}
|
||||
|
||||
void GlobalEnvConstants::InitSharedRootsClasses(ObjectFactory *factory)
|
||||
{
|
||||
// Global constants are readonly.
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
JSHClass *hClass = *factory->InitSClassClass();
|
||||
|
||||
SetConstant(ConstantIndex::HCLASS_CLASS_INDEX, JSTaggedValue(hClass));
|
||||
// To reverse the order, the hclass of string needs to load default supers
|
||||
SetConstant(ConstantIndex::ARRAY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_ARRAY));
|
||||
SetConstant(ConstantIndex::DEFAULT_SUPERS_INDEX,
|
||||
WeakVector::Create(thread, SubtypingOperator::DEFAULT_SUPERS_CAPACITY, MemSpaceType::NON_MOVABLE));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_ARRAY));
|
||||
SetConstant(ConstantIndex::FREE_OBJECT_WITH_NONE_FIELD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, FreeObject::NEXT_OFFSET, JSType::FREE_OBJECT_WITH_NONE_FIELD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, FreeObject::NEXT_OFFSET, JSType::FREE_OBJECT_WITH_NONE_FIELD));
|
||||
SetConstant(ConstantIndex::FREE_OBJECT_WITH_ONE_FIELD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, FreeObject::SIZE_OFFSET, JSType::FREE_OBJECT_WITH_ONE_FIELD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, FreeObject::SIZE_OFFSET, JSType::FREE_OBJECT_WITH_ONE_FIELD));
|
||||
SetConstant(ConstantIndex::FREE_OBJECT_WITH_TWO_FIELD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, FreeObject::SIZE, JSType::FREE_OBJECT_WITH_TWO_FIELD));
|
||||
SetConstant(ConstantIndex::LINE_STRING_CLASS_INDEX, factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::LINE_STRING));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, FreeObject::SIZE, JSType::FREE_OBJECT_WITH_TWO_FIELD));
|
||||
SetConstant(ConstantIndex::LINE_STRING_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::LINE_STRING));
|
||||
SetConstant(ConstantIndex::SLICED_STRING_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::SLICED_STRING));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::SLICED_STRING));
|
||||
SetConstant(ConstantIndex::CONSTANT_STRING_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::CONSTANT_STRING));
|
||||
SetConstant(ConstantIndex::TREE_STRING_CLASS_INDEX, factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TREE_STRING));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::CONSTANT_STRING));
|
||||
SetConstant(ConstantIndex::TREE_STRING_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::TREE_STRING));
|
||||
SetConstant(ConstantIndex::BYTE_ARRAY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::BYTE_ARRAY));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::BYTE_ARRAY));
|
||||
SetConstant(ConstantIndex::CONSTANT_POOL_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::CONSTANT_POOL));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::CONSTANT_POOL));
|
||||
SetConstant(ConstantIndex::PROFILE_TYPE_INFO_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::PROFILE_TYPE_INFO));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::PROFILE_TYPE_INFO));
|
||||
SetConstant(ConstantIndex::AOT_LITERAL_INFO_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::AOT_LITERAL_INFO));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::AOT_LITERAL_INFO));
|
||||
SetConstant(ConstantIndex::VTABLE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::VTABLE));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::VTABLE));
|
||||
SetConstant(ConstantIndex::COW_MUTANT_TAGGED_ARRAY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::COW_MUTANT_TAGGED_ARRAY));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::COW_MUTANT_TAGGED_ARRAY));
|
||||
SetConstant(ConstantIndex::MUTANT_TAGGED_ARRAY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::MUTANT_TAGGED_ARRAY));
|
||||
InitGlobalConstantSpecial(thread);
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::MUTANT_TAGGED_ARRAY));
|
||||
SetConstant(ConstantIndex::DICTIONARY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_DICTIONARY));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::TAGGED_DICTIONARY));
|
||||
SetConstant(ConstantIndex::COW_ARRAY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::COW_TAGGED_ARRAY));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::COW_TAGGED_ARRAY));
|
||||
SetConstant(ConstantIndex::BIGINT_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, BigInt::SIZE, JSType::BIGINT));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, BigInt::SIZE, JSType::BIGINT));
|
||||
SetConstant(ConstantIndex::JS_NATIVE_POINTER_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, JSNativePointer::SIZE, JSType::JS_NATIVE_POINTER));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, JSNativePointer::SIZE, JSType::JS_NATIVE_POINTER));
|
||||
SetConstant(ConstantIndex::ENV_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::LEXICAL_ENV));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::LEXICAL_ENV));
|
||||
SetConstant(ConstantIndex::SYMBOL_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, JSSymbol::SIZE, JSType::SYMBOL));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, JSSymbol::SIZE, JSType::SYMBOL));
|
||||
SetConstant(ConstantIndex::ACCESSOR_DATA_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, AccessorData::SIZE, JSType::ACCESSOR_DATA));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, AccessorData::SIZE, JSType::ACCESSOR_DATA));
|
||||
SetConstant(ConstantIndex::INTERNAL_ACCESSOR_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, AccessorData::SIZE, JSType::INTERNAL_ACCESSOR));
|
||||
SetConstant(ConstantIndex::JS_PROXY_ORDINARY_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSProxy::SIZE, JSType::JS_PROXY));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, AccessorData::SIZE, JSType::INTERNAL_ACCESSOR));
|
||||
SetConstant(ConstantIndex::COMPLETION_RECORD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, CompletionRecord::SIZE, JSType::COMPLETION_RECORD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, CompletionRecord::SIZE, JSType::COMPLETION_RECORD));
|
||||
SetConstant(ConstantIndex::GENERATOR_CONTEST_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, GeneratorContext::SIZE, JSType::JS_GENERATOR_CONTEXT));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, GeneratorContext::SIZE, JSType::JS_GENERATOR_CONTEXT));
|
||||
SetConstant(ConstantIndex::ASYNC_GENERATOR_REQUEST_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, AsyncGeneratorRequest::SIZE,
|
||||
JSType::ASYNC_GENERATOR_REQUEST));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, AsyncGeneratorRequest::SIZE,
|
||||
JSType::ASYNC_GENERATOR_REQUEST));
|
||||
SetConstant(ConstantIndex::ASYNC_ITERATOR_RECORD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, AsyncIteratorRecord::SIZE, JSType::ASYNC_ITERATOR_RECORD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, AsyncIteratorRecord::SIZE, JSType::ASYNC_ITERATOR_RECORD));
|
||||
SetConstant(ConstantIndex::CAPABILITY_RECORD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, PromiseCapability::SIZE, JSType::PROMISE_CAPABILITY));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, PromiseCapability::SIZE, JSType::PROMISE_CAPABILITY));
|
||||
SetConstant(ConstantIndex::REACTIONS_RECORD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, PromiseReaction::SIZE, JSType::PROMISE_REACTIONS));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, PromiseReaction::SIZE, JSType::PROMISE_REACTIONS));
|
||||
SetConstant(ConstantIndex::PROMISE_ITERATOR_RECORD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, PromiseIteratorRecord::SIZE,
|
||||
JSType::PROMISE_ITERATOR_RECORD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, PromiseIteratorRecord::SIZE,
|
||||
JSType::PROMISE_ITERATOR_RECORD));
|
||||
SetConstant(ConstantIndex::PROMISE_RECORD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, PromiseRecord::SIZE, JSType::PROMISE_RECORD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, PromiseRecord::SIZE, JSType::PROMISE_RECORD));
|
||||
SetConstant(ConstantIndex::PROMISE_RESOLVING_FUNCTIONS_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, ResolvingFunctionsRecord::SIZE,
|
||||
JSType::RESOLVING_FUNCTIONS_RECORD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ResolvingFunctionsRecord::SIZE,
|
||||
JSType::RESOLVING_FUNCTIONS_RECORD));
|
||||
SetConstant(ConstantIndex::MICRO_JOB_QUEUE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, job::MicroJobQueue::SIZE, JSType::MICRO_JOB_QUEUE));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, job::MicroJobQueue::SIZE, JSType::MICRO_JOB_QUEUE));
|
||||
SetConstant(ConstantIndex::PENDING_JOB_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, job::PendingJob::SIZE, JSType::PENDING_JOB));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, job::PendingJob::SIZE, JSType::PENDING_JOB));
|
||||
SetConstant(ConstantIndex::PROTO_CHANGE_MARKER_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, ProtoChangeMarker::SIZE, JSType::PROTO_CHANGE_MARKER));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ProtoChangeMarker::SIZE, JSType::PROTO_CHANGE_MARKER));
|
||||
SetConstant(ConstantIndex::PROTO_CHANGE_DETAILS_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, ProtoChangeDetails::SIZE, JSType::PROTOTYPE_INFO));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ProtoChangeDetails::SIZE, JSType::PROTOTYPE_INFO));
|
||||
SetConstant(ConstantIndex::MARKER_CELL_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, MarkerCell::SIZE, JSType::MARKER_CELL));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, MarkerCell::SIZE, JSType::MARKER_CELL));
|
||||
SetConstant(ConstantIndex::TRACK_INFO_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TrackInfo::SIZE, JSType::TRACK_INFO));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TrackInfo::SIZE, JSType::TRACK_INFO));
|
||||
SetConstant(ConstantIndex::PROTOTYPE_HANDLER_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, PrototypeHandler::SIZE, JSType::PROTOTYPE_HANDLER));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, PrototypeHandler::SIZE, JSType::PROTOTYPE_HANDLER));
|
||||
SetConstant(ConstantIndex::TRANSITION_HANDLER_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TransitionHandler::SIZE, JSType::TRANSITION_HANDLER));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TransitionHandler::SIZE, JSType::TRANSITION_HANDLER));
|
||||
SetConstant(ConstantIndex::TRANS_WITH_PROTO_HANDLER_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TransWithProtoHandler::SIZE, JSType::TRANS_WITH_PROTO_HANDLER));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TransWithProtoHandler::SIZE, JSType::TRANS_WITH_PROTO_HANDLER));
|
||||
SetConstant(ConstantIndex::STORE_TS_HANDLER_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, StoreTSHandler::SIZE, JSType::STORE_TS_HANDLER));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, StoreTSHandler::SIZE, JSType::STORE_TS_HANDLER));
|
||||
SetConstant(ConstantIndex::PROPERTY_BOX_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, PropertyBox::SIZE, JSType::PROPERTY_BOX));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, PropertyBox::SIZE, JSType::PROPERTY_BOX));
|
||||
SetConstant(ConstantIndex::PROGRAM_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, Program::SIZE, JSType::PROGRAM));
|
||||
SetConstant(
|
||||
ConstantIndex::IMPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, ImportEntry::SIZE, JSType::IMPORTENTRY_RECORD));
|
||||
SetConstant(
|
||||
ConstantIndex::LOCAL_EXPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, LocalExportEntry::SIZE, JSType::LOCAL_EXPORTENTRY_RECORD));
|
||||
SetConstant(
|
||||
ConstantIndex::INDIRECT_EXPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, IndirectExportEntry::SIZE,
|
||||
JSType::INDIRECT_EXPORTENTRY_RECORD));
|
||||
SetConstant(
|
||||
ConstantIndex::STAR_EXPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, StarExportEntry::SIZE, JSType::STAR_EXPORTENTRY_RECORD));
|
||||
SetConstant(
|
||||
ConstantIndex::SOURCE_TEXT_MODULE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, SourceTextModule::SIZE, JSType::SOURCE_TEXT_MODULE_RECORD));
|
||||
SetConstant(
|
||||
ConstantIndex::RESOLVED_BINDING_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, ResolvedBinding::SIZE, JSType::RESOLVEDBINDING_RECORD));
|
||||
SetConstant(
|
||||
ConstantIndex::RESOLVED_INDEX_BINDING_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, ResolvedIndexBinding::SIZE, JSType::RESOLVEDINDEXBINDING_RECORD));
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, Program::SIZE, JSType::PROGRAM));
|
||||
SetConstant(ConstantIndex::IMPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ImportEntry::SIZE, JSType::IMPORTENTRY_RECORD));
|
||||
SetConstant(ConstantIndex::LOCAL_EXPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, LocalExportEntry::SIZE, JSType::LOCAL_EXPORTENTRY_RECORD));
|
||||
SetConstant(ConstantIndex::INDIRECT_EXPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, IndirectExportEntry::SIZE,
|
||||
JSType::INDIRECT_EXPORTENTRY_RECORD));
|
||||
SetConstant(ConstantIndex::STAR_EXPORT_ENTRY_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, StarExportEntry::SIZE, JSType::STAR_EXPORTENTRY_RECORD));
|
||||
SetConstant(ConstantIndex::SOURCE_TEXT_MODULE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, SourceTextModule::SIZE, JSType::SOURCE_TEXT_MODULE_RECORD));
|
||||
SetConstant(ConstantIndex::RESOLVED_BINDING_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ResolvedBinding::SIZE, JSType::RESOLVEDBINDING_RECORD));
|
||||
SetConstant(ConstantIndex::RESOLVED_INDEX_BINDING_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ResolvedIndexBinding::SIZE, JSType::RESOLVEDINDEXBINDING_RECORD));
|
||||
SetConstant(ConstantIndex::MACHINE_CODE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, 0, JSType::MACHINE_CODE_OBJECT));
|
||||
SetConstant(ConstantIndex::CLASS_INFO_EXTRACTOR_HCLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ClassInfoExtractor::SIZE,
|
||||
JSType::CLASS_INFO_EXTRACTOR));
|
||||
SetConstant(ConstantIndex::TS_OBJECT_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSObjectType::SIZE, JSType::TS_OBJECT_TYPE));
|
||||
SetConstant(ConstantIndex::TS_CLASS_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSClassType::SIZE, JSType::TS_CLASS_TYPE));
|
||||
SetConstant(ConstantIndex::TS_UNION_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSUnionType::SIZE, JSType::TS_UNION_TYPE));
|
||||
SetConstant(ConstantIndex::TS_INTERFACE_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSInterfaceType::SIZE, JSType::TS_INTERFACE_TYPE));
|
||||
SetConstant(ConstantIndex::TS_CLASS_INSTANCE_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSClassInstanceType::SIZE,
|
||||
JSType::TS_CLASS_INSTANCE_TYPE));
|
||||
SetConstant(ConstantIndex::TS_FUNCTION_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSFunctionType::SIZE, JSType::TS_FUNCTION_TYPE));
|
||||
SetConstant(ConstantIndex::TS_ARRAY_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSArrayType::SIZE, JSType::TS_ARRAY_TYPE));
|
||||
SetConstant(ConstantIndex::TS_ITERATOR_INSTANCE_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSIteratorInstanceType::SIZE,
|
||||
JSType::TS_ITERATOR_INSTANCE_TYPE));
|
||||
SetConstant(ConstantIndex::TS_NAMESPACE_TYPE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, TSNamespaceType::SIZE, JSType::TS_NAMESPACE_TYPE));
|
||||
SetConstant(ConstantIndex::CELL_RECORD_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, CellRecord::SIZE, JSType::CELL_RECORD));
|
||||
SetConstant(ConstantIndex::METHOD_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, Method::SIZE, JSType::METHOD));
|
||||
SetConstant(ConstantIndex::LINKED_NODE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, LinkedNode::SIZE, JSType::LINKED_NODE));
|
||||
SetConstant(ConstantIndex::RB_TREENODE_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, RBTreeNode::SIZE, JSType::RB_TREENODE));
|
||||
SetConstant(ConstantIndex::CLASS_LITERAL_HCLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ClassLiteral::SIZE, JSType::CLASS_LITERAL));
|
||||
SetConstant(ConstantIndex::RESOLVED_RECORD_BINDING_CLASS_INDEX,
|
||||
factory->NewSEcmaReadOnlyHClass(hClass, ResolvedRecordBinding::SIZE, JSType::RESOLVEDRECORDBINDING_RECORD));
|
||||
}
|
||||
|
||||
JSHClass *jsProxyCallableClass = *factory->NewEcmaHClass(hClass, JSProxy::SIZE, JSType::JS_PROXY);
|
||||
void GlobalEnvConstants::InitSharedMiscellanious(JSThread *thread, ObjectFactory *factory)
|
||||
{
|
||||
// Accessors
|
||||
auto accessor = factory->NewSInternalAccessor(reinterpret_cast<void *>(JSFunction::PrototypeSetter),
|
||||
reinterpret_cast<void *>(JSFunction::PrototypeGetter));
|
||||
SetConstant(ConstantIndex::FUNCTION_PROTOTYPE_ACCESSOR, accessor);
|
||||
accessor = factory->NewSInternalAccessor(nullptr, reinterpret_cast<void *>(JSFunction::NameGetter));
|
||||
SetConstant(ConstantIndex::FUNCTION_NAME_ACCESSOR, accessor);
|
||||
accessor = factory->NewSInternalAccessor(nullptr, reinterpret_cast<void *>(JSFunction::LengthGetter));
|
||||
SetConstant(ConstantIndex::FUNCTION_LENGTH_ACCESSOR, accessor);
|
||||
accessor = factory->NewSInternalAccessor(reinterpret_cast<void *>(JSArray::LengthSetter),
|
||||
reinterpret_cast<void *>(JSArray::LengthGetter));
|
||||
SetConstant(ConstantIndex::ARRAY_LENGTH_ACCESSOR, accessor);
|
||||
// Specials
|
||||
SetConstant(ConstantIndex::UNDEFINED_INDEX, JSTaggedValue::Undefined());
|
||||
SetConstant(ConstantIndex::NULL_INDEX, JSTaggedValue::Null());
|
||||
SetConstant(ConstantIndex::TRUE_INDEX, JSTaggedValue::True());
|
||||
SetConstant(ConstantIndex::FALSE_INDEX, JSTaggedValue::False());
|
||||
// Emptys
|
||||
auto vm = thread->GetEcmaVM();
|
||||
SetConstant(ConstantIndex::EMPTY_STRING_OBJECT_INDEX, JSTaggedValue(EcmaStringAccessor::CreateEmptyString(vm)));
|
||||
SetConstant(ConstantIndex::SINGLE_CHAR_TABLE_INDEX, SingleCharTable::CreateSingleCharTable(thread));
|
||||
SetConstant(ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX, factory->NewSEmptyArray());
|
||||
SetConstant(ConstantIndex::EMPTY_MUTANT_ARRAY_OBJECT_INDEX, factory->NewSEmptyMutantArray());
|
||||
SetConstant(ConstantIndex::EMPTY_SLAYOUT_INFO_OBJECT_INDEX, factory->CreateSLayoutInfo(0));
|
||||
}
|
||||
|
||||
jsProxyCallableClass->SetCallable(true);
|
||||
SetConstant(ConstantIndex::JS_PROXY_CALLABLE_CLASS_INDEX, JSTaggedValue(jsProxyCallableClass));
|
||||
|
||||
JSHClass *jsProxyConstructClass = *factory->NewEcmaHClass(hClass, JSProxy::SIZE, JSType::JS_PROXY);
|
||||
|
||||
jsProxyConstructClass->SetCallable(true);
|
||||
jsProxyConstructClass->SetConstructor(true);
|
||||
SetConstant(ConstantIndex::JS_PROXY_CONSTRUCT_CLASS_INDEX, JSTaggedValue(jsProxyConstructClass));
|
||||
void GlobalEnvConstants::InitRootsClasses(ObjectFactory *factory)
|
||||
{
|
||||
JSHClass *hClass = JSHClass::Cast(GetHClassClass().GetTaggedObject());
|
||||
|
||||
SetConstant(ConstantIndex::JS_REALM_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSRealm::SIZE, JSType::JS_REALM));
|
||||
SetConstant(ConstantIndex::MACHINE_CODE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, 0, JSType::MACHINE_CODE_OBJECT));
|
||||
SetConstant(ConstantIndex::CLASS_INFO_EXTRACTOR_HCLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, ClassInfoExtractor::SIZE,
|
||||
JSType::CLASS_INFO_EXTRACTOR));
|
||||
SetConstant(ConstantIndex::TS_OBJECT_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSObjectType::SIZE, JSType::TS_OBJECT_TYPE));
|
||||
SetConstant(ConstantIndex::TS_CLASS_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSClassType::SIZE, JSType::TS_CLASS_TYPE));
|
||||
SetConstant(ConstantIndex::TS_UNION_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSUnionType::SIZE, JSType::TS_UNION_TYPE));
|
||||
SetConstant(ConstantIndex::TS_INTERFACE_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSInterfaceType::SIZE, JSType::TS_INTERFACE_TYPE));
|
||||
SetConstant(ConstantIndex::TS_CLASS_INSTANCE_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSClassInstanceType::SIZE,
|
||||
JSType::TS_CLASS_INSTANCE_TYPE));
|
||||
SetConstant(ConstantIndex::TS_FUNCTION_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSFunctionType::SIZE, JSType::TS_FUNCTION_TYPE));
|
||||
SetConstant(ConstantIndex::TS_ARRAY_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSArrayType::SIZE, JSType::TS_ARRAY_TYPE));
|
||||
SetConstant(ConstantIndex::TS_ITERATOR_INSTANCE_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSIteratorInstanceType::SIZE,
|
||||
JSType::TS_ITERATOR_INSTANCE_TYPE));
|
||||
SetConstant(ConstantIndex::TS_NAMESPACE_TYPE_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, TSNamespaceType::SIZE, JSType::TS_NAMESPACE_TYPE));
|
||||
SetConstant(ConstantIndex::JS_REGEXP_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSRegExpIterator::SIZE, JSType::JS_REG_EXP_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_SET_ITERATOR_CLASS_INDEX,
|
||||
@ -254,9 +300,8 @@ void GlobalEnvConstants::InitRootsClass(JSThread *thread, JSHClass *hClass)
|
||||
factory->NewEcmaHClass(hClass, JSMapIterator::SIZE, JSType::JS_MAP_ITERATOR, 0)); // 0: no inlined props
|
||||
SetConstant(ConstantIndex::JS_ARRAY_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSArrayIterator::SIZE, JSType::JS_ARRAY_ITERATOR, 0));
|
||||
SetConstant(
|
||||
ConstantIndex::JS_API_ARRAYLIST_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPIArrayListIterator::SIZE, JSType::JS_API_ARRAYLIST_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_ARRAYLIST_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPIArrayListIterator::SIZE, JSType::JS_API_ARRAYLIST_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_DEQUE_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPIDequeIterator::SIZE, JSType::JS_API_DEQUE_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_LIGHTWEIGHTMAP_ITERATOR_CLASS_INDEX,
|
||||
@ -265,14 +310,12 @@ void GlobalEnvConstants::InitRootsClass(JSThread *thread, JSHClass *hClass)
|
||||
SetConstant(ConstantIndex::JS_API_LIGHTWEIGHTSET_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPILightWeightSetIterator::SIZE,
|
||||
JSType::JS_API_LIGHT_WEIGHT_SET_ITERATOR));
|
||||
SetConstant(
|
||||
ConstantIndex::JS_API_LINKED_LIST_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPILinkedListIterator::SIZE, JSType::JS_API_LINKED_LIST_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_LINKED_LIST_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPILinkedListIterator::SIZE, JSType::JS_API_LINKED_LIST_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_LIST_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPIListIterator::SIZE, JSType::JS_API_LIST_ITERATOR));
|
||||
SetConstant(
|
||||
ConstantIndex::JS_API_PLAIN_ARRAY_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPIPlainArrayIterator::SIZE, JSType::JS_API_PLAIN_ARRAY_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_PLAIN_ARRAY_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPIPlainArrayIterator::SIZE, JSType::JS_API_PLAIN_ARRAY_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_QUEUE_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPIQueueIterator::SIZE, JSType::JS_API_QUEUE_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_STACK_ITERATOR_CLASS_INDEX,
|
||||
@ -287,62 +330,35 @@ void GlobalEnvConstants::InitRootsClass(JSThread *thread, JSHClass *hClass)
|
||||
factory->NewEcmaHClass(hClass, JSAPITreeMapIterator::SIZE, JSType::JS_API_TREEMAP_ITERATOR));
|
||||
SetConstant(ConstantIndex::JS_API_TREE_SET_ITERATOR_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSAPITreeSetIterator::SIZE, JSType::JS_API_TREESET_ITERATOR));
|
||||
SetConstant(ConstantIndex::LINKED_NODE_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, LinkedNode::SIZE, JSType::LINKED_NODE));
|
||||
SetConstant(ConstantIndex::RB_TREENODE_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, RBTreeNode::SIZE, JSType::RB_TREENODE));
|
||||
SetConstant(ConstantIndex::CELL_RECORD_CLASS_INDEX,
|
||||
factory->NewEcmaReadOnlyHClass(hClass, CellRecord::SIZE, JSType::CELL_RECORD));
|
||||
SetConstant(ConstantIndex::OBJECT_HCLASS_INDEX, factory->NewEcmaHClass(JSObject::SIZE, JSType::JS_OBJECT));
|
||||
SetConstant(ConstantIndex::METHOD_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, Method::SIZE, JSType::METHOD));
|
||||
SetConstant(ConstantIndex::CLASS_LITERAL_HCLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, ClassLiteral::SIZE, JSType::CLASS_LITERAL));
|
||||
SetConstant(ConstantIndex::CLASS_PROTOTYPE_HCLASS_INDEX,
|
||||
factory->CreateDefaultClassPrototypeHClass(hClass));
|
||||
SetConstant(ConstantIndex::CLASS_CONSTRUCTOR_HCLASS_INDEX,
|
||||
factory->CreateDefaultClassConstructorHClass(hClass));
|
||||
SetConstant(ConstantIndex::JS_PROXY_ORDINARY_CLASS_INDEX,
|
||||
factory->NewEcmaHClass(hClass, JSProxy::SIZE, JSType::JS_PROXY));
|
||||
// JS_PROXY_CALLABLE_CLASS_INDEX
|
||||
JSHClass *jsProxyCallableClass = *factory->NewEcmaHClass(hClass, JSProxy::SIZE, JSType::JS_PROXY);
|
||||
jsProxyCallableClass->SetCallable(true);
|
||||
SetConstant(ConstantIndex::JS_PROXY_CALLABLE_CLASS_INDEX, JSTaggedValue(jsProxyCallableClass));
|
||||
// JS_PROXY_CONSTRUCT_CLASS_INDEX
|
||||
JSHClass *jsProxyConstructClass = *factory->NewEcmaHClass(hClass, JSProxy::SIZE, JSType::JS_PROXY);
|
||||
jsProxyConstructClass->SetCallable(true);
|
||||
jsProxyConstructClass->SetConstructor(true);
|
||||
SetConstant(ConstantIndex::JS_PROXY_CONSTRUCT_CLASS_INDEX, JSTaggedValue(jsProxyConstructClass));
|
||||
}
|
||||
|
||||
void GlobalEnvConstants::InitGlobalConstantSpecial(JSThread *thread)
|
||||
void GlobalEnvConstants::InitMiscellanious(JSThread *thread, ObjectFactory *factory)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
// SPECIAL INIT
|
||||
SetConstant(ConstantIndex::UNDEFINED_INDEX, JSTaggedValue::Undefined());
|
||||
SetConstant(ConstantIndex::NULL_INDEX, JSTaggedValue::Null());
|
||||
SetConstant(ConstantIndex::TRUE_INDEX, JSTaggedValue::True());
|
||||
SetConstant(ConstantIndex::FALSE_INDEX, JSTaggedValue::False());
|
||||
auto vm = thread->GetEcmaVM();
|
||||
SetConstant(ConstantIndex::EMPTY_STRING_OBJECT_INDEX, JSTaggedValue(EcmaStringAccessor::CreateEmptyString(vm)));
|
||||
SetConstant(ConstantIndex::EMPTY_ARRAY_OBJECT_INDEX, factory->NewEmptyArray());
|
||||
SetConstant(ConstantIndex::EMPTY_MUTANT_ARRAY_OBJECT_INDEX, factory->NewEmptyMutantArray());
|
||||
SetConstant(ConstantIndex::EMPTY_LAYOUT_INFO_OBJECT_INDEX, factory->CreateLayoutInfo(0));
|
||||
SetConstant(ConstantIndex::EMPTY_TAGGED_QUEUE_OBJECT_INDEX, factory->NewTaggedQueue(0));
|
||||
}
|
||||
SetConstant(ConstantIndex::DEFAULT_SUPERS_INDEX,
|
||||
WeakVector::Create(thread, SubtypingOperator::DEFAULT_SUPERS_CAPACITY, MemSpaceType::NON_MOVABLE));
|
||||
|
||||
// NOLINTNEXTLINE(readability-function-size)
|
||||
void GlobalEnvConstants::InitGlobalConstant(JSThread *thread)
|
||||
{
|
||||
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
|
||||
/* non ECMA standard jsapi containers iterators, init to Undefined first */
|
||||
// non ECMA standard jsapi containers iterators, init to Undefined first
|
||||
InitJSAPIContainers();
|
||||
|
||||
#define INIT_GLOBAL_ENV_CONSTANT_STRING(Name, Index, Token) \
|
||||
SetConstant(ConstantIndex::Index, factory->NewFromASCIINonMovable(Token));
|
||||
|
||||
GLOBAL_ENV_CONSTANT_STRING(INIT_GLOBAL_ENV_CONSTANT_STRING)
|
||||
#undef INIT_GLOBAL_ENV_CONSTANT_STRING
|
||||
|
||||
auto accessor = factory->NewInternalAccessor(reinterpret_cast<void *>(JSFunction::PrototypeSetter),
|
||||
reinterpret_cast<void *>(JSFunction::PrototypeGetter));
|
||||
SetConstant(ConstantIndex::FUNCTION_PROTOTYPE_ACCESSOR, accessor);
|
||||
accessor = factory->NewInternalAccessor(nullptr, reinterpret_cast<void *>(JSFunction::NameGetter));
|
||||
SetConstant(ConstantIndex::FUNCTION_NAME_ACCESSOR, accessor);
|
||||
accessor = factory->NewInternalAccessor(nullptr, reinterpret_cast<void *>(JSFunction::LengthGetter));
|
||||
SetConstant(ConstantIndex::FUNCTION_LENGTH_ACCESSOR, accessor);
|
||||
accessor = factory->NewInternalAccessor(reinterpret_cast<void *>(JSArray::LengthSetter),
|
||||
reinterpret_cast<void *>(JSArray::LengthGetter));
|
||||
SetConstant(ConstantIndex::ARRAY_LENGTH_ACCESSOR, accessor);
|
||||
SetConstant(ConstantIndex::CLASS_PROTOTYPE_HCLASS_INDEX,
|
||||
factory->CreateDefaultClassPrototypeHClass(JSHClass::Cast(GetHClassClass().GetTaggedObject())));
|
||||
SetConstant(ConstantIndex::CLASS_CONSTRUCTOR_HCLASS_INDEX,
|
||||
factory->CreateDefaultClassConstructorHClass(JSHClass::Cast(GetHClassClass().GetTaggedObject())));
|
||||
InitGlobalCaches();
|
||||
}
|
||||
|
||||
void GlobalEnvConstants::InitGlobalCaches()
|
||||
|
@ -30,7 +30,7 @@ class JSThread;
|
||||
class ObjectFactory;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define GLOBAL_ENV_CONSTANT_CLASS(V) \
|
||||
#define SHARED_GLOBAL_ENV_CONSTANT_CLASS(V) \
|
||||
/* GC Root */ \
|
||||
V(JSTaggedValue, HClassClass, HCLASS_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, FreeObjectWithNoneFieldClass, FREE_OBJECT_WITH_NONE_FIELD_CLASS_INDEX, ecma_roots_class) \
|
||||
@ -54,7 +54,6 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, SymbolClass, SYMBOL_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, AccessorDataClass, ACCESSOR_DATA_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, InternalAccessorClass, INTERNAL_ACCESSOR_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSProxyOrdinaryClass, JS_PROXY_ORDINARY_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, CompletionRecordClass, COMPLETION_RECORD_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, GeneratorContextClass, GENERATOR_CONTEST_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, AsyncGeneratorRequestRecordClass, ASYNC_GENERATOR_REQUEST_CLASS_INDEX, ecma_roots_class) \
|
||||
@ -83,10 +82,6 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, SourceTextModuleClass, SOURCE_TEXT_MODULE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ResolvedBindingClass, RESOLVED_BINDING_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ResolvedIndexBindingClass, RESOLVED_INDEX_BINDING_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSProxyCallableClass, JS_PROXY_CALLABLE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSProxyConstructClass, JS_PROXY_CONSTRUCT_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSRealmClass, JS_REALM_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSRegExpClass, JS_REGEXP_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, MachineCodeClass, MACHINE_CODE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassInfoExtractorHClass, CLASS_INFO_EXTRACTOR_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, TSObjectTypeClass, TS_OBJECT_TYPE_CLASS_INDEX, ecma_roots_class) \
|
||||
@ -98,6 +93,21 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, TSArrayTypeClass, TS_ARRAY_TYPE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, TSIteratorInstanceTypeClass, TS_ITERATOR_INSTANCE_TYPE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, TSNamespaceTypeClass, TS_NAMESPACE_TYPE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, CellRecordClass, CELL_RECORD_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, AOTLiteralInfoClass, AOT_LITERAL_INFO_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, MethodClass, METHOD_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, LinkedNode, LINKED_NODE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, RBTreeNode, RB_TREENODE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassLiteralClass, CLASS_LITERAL_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, VTableClass, VTABLE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ResolvedRecordBindingClass, RESOLVED_RECORD_BINDING_CLASS_INDEX, ecma_roots_class) \
|
||||
|
||||
#define GLOBAL_ENV_CONSTANT_CLASS(V) \
|
||||
V(JSTaggedValue, JSProxyCallableClass, JS_PROXY_CALLABLE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSProxyConstructClass, JS_PROXY_CONSTRUCT_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSRealmClass, JS_REALM_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSRegExpClass, JS_REGEXP_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSProxyOrdinaryClass, JS_PROXY_ORDINARY_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSSetIteratorClass, JS_SET_ITERATOR_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSRegExpIteratorClass, JS_REGEXP_ITERATOR_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSMapIteratorClass, JS_MAP_ITERATOR_CLASS_INDEX, ecma_roots_class) \
|
||||
@ -116,19 +126,12 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, JSAPIHashSetIteratorClass, JS_API_HASH_SET_ITERATOR_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSAPITreeMapIteratorClass, JS_API_TREE_MAP_ITERATOR_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSAPITreeSetIteratorClass, JS_API_TREE_SET_ITERATOR_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, LinkedNode, LINKED_NODE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, RBTreeNode, RB_TREENODE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSAPIIteratorFuncHClass, JS_API_ITERATOR_FUNC_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, JSAPIAsyncIteratorFuncHClass, JS_API_ASYNCITERATOR_FUNC_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, CellRecordClass, CELL_RECORD_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ObjectClass, OBJECT_HCLASS_INDEX, initial_object_hclass) \
|
||||
V(JSTaggedValue, IteratorResultClass, ITERATOR_RESULT_CLASS, ecma_roots_class) \
|
||||
V(JSTaggedValue, MethodClass, METHOD_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassPrototypeClass, CLASS_PROTOTYPE_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassConstructorClass, CLASS_CONSTRUCTOR_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, AOTLiteralInfoClass, AOT_LITERAL_INFO_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, VTableClass, VTABLE_CLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ClassLiteralClass, CLASS_LITERAL_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ElementNoneClass, ELEMENT_NONE_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ElementHoleClass, ELEMENT_HOLE_HCLASS_INDEX, ecma_roots_class) \
|
||||
V(JSTaggedValue, ElementIntClass, ELEMENT_INT_HCLASS_INDEX, ecma_roots_class) \
|
||||
@ -144,14 +147,7 @@ class ObjectFactory;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define GLOBAL_ENV_CONSTANT_SPECIAL(V) \
|
||||
V(JSTaggedValue, Undefined, UNDEFINED_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, Null, NULL_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, True, TRUE_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, False, FALSE_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyString, EMPTY_STRING_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyLayoutInfo, EMPTY_LAYOUT_INFO_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyArray, EMPTY_ARRAY_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyMutantArray, EMPTY_MUTANT_ARRAY_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, DefaultSupers, DEFAULT_SUPERS_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyTaggedQueue, EMPTY_TAGGED_QUEUE_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, UndefinedCompletionRecord, UNDEFINED_COMPLRTION_RECORD_INDEX, ecma_roots_special) \
|
||||
@ -187,7 +183,7 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, StringFromCharCode, STRING_FROM_CHAR_CODE_INDEX, ecma_roots_special)
|
||||
|
||||
// All of type JSTaggedValue
|
||||
#define GLOBAL_ENV_CONSTANT_STRING(V) \
|
||||
#define SHARED_GLOBAL_ENV_CONSTANT_STRING(V) \
|
||||
V(ConstructorString, CONSTRUCTOR_STRING_INDEX, "constructor") \
|
||||
V(PrototypeString, PROTOTYPE_STRING_INDEX, "prototype") \
|
||||
V(LengthString, LENGTH_STRING_INDEX, "length") \
|
||||
@ -517,12 +513,24 @@ class ObjectFactory;
|
||||
V(JSTaggedValue, LinkedListIteratorPrototype, LINKED_LIST_ITERATOR_PROTOTYPE_INDEX, LinkedListIterator)
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define GLOBAL_ENV_CONSTANT_ACCESSOR(V) \
|
||||
#define SHARED_GLOBAL_ENV_CONSTANT_ACCESSOR(V) \
|
||||
V(JSTaggedValue, FunctionPrototypeAccessor, FUNCTION_PROTOTYPE_ACCESSOR, ecma_roots_accessor) \
|
||||
V(JSTaggedValue, FunctionNameAccessor, FUNCTION_NAME_ACCESSOR, ecma_roots_accessor) \
|
||||
V(JSTaggedValue, FunctionLengthAccessor, FUNCTION_LENGTH_ACCESSOR, ecma_roots_accessor) \
|
||||
V(JSTaggedValue, ArrayLengthAccessor, ARRAY_LENGTH_ACCESSOR, ecma_roots_accessor)
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define SHARED_GLOBAL_ENV_CONSTANT_SPECIAL(V) \
|
||||
V(JSTaggedValue, Undefined, UNDEFINED_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, Null, NULL_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, True, TRUE_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, False, FALSE_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyString, EMPTY_STRING_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, SingleCharTable, SINGLE_CHAR_TABLE_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptySLayoutInfo, EMPTY_SLAYOUT_INFO_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyArray, EMPTY_ARRAY_OBJECT_INDEX, ecma_roots_special) \
|
||||
V(JSTaggedValue, EmptyMutantArray, EMPTY_MUTANT_ARRAY_OBJECT_INDEX, ecma_roots_special)
|
||||
|
||||
#define GLOBAL_ENV_CACHES(V) \
|
||||
V(JSTaggedValue, CachedJSCollatorLocales, CACHED_JSCOLLATOR_LOCALES_INDEX, cachedCollatorLocales)
|
||||
|
||||
@ -531,16 +539,18 @@ enum class ConstantIndex : size_t {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define INDEX_FILTER_COMMON(Index) Index,
|
||||
#define INDEX_FILTER_WITH_TYPE(Type, Name, Index, Desc) INDEX_FILTER_COMMON(Index)
|
||||
#define INDEX_FILTER_STRING(Name, Index, Token) INDEX_FILTER_COMMON(Index)
|
||||
// Caveats: make sure shareds starts from 0 and placed before non-shareds.
|
||||
SHARED_GLOBAL_ENV_CONSTANT_CLASS(INDEX_FILTER_WITH_TYPE)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_STRING(INDEX_FILTER_STRING)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_ACCESSOR(INDEX_FILTER_WITH_TYPE)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_SPECIAL(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_ACCESSOR(INDEX_FILTER_WITH_TYPE)
|
||||
GLOBAL_ENV_CACHES(INDEX_FILTER_WITH_TYPE)
|
||||
#undef INDEX_FILTER_WITH_TYPE
|
||||
|
||||
#define INDEX_FILTER_STRING(Name, Index, Token) INDEX_FILTER_COMMON(Index)
|
||||
GLOBAL_ENV_CONSTANT_STRING(INDEX_FILTER_STRING)
|
||||
#undef INDEX_FILTER_STRING
|
||||
#undef INDEX_FILTER_WITH_TYPE
|
||||
#undef INDEX_FILTER_COMMON
|
||||
|
||||
CONSTANT_COUNT,
|
||||
@ -548,6 +558,13 @@ enum class ConstantIndex : size_t {
|
||||
CONSTANT_BEGIN = 0,
|
||||
CONSTANT_END = CONSTANT_COUNT,
|
||||
|
||||
SHARED_BEGIN = HCLASS_CLASS_INDEX,
|
||||
SHARED_END = EMPTY_MUTANT_ARRAY_OBJECT_INDEX,
|
||||
|
||||
SHARED_HCLASS_BEGIN = HCLASS_CLASS_INDEX,
|
||||
SHARED_HCLASS_END = VTABLE_CLASS_INDEX,
|
||||
NON_SHARED_HCLASS_BEGIN = JS_PROXY_CALLABLE_CLASS_INDEX,
|
||||
NON_SHARED_HCLASS_END = ELEMENT_HOLE_TAGGED_HCLASS_INDEX,
|
||||
READ_ONLY_CONSTANT_BEGIN = CONSTANT_BEGIN,
|
||||
READ_ONLY_CONSTANT_END = CONSTANT_END,
|
||||
JSAPI_CONTAINERS_BEGIN = ARRAYLIST_FUNCTION_INDEX,
|
||||
@ -569,14 +586,7 @@ public:
|
||||
|
||||
const JSTaggedValue *EndSlot() const;
|
||||
|
||||
void Init(JSThread *thread, JSHClass *hClass);
|
||||
|
||||
void InitRootsClass(JSThread *thread, JSHClass *hClass);
|
||||
void InitGlobalConstantSpecial(JSThread *thread);
|
||||
|
||||
void InitGlobalConstant(JSThread *thread);
|
||||
void InitGlobalCaches();
|
||||
void InitJSAPIContainers();
|
||||
void Init(JSThread *thread);
|
||||
|
||||
void InitSpecialForSnapshot();
|
||||
|
||||
@ -596,19 +606,18 @@ public:
|
||||
const Type Get##Name() const; \
|
||||
const JSHandle<Type> GetHandled##Name() const; \
|
||||
static size_t GetOffsetOf##Name();
|
||||
|
||||
#define DECL_GET_WITH_TYPE(Type, Name, Index, Desc) DECL_GET_COMMON(Type, Name)
|
||||
#define DECL_GET_STRING(Name, Index, Token) DECL_GET_COMMON(JSTaggedValue, Name)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_WITH_TYPE)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_STRING(DECL_GET_STRING)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_ACCESSOR(DECL_GET_WITH_TYPE)
|
||||
SHARED_GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CLASS(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_SPECIAL(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_CONSTANT(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CONSTANT_ACCESSOR(DECL_GET_WITH_TYPE)
|
||||
GLOBAL_ENV_CACHES(DECL_GET_WITH_TYPE)
|
||||
#undef DECL_GET_WITH_TYPE
|
||||
|
||||
#define DECL_GET_STRING(Name, Index, Token) DECL_GET_COMMON(JSTaggedValue, Name)
|
||||
GLOBAL_ENV_CONSTANT_STRING(DECL_GET_STRING)
|
||||
#undef DECL_GET_STRING
|
||||
|
||||
#undef DECL_GET_WITH_TYPE
|
||||
#undef DECL_GET_COMMON
|
||||
|
||||
void VisitRangeSlot(const RootRangeVisitor &visitor)
|
||||
@ -672,6 +681,14 @@ public:
|
||||
JSTaggedValue::TaggedTypeSize() * static_cast<size_t>(ConstantIndex::CONSTANT_COUNT);
|
||||
|
||||
private:
|
||||
void InitSharedStrings(ObjectFactory *factory);
|
||||
void InitSharedRootsClasses(ObjectFactory *factory);
|
||||
void InitSharedMiscellanious(JSThread *thread, ObjectFactory *factory);
|
||||
void InitRootsClasses(ObjectFactory *factory);
|
||||
void InitMiscellanious(JSThread *thread, ObjectFactory *factory);
|
||||
void InitGlobalCaches();
|
||||
void InitJSAPIContainers();
|
||||
|
||||
JSTaggedValue constants_[static_cast<int>(ConstantIndex::CONSTANT_COUNT)]; // NOLINT(modernize-avoid-c-arrays)
|
||||
};
|
||||
STATIC_ASSERT_EQ_ARCH(sizeof(GlobalEnvConstants), GlobalEnvConstants::SizeArch32, GlobalEnvConstants::SizeArch64);
|
||||
|
@ -26,13 +26,8 @@
|
||||
V(JSTaggedValue, ObjectFunctionClass, OBJECT_FUNCTION_CLASS_INDEX) \
|
||||
V(JSTaggedValue, ObjectFunctionPrototype, OBJECT_FUNCTION_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, ObjectFunctionPrototypeClass, OBJECT_FUNCTION_PROTOTYPE_CLASS_INDEX) \
|
||||
V(JSTaggedValue, SObjectFunction, SHARED_OBJECT_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, SObjectFunctionPrototype, SHARED_OBJECT_FUNCTION_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, FunctionFunction, FUNCTION_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, FunctionPrototype, FUNCTION_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, SFunctionFunction, SHARED_FUNCTION_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, SFunctionPrototype, SHARED_FUNCTION_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, SConstructorClass, SHARED_CONSTRUCTOR_CLASS_INDEX) \
|
||||
V(JSTaggedValue, NumberFunction, NUMBER_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, NumberPrototype, NUMBER_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, BigIntFunction, BIGINT_FUNCTION_INDEX) \
|
||||
@ -189,7 +184,6 @@
|
||||
V(JSTaggedValue, FunctionClassWithoutProto, FUNCTION_CLASS_WITHOUT_PROTO) \
|
||||
V(JSTaggedValue, FunctionClassWithoutName, FUNCTION_CLASS_WITHOUT_NAME) \
|
||||
V(JSTaggedValue, BoundFunctionClass, BOUND_FUNCTION_CLASS) \
|
||||
V(JSTaggedValue, SFunctionClassWithoutProto, SHARED_FUNCTION_CLASS_WITHOUT_PROTO) \
|
||||
V(JSTaggedValue, ArgumentsClass, ARGUMENTS_CLASS) \
|
||||
V(JSTaggedValue, ArgumentsCallerAccessor, ARGUMENTS_CALLER_ACCESSOR) \
|
||||
V(JSTaggedValue, ArgumentsCalleeAccessor, ARGUMENTS_CALLEE_ACCESSOR) \
|
||||
@ -215,7 +209,6 @@
|
||||
V(JSTaggedValue, SpecificTypedArrayFunctionClass, SPERCIFIC_TYPED_ARRAY_FUNCTION_CLASS) \
|
||||
V(JSTaggedValue, ConstructorFunctionClass, CONSTRUCTOR_FUNCTION_CLASS) \
|
||||
V(JSTaggedValue, NormalFunctionClass, NORMAL_FUNCTION_CLASS) \
|
||||
V(JSTaggedValue, SNormalFunctionClass, SHARED_NORMAL_FUNCTION_CLASS) \
|
||||
V(JSTaggedValue, JSIntlBoundFunctionClass, JS_INTL_BOUND_FUNCTION_CLASS) \
|
||||
V(JSTaggedValue, NumberFormatLocales, NUMBER_FORMAT_LOCALES_INDEX) \
|
||||
V(JSTaggedValue, DateTimeFormatLocales, DATE_TIMEFORMAT_LOCALES_INDEX) \
|
||||
@ -240,7 +233,18 @@
|
||||
V(JSTaggedValue, IteratorSymbol, ITERATOR_SYMBOL_INDEX) \
|
||||
V(JSTaggedValue, SpeciesSymbol, SPECIES_SYMBOL_INDEX)
|
||||
|
||||
#define GLOBAL_ENV_SHARED_FIELDS(V) \
|
||||
V(JSTaggedValue, SObjectFunction, SHARED_OBJECT_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, SObjectFunctionPrototype, SHARED_OBJECT_FUNCTION_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, SFunctionFunction, SHARED_FUNCTION_FUNCTION_INDEX) \
|
||||
V(JSTaggedValue, SFunctionPrototype, SHARED_FUNCTION_PROTOTYPE_INDEX) \
|
||||
V(JSTaggedValue, SConstructorClass, SHARED_CONSTRUCTOR_CLASS_INDEX) \
|
||||
V(JSTaggedValue, SFunctionClassWithoutProto, SHARED_FUNCTION_CLASS_WITHOUT_PROTO) \
|
||||
V(JSTaggedValue, SFunctionClassWithoutAccessor, SHARED_FUNCTION_CLASS_WITHOUT_ACCESSOR) \
|
||||
V(JSTaggedValue, SNormalFunctionClass, SHARED_NORMAL_FUNCTION_CLASS)
|
||||
|
||||
#define GLOBAL_ENV_FIELDS(V) \
|
||||
GLOBAL_ENV_SHARED_FIELDS(V) \
|
||||
GLOBAL_ENV_COMMON_FIELDS(V) \
|
||||
GLOBAL_ENV_DETECTOR_SYMBOL_FIELDS(V) \
|
||||
GLOBAL_ENV_DETECTOR_FIELDS(V)
|
||||
|
@ -67,7 +67,7 @@ public:
|
||||
using SWholeKindBit = KindBit;
|
||||
static_assert(SKindBit::START_BIT == SWholeKindBit::START_BIT);
|
||||
static_assert(SSharedBit::Mask() || SKindBit::Mask() == KindBit::Mask());
|
||||
using STrackTypeBit = AttrIndexBit::NextField<uint32_t, PropertyAttributes::TRACK_TYPE_NUM>;
|
||||
using SFieldTypeBit = AttrIndexBit::NextField<SharedFieldType, PropertyAttributes::FIELD_TYPE_NUM>;
|
||||
static_assert(static_cast<size_t>(StoreHandlerKind::S_TOTAL_KINDS) <= (1 << STORE_KIND_BIT_LENGTH));
|
||||
|
||||
HandlerBase() = default;
|
||||
@ -78,9 +78,9 @@ public:
|
||||
return AccessorBit::Get(handler);
|
||||
}
|
||||
|
||||
static inline TrackType GetTrackType(uint32_t handler)
|
||||
static inline SharedFieldType GetFieldType(uint32_t handler)
|
||||
{
|
||||
return static_cast<TrackType>(STrackTypeBit::Get(handler));
|
||||
return static_cast<SharedFieldType>(SFieldTypeBit::Get(handler));
|
||||
}
|
||||
|
||||
static inline bool IsNonExist(uint32_t handler)
|
||||
@ -287,9 +287,9 @@ public:
|
||||
SSharedBit::Set<uint32_t>(op.GetReceiver()->IsJSShared(), &handler);
|
||||
TaggedArray *array = TaggedArray::Cast(receiver->GetProperties().GetTaggedObject());
|
||||
if (!array->IsDictionaryMode()) {
|
||||
STrackTypeBit::Set(static_cast<uint32_t>(op.GetAttr().GetTrackType()), &handler);
|
||||
SFieldTypeBit::Set(op.GetAttr().GetSharedFieldType(), &handler);
|
||||
} else {
|
||||
STrackTypeBit::Set(static_cast<uint32_t>(op.GetAttr().GetDictTrackType()), &handler);
|
||||
SFieldTypeBit::Set(op.GetAttr().GetDictSharedFieldType(), &handler);
|
||||
}
|
||||
if (op.IsElement()) {
|
||||
return StoreElement(thread, op.GetReceiver(), handler);
|
||||
@ -384,8 +384,11 @@ public:
|
||||
if (op.IsFound()) {
|
||||
handler->SetHolder(thread, op.GetHolder());
|
||||
}
|
||||
auto result = JSHClass::EnableProtoChangeMarker(thread, hclass);
|
||||
handler->SetProtoCell(thread, result);
|
||||
// ShareToLocal is prohibited
|
||||
if (!hclass->IsJSShared()) {
|
||||
auto result = JSHClass::EnableProtoChangeMarker(thread, hclass);
|
||||
handler->SetProtoCell(thread, result);
|
||||
}
|
||||
return JSHandle<JSTaggedValue>::Cast(handler);
|
||||
}
|
||||
static inline JSHandle<JSTaggedValue> StorePrototype(const JSThread *thread, const ObjectOperator &op,
|
||||
@ -396,8 +399,11 @@ public:
|
||||
JSHandle<JSTaggedValue> handlerInfo = StoreHandler::StoreProperty(thread, op);
|
||||
handler->SetHandlerInfo(thread, handlerInfo);
|
||||
handler->SetHolder(thread, op.GetHolder());
|
||||
auto result = JSHClass::EnableProtoChangeMarker(thread, hclass);
|
||||
handler->SetProtoCell(thread, result);
|
||||
// ShareToLocal is prohibited
|
||||
if (!hclass->IsJSShared()) {
|
||||
auto result = JSHClass::EnableProtoChangeMarker(thread, hclass);
|
||||
handler->SetProtoCell(thread, result);
|
||||
}
|
||||
return JSHandle<JSTaggedValue>::Cast(handler);
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user