mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-02-09 05:17:57 +00:00
Fix aot flags mismatch when new method by aot methodLiteral in interp
Issue: https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I9711X?from=project-issue Signed-off-by: zhangyukun8 <zhangyukun8@huawei.com> Change-Id: I8431de2f73dd4f7f59f48577214b7d981da0a9e7
This commit is contained in:
parent
d1160fcf35
commit
629899bb1f
@ -405,6 +405,38 @@ JSTaggedValue BuiltinsArkTools::IsAOTDeoptimized(EcmaRuntimeCallInfo *info)
|
||||
return JSTaggedValue(false);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArkTools::CheckDeoptStatus(EcmaRuntimeCallInfo *info)
|
||||
{
|
||||
ASSERT(info);
|
||||
JSThread *thread = info->GetThread();
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
|
||||
JSHandle<JSTaggedValue> obj = GetCallArg(info, 0);
|
||||
JSHandle<JSFunction> func(thread, obj.GetTaggedValue());
|
||||
Method *method = func->GetCallTarget();
|
||||
bool isAotCompiled = method->IsAotWithCallField();
|
||||
uint16_t threshold = method->GetDeoptThreshold();
|
||||
if (threshold > 0) {
|
||||
return JSTaggedValue(isAotCompiled);
|
||||
}
|
||||
// check status before deopt
|
||||
JSHandle<JSTaggedValue> hasDeopt = GetCallArg(info, 1);
|
||||
if (hasDeopt->IsFalse()) {
|
||||
return JSTaggedValue(!isAotCompiled);
|
||||
}
|
||||
if (!hasDeopt->IsTrue()) {
|
||||
return JSTaggedValue(false);
|
||||
}
|
||||
// check status after deopt
|
||||
if (isAotCompiled ||
|
||||
method->IsFastCall() ||
|
||||
method->GetDeoptType() != kungfu::DeoptType::NOTCHECK ||
|
||||
method->GetCodeEntryOrLiteral() == 0) {
|
||||
return JSTaggedValue(false);
|
||||
}
|
||||
return JSTaggedValue(true);
|
||||
}
|
||||
|
||||
JSTaggedValue BuiltinsArkTools::PrintTypedOpProfilerAndReset(EcmaRuntimeCallInfo *info)
|
||||
{
|
||||
ASSERT(info);
|
||||
|
@ -48,6 +48,7 @@
|
||||
V("isAOTDeoptimized", IsAOTDeoptimized, 1, INVALID) \
|
||||
V("printTypedOpProfilerAndReset", PrintTypedOpProfilerAndReset, 1, INVALID) \
|
||||
V("isOnHeap", IsOnHeap, 1, INVALID) \
|
||||
V("checkDeoptStatus", CheckDeoptStatus, 2, INVALID) \
|
||||
V("checkCircularImport", CheckCircularImport, 2, INVALID)
|
||||
|
||||
#define BUILTIN_ARK_TOOLS_FUNCTIONS_REGRESS(V) \
|
||||
@ -187,6 +188,9 @@ public:
|
||||
// ArkTools.isAOTCompiledAssert(func)
|
||||
static JSTaggedValue IsAOTDeoptimized(EcmaRuntimeCallInfo *info);
|
||||
|
||||
// ArkTools.CheckDeoptStatus(func, deopt?)
|
||||
static JSTaggedValue CheckDeoptStatus(EcmaRuntimeCallInfo *info);
|
||||
|
||||
// ArkTools.isOnHeap(object)
|
||||
static JSTaggedValue IsOnHeap(EcmaRuntimeCallInfo *info);
|
||||
|
||||
|
@ -281,7 +281,7 @@ void AOTFileManager::SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JS
|
||||
mainMethod->SetNativeBit(false);
|
||||
Method *method = mainFunc->GetCallTarget();
|
||||
method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
||||
method->SetCodeEntryAndMarkAOT(static_cast<uintptr_t>(mainEntry));
|
||||
method->SetCodeEntryAndMarkAOTWhenBinding(static_cast<uintptr_t>(mainEntry));
|
||||
method->SetIsFastCall(isFastCall);
|
||||
#ifndef NDEBUG
|
||||
PrintAOTEntry(jsPandaFile, method, mainEntry);
|
||||
@ -307,7 +307,7 @@ void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *met
|
||||
return;
|
||||
}
|
||||
method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
||||
method->SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||
method->SetIsFastCall(entry.isFastCall_);
|
||||
if (canFastCall != nullptr) {
|
||||
*canFastCall = entry.isFastCall_;
|
||||
|
@ -534,7 +534,7 @@ void Deoptimizier::UpdateAndDumpDeoptInfo(kungfu::DeoptType type)
|
||||
method->SetDeoptType(type);
|
||||
method->SetDeoptThreshold(--deoptThreshold);
|
||||
} else {
|
||||
method->ClearAOTFlags();
|
||||
method->ClearAOTStatusWhenDeopt();
|
||||
if (method->GetMachineCode() != JSTaggedValue::Undefined()) {
|
||||
method->SetMachineCode(thread_, JSTaggedValue::Undefined());
|
||||
}
|
||||
|
@ -1337,7 +1337,7 @@ JSHandle<JSTaggedValue> JSDeserializer::ReadMethod()
|
||||
if (!ReadNativePointer(&codeEntry)) {
|
||||
return JSHandle<JSTaggedValue>();
|
||||
}
|
||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
||||
method->SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||
|
||||
uint8_t deoptThreshold = thread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold();
|
||||
method->SetDeoptThreshold(deoptThreshold);
|
||||
|
@ -125,11 +125,33 @@ const JSTaggedValue Method::GetRecordName() const
|
||||
void Method::SetCompiledFuncEntry(uintptr_t codeEntry, bool isFastCall)
|
||||
{
|
||||
ASSERT(codeEntry != 0);
|
||||
SetCodeEntryAndMarkAOT(codeEntry);
|
||||
SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||
|
||||
SetIsFastCall(isFastCall);
|
||||
MethodLiteral *methodLiteral = GetMethodLiteral();
|
||||
methodLiteral->SetAotCodeBit(true);
|
||||
methodLiteral->SetIsFastCall(isFastCall);
|
||||
}
|
||||
|
||||
void Method::SetCodeEntryAndMarkAOTWhenBinding(uintptr_t codeEntry)
|
||||
{
|
||||
SetAotCodeBit(true);
|
||||
SetNativeBit(false);
|
||||
SetCodeEntryOrLiteral(codeEntry);
|
||||
}
|
||||
|
||||
void Method::ClearAOTStatusWhenDeopt()
|
||||
{
|
||||
ClearAOTFlagsWhenInit();
|
||||
SetDeoptType(kungfu::DeoptType::NOTCHECK);
|
||||
const JSPandaFile *jsPandaFile = GetJSPandaFile();
|
||||
MethodLiteral *methodLiteral = jsPandaFile->FindMethodLiteral(GetMethodId().GetOffset());
|
||||
SetCodeEntryOrLiteral(reinterpret_cast<uintptr_t>(methodLiteral));
|
||||
}
|
||||
|
||||
void Method::ClearAOTFlagsWhenInit()
|
||||
{
|
||||
SetAotCodeBit(false);
|
||||
SetIsFastCall(false);
|
||||
}
|
||||
} // namespace panda::ecmascript
|
||||
|
@ -386,20 +386,11 @@ public:
|
||||
}
|
||||
|
||||
// add for AOT
|
||||
void SetCodeEntryAndMarkAOT(uintptr_t codeEntry)
|
||||
{
|
||||
SetAotCodeBit(true);
|
||||
SetNativeBit(false);
|
||||
SetCodeEntryOrLiteral(codeEntry);
|
||||
}
|
||||
void SetCodeEntryAndMarkAOTWhenBinding(uintptr_t codeEntry);
|
||||
|
||||
void ClearAOTFlags()
|
||||
{
|
||||
SetAotCodeBit(false);
|
||||
SetIsFastCall(false);
|
||||
SetDeoptType(kungfu::DeoptType::NOTCHECK);
|
||||
SetCodeEntryOrLiteral(reinterpret_cast<uintptr_t>(nullptr));
|
||||
}
|
||||
void ClearAOTStatusWhenDeopt();
|
||||
|
||||
void ClearAOTFlagsWhenInit();
|
||||
|
||||
void SetCompiledFuncEntry(uintptr_t codeEntry, bool isFastCall);
|
||||
|
||||
|
@ -1840,6 +1840,8 @@ JSHandle<Method> ObjectFactory::NewMethod(const JSPandaFile *jsPandaFile, Method
|
||||
if (needSetAotFlag) {
|
||||
thread_->GetEcmaVM()->GetAOTFileManager()->
|
||||
SetAOTFuncEntry(jsPandaFile, *method, entryIndex, canFastCall);
|
||||
} else {
|
||||
method->ClearAOTFlagsWhenInit();
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
@ -3025,7 +3025,7 @@ void RuntimeStubs::SaveFrameToContext(JSThread *thread, JSHandle<GeneratorContex
|
||||
JSTaggedValue function = frameHandler.GetFunction();
|
||||
Method *method = JSFunction::Cast(function.GetTaggedObject())->GetCallTarget();
|
||||
if (method->IsAotWithCallField()) {
|
||||
method->ClearAOTFlags();
|
||||
method->ClearAOTStatusWhenDeopt();
|
||||
}
|
||||
context->SetMethod(thread, function);
|
||||
context->SetThis(thread, frameHandler.GetThis());
|
||||
|
@ -1957,7 +1957,7 @@ HWTEST_F_L0(JSSerializerTest, SerializeAOTMethod)
|
||||
method->SetConstantPool(thread, constPool.GetTaggedValue());
|
||||
|
||||
uintptr_t codeEntry = 0x1234;
|
||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
||||
method->SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||
|
||||
JSSerializer *serializer = new JSSerializer(thread);
|
||||
bool success = serializer->SerializeJSTaggedValue(JSHandle<JSTaggedValue>::Cast(method));
|
||||
|
@ -15,4 +15,5 @@ import("//arkcompiler/ets_runtime/test/test_helper.gni")
|
||||
|
||||
host_aot_assert_test_action("deopt") {
|
||||
deps = []
|
||||
is_only_typed_path = true
|
||||
}
|
||||
|
@ -19,9 +19,13 @@ function tryHello(v: number): void {
|
||||
let ret: number = a + v;
|
||||
assert_equal(ret, "1a");
|
||||
}
|
||||
|
||||
assert_equal(ArkTools.checkDeoptStatus(tryHello, false), true);
|
||||
tryHello(<number><Object>'a');
|
||||
|
||||
assert_equal(ArkTools.checkDeoptStatus(tryHello, true), true);
|
||||
for (let i = 0; i < 25; i++) {
|
||||
tryHello(<number><Object>'a');
|
||||
}
|
||||
assert_equal(ArkTools.checkDeoptStatus(tryHello, true), true);
|
||||
|
||||
function tryIf(v: number, b: number): void {
|
||||
let a : number = 1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user