diff --git a/ecmascript/compiler/lazy_deopt_dependency.cpp b/ecmascript/compiler/lazy_deopt_dependency.cpp index edad8a570afc98864d3ac20d700f2569cc59d44e..df422ace6cdf42d004cad770c81bcd287c8c125b 100644 --- a/ecmascript/compiler/lazy_deopt_dependency.cpp +++ b/ecmascript/compiler/lazy_deopt_dependency.cpp @@ -136,7 +136,7 @@ bool LazyDeoptAllDependencies::InitializeProtoChainForDependency(JSThread *threa if (receiverHClass->IsCompositeHClass()) { if (receiverHClass->IsString()) { ASSERT(globalEnv != nullptr); - current = globalEnv->GetStringPrototype().GetTaggedValue(); + current = globalEnv->GetStringPrototypeWithBarrier().GetTaggedValue(); holderHClass = nullptr; } else { return false; diff --git a/ecmascript/compiler/ntype_hcr_lowering.cpp b/ecmascript/compiler/ntype_hcr_lowering.cpp index 5ca363a1069bf3f2658e5632954bfe198db39ebb..7a21f2e95d2bfed026375daccb3f6b77ea5bfcbc 100644 --- a/ecmascript/compiler/ntype_hcr_lowering.cpp +++ b/ecmascript/compiler/ntype_hcr_lowering.cpp @@ -227,7 +227,7 @@ GateRef NTypeHCRLowering::NewJSArrayLiteral(GateRef glue, GateRef gate, GateRef GateRef globalEnv = circuit_->GetGlobalEnvCache(); hclass = builder_.GetGlobalEnvValue(VariableType::JS_POINTER(), glue, globalEnv, static_cast(hclassIndex)); - JSHandle arrayFunc(compilationEnv_->GetGlobalEnv()->GetArrayFunction()); + JSHandle arrayFunc(compilationEnv_->GetGlobalEnv()->GetArrayFunctionWithBarrier()); JSTaggedValue protoOrHClass = arrayFunc->GetProtoOrHClass(compilationEnv_->GetHostThread()); JSHClass *arrayHC = JSHClass::Cast(protoOrHClass.GetTaggedObject()); size_t arraySize = arrayHC->GetObjectSize(); diff --git a/ecmascript/compiler/slowpath_lowering.cpp b/ecmascript/compiler/slowpath_lowering.cpp index 30f1e9d82d72248c7798fb5c93f3221d3829359f..5713b21fce8b772d31598cc0ab057058cd69018c 100644 --- a/ecmascript/compiler/slowpath_lowering.cpp +++ b/ecmascript/compiler/slowpath_lowering.cpp @@ -3125,17 +3125,17 @@ bool SlowPathLowering::OptimizeDefineFuncForJit(GateRef gate, GateRef jsFunc, Ga int callTarget = CommonStubCSigns::NUM_OF_STUBS; switch (kind) { case FunctionKind::NORMAL_FUNCTION: { - hclass = compilationEnv_->GetGlobalEnv()->GetFunctionClassWithoutProto(); + hclass = compilationEnv_->GetGlobalEnv()->GetFunctionClassWithoutProtoWithBarrier(); callTarget = CommonStubCSigns::DefineNormalFuncForJit; break; } case FunctionKind::ARROW_FUNCTION: { - hclass = compilationEnv_->GetGlobalEnv()->GetFunctionClassWithoutProto(); + hclass = compilationEnv_->GetGlobalEnv()->GetFunctionClassWithoutProtoWithBarrier(); callTarget = CommonStubCSigns::DefineArrowFuncForJit; break; } case FunctionKind::BASE_CONSTRUCTOR: { - hclass = compilationEnv_->GetGlobalEnv()->GetFunctionClassWithProto(); + hclass = compilationEnv_->GetGlobalEnv()->GetFunctionClassWithProtoWithBarrier(); callTarget = CommonStubCSigns::DefineBaseConstructorForJit; break; } @@ -3689,7 +3689,7 @@ void SlowPathLowering::LowerCallNewBuiltin(GateRef gate) args[i] = acc_.GetValueIn(gate, i); } ASSERT(num >= 3); // 3: skip argc argv newtarget - + GateRef ctor = acc_.GetValueIn(gate, static_cast(CommonArgIdx::FUNC)); if (g_isEnableCMCGC) { diff --git a/ecmascript/compiler/type_info_accessors.cpp b/ecmascript/compiler/type_info_accessors.cpp index 14cf4fc8db2d2b5a9e6c04e660a0c6033003328c..94f4a40c24f047551d309505888579438bda8289 100644 --- a/ecmascript/compiler/type_info_accessors.cpp +++ b/ecmascript/compiler/type_info_accessors.cpp @@ -1118,7 +1118,7 @@ JSTaggedValue InstanceOfTypeInfoAccessor::GetKeyTaggedValue() const { JSHandle globalEnv = compilationEnv_->GetGlobalEnv(); auto hasInstanceEnvIndex = static_cast(GlobalEnvField::HASINSTANCE_SYMBOL_INDEX); - return globalEnv->GetGlobalEnvObjectByIndex(hasInstanceEnvIndex).GetTaggedValue(); + return globalEnv->GetGlobalEnvObjectWithBarrierByIndex(hasInstanceEnvIndex).GetTaggedValue(); } void InstanceOfTypeInfoAccessor::AotAccessorStrategy::FetchPGORWTypesDual() diff --git a/ecmascript/compiler/typed_bytecode_lowering.cpp b/ecmascript/compiler/typed_bytecode_lowering.cpp index 1cc62b7cd2e33ddd9db31de714aa6e3ba5f2f810..7eeab1c00f8ecb6955e2b07b9cf3b9deb330c1a8 100644 --- a/ecmascript/compiler/typed_bytecode_lowering.cpp +++ b/ecmascript/compiler/typed_bytecode_lowering.cpp @@ -1328,7 +1328,7 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForGlobalsId(const LoadBuilt return true; } else if (globalsId.IsGlobalEnvId()) { // ctor Hclass GlobalEnvField index = static_cast(globalsId.GetGlobalEnvId()); - JSHClass *hclass = JSHClass::Cast(compilationEnv_->GetGlobalEnv()->GetGlobalEnvObjectByIndex( + JSHClass *hclass = JSHClass::Cast(compilationEnv_->GetGlobalEnv()->GetGlobalEnvObjectWithBarrierByIndex( static_cast(index))->GetTaggedObject()); PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinHClass(compilationEnv_->GetJSThread(), hclass, key); if (!plr.IsFound() || plr.IsAccessor()) { @@ -1363,7 +1363,7 @@ bool TypedBytecodeLowering::TryLowerTypedLdobjBynameFromGloablBuiltin(GateRef ga uint64_t index = acc_.TryGetValue(receiver); BuiltinType type = static_cast(index); if (type == BuiltinType::BT_MATH) { - auto math = globalEnv->GetMathFunction(); + auto math = globalEnv->GetMathFunctionWithBarrier(); JSHClass *hclass = math.GetTaggedValue().GetTaggedObject()->GetClass(); JSTaggedValue key = tacc.GetKeyTaggedValue(); if (key.IsUndefined()) { @@ -1454,7 +1454,8 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltinMethod(const LoadB } size_t protoFieldIndex = static_cast(*protoField); JSHandle globalEnv = compilationEnv_->GetGlobalEnv(); - JSHClass *prototypeHClass = globalEnv->GetGlobalEnvObjectByIndex(protoFieldIndex)->GetTaggedObject()->GetClass(); + JSHClass *prototypeHClass = + globalEnv->GetGlobalEnvObjectWithBarrierByIndex(protoFieldIndex)->GetTaggedObject()->GetClass(); PropertyLookupResult plr = JSHClass::LookupPropertyInBuiltinPrototypeHClass(compilationEnv_->GetJSThread(), prototypeHClass, key); bool isPrototypeOfPrototype = false; @@ -1466,7 +1467,8 @@ bool TypedBytecodeLowering::TryLowerTypedLdObjByNameForBuiltinMethod(const LoadB return false; } protoFieldIndex = static_cast(*protoField); - prototypeHClass = globalEnv->GetGlobalEnvObjectByIndex(protoFieldIndex)->GetTaggedObject()->GetClass(); + prototypeHClass = + globalEnv->GetGlobalEnvObjectWithBarrierByIndex(protoFieldIndex)->GetTaggedObject()->GetClass(); plr = JSHClass::LookupPropertyInBuiltinPrototypeHClass(compilationEnv_->GetJSThread(), prototypeHClass, key); if (!plr.IsFound() || plr.IsAccessor()) { @@ -2825,7 +2827,7 @@ void TypedBytecodeLowering::LowerCreateEmptyObject(GateRef gate) GateRef globalEnv = circuit_->GetGlobalEnvCache(); GateRef hclass = builder_.GetGlobalEnvObjHClass(globalEnv, GlobalEnv::OBJECT_FUNCTION_INDEX); - JSHandle objectFunc(compilationEnv_->GetGlobalEnv()->GetObjectFunction()); + JSHandle objectFunc(compilationEnv_->GetGlobalEnv()->GetObjectFunctionWithBarrier()); JSTaggedValue protoOrHClass = objectFunc->GetProtoOrHClass(compilationEnv_->GetJSThread()); JSHClass *objectHC = JSHClass::Cast(protoOrHClass.GetTaggedObject()); size_t objectSize = objectHC->GetObjectSize(); diff --git a/ecmascript/compiler/typed_native_inline_lowering.cpp b/ecmascript/compiler/typed_native_inline_lowering.cpp index 9f8caa9b88548dfb3c7da8b7cbf963c6e4204e08..bd2b0be290ef52bad81a19edb0056979fb0de0c7 100644 --- a/ecmascript/compiler/typed_native_inline_lowering.cpp +++ b/ecmascript/compiler/typed_native_inline_lowering.cpp @@ -1116,7 +1116,7 @@ GateRef AllocateNewNumber(GateRef glue, const CompilationEnv *compilationEnv, Ci GateRef protoOrHclass, GateRef result) { Jit::JitLockHolder lock(compilationEnv, "AllocateNewNumber"); - JSHandle numberFunctionCT(compilationEnv->GetGlobalEnv()->GetNumberFunction()); + JSHandle numberFunctionCT(compilationEnv->GetGlobalEnv()->GetNumberFunctionWithBarrier()); JSTaggedValue protoOrHClassCT = numberFunctionCT->GetProtoOrHClass(compilationEnv->GetJSThread()); JSHClass *numberHClassCT = JSHClass::Cast(protoOrHClassCT.GetTaggedObject()); size_t objectSize = numberHClassCT->GetObjectSize(); diff --git a/ecmascript/global_env.h b/ecmascript/global_env.h index afb6094b8cde1547878fd3961c08a2226880aa50..1697837721a12299af3a7ead00e5a50304d68caf 100644 --- a/ecmascript/global_env.h +++ b/ecmascript/global_env.h @@ -68,6 +68,20 @@ public: return result; } + JSHandle GetGlobalEnvObjectWithBarrierByIndex(size_t index) const + { + ASSERT(index < FINAL_INDEX); + uintptr_t address = ComputeObjectAddress(index); + if (g_isEnableCMCGC) { + JSTaggedValue value(reinterpret_cast( + common::BaseRuntime::ReadBarrier(reinterpret_cast(address)))); + *reinterpret_cast(address) = value; + } + + JSHandle result(address); + return result; + } + JSHandle GetNoLazyEnvObjectByIndex(size_t index) const { JSHandle result = GetGlobalEnvObjectByIndex(index); @@ -228,6 +242,24 @@ public: } \ return result; \ } \ + inline JSHandle Get##name##WithBarrier() const \ + { \ + /* every GLOBAL_ENV_FIELD is JSTaggedValue */ \ + size_t offset = HEADER_SIZE + (index)*JSTaggedValue::TaggedTypeSize(); \ + const uintptr_t address = reinterpret_cast(this) + offset; \ + if (g_isEnableCMCGC) { \ + JSTaggedValue value(reinterpret_cast( \ + common::BaseRuntime::ReadBarrier(reinterpret_cast(address)))); \ + *reinterpret_cast(address) = value; \ + } \ + JSHandle result(address); \ + if (result.GetTaggedValue().IsInternalAccessor()) { \ + JSThread *thread = GetJSThread(); \ + AccessorData *accessor = AccessorData::Cast(result.GetTaggedValue().GetTaggedObject()); \ + accessor->CallInternalGet(thread, JSHandle::Cast(GetJSGlobalObject())); \ + } \ + return result; \ + } \ inline JSTaggedValue GetTagged##name() const \ { \ uint32_t offset = HEADER_SIZE + index * JSTaggedValue::TaggedTypeSize(); \ @@ -292,7 +324,7 @@ public: return nullptr; } auto index = static_cast(buildinTypedArrayHClassIndex); - JSHandle result = GetGlobalEnvObjectByIndex(index); + JSHandle result = GetGlobalEnvObjectWithBarrierByIndex(index); return reinterpret_cast(result->GetRawData()); } diff --git a/ecmascript/jit/jit_profiler.cpp b/ecmascript/jit/jit_profiler.cpp index c2809e9608d031f90fe65ad2e8f62edef6c42313..4d39ad55d62753313d526baa58e674428afa8be8 100644 --- a/ecmascript/jit/jit_profiler.cpp +++ b/ecmascript/jit/jit_profiler.cpp @@ -915,9 +915,9 @@ void JITProfiler::ConvertInstanceof(int32_t bcOffset, uint32_t slotId) if (object->GetClass()->IsHClass()) { JSHClass *hclass = JSHClass::Cast(object); // Since pgo does not support symbol, we choose to return if hclass having @@hasInstance - JSTaggedValue key = GetCurrentGlobalEnv()->GetHasInstanceSymbol().GetTaggedValue(); + JSTaggedValue key = GetCurrentGlobalEnv()->GetHasInstanceSymbolWithBarrier().GetTaggedValue(); JSHClass *functionPrototypeHC = - JSObject::Cast(GetCurrentGlobalEnv()->GetFunctionPrototype().GetTaggedValue())->GetClass(); + JSObject::Cast(GetCurrentGlobalEnv()->GetFunctionPrototypeWithBarrier().GetTaggedValue())->GetClass(); JSTaggedValue foundHClass = TryFindKeyInPrototypeChain(object, hclass, key); if (!foundHClass.IsUndefined() && JSHClass::Cast(foundHClass.GetTaggedObject()) != functionPrototypeHC) { return; @@ -1108,8 +1108,7 @@ bool JITProfiler::AddBuiltinsInfoByNameInInstance(ApEntityId abcId, int32_t bcOf if (builtinsId == BuiltinTypeId::ARRAY) { bool receiverIsPrototype = receiver->IsPrototype(); exceptRecvHClass = mainThread_->GetArrayInstanceHClass(GetCurrentGlobalEnv(), - receiver->GetElementsKind(), - receiverIsPrototype); + receiver->GetElementsKind(), receiverIsPrototype, JSThread::ThreadKind::JitThread); } else if (builtinsId == BuiltinTypeId::STRING) { exceptRecvHClass = receiver; } else { @@ -1120,8 +1119,8 @@ bool JITProfiler::AddBuiltinsInfoByNameInInstance(ApEntityId abcId, int32_t bcOf // When JSType cannot uniquely identify builtins object, it is necessary to // query the receiver on the global constants. if (builtinsId == BuiltinTypeId::OBJECT) { - exceptRecvHClass = - JSHClass::Cast(GetCurrentGlobalEnv()->GetIteratorResultClass().GetTaggedValue().GetTaggedObject()); + exceptRecvHClass = JSHClass::Cast( + GetCurrentGlobalEnv()->GetIteratorResultClassWithBarrier().GetTaggedValue().GetTaggedObject()); if (exceptRecvHClass == receiver) { GlobalIndex globalsId; globalsId.UpdateGlobalEnvId(static_cast(GlobalEnvField::ITERATOR_RESULT_CLASS_INDEX)); @@ -1155,8 +1154,7 @@ bool JITProfiler::AddBuiltinsInfoByNameInProt(ApEntityId abcId, int32_t bcOffset if (builtinsId == BuiltinTypeId::ARRAY) { bool receiverIsPrototype = receiver->IsPrototype(); exceptRecvHClass = mainThread_->GetArrayInstanceHClass(GetCurrentGlobalEnv(), - receiver->GetElementsKind(), - receiverIsPrototype); + receiver->GetElementsKind(), receiverIsPrototype, JSThread::ThreadKind::JitThread); } else if (builtinsId == BuiltinTypeId::STRING) { exceptRecvHClass = receiver; } else { diff --git a/ecmascript/js_thread.cpp b/ecmascript/js_thread.cpp index 93fdff6b70ea2969d595ef3030e3dbad81552f54..1840dbd085c4d9102cceaae4fb66ed1d1eff41f6 100644 --- a/ecmascript/js_thread.cpp +++ b/ecmascript/js_thread.cpp @@ -1507,14 +1507,20 @@ void JSThread::SetMutatorLockState(MutatorLock::MutatorLockState newState) JSHClass *JSThread::GetArrayInstanceHClass(ElementsKind kind, bool isPrototype) const { JSHandle env = GetGlobalEnv(); - return GetArrayInstanceHClass(env, kind, isPrototype); + return GetArrayInstanceHClass(env, kind, isPrototype, JSThread::ThreadKind::OtherThread); } -JSHClass *JSThread::GetArrayInstanceHClass(JSHandle env, ElementsKind kind, bool isPrototype) const +JSHClass *JSThread::GetArrayInstanceHClass(JSHandle env, ElementsKind kind, + bool isPrototype, ThreadKind threadKind) const { GlobalEnvField index = glueData_.arrayHClassIndexes_.GetArrayInstanceHClassIndex(kind, isPrototype); - auto exceptArrayHClass = env->GetGlobalEnvObjectByIndex(static_cast(index)).GetTaggedValue(); - auto exceptRecvHClass = JSHClass::Cast(exceptArrayHClass.GetTaggedObject()); + JSHandle exceptArrayHClassHandle; + if (threadKind == JSThread::ThreadKind::JitThread) { + exceptArrayHClassHandle = env->GetGlobalEnvObjectWithBarrierByIndex(static_cast(index)); + } else { + exceptArrayHClassHandle = env->GetGlobalEnvObjectByIndex(static_cast(index)); + } + auto exceptRecvHClass = JSHClass::Cast(exceptArrayHClassHandle.GetTaggedValue().GetTaggedObject()); ASSERT(exceptRecvHClass->IsJSArray()); return exceptRecvHClass; } diff --git a/ecmascript/js_thread.h b/ecmascript/js_thread.h index 408779420d267f1bea71fb12285f2b196129c775..10251954e3f8a3dbfc0ec00598aec594415879f5 100644 --- a/ecmascript/js_thread.h +++ b/ecmascript/js_thread.h @@ -201,6 +201,11 @@ public: SwitchToMainStackInfo, }; + enum class ThreadKind { + JitThread = 0, + OtherThread + }; + struct StackInfo { uint64_t stackLimit; uint64_t lastLeaveFrame; @@ -409,7 +414,8 @@ public: JSHClass *GetBuiltinExtraHClass(BuiltinTypeId type) const; JSHClass *GetArrayInstanceHClass(ElementsKind kind, bool isPrototype) const; - JSHClass *GetArrayInstanceHClass(JSHandle env, ElementsKind kind, bool isPrototype) const; + JSHClass *GetArrayInstanceHClass(JSHandle env, ElementsKind kind, + bool isPrototype, ThreadKind threadKind) const; GlobalEnvField GetArrayInstanceHClassIndex(ElementsKind kind, bool isPrototype) const { diff --git a/ecmascript/pgo_profiler/pgo_profiler.cpp b/ecmascript/pgo_profiler/pgo_profiler.cpp index ba68c4b4f62d590265d49d8c40fb2252029b1f77..8e9dda3c6f1ddeff0dc3d0c621ed0abfc1990ffa 100644 --- a/ecmascript/pgo_profiler/pgo_profiler.cpp +++ b/ecmascript/pgo_profiler/pgo_profiler.cpp @@ -1681,7 +1681,7 @@ bool PGOProfiler::AddBuiltinsInfoByNameInInstance(ApEntityId abcId, const CStrin if (builtinsId == BuiltinTypeId::ARRAY) { bool receiverIsPrototype = receiver->IsPrototype(); exceptRecvHClass = thread->GetArrayInstanceHClass(GetCurrentGlobalEnv(), receiver->GetElementsKind(), - receiverIsPrototype); + receiverIsPrototype, JSThread::ThreadKind::OtherThread); } else if (builtinsId == BuiltinTypeId::STRING) { exceptRecvHClass = receiver; } else { @@ -1720,7 +1720,7 @@ bool PGOProfiler::AddBuiltinsInfoByNameInProt(ApEntityId abcId, const CString &r if (builtinsId == BuiltinTypeId::ARRAY) { bool receiverIsPrototype = receiver->IsPrototype(); exceptRecvHClass = thread->GetArrayInstanceHClass(GetCurrentGlobalEnv(), receiver->GetElementsKind(), - receiverIsPrototype); + receiverIsPrototype, JSThread::ThreadKind::OtherThread); } else if (builtinsId == BuiltinTypeId::STRING) { exceptRecvHClass = receiver; } else {