From beeaf68c740702129808dc41355d88afd129e243 Mon Sep 17 00:00:00 2001 From: luobinghao Date: Tue, 9 Sep 2025 10:25:35 +0800 Subject: [PATCH] [bugfix]: fix aot crash Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/ICX1NZ Signed-off-by: luobinghao Change-Id: Idce62dfb804681d4e1cca6522b5c9f7730c23e73 --- ecmascript/compiler/circuit_builder.cpp | 27 ++++++++++++++++++++++++- ecmascript/compiler/circuit_builder.h | 1 + ecmascript/compiler/stub_builder.cpp | 5 +++++ ecmascript/compiler/stub_builder.h | 1 + ecmascript/ecma_vm.cpp | 23 +++++++++++++-------- ecmascript/ecma_vm.h | 1 + ecmascript/stubs/runtime_stub_list.h | 1 + ecmascript/stubs/runtime_stubs.cpp | 9 +++++++++ 8 files changed, 59 insertions(+), 9 deletions(-) diff --git a/ecmascript/compiler/circuit_builder.cpp b/ecmascript/compiler/circuit_builder.cpp index 9b591c8091..5a6c5d2ff7 100644 --- a/ecmascript/compiler/circuit_builder.cpp +++ b/ecmascript/compiler/circuit_builder.cpp @@ -644,6 +644,11 @@ GateRef CircuitBuilder::GetConstPoolFromFunction(GateRef glue, GateRef jsFunc) return Load(VariableType::JS_ANY(), glue, method, IntPtr(Method::CONSTANT_POOL_OFFSET)); } +GateRef CircuitBuilder::GetSharedConstpoolFromMethod(GateRef glue, GateRef method) +{ + return Load(VariableType::JS_ANY(), glue, method, IntPtr(Method::CONSTANT_POOL_OFFSET)); +} + GateRef CircuitBuilder::GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool) { Label entryPass(env_); @@ -1020,17 +1025,37 @@ GateRef CircuitBuilder::GetObjectFromConstPool(GateRef glue, GateRef hirGate, Ga if (type == ConstPoolType::METHOD) { Label isHeapObj(env_); Label checkInteger(env_); + Label checkCalleeUnsharedConstpool(env_); + Label checkCalleeUnsharedConstpoolNotHole(env_); + Label initCalleeUnsharedConstpool(env_); BRANCH(TaggedIsHeapObject(*result), &isHeapObj, &checkInteger); Bind(&isHeapObj); { Label isAOTLiteralInfo(env_); - BRANCH(IsAOTLiteralInfo(glue, *result), &isAOTLiteralInfo, &exit); + BRANCH(IsAOTLiteralInfo(glue, *result), &isAOTLiteralInfo, &checkCalleeUnsharedConstpool); Bind(&isAOTLiteralInfo); { result = CallRuntime(glue, RTSTUB_ID(GetMethodFromCache), Gate::InvalidGateRef, { sharedConstPool, Int32ToTaggedInt(index) }, hirGate); Jump(&exit); } + Bind(&checkCalleeUnsharedConstpool); + { + GateRef calleeSharedConstpool = GetSharedConstpoolFromMethod(glue, *result); + BRANCH_LIKELY(Equal(calleeSharedConstpool, sharedConstPool), &exit, + &checkCalleeUnsharedConstpoolNotHole); + { + Bind(&checkCalleeUnsharedConstpoolNotHole); + BRANCH(TaggedIsHole(GetUnsharedConstpoolFromGlue(glue, calleeSharedConstpool)), + &initCalleeUnsharedConstpool, &exit); + Bind(&initCalleeUnsharedConstpool); + { + CallRuntime(glue, RTSTUB_ID(CreateUnsharedConstpool), Gate::InvalidGateRef, + {calleeSharedConstpool}, hirGate); + Jump(&exit); + } + } + } } Bind(&checkInteger); { diff --git a/ecmascript/compiler/circuit_builder.h b/ecmascript/compiler/circuit_builder.h index 8a20ae7053..1484f4294b 100644 --- a/ecmascript/compiler/circuit_builder.h +++ b/ecmascript/compiler/circuit_builder.h @@ -334,6 +334,7 @@ public: // Get GateRef GetConstPoolFromFunction(GateRef glue, GateRef jsFunc); + GateRef GetSharedConstpoolFromMethod(GateRef glue, GateRef method); GateRef GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool); GateRef GetUnsharedConstpoolIndex(GateRef glue, GateRef constpool); GateRef GetUnsharedConstpool(GateRef glue, GateRef arrayAddr, GateRef index); diff --git a/ecmascript/compiler/stub_builder.cpp b/ecmascript/compiler/stub_builder.cpp index e057b09874..761c77392c 100644 --- a/ecmascript/compiler/stub_builder.cpp +++ b/ecmascript/compiler/stub_builder.cpp @@ -8803,6 +8803,11 @@ GateRef StubBuilder::GetConstPoolFromFunction(GateRef glue, GateRef jsFunc) return env_->GetBuilder()->GetConstPoolFromFunction(glue, jsFunc); } +GateRef StubBuilder::GetSharedConstpoolFromMethod(GateRef glue, GateRef method) +{ + return env_->GetBuilder()->GetSharedConstpoolFromMethod(glue, method); +} + GateRef StubBuilder::GetStringFromConstPool(GateRef glue, GateRef constpool, GateRef index) { GateRef module = Circuit::NullGate(); diff --git a/ecmascript/compiler/stub_builder.h b/ecmascript/compiler/stub_builder.h index 859a205a52..52d3c94d46 100644 --- a/ecmascript/compiler/stub_builder.h +++ b/ecmascript/compiler/stub_builder.h @@ -979,6 +979,7 @@ public: inline GateRef GetObjectFromConstPool(GateRef glue, GateRef constpool, GateRef index); GateRef GetConstPoolFromFunction(GateRef glue, GateRef jsFunc); + GateRef GetSharedConstpoolFromMethod(GateRef glue, GateRef method); GateRef GetStringFromConstPool(GateRef glue, GateRef constpool, GateRef index); GateRef GetMethodFromConstPool(GateRef glue, GateRef constpool, GateRef index); GateRef GetArrayLiteralFromConstPool(GateRef glue, GateRef constpool, GateRef index, GateRef module); diff --git a/ecmascript/ecma_vm.cpp b/ecmascript/ecma_vm.cpp index b8fa05a65b..dd0bc60002 100644 --- a/ecmascript/ecma_vm.cpp +++ b/ecmascript/ecma_vm.cpp @@ -1663,18 +1663,25 @@ JSTaggedValue EcmaVM::FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpoo { JSTaggedValue unsharedConstpool = FindUnsharedConstpool(sharedConstpool); if (unsharedConstpool.IsHole()) { - ConstantPool *shareCp = ConstantPool::Cast(sharedConstpool.GetTaggedObject()); - int32_t constpoolIndex = shareCp->GetUnsharedConstpoolIndex(); - // unshared constpool index is default INT32_MAX. - ASSERT(0 <= constpoolIndex && constpoolIndex != INT32_MAX); - JSHandle unshareCp = ConstantPool::CreateUnSharedConstPoolBySharedConstpool( - thread_->GetEcmaVM(), shareCp->GetJSPandaFile(), shareCp); - unsharedConstpool = unshareCp.GetTaggedValue(); - SetUnsharedConstpool(constpoolIndex, unsharedConstpool); + return CreateUnsharedConstpool(sharedConstpool); } return unsharedConstpool; } +JSTaggedValue EcmaVM::CreateUnsharedConstpool(JSTaggedValue sharedConstpool) +{ + JSTaggedValue unsharedConstpool = JSTaggedValue::Hole(); + ConstantPool *shareCp = ConstantPool::Cast(sharedConstpool.GetTaggedObject()); + int32_t constpoolIndex = shareCp->GetUnsharedConstpoolIndex(); + // unshared constpool index is default INT32_MAX. + ASSERT(0 <= constpoolIndex && constpoolIndex != INT32_MAX); + JSHandle unshareCp = ConstantPool::CreateUnSharedConstPoolBySharedConstpool( + thread_->GetEcmaVM(), shareCp->GetJSPandaFile(), shareCp); + unsharedConstpool = unshareCp.GetTaggedValue(); + SetUnsharedConstpool(constpoolIndex, unsharedConstpool); + return unsharedConstpool; +} + void EcmaVM::EraseUnusedConstpool(const JSPandaFile *jsPandaFile, int32_t index, int32_t constpoolIndex) { // unshared constpool index is default INT32_MAX. diff --git a/ecmascript/ecma_vm.h b/ecmascript/ecma_vm.h index 5b44292f67..f7eaf4961f 100644 --- a/ecmascript/ecma_vm.h +++ b/ecmascript/ecma_vm.h @@ -1177,6 +1177,7 @@ public: } JSTaggedValue PUBLIC_API FindUnsharedConstpool(JSTaggedValue sharedConstpool); JSTaggedValue PUBLIC_API FindOrCreateUnsharedConstpool(JSTaggedValue sharedConstpool); + JSTaggedValue PUBLIC_API CreateUnsharedConstpool(JSTaggedValue sharedConstpool); void EraseUnusedConstpool(const JSPandaFile *jsPandaFile, int32_t index, int32_t constpoolIndex); JSTaggedValue PUBLIC_API FindConstpool(const JSPandaFile *jsPandaFile, int32_t index); // For new version instruction. diff --git a/ecmascript/stubs/runtime_stub_list.h b/ecmascript/stubs/runtime_stub_list.h index f9dcd9c4f0..b872540b89 100644 --- a/ecmascript/stubs/runtime_stub_list.h +++ b/ecmascript/stubs/runtime_stub_list.h @@ -516,6 +516,7 @@ namespace panda::ecmascript { V(GetArrayLiteralFromCache) \ V(GetObjectLiteralFromCache) \ V(GetStringFromCache) \ + V(CreateUnsharedConstpool) \ V(BigIntEqual) \ V(StringEqual) \ V(StringIndexOf) \ diff --git a/ecmascript/stubs/runtime_stubs.cpp b/ecmascript/stubs/runtime_stubs.cpp index a4b7e002af..fb3b00da2c 100644 --- a/ecmascript/stubs/runtime_stubs.cpp +++ b/ecmascript/stubs/runtime_stubs.cpp @@ -1383,6 +1383,15 @@ DEF_RUNTIME_STUBS(GetArrayLiteralFromCache) thread, cp, index.GetInt(), module.GetTaggedValue()).GetRawData(); } +DEF_RUNTIME_STUBS(CreateUnsharedConstpool) +{ + RUNTIME_STUBS_HEADER(CreateUnsharedConstpool); + JSHandle sharedConstpool = GetHArg(argv, argc, 0); // 0: means the first parameter + ASSERT(thread->GetEcmaVM()->FindUnsharedConstpool(sharedConstpool.GetTaggedValue()).IsHole()); + thread->GetEcmaVM()->CreateUnsharedConstpool(sharedConstpool.GetTaggedValue()); + return JSTaggedValue::Undefined().GetRawData(); +} + DEF_RUNTIME_STUBS(StObjByValue) { RUNTIME_STUBS_HEADER(StObjByValue); -- Gitee