mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-02-13 08:15:47 +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);
|
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)
|
JSTaggedValue BuiltinsArkTools::PrintTypedOpProfilerAndReset(EcmaRuntimeCallInfo *info)
|
||||||
{
|
{
|
||||||
ASSERT(info);
|
ASSERT(info);
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
V("isAOTDeoptimized", IsAOTDeoptimized, 1, INVALID) \
|
V("isAOTDeoptimized", IsAOTDeoptimized, 1, INVALID) \
|
||||||
V("printTypedOpProfilerAndReset", PrintTypedOpProfilerAndReset, 1, INVALID) \
|
V("printTypedOpProfilerAndReset", PrintTypedOpProfilerAndReset, 1, INVALID) \
|
||||||
V("isOnHeap", IsOnHeap, 1, INVALID) \
|
V("isOnHeap", IsOnHeap, 1, INVALID) \
|
||||||
|
V("checkDeoptStatus", CheckDeoptStatus, 2, INVALID) \
|
||||||
V("checkCircularImport", CheckCircularImport, 2, INVALID)
|
V("checkCircularImport", CheckCircularImport, 2, INVALID)
|
||||||
|
|
||||||
#define BUILTIN_ARK_TOOLS_FUNCTIONS_REGRESS(V) \
|
#define BUILTIN_ARK_TOOLS_FUNCTIONS_REGRESS(V) \
|
||||||
@ -187,6 +188,9 @@ public:
|
|||||||
// ArkTools.isAOTCompiledAssert(func)
|
// ArkTools.isAOTCompiledAssert(func)
|
||||||
static JSTaggedValue IsAOTDeoptimized(EcmaRuntimeCallInfo *info);
|
static JSTaggedValue IsAOTDeoptimized(EcmaRuntimeCallInfo *info);
|
||||||
|
|
||||||
|
// ArkTools.CheckDeoptStatus(func, deopt?)
|
||||||
|
static JSTaggedValue CheckDeoptStatus(EcmaRuntimeCallInfo *info);
|
||||||
|
|
||||||
// ArkTools.isOnHeap(object)
|
// ArkTools.isOnHeap(object)
|
||||||
static JSTaggedValue IsOnHeap(EcmaRuntimeCallInfo *info);
|
static JSTaggedValue IsOnHeap(EcmaRuntimeCallInfo *info);
|
||||||
|
|
||||||
|
@ -281,7 +281,7 @@ void AOTFileManager::SetAOTMainFuncEntry(JSHandle<JSFunction> mainFunc, const JS
|
|||||||
mainMethod->SetNativeBit(false);
|
mainMethod->SetNativeBit(false);
|
||||||
Method *method = mainFunc->GetCallTarget();
|
Method *method = mainFunc->GetCallTarget();
|
||||||
method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
||||||
method->SetCodeEntryAndMarkAOT(static_cast<uintptr_t>(mainEntry));
|
method->SetCodeEntryAndMarkAOTWhenBinding(static_cast<uintptr_t>(mainEntry));
|
||||||
method->SetIsFastCall(isFastCall);
|
method->SetIsFastCall(isFastCall);
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
PrintAOTEntry(jsPandaFile, method, mainEntry);
|
PrintAOTEntry(jsPandaFile, method, mainEntry);
|
||||||
@ -307,7 +307,7 @@ void AOTFileManager::SetAOTFuncEntry(const JSPandaFile *jsPandaFile, Method *met
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
method->SetDeoptThreshold(vm_->GetJSOptions().GetDeoptThreshold());
|
||||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
method->SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||||
method->SetIsFastCall(entry.isFastCall_);
|
method->SetIsFastCall(entry.isFastCall_);
|
||||||
if (canFastCall != nullptr) {
|
if (canFastCall != nullptr) {
|
||||||
*canFastCall = entry.isFastCall_;
|
*canFastCall = entry.isFastCall_;
|
||||||
|
@ -534,7 +534,7 @@ void Deoptimizier::UpdateAndDumpDeoptInfo(kungfu::DeoptType type)
|
|||||||
method->SetDeoptType(type);
|
method->SetDeoptType(type);
|
||||||
method->SetDeoptThreshold(--deoptThreshold);
|
method->SetDeoptThreshold(--deoptThreshold);
|
||||||
} else {
|
} else {
|
||||||
method->ClearAOTFlags();
|
method->ClearAOTStatusWhenDeopt();
|
||||||
if (method->GetMachineCode() != JSTaggedValue::Undefined()) {
|
if (method->GetMachineCode() != JSTaggedValue::Undefined()) {
|
||||||
method->SetMachineCode(thread_, JSTaggedValue::Undefined());
|
method->SetMachineCode(thread_, JSTaggedValue::Undefined());
|
||||||
}
|
}
|
||||||
|
@ -1337,7 +1337,7 @@ JSHandle<JSTaggedValue> JSDeserializer::ReadMethod()
|
|||||||
if (!ReadNativePointer(&codeEntry)) {
|
if (!ReadNativePointer(&codeEntry)) {
|
||||||
return JSHandle<JSTaggedValue>();
|
return JSHandle<JSTaggedValue>();
|
||||||
}
|
}
|
||||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
method->SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||||
|
|
||||||
uint8_t deoptThreshold = thread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold();
|
uint8_t deoptThreshold = thread_->GetEcmaVM()->GetJSOptions().GetDeoptThreshold();
|
||||||
method->SetDeoptThreshold(deoptThreshold);
|
method->SetDeoptThreshold(deoptThreshold);
|
||||||
|
@ -125,11 +125,33 @@ const JSTaggedValue Method::GetRecordName() const
|
|||||||
void Method::SetCompiledFuncEntry(uintptr_t codeEntry, bool isFastCall)
|
void Method::SetCompiledFuncEntry(uintptr_t codeEntry, bool isFastCall)
|
||||||
{
|
{
|
||||||
ASSERT(codeEntry != 0);
|
ASSERT(codeEntry != 0);
|
||||||
SetCodeEntryAndMarkAOT(codeEntry);
|
SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||||
|
|
||||||
SetIsFastCall(isFastCall);
|
SetIsFastCall(isFastCall);
|
||||||
MethodLiteral *methodLiteral = GetMethodLiteral();
|
MethodLiteral *methodLiteral = GetMethodLiteral();
|
||||||
methodLiteral->SetAotCodeBit(true);
|
methodLiteral->SetAotCodeBit(true);
|
||||||
methodLiteral->SetIsFastCall(isFastCall);
|
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
|
} // namespace panda::ecmascript
|
||||||
|
@ -386,20 +386,11 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// add for AOT
|
// add for AOT
|
||||||
void SetCodeEntryAndMarkAOT(uintptr_t codeEntry)
|
void SetCodeEntryAndMarkAOTWhenBinding(uintptr_t codeEntry);
|
||||||
{
|
|
||||||
SetAotCodeBit(true);
|
|
||||||
SetNativeBit(false);
|
|
||||||
SetCodeEntryOrLiteral(codeEntry);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ClearAOTFlags()
|
void ClearAOTStatusWhenDeopt();
|
||||||
{
|
|
||||||
SetAotCodeBit(false);
|
void ClearAOTFlagsWhenInit();
|
||||||
SetIsFastCall(false);
|
|
||||||
SetDeoptType(kungfu::DeoptType::NOTCHECK);
|
|
||||||
SetCodeEntryOrLiteral(reinterpret_cast<uintptr_t>(nullptr));
|
|
||||||
}
|
|
||||||
|
|
||||||
void SetCompiledFuncEntry(uintptr_t codeEntry, bool isFastCall);
|
void SetCompiledFuncEntry(uintptr_t codeEntry, bool isFastCall);
|
||||||
|
|
||||||
|
@ -1840,6 +1840,8 @@ JSHandle<Method> ObjectFactory::NewMethod(const JSPandaFile *jsPandaFile, Method
|
|||||||
if (needSetAotFlag) {
|
if (needSetAotFlag) {
|
||||||
thread_->GetEcmaVM()->GetAOTFileManager()->
|
thread_->GetEcmaVM()->GetAOTFileManager()->
|
||||||
SetAOTFuncEntry(jsPandaFile, *method, entryIndex, canFastCall);
|
SetAOTFuncEntry(jsPandaFile, *method, entryIndex, canFastCall);
|
||||||
|
} else {
|
||||||
|
method->ClearAOTFlagsWhenInit();
|
||||||
}
|
}
|
||||||
return method;
|
return method;
|
||||||
}
|
}
|
||||||
|
@ -3025,7 +3025,7 @@ void RuntimeStubs::SaveFrameToContext(JSThread *thread, JSHandle<GeneratorContex
|
|||||||
JSTaggedValue function = frameHandler.GetFunction();
|
JSTaggedValue function = frameHandler.GetFunction();
|
||||||
Method *method = JSFunction::Cast(function.GetTaggedObject())->GetCallTarget();
|
Method *method = JSFunction::Cast(function.GetTaggedObject())->GetCallTarget();
|
||||||
if (method->IsAotWithCallField()) {
|
if (method->IsAotWithCallField()) {
|
||||||
method->ClearAOTFlags();
|
method->ClearAOTStatusWhenDeopt();
|
||||||
}
|
}
|
||||||
context->SetMethod(thread, function);
|
context->SetMethod(thread, function);
|
||||||
context->SetThis(thread, frameHandler.GetThis());
|
context->SetThis(thread, frameHandler.GetThis());
|
||||||
|
@ -1957,7 +1957,7 @@ HWTEST_F_L0(JSSerializerTest, SerializeAOTMethod)
|
|||||||
method->SetConstantPool(thread, constPool.GetTaggedValue());
|
method->SetConstantPool(thread, constPool.GetTaggedValue());
|
||||||
|
|
||||||
uintptr_t codeEntry = 0x1234;
|
uintptr_t codeEntry = 0x1234;
|
||||||
method->SetCodeEntryAndMarkAOT(codeEntry);
|
method->SetCodeEntryAndMarkAOTWhenBinding(codeEntry);
|
||||||
|
|
||||||
JSSerializer *serializer = new JSSerializer(thread);
|
JSSerializer *serializer = new JSSerializer(thread);
|
||||||
bool success = serializer->SerializeJSTaggedValue(JSHandle<JSTaggedValue>::Cast(method));
|
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") {
|
host_aot_assert_test_action("deopt") {
|
||||||
deps = []
|
deps = []
|
||||||
|
is_only_typed_path = true
|
||||||
}
|
}
|
||||||
|
@ -19,9 +19,13 @@ function tryHello(v: number): void {
|
|||||||
let ret: number = a + v;
|
let ret: number = a + v;
|
||||||
assert_equal(ret, "1a");
|
assert_equal(ret, "1a");
|
||||||
}
|
}
|
||||||
|
assert_equal(ArkTools.checkDeoptStatus(tryHello, false), true);
|
||||||
tryHello(<number><Object>'a');
|
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 {
|
function tryIf(v: number, b: number): void {
|
||||||
let a : number = 1;
|
let a : number = 1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user