[bug]: fix worker thread deopt

Fix worker thread deopt

Issue:               https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/IAGZ5G
Signed-off-by: luobinghao <luobinghao@huawei.com>
This commit is contained in:
luobinghao 2024-08-11 21:47:33 +08:00
parent 831eb9d630
commit 8aafba29a8
7 changed files with 55 additions and 32 deletions

View File

@ -2310,6 +2310,11 @@ inline GateRef StubBuilder::GetUnsharedConstpoolIndex(GateRef constpool)
return GetValueFromTaggedArray(constpool, unshareIdx);
}
inline GateRef StubBuilder::GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool)
{
return env_->GetBuilder()->GetUnsharedConstpoolFromGlue(glue, constpool);
}
inline GateRef StubBuilder::GetUnsharedConstpool(GateRef arrayAddr, GateRef index)
{
GateRef dataOffset =

View File

@ -9940,25 +9940,29 @@ GateRef StubBuilder::DefineFunc(GateRef glue, GateRef constpool, GateRef index,
DEFVARIABLE(val, VariableType::JS_ANY(), Undefined());
DEFVARIABLE(result, VariableType::JS_ANY(), Undefined());
val = GetValueFromTaggedArray(constpool, index);
Label isHeapObject(env);
Label afterAOTLiteral(env);
BRANCH(TaggedIsHeapObject(*val), &isHeapObject, &afterAOTLiteral);
Label tryGetAOTIhc(env);
//AOT ihc infos always in unshareConstpool
//If is runing on AOT,unshareConstpool is definitely not a hole
//So wo can skip if unshareConstpool is hole
GateRef unsharedConstpool = GetUnsharedConstpoolFromGlue(glue, constpool);
BRANCH(TaggedIsHole(unsharedConstpool), &afterAOTLiteral, &tryGetAOTIhc);
Bind(&tryGetAOTIhc);
{
Bind(&isHeapObject);
Label isAOTLiteral(env);
BRANCH(IsAOTLiteralInfo(*val), &isAOTLiteral, &afterAOTLiteral);
val = GetValueFromTaggedArray(unsharedConstpool, index);
BRANCH(TaggedIsHeapObject(*val), &isHeapObject, &afterAOTLiteral);
{
Bind(&isAOTLiteral);
// Avoiding shareobj references to unshareobj.
GateRef unshareIdx = GetUnsharedConstpoolIndex(constpool);
GateId 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(&isHeapObject);
Label isAOTLiteral(env);
BRANCH(IsAOTLiteralInfo(*val), &isAOTLiteral, &afterAOTLiteral);
{
Bind(&isAOTLiteral);
{
ihc = GetIhcFromAOTLiteralInfo(*val);
Jump(&afterAOTLiteral);
}
}
}
}
Bind(&afterAOTLiteral);
@ -9985,7 +9989,7 @@ GateRef StubBuilder::DefineFunc(GateRef glue, GateRef constpool, GateRef index,
BRANCH(TaggedIsUndefined(*ihc), &exit, &ihcNotUndefined);
Bind(&ihcNotUndefined);
{
CallRuntime(glue, RTSTUB_ID(AOTEnableProtoChangeMarker), { *result, *ihc});
CallRuntime(glue, RTSTUB_ID(AOTEnableProtoChangeMarker), {*result, *ihc, *val});
Jump(&exit);
}
Bind(&exit);

View File

@ -561,6 +561,7 @@ ShortcutBoolOr([&]{ return first; }, [&]{ return second; })
void ThrowTypeAndReturn(GateRef glue, int messageId, GateRef val);
GateRef GetValueFromTaggedArray(GateRef elements, GateRef index);
GateRef GetUnsharedConstpoolIndex(GateRef constpool);
GateRef GetUnsharedConstpoolFromGlue(GateRef glue, GateRef constpool);
GateRef GetUnsharedConstpool(GateRef array, GateRef index);
GateRef GetValueFromMutantTaggedArray(GateRef elements, GateRef index);
void CheckUpdateSharedType(bool isDicMode, Variable *result, GateRef glue, GateRef receiver, GateRef attr,

View File

@ -2204,12 +2204,15 @@ JSTaggedValue RuntimeStubs::RuntimeNewObjRange(JSThread *thread, const JSHandle<
return tagged;
}
void RuntimeStubs::DefineFuncTryUseAOTHClass(JSThread *thread, const JSHandle<JSFunction> &func,
const JSHandle<JSTaggedValue> &ihc)
void RuntimeStubs::DefineFuncTryUseAOTHClass(JSThread* thread,
const JSHandle<JSFunction>& func,
const JSHandle<JSTaggedValue>& ihc,
const JSHandle<AOTLiteralInfo>& aotLiteralInfo)
{
FunctionKind kind = Method::Cast(func->GetMethod())->GetFunctionKind();
// The HClass of AOT comes from .ai deserialization
if (!ihc->IsUndefined() && kind == FunctionKind::BASE_CONSTRUCTOR) {
ASSERT(!aotLiteralInfo.GetTaggedValue().IsHole());
JSHandle<GlobalEnv> env = thread->GetEcmaVM()->GetGlobalEnv();
const GlobalEnvConstants *globalConst = thread->GlobalConstants();
func->SetProtoOrHClass(thread, ihc);
@ -2232,6 +2235,8 @@ void RuntimeStubs::DefineFuncTryUseAOTHClass(JSThread *thread, const JSHandle<JS
} else {
JSHClass::EnablePHCProtoChangeMarker(thread, JSHandle<JSHClass>(thread, clsPrototype->GetClass()));
}
//avoid one thread uses ihc twice or more times
aotLiteralInfo->SetIhc(JSTaggedValue::Undefined());
}
}
@ -2242,16 +2247,20 @@ JSTaggedValue RuntimeStubs::RuntimeDefinefunc(JSThread *thread, const JSHandle<J
{
JSHandle<ConstantPool> constpoolHandle = JSHandle<ConstantPool>::Cast(constpool);
JSMutableHandle<JSTaggedValue> ihc(thread, JSTaggedValue::Undefined());
JSTaggedValue val = constpoolHandle->GetObjectFromCache(methodId);
if (val.IsAOTLiteralInfo()) {
JSTaggedValue unsharedCp =
thread->GetCurrentEcmaContext()->FindOrCreateUnsharedConstpool(constpool.GetTaggedValue());
JSMutableHandle<AOTLiteralInfo> aotLiteralInfo(thread, JSTaggedValue::Hole());
//AOT ihc infos always in unshareConstpool
//If is runing on AOT,unshareConstpool is definitely not a hole
//So wo can skip if unshareConstpool is hole
JSTaggedValue unsharedCp = thread->GetCurrentEcmaContext()->FindUnsharedConstpool(constpoolHandle.GetTaggedValue());
if (!unsharedCp.IsHole()) {
JSHandle<ConstantPool> unsharedCpHandle(thread, unsharedCp);
val = unsharedCpHandle->GetObjectFromCache(methodId);
JSHandle<AOTLiteralInfo> aotLiteralInfo(thread, val);
ihc.Update(aotLiteralInfo->GetIhc());
JSTaggedValue val = unsharedCpHandle->GetObjectFromCache(methodId);
if (val.IsAOTLiteralInfo()) {
aotLiteralInfo.Update(val);
ihc.Update(aotLiteralInfo->GetIhc());
}
}
JSTaggedValue method = ConstantPool::GetMethodFromCache(thread, constpool.GetTaggedValue(), methodId);
JSTaggedValue method = ConstantPool::GetMethodFromCache(thread, constpoolHandle.GetTaggedValue(), methodId);
const JSHandle<Method> methodHandle(thread, method);
ObjectFactory *factory = thread->GetEcmaVM()->GetFactory();
JSHandle<JSFunction> result;
@ -2268,7 +2277,7 @@ JSTaggedValue RuntimeStubs::RuntimeDefinefunc(JSThread *thread, const JSHandle<J
result->SetLexicalEnv(thread, envHandle.GetTaggedValue());
result->SetHomeObject(thread, homeObject.GetTaggedValue());
}
DefineFuncTryUseAOTHClass(thread, result, ihc);
DefineFuncTryUseAOTHClass(thread, result, ihc, aotLiteralInfo);
result->SetLength(length);
QuickFixHelper::SetPatchModule(thread, methodHandle, result);

View File

@ -3905,8 +3905,9 @@ DEF_RUNTIME_STUBS(AOTEnableProtoChangeMarker)
{
RUNTIME_STUBS_HEADER(AOTEnableProtoChangeMarker);
JSHandle<JSFunction> result(GetHArg<JSTaggedValue>(argv, argc, 0)); // 0: means the zeroth parameter
JSHandle<JSTaggedValue> ihc = GetHArg<JSTaggedValue>(argv, argc, 1); // 1: means the third parameter
DefineFuncTryUseAOTHClass(thread, result, ihc);
JSHandle<JSTaggedValue> ihc = GetHArg<JSTaggedValue>(argv, argc, 1); // 1: means the first parameter
JSHandle<AOTLiteralInfo> aotLiteralInfo(GetHArg<JSTaggedValue>(argv, argc, 2)); // 2: means the second parameter
DefineFuncTryUseAOTHClass(thread, result, ihc, aotLiteralInfo);
return JSTaggedValue::Hole().GetRawData();
}

View File

@ -34,7 +34,7 @@ class ObjectFactory;
class JSBoundFunction;
class JSProxy;
class JSTypedArray;
class AOTLiteralInfo;
class GeneratorContext;
struct EcmaRuntimeCallInfo;
@ -397,8 +397,10 @@ private:
uint16_t methodId, const JSHandle<JSTaggedValue> &module,
uint16_t length, const JSHandle<JSTaggedValue> &envHandle,
const JSHandle<JSTaggedValue> &homeObject);
static inline void DefineFuncTryUseAOTHClass(JSThread *thread, const JSHandle<JSFunction> &func,
const JSHandle<JSTaggedValue> &ihc);
static inline void DefineFuncTryUseAOTHClass(JSThread* thread,
const JSHandle<JSFunction>& func,
const JSHandle<JSTaggedValue>& ihc,
const JSHandle<AOTLiteralInfo>& aotLiteralInfo);
static inline JSTaggedValue RuntimeCreateRegExpWithLiteral(JSThread *thread, const JSHandle<JSTaggedValue> &pattern,
uint8_t flags);
static inline JSTaggedValue RuntimeThrowIfSuperNotCorrectCall(JSThread *thread, uint16_t index,

View File

@ -73,6 +73,7 @@ ArkTools.printTypedOpProfiler("MONO_STORE_PROPERTY");
ArkTools.clearTypedOpProfiler();
print(ArkTools.isAOTDeoptimized(Test2));
//make sure ihc in one thread can only be used once
function Test3() {
for(let i = 0; i<2; ++i) {
function A() {