!6522 Sendable class

Merge pull request !6522 from Gymee/dev_shareheap
This commit is contained in:
openharmony_ci 2024-03-20 05:34:17 +00:00 committed by Gitee
commit d1ad59c7dc
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
304 changed files with 10986 additions and 3325 deletions

View File

@ -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",

View File

@ -47,6 +47,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -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);

View File

@ -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;

View File

@ -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),

View File

@ -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);

View 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

View File

@ -49,6 +49,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -49,6 +49,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -52,6 +52,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -52,6 +52,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -46,6 +46,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -47,6 +47,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -51,6 +51,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -48,6 +48,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -48,6 +48,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -47,6 +47,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -48,6 +48,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -47,6 +47,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -47,6 +47,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -48,6 +48,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View File

@ -56,6 +56,7 @@ public:
instance->SetEnableForceGC(true);
ASSERT_TRUE(instance != nullptr) << "Cannot create EcmaVM";
thread = instance->GetJSThread();
thread->ManagedCodeBegin();
scope = new EcmaHandleScope(thread);
}

View 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

View File

@ -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) \

View File

@ -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;

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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};

View File

@ -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)
{

View File

@ -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};

View File

@ -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) \

View File

@ -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, &notIndex);
Bind(&isIndex);
{

View File

@ -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));

View File

@ -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

View File

@ -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) \

View File

@ -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)

View File

@ -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);

View File

@ -991,7 +991,7 @@ void JsProxyCallInternalStubBuilder::GenerateCircuit()
BRANCH(IsClassConstructor(method), &slowPath1, &notCallConstructor1);
Bind(&notCallConstructor1);
GateRef meth = GetMethodFromFunction(method);
GateRef code = GetAotCodeAddr(meth);
GateRef code = GetAotCodeAddr(method);
BRANCH(JudgeAotAndFastCallWithMethod(meth, CircuitBuilder::JudgeMethodType::HAS_AOT_FASTCALL),
&fastCall1, &notFastCall1);
Bind(&fastCall1);

View File

@ -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)
{

View File

@ -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,

View File

@ -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, &notException);
Bind(&notException);
@ -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, &notException);
Bind(&notException);
@ -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, &notException);
Bind(&notException);
@ -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, &notException);
Bind(&notException);
@ -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, &notException);
Bind(&notException);
{
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, &notException);
Bind(&notException);
{
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)

View File

@ -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);

View File

@ -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:

View File

@ -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;

View File

@ -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_);

View File

@ -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);

View File

@ -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) \

View File

@ -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, &notException);
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_,

View File

@ -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()};

View File

@ -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());

View File

@ -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};

View File

@ -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_);

View File

@ -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;

View File

@ -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);

View File

@ -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) \

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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, &notMatch);
{
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, &notValidIndex);
@ -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, &notShared);
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), &notFind, &find);
Bind(&notFind);
{
@ -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(&notDicMode);
{
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, &notAccessor);
@ -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), &notFind, &find);
Bind(&notFind);
{
@ -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), &notFind, &find);
Bind(&notFind);
{
@ -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];

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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));

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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 __

View File

@ -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);
}

View File

@ -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, &notProto,
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);
}

View File

@ -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;
}

View File

@ -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));
}
}
}

View File

@ -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};

View File

@ -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)
{

View File

@ -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

View File

@ -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

View File

@ -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) {

View File

@ -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;

View File

@ -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());

View File

@ -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>(&regexpCache_)));
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&regexpGlobal_)));
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>(&microJobQueue_)));
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&pointerToIndexDictionary_)));
if (!regexpCache_.IsHole()) {
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&regexpCache_)));
}
if (!regexpGlobal_.IsHole()) {
v(Root::ROOT_VM, ObjectSlot(reinterpret_cast<uintptr_t>(&regexpGlobal_)));
}
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>(&microJobQueue_)));
}
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)

View File

@ -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_ {};

View File

@ -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()

View File

@ -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();
}

View File

@ -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);

View File

@ -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()) {

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_;

View File

@ -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

View File

@ -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
{

View File

@ -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,

View File

@ -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());

View File

@ -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

View File

@ -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()

View File

@ -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);

View File

@ -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)

View File

@ -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