From 4301fe29c4514d0d1d3e0642426a6fc748d2fdd9 Mon Sep 17 00:00:00 2001 From: w00443755 Date: Fri, 5 Sep 2025 15:37:45 +0800 Subject: [PATCH] Bugfix for JIT getting global env object Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICWLEQ Change-Id: If8c82163541c96e26a7c1ac59222f735f9afd0e1 Signed-off-by: w00443755 --- ecmascript/compiler/lazy_deopt_dependency.cpp | 2 +- ecmascript/compiler/ntype_hcr_lowering.cpp | 2 +- ecmascript/compiler/slowpath_lowering.cpp | 8 ++--- ecmascript/compiler/type_info_accessors.cpp | 2 +- .../compiler/typed_bytecode_lowering.cpp | 12 ++++---- .../compiler/typed_native_inline_lowering.cpp | 2 +- ecmascript/global_env.h | 29 ++++++++++++++++++- ecmascript/jit/jit_profiler.cpp | 14 ++++----- ecmascript/js_thread.cpp | 14 ++++++--- ecmascript/js_thread.h | 3 +- ecmascript/pgo_profiler/pgo_profiler.cpp | 8 ++--- 11 files changed, 65 insertions(+), 31 deletions(-) diff --git a/ecmascript/compiler/lazy_deopt_dependency.cpp b/ecmascript/compiler/lazy_deopt_dependency.cpp index edad8a570a..df422ace6c 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 5ca363a106..7a21f2e95d 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 30f1e9d82d..5713b21fce 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 14cf4fc8db..94f4a40c24 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 1cc62b7cd2..7eeab1c00f 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 9f8caa9b88..bd2b0be290 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 afb6094b8c..6ea1fc2b40 100644 --- a/ecmascript/global_env.h +++ b/ecmascript/global_env.h @@ -68,6 +68,17 @@ public: return result; } + JSHandle GetGlobalEnvObjectWithBarrierByIndex(size_t index) const + { + ASSERT(index < FINAL_INDEX); + uintptr_t address = ComputeObjectAddress(index); + 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 +239,22 @@ 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; \ + 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 +319,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 c2809e9608..b1e05ef5b5 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, true); } 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, true); } else if (builtinsId == BuiltinTypeId::STRING) { exceptRecvHClass = receiver; } else { diff --git a/ecmascript/js_thread.cpp b/ecmascript/js_thread.cpp index 93fdff6b70..f388a6b0d2 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, false); } -JSHClass *JSThread::GetArrayInstanceHClass(JSHandle env, ElementsKind kind, bool isPrototype) const +JSHClass *JSThread::GetArrayInstanceHClass(JSHandle env, ElementsKind kind, + bool isPrototype, bool needBarrier) 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 (needBarrier) { + 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 408779420d..d072bf8e02 100644 --- a/ecmascript/js_thread.h +++ b/ecmascript/js_thread.h @@ -409,7 +409,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, bool needBarrier) 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 ba68c4b4f6..a289e8db41 100644 --- a/ecmascript/pgo_profiler/pgo_profiler.cpp +++ b/ecmascript/pgo_profiler/pgo_profiler.cpp @@ -1680,8 +1680,8 @@ bool PGOProfiler::AddBuiltinsInfoByNameInInstance(ApEntityId abcId, const CStrin JSHClass *exceptRecvHClass = nullptr; if (builtinsId == BuiltinTypeId::ARRAY) { bool receiverIsPrototype = receiver->IsPrototype(); - exceptRecvHClass = thread->GetArrayInstanceHClass(GetCurrentGlobalEnv(), receiver->GetElementsKind(), - receiverIsPrototype); + exceptRecvHClass = thread->GetArrayInstanceHClass( + GetCurrentGlobalEnv(), receiver->GetElementsKind(), receiverIsPrototype, false); } else if (builtinsId == BuiltinTypeId::STRING) { exceptRecvHClass = receiver; } else { @@ -1719,8 +1719,8 @@ bool PGOProfiler::AddBuiltinsInfoByNameInProt(ApEntityId abcId, const CString &r JSHClass *exceptRecvHClass = nullptr; if (builtinsId == BuiltinTypeId::ARRAY) { bool receiverIsPrototype = receiver->IsPrototype(); - exceptRecvHClass = thread->GetArrayInstanceHClass(GetCurrentGlobalEnv(), receiver->GetElementsKind(), - receiverIsPrototype); + exceptRecvHClass = thread->GetArrayInstanceHClass( + GetCurrentGlobalEnv(), receiver->GetElementsKind(), receiverIsPrototype, false); } else if (builtinsId == BuiltinTypeId::STRING) { exceptRecvHClass = receiver; } else { -- Gitee