mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2024-11-24 02:30:03 +00:00
Add AsmInterpreterFrame
Add AsmInterpreterFrame for ASM. Issue: #I4YF9X Signed-off-by: lichenshuai <lichenshuai@huawei.com> Change-Id: I4efc781a9fca90de4a0aed5b6a91a8122cfa16ab
This commit is contained in:
parent
1789e38335
commit
cfc0b0b12f
@ -23,7 +23,7 @@ namespace panda::ecmascript {
|
||||
#define ECMASCRIPT_ENABLE_DEBUG_MODE 0
|
||||
#define ECMASCRIPT_ENABLE_ARK_CONTAINER 1
|
||||
#define ECMASCRIPT_ENABLE_TS_AOT_PRINT 0
|
||||
#define ECMASCRIPT_COMPILE_INTERPRETER_ASM 0
|
||||
#define ECMASCRIPT_COMPILE_ASM_INTERPRETER 0
|
||||
#define ECMASCRIPT_ENABLE_ASM_INTERPRETER_LOG 0
|
||||
|
||||
#define ECMASCRIPT_ENABLE_RUNTIME_STAT 0 // NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
|
@ -173,7 +173,7 @@ GateRef InterpreterStub::ReadInst16_5(GateRef pc)
|
||||
|
||||
GateRef InterpreterStub::GetFrame(GateRef CurrentSp)
|
||||
{
|
||||
return IntPtrSub(CurrentSp, GetIntPtrConstant(InterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
|
||||
return IntPtrSub(CurrentSp, GetIntPtrConstant(AsmInterpretedFrame::GetSize(GetEnvironment()->IsArch32Bit())));
|
||||
}
|
||||
|
||||
GateRef InterpreterStub::GetPcFromFrame(GateRef frame)
|
||||
@ -184,25 +184,25 @@ GateRef InterpreterStub::GetPcFromFrame(GateRef frame)
|
||||
GateRef InterpreterStub::GetFunctionFromFrame(GateRef frame)
|
||||
{
|
||||
return Load(VariableType::JS_POINTER(), frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())));
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())));
|
||||
}
|
||||
|
||||
GateRef InterpreterStub::GetCallSizeFromFrame(GateRef frame)
|
||||
{
|
||||
return Load(VariableType::POINTER(), frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())));
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())));
|
||||
}
|
||||
|
||||
GateRef InterpreterStub::GetAccFromFrame(GateRef frame)
|
||||
{
|
||||
return Load(VariableType::JS_ANY(), frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())));
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())));
|
||||
}
|
||||
|
||||
GateRef InterpreterStub::GetEnvFromFrame(GateRef frame)
|
||||
{
|
||||
return Load(VariableType::JS_POINTER(), frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())));
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())));
|
||||
}
|
||||
|
||||
GateRef InterpreterStub::GetEnvFromFunction(GateRef function)
|
||||
@ -234,12 +234,6 @@ GateRef InterpreterStub::GetResumeModeFromGeneratorObject(GateRef obj)
|
||||
GetInt32Constant((1LU << JSGeneratorObject::ResumeModeBits::SIZE) - 1));
|
||||
}
|
||||
|
||||
void InterpreterStub::SetEnvToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
{
|
||||
Store(VariableType::INT64(), glue, frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
}
|
||||
|
||||
void InterpreterStub::SetPcToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
{
|
||||
Store(VariableType::INT64(), glue, frame, GetIntPtrConstant(0), value);
|
||||
@ -247,20 +241,26 @@ void InterpreterStub::SetPcToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
|
||||
void InterpreterStub::SetCallSizeToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
{
|
||||
Store(VariableType::INT64(), glue, frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
Store(VariableType::POINTER(), glue, frame,
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetCallSizeOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
}
|
||||
|
||||
void InterpreterStub::SetAccToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
{
|
||||
Store(VariableType::INT64(), glue, frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetAccOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
}
|
||||
|
||||
void InterpreterStub::SetEnvToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
{
|
||||
Store(VariableType::INT64(), glue, frame,
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetEnvOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
}
|
||||
|
||||
void InterpreterStub::SetFunctionToFrame(GateRef glue, GateRef frame, GateRef value)
|
||||
{
|
||||
Store(VariableType::INT64(), glue, frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetFunctionOffset(GetEnvironment()->IsArch32Bit())), value);
|
||||
}
|
||||
|
||||
void InterpreterStub::SetConstantPoolToFunction(GateRef glue, GateRef function, GateRef value)
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "ecmascript/compiler/variable_type.h"
|
||||
#include "ecmascript/global_env_constants.h"
|
||||
#include "ecmascript/ic/profile_type_info.h"
|
||||
#include "ecmascript/interpreter/interpreter.h"
|
||||
#include "ecmascript/interpreter/interpreter_assembly.h"
|
||||
#include "ecmascript/js_array.h"
|
||||
#include "ecmascript/js_function.h"
|
||||
#include "ecmascript/js_generator_object.h"
|
||||
@ -87,7 +87,7 @@ void name##Stub::GenerateCircuitImpl(GateRef glue, GateRef pc, GateRef sp,
|
||||
{ \
|
||||
varProfileTypeInfo = CallRuntimeTrampoline(glue, \
|
||||
GetInt64Constant(RTSTUB_ID(UpdateHotnessCounter)), {}); \
|
||||
varHotnessCounter = GetInt32Constant(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD); \
|
||||
varHotnessCounter = GetInt32Constant(InterpreterAssembly::METHOD_HOTNESS_THRESHOLD); \
|
||||
Jump(&dispatch); \
|
||||
} \
|
||||
Bind(&dispatch);
|
||||
@ -4254,7 +4254,7 @@ DECLARE_ASM_HANDLER(HandleReturnDyn)
|
||||
|
||||
Bind(&tryContinue);
|
||||
varSp = Load(VariableType::POINTER(), frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetBaseOffset(env->IsArch32Bit())));
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetBaseOffset(env->IsArch32Bit())));
|
||||
GateRef prevState = GetFrame(*varSp);
|
||||
varPc = GetPcFromFrame(prevState);
|
||||
Branch(IntPtrEqual(*varPc, GetIntPtrConstant(0)), &pcEqualNullptr, &pcNotEqualNullptr);
|
||||
@ -4314,7 +4314,7 @@ DECLARE_ASM_HANDLER(HandleReturnUndefinedPref)
|
||||
|
||||
Bind(&tryContinue);
|
||||
varSp = Load(VariableType::POINTER(), frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetBaseOffset(env->IsArch32Bit())));
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetBaseOffset(env->IsArch32Bit())));
|
||||
GateRef prevState = GetFrame(*varSp);
|
||||
varPc = GetPcFromFrame(prevState);
|
||||
varAcc = GetUndefinedConstant();
|
||||
@ -4389,7 +4389,7 @@ DECLARE_ASM_HANDLER(HandleSuspendGeneratorPrefV8V8)
|
||||
|
||||
Bind(&tryContinue);
|
||||
varSp = Load(VariableType::POINTER(), frame,
|
||||
GetIntPtrConstant(InterpretedFrame::GetBaseOffset(env->IsArch32Bit())));
|
||||
GetIntPtrConstant(AsmInterpretedFrame::GetBaseOffset(env->IsArch32Bit())));
|
||||
GateRef prevState = GetFrame(*varSp);
|
||||
varPc = GetPcFromFrame(prevState);
|
||||
Branch(IntPtrEqual(*varPc, GetIntPtrConstant(0)), &pcEqualNullptr, &pcNotEqualNullptr);
|
||||
@ -5009,7 +5009,7 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
Branch(IsCallable(func), &funcIsCallable, &funcNotCallable); \
|
||||
Bind(&funcNotCallable); \
|
||||
{ \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetNotCallableException)), {}); \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetNotCallableException)), {}); \
|
||||
DISPATCH_LAST(); \
|
||||
} \
|
||||
Bind(&funcIsCallable); \
|
||||
@ -5035,7 +5035,7 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
GateRef callFieldOffset = GetIntPtrConstant(JSMethod::GetCallFieldOffset(env->IsArch32Bit())); \
|
||||
GateRef callField = Load(VariableType::INT64(), method, callFieldOffset); \
|
||||
DEFVARIABLE(newSp, VariableType::POINTER(), \
|
||||
PointerSub(sp, GetIntPtrConstant(InterpretedFrame::GetSize(env->IsArch32Bit()))))
|
||||
PointerSub(sp, GetIntPtrConstant(AsmInterpretedFrame::GetSize(env->IsArch32Bit()))))
|
||||
|
||||
#define CALL_PUSH_UNDEFINED(n) \
|
||||
i = GetInt32Constant(0); \
|
||||
@ -5137,12 +5137,12 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
&stackOverflow, &stackNotOverflow); \
|
||||
Bind(&stackOverflow); \
|
||||
{ \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetStackOverflowException)), {}); \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetStackOverflowException)), {}); \
|
||||
DISPATCH_LAST(); \
|
||||
} \
|
||||
Bind(&stackNotOverflow); \
|
||||
GateRef state = GetFrame(*newSp); \
|
||||
GateRef prevOffset = GetIntPtrConstant(InterpretedFrame::GetBaseOffset(env->IsArch32Bit())); \
|
||||
GateRef prevOffset = GetIntPtrConstant(AsmInterpretedFrame::GetBaseOffset(env->IsArch32Bit())); \
|
||||
Store(VariableType::POINTER(), glue, state, prevOffset, sp); \
|
||||
GateRef frameTypeOffset = IntPtrAdd(prevOffset, GetIntPtrSize()); \
|
||||
Store(VariableType::INT64(), glue, state, frameTypeOffset, \
|
||||
@ -5151,7 +5151,7 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
SetFunctionToFrame(glue, state, func); \
|
||||
SetCurrentSpFrame(glue, *newSp); \
|
||||
GateRef numArgs = Int32Add(GetInt32Constant(NUM_MANDATORY_JSFUNC_ARGS), actualNumArgs); \
|
||||
GateRef retValue = CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(CallNative)), \
|
||||
GateRef retValue = CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(CallNative)), \
|
||||
{IntBuildTaggedTypeWithNoGC(numArgs), *newSp, method}); \
|
||||
SetCurrentSpFrame(glue, sp); \
|
||||
DEFVARIABLE(varAcc, VariableType::JS_ANY(), retValue); \
|
||||
@ -5163,7 +5163,7 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
Branch(IsClassConstructor(func), &funcIsClassConstructor, &funcNotClassConstructor); \
|
||||
Bind(&funcIsClassConstructor); \
|
||||
{ \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetCallConstructorException)), {}); \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetCallConstructorException)), {}); \
|
||||
DISPATCH_LAST(); \
|
||||
} \
|
||||
Bind(&funcNotClassConstructor); \
|
||||
@ -5243,14 +5243,14 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
&stackOverflow, &stackNotOverflow); \
|
||||
Bind(&stackOverflow); \
|
||||
{ \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetStackOverflowException)), {}); \
|
||||
CallRuntimeTrampoline(glue, GetInt64Constant(RTSTUB_ID(SetStackOverflowException)), {}); \
|
||||
DISPATCH_LAST(); \
|
||||
} \
|
||||
Bind(&stackNotOverflow); \
|
||||
SetCallSizeToFrame(glue, GetFrame(sp), \
|
||||
GetIntPtrConstant(BytecodeInstruction::Size(BytecodeInstruction::Format::format))); \
|
||||
GateRef state = GetFrame(*newSp); \
|
||||
GateRef prevOffset = GetIntPtrConstant(InterpretedFrame::GetBaseOffset(env->IsArch32Bit())); \
|
||||
GateRef prevOffset = GetIntPtrConstant(AsmInterpretedFrame::GetBaseOffset(env->IsArch32Bit())); \
|
||||
Store(VariableType::POINTER(), glue, state, prevOffset, sp); \
|
||||
GateRef frameTypeOffset = IntPtrAdd(prevOffset, GetIntPtrConstant( \
|
||||
env->IsArch32Bit() ? InterpretedFrameBase::TYPE_OFFSET_32 : InterpretedFrameBase::TYPE_OFFSET_64)); \
|
||||
@ -5283,18 +5283,18 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
newSp = PointerSub(*newSp, GetIntPtrConstant(sizeof(JSTaggedType))); \
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a0Value)
|
||||
|
||||
#define CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8() \
|
||||
Label push0(env); \
|
||||
Label skip0(env); \
|
||||
Branch(Int32GreaterThanOrEqual(declaredNumArgs, \
|
||||
GetInt32Constant(EcmaInterpreter::ActualNumArgsOfCall::CALLARG1)), &push0, &skip0); \
|
||||
Bind(&push0); \
|
||||
{ \
|
||||
GateRef a0Value = GetVregValue(sp, ZExtInt8ToPtr(a0)); \
|
||||
newSp = PointerSub(*newSp, GetIntPtrConstant(sizeof(JSTaggedType))); \
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a0Value); \
|
||||
Jump(&skip0); \
|
||||
} \
|
||||
#define CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8() \
|
||||
Label push0(env); \
|
||||
Label skip0(env); \
|
||||
Branch(Int32GreaterThanOrEqual(declaredNumArgs, \
|
||||
GetInt32Constant(InterpreterAssembly::ActualNumArgsOfCall::CALLARG1)), &push0, &skip0); \
|
||||
Bind(&push0); \
|
||||
{ \
|
||||
GateRef a0Value = GetVregValue(sp, ZExtInt8ToPtr(a0)); \
|
||||
newSp = PointerSub(*newSp, GetIntPtrConstant(sizeof(JSTaggedType))); \
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a0Value); \
|
||||
Jump(&skip0); \
|
||||
} \
|
||||
Bind(&skip0)
|
||||
|
||||
#define CALL_PUSH_ARGS_PREF_V8_V8_V8() \
|
||||
@ -5303,19 +5303,19 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a1Value); \
|
||||
CALL_PUSH_ARGS_PREF_V8_V8()
|
||||
|
||||
#define CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8_V8() \
|
||||
Label push1(env); \
|
||||
Label skip1(env); \
|
||||
Branch(Int32GreaterThanOrEqual(declaredNumArgs, \
|
||||
GetInt32Constant(EcmaInterpreter::ActualNumArgsOfCall::CALLARGS2)), &push1, &skip1); \
|
||||
Bind(&push1); \
|
||||
{ \
|
||||
GateRef a1Value = GetVregValue(sp, ZExtInt8ToPtr(a1)); \
|
||||
newSp = PointerSub(*newSp, GetIntPtrConstant(sizeof(JSTaggedType))); \
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a1Value); \
|
||||
Jump(&skip1); \
|
||||
} \
|
||||
Bind(&skip1); \
|
||||
#define CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8_V8() \
|
||||
Label push1(env); \
|
||||
Label skip1(env); \
|
||||
Branch(Int32GreaterThanOrEqual(declaredNumArgs, \
|
||||
GetInt32Constant(InterpreterAssembly::ActualNumArgsOfCall::CALLARGS2)), &push1, &skip1); \
|
||||
Bind(&push1); \
|
||||
{ \
|
||||
GateRef a1Value = GetVregValue(sp, ZExtInt8ToPtr(a1)); \
|
||||
newSp = PointerSub(*newSp, GetIntPtrConstant(sizeof(JSTaggedType))); \
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a1Value); \
|
||||
Jump(&skip1); \
|
||||
} \
|
||||
Bind(&skip1); \
|
||||
CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8()
|
||||
|
||||
#define CALL_PUSH_ARGS_PREF_V8_V8_V8_V8() \
|
||||
@ -5324,19 +5324,19 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a2Value); \
|
||||
CALL_PUSH_ARGS_PREF_V8_V8_V8()
|
||||
|
||||
#define CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8_V8_V8() \
|
||||
Label push2(env); \
|
||||
Label skip2(env); \
|
||||
Branch(Int32GreaterThanOrEqual(declaredNumArgs, \
|
||||
GetInt32Constant(EcmaInterpreter::ActualNumArgsOfCall::CALLARGS3)), &push2, &skip2); \
|
||||
Bind(&push2); \
|
||||
{ \
|
||||
GateRef a2Value = GetVregValue(sp, ZExtInt8ToPtr(a2)); \
|
||||
newSp = PointerSub(*newSp, GetIntPtrConstant(sizeof(JSTaggedType))); \
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a2Value); \
|
||||
Jump(&skip2); \
|
||||
} \
|
||||
Bind(&skip2); \
|
||||
#define CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8_V8_V8() \
|
||||
Label push2(env); \
|
||||
Label skip2(env); \
|
||||
Branch(Int32GreaterThanOrEqual(declaredNumArgs, \
|
||||
GetInt32Constant(InterpreterAssembly::ActualNumArgsOfCall::CALLARGS3)), &push2, &skip2); \
|
||||
Bind(&push2); \
|
||||
{ \
|
||||
GateRef a2Value = GetVregValue(sp, ZExtInt8ToPtr(a2)); \
|
||||
newSp = PointerSub(*newSp, GetIntPtrConstant(sizeof(JSTaggedType))); \
|
||||
Store(VariableType::INT64(), glue, *newSp, GetIntPtrConstant(0), a2Value); \
|
||||
Jump(&skip2); \
|
||||
} \
|
||||
Bind(&skip2); \
|
||||
CALL_PUSH_ARGS_NO_EXTRA_PREF_V8_V8_V8()
|
||||
|
||||
#define CALL_PUSH_ARGS_PREF_IMM16_V8() \
|
||||
@ -5395,7 +5395,7 @@ DECLARE_ASM_HANDLER(HandleCallArg0DynPrefV8)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
||||
GateRef actualNumArgs = GetInt32Constant(EcmaInterpreter::ActualNumArgsOfCall::CALLARG0);
|
||||
GateRef actualNumArgs = GetInt32Constant(InterpreterAssembly::ActualNumArgsOfCall::CALLARG0);
|
||||
GateRef funcReg = ReadInst8_1(pc);
|
||||
CALL_INITIALIZE();
|
||||
GateRef callThis = FalseConstant();
|
||||
@ -5406,7 +5406,7 @@ DECLARE_ASM_HANDLER(HandleCallArg1DynPrefV8V8)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
||||
GateRef actualNumArgs = GetInt32Constant(EcmaInterpreter::ActualNumArgsOfCall::CALLARG1);
|
||||
GateRef actualNumArgs = GetInt32Constant(InterpreterAssembly::ActualNumArgsOfCall::CALLARG1);
|
||||
GateRef funcReg = ReadInst8_1(pc);
|
||||
GateRef a0 = ReadInst8_2(pc);
|
||||
CALL_INITIALIZE();
|
||||
@ -5418,7 +5418,7 @@ DECLARE_ASM_HANDLER(HandleCallArgs2DynPrefV8V8V8)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
||||
GateRef actualNumArgs = GetInt32Constant(EcmaInterpreter::ActualNumArgsOfCall::CALLARGS2);
|
||||
GateRef actualNumArgs = GetInt32Constant(InterpreterAssembly::ActualNumArgsOfCall::CALLARGS2);
|
||||
GateRef funcReg = ReadInst8_1(pc);
|
||||
GateRef a0 = ReadInst8_2(pc);
|
||||
GateRef a1 = ReadInst8_3(pc);
|
||||
@ -5431,7 +5431,7 @@ DECLARE_ASM_HANDLER(HandleCallArgs3DynPrefV8V8V8V8)
|
||||
{
|
||||
auto env = GetEnvironment();
|
||||
|
||||
GateRef actualNumArgs = GetInt32Constant(EcmaInterpreter::ActualNumArgsOfCall::CALLARGS3);
|
||||
GateRef actualNumArgs = GetInt32Constant(InterpreterAssembly::ActualNumArgsOfCall::CALLARGS3);
|
||||
GateRef funcReg = ReadInst8_1(pc);
|
||||
GateRef a0 = ReadInst8_2(pc);
|
||||
GateRef a1 = ReadInst8_3(pc);
|
||||
|
@ -138,6 +138,7 @@ EcmaVM::EcmaVM(JSRuntimeOptions options)
|
||||
}
|
||||
snapshotFileName_ = options_.GetSnapshotFile();
|
||||
frameworkAbcFileName_ = options_.GetFrameworkAbcFile();
|
||||
options_.ParseAsmInterOption();
|
||||
|
||||
auto runtime = Runtime::GetCurrent();
|
||||
notificationManager_ = chunk_.New<RuntimeNotificationManager>(runtime->GetInternalAllocator());
|
||||
@ -161,7 +162,6 @@ bool EcmaVM::Initialize()
|
||||
LOG_ECMA(FATAL) << "alloc factory_ failed";
|
||||
UNREACHABLE();
|
||||
}
|
||||
options_.ParseAsmInterOption();
|
||||
[[maybe_unused]] EcmaHandleScope scope(thread_);
|
||||
if (!snapshotDeserializeEnable_ || !VerifyFilePath(snapshotFileName_)) {
|
||||
LOG_ECMA(DEBUG) << "EcmaVM::Initialize run builtins";
|
||||
|
@ -319,12 +319,10 @@ public:
|
||||
};
|
||||
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedFrameBase), InterpretedFrameBase::SizeArch32, InterpretedFrameBase::SizeArch64);
|
||||
|
||||
// align with 8
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
||||
struct InterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
||||
base::AlignedPointer,
|
||||
base::AlignedPointer,
|
||||
base::AlignedSize,
|
||||
JSTaggedValue,
|
||||
JSTaggedValue,
|
||||
JSTaggedValue,
|
||||
@ -334,7 +332,6 @@ struct InterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSi
|
||||
enum class Index : size_t {
|
||||
PcIndex = 0,
|
||||
SpIndex,
|
||||
CallSizeIndex,
|
||||
ConstPoolIndex,
|
||||
FunctionIndex,
|
||||
ProFileTypeInfoIndex,
|
||||
@ -343,7 +340,6 @@ struct InterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSi
|
||||
BaseIndex,
|
||||
NumOfMembers
|
||||
};
|
||||
|
||||
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
||||
|
||||
inline JSTaggedType* GetPrevFrameFp()
|
||||
@ -356,54 +352,8 @@ struct InterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSi
|
||||
return reinterpret_cast<InterpretedFrame *>(sp) - 1;
|
||||
}
|
||||
|
||||
static uint32_t GetSpOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::SpIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static uint32_t GetCallSizeOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::CallSizeIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static uint32_t GetConstpoolOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::ConstPoolIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static uint32_t GetFunctionOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::FunctionIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static uint32_t GetProfileTypeInfoOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::ProFileTypeInfoIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static uint32_t GetAccOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::AccIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static uint32_t GetEnvOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::EnvIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static uint32_t GetBaseOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static constexpr uint32_t GetSize(bool isArch32)
|
||||
{
|
||||
return isArch32 ? InterpretedFrame::SizeArch32 : InterpretedFrame::SizeArch64;
|
||||
}
|
||||
|
||||
alignas(EAS) const uint8_t *pc {nullptr};
|
||||
alignas(EAS) JSTaggedType *sp {nullptr};
|
||||
alignas(EAS) size_t callSize {0};
|
||||
alignas(EAS) JSTaggedValue constpool {JSTaggedValue::Hole()};
|
||||
alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
|
||||
alignas(EAS) JSTaggedValue profileTypeInfo {JSTaggedValue::Hole()};
|
||||
@ -411,10 +361,77 @@ struct InterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSi
|
||||
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
||||
alignas(EAS) InterpretedFrameBase base;
|
||||
};
|
||||
|
||||
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedFrame), InterpretedFrame::SizeArch32, InterpretedFrame::SizeArch64);
|
||||
static_assert(sizeof(InterpretedFrame) % sizeof(uint64_t) == 0u); // the size should be the multiple of 8 bytes
|
||||
|
||||
static_assert(sizeof(InterpretedFrame) % sizeof(uint64_t) == 0u);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
||||
struct AsmInterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
||||
base::AlignedPointer,
|
||||
base::AlignedSize,
|
||||
JSTaggedValue,
|
||||
JSTaggedValue,
|
||||
JSTaggedValue,
|
||||
InterpretedFrameBase> {
|
||||
enum class Index : size_t {
|
||||
PcIndex = 0,
|
||||
CallSizeIndex,
|
||||
FunctionIndex,
|
||||
AccIndex,
|
||||
EnvIndex,
|
||||
BaseIndex,
|
||||
NumOfMembers
|
||||
};
|
||||
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
||||
|
||||
inline JSTaggedType* GetPrevFrameFp()
|
||||
{
|
||||
return base.prev;
|
||||
}
|
||||
|
||||
static AsmInterpretedFrame* GetFrameFromSp(JSTaggedType *sp)
|
||||
{
|
||||
return reinterpret_cast<AsmInterpretedFrame *>(sp) - 1;
|
||||
}
|
||||
|
||||
static size_t GetCallSizeOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::CallSizeIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static size_t GetFunctionOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::FunctionIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static size_t GetAccOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::AccIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static size_t GetEnvOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::EnvIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static size_t GetBaseOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32);
|
||||
}
|
||||
|
||||
static constexpr size_t GetSize(bool isArch32)
|
||||
{
|
||||
return isArch32 ? AsmInterpretedFrame::SizeArch32 : AsmInterpretedFrame::SizeArch64;
|
||||
}
|
||||
|
||||
alignas(EAS) const uint8_t *pc {nullptr};
|
||||
alignas(EAS) size_t callSize {0};
|
||||
alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
|
||||
alignas(EAS) JSTaggedValue acc {JSTaggedValue::Hole()};
|
||||
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
||||
alignas(EAS) InterpretedFrameBase base;
|
||||
};
|
||||
STATIC_ASSERT_EQ_ARCH(sizeof(AsmInterpretedFrame), AsmInterpretedFrame::SizeArch32, AsmInterpretedFrame::SizeArch64);
|
||||
static_assert(sizeof(AsmInterpretedFrame) % sizeof(uint64_t) == 0u); // the size should be the multiple of 8 bytes
|
||||
|
||||
struct OptimizedLeaveFrame {
|
||||
FrameType type;
|
||||
|
@ -70,7 +70,11 @@ void InterpretedFrameHandler::PrevFrame()
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
sp_ = frame->base.prev;
|
||||
}
|
||||
|
||||
@ -84,7 +88,11 @@ InterpretedFrameHandler InterpretedFrameHandler::GetPrevFrame() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
return InterpretedFrameHandler(frame->base.prev);
|
||||
}
|
||||
|
||||
@ -106,7 +114,11 @@ JSTaggedValue InterpretedFrameHandler::GetAcc() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
return frame->acc;
|
||||
}
|
||||
|
||||
@ -114,7 +126,11 @@ uint32_t InterpretedFrameHandler::GetSize() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
JSTaggedType *prevSp = frame->base.prev;
|
||||
ASSERT(prevSp != nullptr);
|
||||
auto size = (prevSp - sp_) - FRAME_STATE_SIZE;
|
||||
@ -125,7 +141,11 @@ uint32_t InterpretedFrameHandler::GetBytecodeOffset() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
JSMethod *method = ECMAObject::Cast(frame->function.GetTaggedObject())->GetCallTarget();
|
||||
auto offset = frame->pc - method->GetBytecodeArray();
|
||||
return static_cast<uint32_t>(offset);
|
||||
@ -135,7 +155,11 @@ JSMethod *InterpretedFrameHandler::GetMethod() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
return ECMAObject::Cast(frame->function.GetTaggedObject())->GetCallTarget();
|
||||
}
|
||||
|
||||
@ -143,7 +167,11 @@ JSTaggedValue InterpretedFrameHandler::GetFunction() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
return frame->function;
|
||||
}
|
||||
|
||||
@ -151,7 +179,11 @@ const uint8_t *InterpretedFrameHandler::GetPc() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
return frame->pc;
|
||||
}
|
||||
|
||||
@ -165,15 +197,30 @@ ConstantPool *InterpretedFrameHandler::GetConstpool() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
JSTaggedValue function = frame->function;
|
||||
if (function.IsJSFunction()) {
|
||||
JSTaggedValue constpool = JSFunction::Cast(function.GetTaggedObject())->GetConstantPool();
|
||||
return ConstantPool::Cast(constpool.GetTaggedObject());
|
||||
} else {
|
||||
return nullptr;
|
||||
}
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
return ConstantPool::Cast(frame->constpool.GetTaggedObject());
|
||||
#endif
|
||||
}
|
||||
|
||||
JSTaggedValue InterpretedFrameHandler::GetEnv() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
#endif
|
||||
return frame->env;
|
||||
}
|
||||
|
||||
@ -182,8 +229,23 @@ void InterpretedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisi
|
||||
JSTaggedType *current = sp_;
|
||||
if (current != nullptr) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = reinterpret_cast<AsmInterpretedFrame *>(current) - 1;
|
||||
if (frame->function != JSTaggedValue::Hole()) {
|
||||
uintptr_t start = ToUintPtr(current);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
AsmInterpretedFrame *prev_frame = reinterpret_cast<AsmInterpretedFrame *>(frame->base.prev) - 1;
|
||||
uintptr_t end = ToUintPtr(prev_frame);
|
||||
v1(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
|
||||
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->function)));
|
||||
if (frame->pc != nullptr) {
|
||||
// interpreter frame
|
||||
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->acc)));
|
||||
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->env)));
|
||||
}
|
||||
}
|
||||
#else
|
||||
InterpretedFrame *frame = reinterpret_cast<InterpretedFrame *>(current) - 1;
|
||||
|
||||
if (frame->sp != nullptr) {
|
||||
uintptr_t start = ToUintPtr(current);
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
@ -199,6 +261,7 @@ void InterpretedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisi
|
||||
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&frame->profileTypeInfo)));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@ -321,7 +384,11 @@ void FrameIterator::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) c
|
||||
while (current) {
|
||||
FrameType type = FrameHandler(current).GetFrameType();
|
||||
if (type == FrameType::INTERPRETER_FRAME || type == FrameType::INTERPRETER_FAST_NEW_FRAME) {
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterpretedFrame *frame = AsmInterpretedFrame::GetFrameFromSp(current);
|
||||
#else
|
||||
InterpretedFrame *frame = InterpretedFrame::GetFrameFromSp(current);
|
||||
#endif
|
||||
InterpretedFrameHandler(current).Iterate(v0, v1);
|
||||
current = frame->GetPrevFrameFp();
|
||||
} else if (type == FrameType::OPTIMIZED_FRAME) {
|
||||
|
@ -45,9 +45,15 @@ public:
|
||||
bool IsBreakFrame() const
|
||||
{
|
||||
ASSERT(HasFrame());
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
AsmInterpretedFrame *state = AsmInterpretedFrame::GetFrameFromSp(sp_);
|
||||
return state->function == JSTaggedValue::Hole();
|
||||
#else
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
InterpretedFrame *state = InterpretedFrame::GetFrameFromSp(sp_);
|
||||
return state->sp == nullptr;
|
||||
#endif
|
||||
}
|
||||
void PrevFrame();
|
||||
|
||||
|
@ -439,6 +439,12 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const JSHandle<JSFuncti
|
||||
JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& params)
|
||||
{
|
||||
INTERPRETER_TRACE(thread, Execute);
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterParsedOption asmInterOpt = thread->GetEcmaVM()->GetJSOptions().GetAsmInterParsedOption();
|
||||
if (asmInterOpt.enableAsm) {
|
||||
return InterpreterAssembly::Execute(thread, params);
|
||||
}
|
||||
#endif
|
||||
JSMethod *method = params.callTarget->GetCallTarget();
|
||||
if (method->IsNativeWithCallField()) {
|
||||
return EcmaInterpreter::ExecuteNative(thread, params);
|
||||
@ -544,12 +550,7 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(pc);
|
||||
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodEntryEvent(thread, method);
|
||||
AsmInterParsedOption asmInterOpt = thread->GetEcmaVM()->GetJSOptions().GetAsmInterParsedOption();
|
||||
if (asmInterOpt.enableAsm) {
|
||||
InterpreterAssembly::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), pc, newSp);
|
||||
} else {
|
||||
EcmaInterpreter::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), pc, newSp);
|
||||
}
|
||||
EcmaInterpreter::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), pc, newSp);
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodExitEvent(thread, method);
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
@ -565,6 +566,12 @@ JSTaggedValue EcmaInterpreter::Execute(JSThread *thread, const CallParams& param
|
||||
JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSHandle<GeneratorContext> context)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterParsedOption asmInterOpt = thread->GetEcmaVM()->GetJSOptions().GetAsmInterParsedOption();
|
||||
if (asmInterOpt.enableAsm) {
|
||||
return InterpreterAssembly::GeneratorReEnterInterpreter(thread, context);
|
||||
}
|
||||
#endif
|
||||
JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
|
||||
JSMethod *method = func->GetCallTarget();
|
||||
|
||||
@ -617,12 +624,7 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH
|
||||
thread->SetCurrentSPFrame(newSp);
|
||||
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodEntryEvent(thread, method);
|
||||
AsmInterParsedOption asmInterOpt = thread->GetEcmaVM()->GetJSOptions().GetAsmInterParsedOption();
|
||||
if (asmInterOpt.enableAsm) {
|
||||
InterpreterAssembly::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), resumePc, newSp);
|
||||
} else {
|
||||
EcmaInterpreter::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), resumePc, newSp);
|
||||
}
|
||||
EcmaInterpreter::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), resumePc, newSp);
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodExitEvent(thread, method);
|
||||
|
||||
JSTaggedValue res = state->acc;
|
||||
@ -634,6 +636,12 @@ JSTaggedValue EcmaInterpreter::GeneratorReEnterInterpreter(JSThread *thread, JSH
|
||||
void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> context)
|
||||
{
|
||||
[[maybe_unused]] EcmaHandleScope handleScope(thread);
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterParsedOption asmInterOpt = thread->GetEcmaVM()->GetJSOptions().GetAsmInterParsedOption();
|
||||
if (asmInterOpt.enableAsm) {
|
||||
return InterpreterAssembly::ChangeGenContext(thread, context);
|
||||
}
|
||||
#endif
|
||||
JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
|
||||
JSMethod *method = func->GetCallTarget();
|
||||
|
||||
@ -687,6 +695,12 @@ void EcmaInterpreter::ChangeGenContext(JSThread *thread, JSHandle<GeneratorConte
|
||||
|
||||
void EcmaInterpreter::ResumeContext(JSThread *thread)
|
||||
{
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterParsedOption asmInterOpt = thread->GetEcmaVM()->GetJSOptions().GetAsmInterParsedOption();
|
||||
if (asmInterOpt.enableAsm) {
|
||||
return InterpreterAssembly::ResumeContext(thread);
|
||||
}
|
||||
#endif
|
||||
JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
thread->SetCurrentSPFrame(state->base.prev);
|
||||
@ -3742,6 +3756,12 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
|
||||
void EcmaInterpreter::InitStackFrame(JSThread *thread)
|
||||
{
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
AsmInterParsedOption asmInterOpt = thread->GetEcmaVM()->GetJSOptions().GetAsmInterParsedOption();
|
||||
if (asmInterOpt.enableAsm) {
|
||||
return InterpreterAssembly::InitStackFrame(thread);
|
||||
}
|
||||
#endif
|
||||
uint64_t *prevSp = const_cast<uint64_t *>(thread->GetCurrentSPFrame());
|
||||
InterpretedFrame *state = GET_FRAME(prevSp);
|
||||
state->pc = nullptr;
|
||||
@ -4072,6 +4092,45 @@ std::string GetEcmaOpcodeStr(EcmaOpcode opcode)
|
||||
}
|
||||
return "bytecode-" + std::to_string(opcode);
|
||||
}
|
||||
#undef LOG_INST
|
||||
#undef HANDLE_OPCODE
|
||||
#undef ADVANCE_PC
|
||||
#undef GOTO_NEXT
|
||||
#undef DISPATCH
|
||||
#undef DISPATCH_OFFSET
|
||||
#undef GET_FRAME
|
||||
#undef SAVE_PC
|
||||
#undef SAVE_ACC
|
||||
#undef RESTORE_ACC
|
||||
#undef INTERPRETER_GOTO_EXCEPTION_HANDLER
|
||||
#undef INTERPRETER_HANDLE_RETURN
|
||||
#undef CHECK_SWITCH_TO_DEBUGGER_TABLE
|
||||
#undef REAL_GOTO_DISPATCH_OPCODE
|
||||
#undef REAL_GOTO_EXCEPTION_HANDLER
|
||||
#undef INTERPRETER_RETURN_IF_ABRUPT
|
||||
#undef NOTIFY_DEBUGGER_EVENT
|
||||
#undef CALL_INITIALIZE
|
||||
#undef CALL_PUSH_UNDEFINED
|
||||
#undef CALL_PUSH_ARGS_0
|
||||
#undef CALL_PUSH_ARGS_1
|
||||
#undef CALL_PUSH_ARGS_2
|
||||
#undef CALL_PUSH_ARGS_3
|
||||
#undef CALL_PUSH_ARGS_I
|
||||
#undef CALL_PUSH_ARGS_I_THIS
|
||||
#undef CALL_PUSH_ARGS_0_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_1_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_2_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_3_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_I_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_I_THIS_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS
|
||||
#undef UPDATE_HOTNESS_COUNTER_NON_ACC
|
||||
#undef UPDATE_HOTNESS_COUNTER
|
||||
#undef GET_VREG
|
||||
#undef GET_VREG_VALUE
|
||||
#undef SET_VREG
|
||||
#undef GET_ACC
|
||||
#undef SET_ACC
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
|
@ -28,7 +28,11 @@ class ECMAObject;
|
||||
class GeneratorContext;
|
||||
|
||||
// NOLINTNEXTLINE(bugprone-sizeof-expression)
|
||||
#if ECMASCRIPT_COMPILE_ASM_INTERPRETER
|
||||
static const uint32_t FRAME_STATE_SIZE = sizeof(AsmInterpretedFrame) / sizeof(uint64_t);
|
||||
#else
|
||||
static const uint32_t FRAME_STATE_SIZE = sizeof(InterpretedFrame) / sizeof(uint64_t);
|
||||
#endif
|
||||
|
||||
static constexpr uint32_t RESERVED_CALL_ARGCOUNT = 3;
|
||||
static constexpr uint32_t RESERVED_INDEX_CALL_TARGET = 0;
|
||||
|
@ -63,7 +63,7 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
ADVANCE_PC(offset) \
|
||||
SAVE_PC(); \
|
||||
SAVE_ACC(); \
|
||||
InterpretedFrame *frame = GET_FRAME(sp); \
|
||||
AsmInterpretedFrame *frame = GET_ASM_FRAME(sp); \
|
||||
auto currentMethod = ECMAObject::Cast(frame->function.GetTaggedObject())->GetCallTarget(); \
|
||||
currentMethod->SetHotnessCounter(static_cast<uint32_t>(hotnessCounter)); \
|
||||
return; \
|
||||
@ -72,14 +72,14 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
#define DISPATCH(format) DISPATCH_OFFSET(BytecodeInstruction::Size(format))
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define GET_FRAME(CurrentSp) \
|
||||
(reinterpret_cast<InterpretedFrame *>(CurrentSp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#define GET_ASM_FRAME(CurrentSp) \
|
||||
(reinterpret_cast<AsmInterpretedFrame *>(CurrentSp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define SAVE_PC() (GET_FRAME(sp)->pc = pc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#define SAVE_PC() (GET_ASM_FRAME(sp)->pc = pc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define SAVE_ACC() (GET_FRAME(sp)->acc = acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#define SAVE_ACC() (GET_ASM_FRAME(sp)->acc = acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define RESTORE_ACC() (acc = GET_FRAME(sp)->acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
#define RESTORE_ACC() (acc = GET_ASM_FRAME(sp)->acc) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
||||
#define INTERPRETER_GOTO_EXCEPTION_HANDLER() \
|
||||
@ -337,11 +337,10 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
} \
|
||||
EcmaRuntimeCallInfo ecmaRuntimeCallInfo(thread, actualNumArgs + NUM_MANDATORY_JSFUNC_ARGS, \
|
||||
reinterpret_cast<JSTaggedValue *>(newSp)); \
|
||||
InterpretedFrame *state = GET_FRAME(newSp); \
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp); \
|
||||
state->base.prev = sp; \
|
||||
state->base.type = FrameType::INTERPRETER_FRAME; \
|
||||
state->pc = nullptr; \
|
||||
state->sp = newSp; \
|
||||
state->function = funcValue; \
|
||||
thread->SetCurrentSPFrame(newSp); \
|
||||
LOG(DEBUG, INTERPRETER) << "Entry: Runtime Call."; \
|
||||
@ -387,22 +386,18 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
int32_t numVregs = static_cast<int32_t>(JSMethod::NumVregsBits::Decode(callField)); \
|
||||
/* push vregs */ \
|
||||
CALL_PUSH_UNDEFINED(numVregs); \
|
||||
SAVE_PC(); \
|
||||
if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) { \
|
||||
INTERPRETER_GOTO_EXCEPTION_HANDLER(); \
|
||||
} \
|
||||
GET_FRAME(sp)->callSize = GetJumpSizeAfterCall(pc); \
|
||||
InterpretedFrame *state = GET_FRAME(newSp); \
|
||||
SAVE_PC(); \
|
||||
GET_ASM_FRAME(sp)->callSize = GetJumpSizeAfterCall(pc); \
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp); \
|
||||
state->base.prev = sp; \
|
||||
state->base.type = FrameType::INTERPRETER_FRAME; \
|
||||
state->pc = pc = JSMethod::Cast(method)->GetBytecodeArray(); \
|
||||
state->sp = sp = newSp; \
|
||||
pc = JSMethod::Cast(method)->GetBytecodeArray(); /* will be stored in DISPATCH_OFFSET */ \
|
||||
sp = newSp; /* for DISPATCH_OFFSET */ \
|
||||
state->function = funcValue; \
|
||||
state->acc = JSTaggedValue::Hole(); \
|
||||
state->constpool = JSFunction::Cast(funcObject)->GetConstantPool(); \
|
||||
constpool = state->constpool; \
|
||||
state->profileTypeInfo = JSFunction::Cast(funcObject)->GetProfileTypeInfo(); \
|
||||
profileTypeInfo = state->profileTypeInfo; \
|
||||
acc = JSTaggedValue::Hole(); /* will be stored in DISPATCH_OFFSET */ \
|
||||
JSTaggedValue env = JSFunction::Cast(funcObject)->GetLexicalEnv(); \
|
||||
state->env = env; \
|
||||
hotnessCounter = static_cast<int32_t>(method->GetHotnessCounter()); \
|
||||
@ -418,7 +413,7 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
void InterpreterAssembly::RunInternal(JSThread *thread, ConstantPool *constpool, const uint8_t *pc, JSTaggedType *sp)
|
||||
{
|
||||
JSTaggedValue acc = JSTaggedValue::Hole();
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
auto method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget();
|
||||
auto hotnessCounter = static_cast<int32_t>(method->GetHotnessCounter());
|
||||
auto profileTypeInfo = JSFunction::Cast(state->function.GetTaggedObject())->GetProfileTypeInfo();
|
||||
@ -428,6 +423,292 @@ void InterpreterAssembly::RunInternal(JSThread *thread, ConstantPool *constpool,
|
||||
asmEntry(thread->GetGlueAddr(), pc, sp, JSTaggedValue(constpool), profileTypeInfo, acc, hotnessCounter);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::InitStackFrame(JSThread *thread)
|
||||
{
|
||||
uint64_t *prevSp = const_cast<uint64_t *>(thread->GetCurrentSPFrame());
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(prevSp);
|
||||
state->pc = nullptr;
|
||||
state->function = JSTaggedValue::Hole();
|
||||
state->acc = JSTaggedValue::Hole();
|
||||
state->base.type = FrameType::INTERPRETER_FRAME;
|
||||
state->base.prev = nullptr;
|
||||
}
|
||||
|
||||
JSTaggedValue InterpreterAssembly::ExecuteNative(JSThread *thread, const CallParams& params)
|
||||
{
|
||||
JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
|
||||
JSMethod *method = params.callTarget->GetCallTarget();
|
||||
ASSERT(method->GetNumVregsWithCallField() == 0);
|
||||
uint32_t numActualArgs = params.argc + RESERVED_CALL_ARGCOUNT;
|
||||
// Tags and values of thread, new_tgt and argv_length are put into frames too for native frames
|
||||
// NOLINTNEXTLINE(hicpp-signed-bitwise)
|
||||
size_t frameSize = FRAME_STATE_SIZE + numActualArgs;
|
||||
JSTaggedType *newSp = sp - frameSize; // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
EcmaRuntimeCallInfo ecmaRuntimeCallInfo(thread, numActualArgs, reinterpret_cast<JSTaggedValue *>(newSp));
|
||||
newSp[RESERVED_INDEX_CALL_TARGET] = reinterpret_cast<JSTaggedType>(params.callTarget);
|
||||
newSp[RESERVED_INDEX_NEW_TARGET] = params.newTarget;
|
||||
newSp[RESERVED_INDEX_THIS] = params.thisArg;
|
||||
for (size_t i = 0; i < params.argc; i++) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
newSp[i + RESERVED_CALL_ARGCOUNT] = params.argv[i];
|
||||
}
|
||||
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp);
|
||||
state->base.prev = sp;
|
||||
state->base.type = FrameType::INTERPRETER_FRAME;
|
||||
state->pc = nullptr;
|
||||
state->function = JSTaggedValue(params.callTarget);
|
||||
thread->SetCurrentSPFrame(newSp);
|
||||
#if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
|
||||
CpuProfiler::IsNeedAndGetStack(thread);
|
||||
#endif
|
||||
thread->CheckSafepoint();
|
||||
LOG(DEBUG, INTERPRETER) << "Entry: Runtime Call.";
|
||||
JSTaggedValue tagged =
|
||||
reinterpret_cast<EcmaEntrypoint>(const_cast<void *>(method->GetNativePointer()))(&ecmaRuntimeCallInfo);
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call.";
|
||||
thread->SetCurrentSPFrame(sp);
|
||||
#if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
|
||||
CpuProfiler::IsNeedAndGetStack(thread);
|
||||
#endif
|
||||
return tagged;
|
||||
}
|
||||
|
||||
JSTaggedValue InterpreterAssembly::Execute(JSThread *thread, const CallParams& params)
|
||||
{
|
||||
JSMethod *method = params.callTarget->GetCallTarget();
|
||||
if (method->IsNativeWithCallField()) {
|
||||
return InterpreterAssembly::ExecuteNative(thread, params);
|
||||
}
|
||||
JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
JSTaggedType *newSp = sp - FRAME_STATE_SIZE;
|
||||
// push break state
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
AsmInterpretedFrame *breakState = GET_ASM_FRAME(newSp);
|
||||
auto leaveFrame = const_cast<JSTaggedType *>(thread->GetLastLeaveFrame());
|
||||
if (leaveFrame != nullptr) {
|
||||
[[maybe_unused]] OptimizedLeaveFrame *frame = OptimizedLeaveFrame::GetFrameFromSp(leaveFrame);
|
||||
frame->callsiteFp = reinterpret_cast<uintptr_t>(sp);
|
||||
breakState->base.prev = leaveFrame;
|
||||
} else {
|
||||
breakState->base.prev = sp;
|
||||
}
|
||||
breakState->pc = nullptr;
|
||||
breakState->function = JSTaggedValue::Hole();
|
||||
breakState->base.type = FrameType::INTERPRETER_FRAME;
|
||||
JSTaggedType *prevSp = newSp;
|
||||
|
||||
int32_t actualNumArgs = static_cast<int32_t>(params.argc);
|
||||
int32_t declaredNumArgs = static_cast<int32_t>(method->GetNumArgsWithCallField());
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
newSp -= FRAME_STATE_SIZE;
|
||||
// push args
|
||||
if (actualNumArgs == declaredNumArgs) {
|
||||
// fast path, just push all args directly
|
||||
for (int i = actualNumArgs - 1; i >= 0; i--) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
*(--newSp) = params.argv[i];
|
||||
}
|
||||
} else {
|
||||
// slow path
|
||||
if (!method->HaveExtraWithCallField()) {
|
||||
// push length = declaredNumArgs, may push undefined
|
||||
CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);
|
||||
for (int i = std::min(actualNumArgs, declaredNumArgs) - 1; i >= 0; i--) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
*(--newSp) = params.argv[i];
|
||||
}
|
||||
} else {
|
||||
// push actualNumArgs in the end, then all args, may push undefined
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
*(--newSp) = JSTaggedValue(actualNumArgs).GetRawData();
|
||||
CALL_PUSH_UNDEFINED(declaredNumArgs - actualNumArgs);
|
||||
for (int i = actualNumArgs - 1; i >= 0; i--) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
*(--newSp) = params.argv[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
uint64_t callField = method->GetCallField();
|
||||
if ((callField & CALL_TYPE_MASK) != 0) {
|
||||
// not normal call type, setting func/newTarget/this cannot be skipped
|
||||
if (method->HaveThisWithCallField()) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
*(--newSp) = params.thisArg; // push this
|
||||
}
|
||||
if (method->HaveNewTargetWithCallField()) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
*(--newSp) = params.newTarget; // push new target
|
||||
}
|
||||
if (method->HaveFuncWithCallField()) {
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
*(--newSp) = reinterpret_cast<JSTaggedType>(params.callTarget); // push func
|
||||
}
|
||||
}
|
||||
int32_t numVregs = static_cast<int32_t>(method->GetNumVregsWithCallField());
|
||||
// push vregs
|
||||
CALL_PUSH_UNDEFINED(numVregs);
|
||||
if (UNLIKELY(thread->DoStackOverflowCheck(newSp))) {
|
||||
return JSTaggedValue::Undefined();
|
||||
}
|
||||
|
||||
const uint8_t *pc = method->GetBytecodeArray();
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp);
|
||||
state->pc = pc;
|
||||
state->function = JSTaggedValue(params.callTarget);
|
||||
state->acc = JSTaggedValue::Hole();
|
||||
JSHandle<JSTaggedValue> callTargetHandle(thread, params.callTarget);
|
||||
JSHandle<JSFunction> thisFunc = JSHandle<JSFunction>::Cast(callTargetHandle);
|
||||
JSTaggedValue constpool = thisFunc->GetConstantPool();
|
||||
state->base.prev = prevSp;
|
||||
state->base.type = FrameType::INTERPRETER_FRAME;
|
||||
|
||||
JSTaggedValue env = thisFunc->GetLexicalEnv();
|
||||
state->env = env;
|
||||
thread->SetCurrentSPFrame(newSp);
|
||||
#if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
|
||||
CpuProfiler::IsNeedAndGetStack(thread);
|
||||
#endif
|
||||
thread->CheckSafepoint();
|
||||
LOG(DEBUG, INTERPRETER) << "break Entry: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(newSp) << " "
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(pc);
|
||||
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodEntryEvent(thread, method);
|
||||
InterpreterAssembly::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), pc, newSp);
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodExitEvent(thread, method);
|
||||
|
||||
// NOLINTNEXTLINE(readability-identifier-naming)
|
||||
const JSTaggedValue resAcc = state->acc;
|
||||
// pop frame
|
||||
thread->SetCurrentSPFrame(sp);
|
||||
#if ECMASCRIPT_ENABLE_ACTIVE_CPUPROFILER
|
||||
CpuProfiler::IsNeedAndGetStack(thread);
|
||||
#endif
|
||||
return resAcc;
|
||||
}
|
||||
|
||||
JSTaggedValue InterpreterAssembly::GeneratorReEnterInterpreter(JSThread *thread, JSHandle<GeneratorContext> context)
|
||||
{
|
||||
JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
|
||||
JSMethod *method = func->GetCallTarget();
|
||||
|
||||
JSTaggedType *currentSp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
|
||||
// push break frame
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
JSTaggedType *breakSp = currentSp - FRAME_STATE_SIZE;
|
||||
if (thread->DoStackOverflowCheck(breakSp) || thread->HasPendingException()) {
|
||||
return JSTaggedValue::Exception();
|
||||
}
|
||||
AsmInterpretedFrame *breakState = GET_ASM_FRAME(breakSp);
|
||||
breakState->pc = nullptr;
|
||||
breakState->function = JSTaggedValue::Hole();
|
||||
breakState->base.prev = currentSp;
|
||||
breakState->base.type = FrameType::INTERPRETER_FRAME;
|
||||
|
||||
// create new frame and resume sp and pc
|
||||
uint32_t nregs = context->GetNRegs();
|
||||
size_t newFrameSize = FRAME_STATE_SIZE + nregs;
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic
|
||||
JSTaggedType *newSp = breakSp - newFrameSize;
|
||||
if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
|
||||
return JSTaggedValue::Exception();
|
||||
}
|
||||
JSHandle<TaggedArray> regsArray(thread, context->GetRegsArray());
|
||||
for (size_t i = 0; i < nregs; i++) {
|
||||
newSp[i] = regsArray->Get(i).GetRawData(); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
}
|
||||
JSTaggedValue constpool = func->GetConstantPool();
|
||||
uint32_t pcOffset = context->GetBCOffset();
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
const uint8_t *resumePc = method->GetBytecodeArray() + pcOffset +
|
||||
BytecodeInstruction::Size(BytecodeInstruction::Format::PREF_V8_V8);
|
||||
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp);
|
||||
state->pc = resumePc;
|
||||
state->function = func.GetTaggedValue();
|
||||
state->acc = context->GetAcc();
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
state->base.prev = breakSp;
|
||||
state->base.type = FrameType::INTERPRETER_FRAME;
|
||||
JSTaggedValue env = context->GetLexicalEnv();
|
||||
state->env = env;
|
||||
// execute interpreter
|
||||
thread->SetCurrentSPFrame(newSp);
|
||||
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodEntryEvent(thread, method);
|
||||
InterpreterAssembly::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), resumePc, newSp);
|
||||
thread->GetEcmaVM()->GetNotificationManager()->MethodExitEvent(thread, method);
|
||||
|
||||
JSTaggedValue res = state->acc;
|
||||
// pop frame
|
||||
thread->SetCurrentSPFrame(currentSp);
|
||||
return res;
|
||||
}
|
||||
|
||||
void InterpreterAssembly::ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> context)
|
||||
{
|
||||
JSHandle<JSFunction> func = JSHandle<JSFunction>::Cast(JSHandle<JSTaggedValue>(thread, context->GetMethod()));
|
||||
JSMethod *method = func->GetCallTarget();
|
||||
|
||||
JSTaggedType *currentSp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
|
||||
// push break frame
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
JSTaggedType *breakSp = currentSp - FRAME_STATE_SIZE;
|
||||
if (thread->DoStackOverflowCheck(breakSp) || thread->HasPendingException()) {
|
||||
return;
|
||||
}
|
||||
AsmInterpretedFrame *breakState = GET_ASM_FRAME(breakSp);
|
||||
breakState->pc = nullptr;
|
||||
breakState->function = JSTaggedValue::Hole();
|
||||
breakState->base.prev = currentSp;
|
||||
breakState->base.type = FrameType::INTERPRETER_FRAME;
|
||||
|
||||
// create new frame and resume sp and pc
|
||||
uint32_t nregs = context->GetNRegs();
|
||||
size_t newFrameSize = FRAME_STATE_SIZE + nregs;
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic
|
||||
JSTaggedType *newSp = breakSp - newFrameSize;
|
||||
if (thread->DoStackOverflowCheck(newSp) || thread->HasPendingException()) {
|
||||
return;
|
||||
}
|
||||
JSHandle<TaggedArray> regsArray(thread, context->GetRegsArray());
|
||||
for (size_t i = 0; i < nregs; i++) {
|
||||
newSp[i] = regsArray->Get(i).GetRawData(); // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
}
|
||||
uint32_t pcOffset = context->GetBCOffset();
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
const uint8_t *pc = method->GetBytecodeArray() + pcOffset;
|
||||
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp);
|
||||
state->pc = pc;
|
||||
state->function = func.GetTaggedValue();
|
||||
state->acc = context->GetAcc();
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
state->base.prev = breakSp;
|
||||
state->base.type = FrameType::INTERPRETER_FRAME;
|
||||
state->env = context->GetLexicalEnv();
|
||||
|
||||
thread->SetCurrentSPFrame(newSp);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::ResumeContext(JSThread *thread)
|
||||
{
|
||||
JSTaggedType *sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
thread->SetCurrentSPFrame(state->base.prev);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::HandleMovV4V4(
|
||||
JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo,
|
||||
JSTaggedValue acc, int32_t hotnessCounter)
|
||||
@ -746,8 +1027,8 @@ void InterpreterAssembly::HandleReturnDyn(
|
||||
JSTaggedValue acc, int32_t hotnessCounter)
|
||||
{
|
||||
LOG_INST() << "returnla ";
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(state->sp) << " "
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(state->pc);
|
||||
JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget();
|
||||
[[maybe_unused]] auto fistPC = method->GetInstructions();
|
||||
@ -755,7 +1036,7 @@ void InterpreterAssembly::HandleReturnDyn(
|
||||
method->SetHotnessCounter(static_cast<uint32_t>(hotnessCounter));
|
||||
sp = state->base.prev;
|
||||
ASSERT(sp != nullptr);
|
||||
InterpretedFrame *prevState = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *prevState = GET_ASM_FRAME(sp);
|
||||
pc = prevState->pc;
|
||||
|
||||
// break frame
|
||||
@ -766,13 +1047,12 @@ void InterpreterAssembly::HandleReturnDyn(
|
||||
}
|
||||
thread->SetCurrentSPFrame(sp);
|
||||
|
||||
constpool = prevState->constpool;
|
||||
profileTypeInfo = prevState->profileTypeInfo;
|
||||
method = ECMAObject::Cast(prevState->function.GetTaggedObject())->GetCallTarget();
|
||||
JSFunction* prevFunc = JSFunction::Cast(prevState->function.GetTaggedObject());
|
||||
method = prevFunc->GetMethod();
|
||||
hotnessCounter = static_cast<int32_t>(method->GetHotnessCounter());
|
||||
|
||||
size_t jumpSize = GetJumpSizeAfterCall(pc);
|
||||
DISPATCH_OFFSET(jumpSize);
|
||||
ASSERT(prevState->callSize == GetJumpSizeAfterCall(pc));
|
||||
DISPATCH_OFFSET(prevState->callSize);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::HandleReturnUndefinedPref(
|
||||
@ -780,7 +1060,7 @@ void InterpreterAssembly::HandleReturnUndefinedPref(
|
||||
JSTaggedValue acc, int32_t hotnessCounter)
|
||||
{
|
||||
LOG_INST() << "return.undefined";
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(state->pc);
|
||||
JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget();
|
||||
@ -789,7 +1069,7 @@ void InterpreterAssembly::HandleReturnUndefinedPref(
|
||||
method->SetHotnessCounter(static_cast<uint32_t>(hotnessCounter));
|
||||
sp = state->base.prev;
|
||||
ASSERT(sp != nullptr);
|
||||
InterpretedFrame *prevState = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *prevState = GET_ASM_FRAME(sp);
|
||||
pc = prevState->pc;
|
||||
|
||||
// break frame
|
||||
@ -800,14 +1080,13 @@ void InterpreterAssembly::HandleReturnUndefinedPref(
|
||||
}
|
||||
thread->SetCurrentSPFrame(sp);
|
||||
|
||||
constpool = prevState->constpool;
|
||||
profileTypeInfo = prevState->profileTypeInfo;
|
||||
method = ECMAObject::Cast(prevState->function.GetTaggedObject())->GetCallTarget();
|
||||
JSFunction* prevFunc = JSFunction::Cast(prevState->function.GetTaggedObject());
|
||||
method = prevFunc->GetMethod();
|
||||
hotnessCounter = static_cast<int32_t>(method->GetHotnessCounter());
|
||||
|
||||
acc = JSTaggedValue::Undefined();
|
||||
size_t jumpSize = GetJumpSizeAfterCall(pc);
|
||||
DISPATCH_OFFSET(jumpSize);
|
||||
ASSERT(prevState->callSize == GetJumpSizeAfterCall(pc));
|
||||
DISPATCH_OFFSET(prevState->callSize);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::HandleLdNanPref(
|
||||
@ -904,7 +1183,7 @@ void InterpreterAssembly::HandleLdLexEnvDynPref(
|
||||
JSTaggedValue acc, int32_t hotnessCounter)
|
||||
{
|
||||
LOG_INST() << "intrinsics::ldlexenvDyn ";
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue currentLexenv = state->env;
|
||||
SET_ACC(currentLexenv);
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_NONE);
|
||||
@ -1807,7 +2086,7 @@ void InterpreterAssembly::HandleDefineFuncDynPrefId16Imm16V8(
|
||||
JSTaggedValue envHandle = GET_VREG_VALUE(v0);
|
||||
result->SetLexicalEnv(thread, envHandle);
|
||||
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_ASM_FRAME(sp)->function).GetTaggedObject());
|
||||
result->SetModule(thread, currentFunc->GetModule());
|
||||
SET_ACC(JSTaggedValue(result))
|
||||
|
||||
@ -1844,7 +2123,7 @@ void InterpreterAssembly::HandleDefineNCFuncDynPrefId16Imm16V8(
|
||||
result->SetLexicalEnv(thread, env);
|
||||
result->SetHomeObject(thread, homeObject);
|
||||
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_ASM_FRAME(sp)->function).GetTaggedObject());
|
||||
result->SetModule(thread, currentFunc->GetModule());
|
||||
SET_ACC(JSTaggedValue(result));
|
||||
|
||||
@ -1878,7 +2157,7 @@ void InterpreterAssembly::HandleDefineMethodPrefId16Imm16V8(
|
||||
JSTaggedValue taggedCurEnv = GET_VREG_VALUE(v0);
|
||||
result->SetLexicalEnv(thread, taggedCurEnv);
|
||||
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_ASM_FRAME(sp)->function).GetTaggedObject());
|
||||
result->SetModule(thread, currentFunc->GetModule());
|
||||
SET_ACC(JSTaggedValue(result));
|
||||
|
||||
@ -2011,7 +2290,7 @@ void InterpreterAssembly::HandleLdLexVarDynPrefImm16Imm16(
|
||||
|
||||
LOG_INST() << "intrinsics::ldlexvardyn"
|
||||
<< " level:" << level << " slot:" << slot;
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue currentLexenv = state->env;
|
||||
JSTaggedValue env(currentLexenv);
|
||||
for (int i = 0; i < level; i++) {
|
||||
@ -2032,7 +2311,7 @@ void InterpreterAssembly::HandleLdLexVarDynPrefImm8Imm8(
|
||||
|
||||
LOG_INST() << "intrinsics::ldlexvardyn"
|
||||
<< " level:" << level << " slot:" << slot;
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue currentLexenv = state->env;
|
||||
JSTaggedValue env(currentLexenv);
|
||||
for (int i = 0; i < level; i++) {
|
||||
@ -2053,7 +2332,7 @@ void InterpreterAssembly::HandleLdLexVarDynPrefImm4Imm4(
|
||||
|
||||
LOG_INST() << "intrinsics::ldlexvardyn"
|
||||
<< " level:" << level << " slot:" << slot;
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue currentLexenv = state->env;
|
||||
JSTaggedValue env(currentLexenv);
|
||||
for (int i = 0; i < level; i++) {
|
||||
@ -2076,7 +2355,7 @@ void InterpreterAssembly::HandleStLexVarDynPrefImm16Imm16V8(
|
||||
<< " level:" << level << " slot:" << slot << " v" << v0;
|
||||
|
||||
JSTaggedValue value = GET_VREG_VALUE(v0);
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue env = state->env;
|
||||
for (int i = 0; i < level; i++) {
|
||||
JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
|
||||
@ -2099,7 +2378,7 @@ void InterpreterAssembly::HandleStLexVarDynPrefImm8Imm8V8(
|
||||
<< " level:" << level << " slot:" << slot << " v" << v0;
|
||||
|
||||
JSTaggedValue value = GET_VREG_VALUE(v0);
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue env = state->env;
|
||||
for (int i = 0; i < level; i++) {
|
||||
JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
|
||||
@ -2122,7 +2401,7 @@ void InterpreterAssembly::HandleStLexVarDynPrefImm4Imm4V8(
|
||||
<< " level:" << level << " slot:" << slot << " v" << v0;
|
||||
|
||||
JSTaggedValue value = GET_VREG_VALUE(v0);
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue env = state->env;
|
||||
for (int i = 0; i < level; i++) {
|
||||
JSTaggedValue taggedParentEnv = LexicalEnv::Cast(env.GetTaggedObject())->GetParentEnv();
|
||||
@ -2149,7 +2428,7 @@ void InterpreterAssembly::HandleNewLexEnvDynPrefImm16(
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
}
|
||||
SET_ACC(res);
|
||||
GET_FRAME(sp)->env = res;
|
||||
GET_ASM_FRAME(sp)->env = res;
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_IMM16);
|
||||
}
|
||||
|
||||
@ -2157,10 +2436,10 @@ void InterpreterAssembly::HandlePopLexEnvDynPref(
|
||||
JSThread *thread, const uint8_t *pc, JSTaggedType *sp, JSTaggedValue constpool, JSTaggedValue profileTypeInfo,
|
||||
JSTaggedValue acc, int32_t hotnessCounter)
|
||||
{
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSTaggedValue currentLexenv = state->env;
|
||||
JSTaggedValue parentLexenv = LexicalEnv::Cast(currentLexenv.GetTaggedObject())->GetParentEnv();
|
||||
GET_FRAME(sp)->env = parentLexenv;
|
||||
GET_ASM_FRAME(sp)->env = parentLexenv;
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_NONE);
|
||||
}
|
||||
|
||||
@ -2197,7 +2476,7 @@ void InterpreterAssembly::HandleSuspendGeneratorPrefV8V8(
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
SET_ACC(res);
|
||||
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget();
|
||||
[[maybe_unused]] auto fistPC = method->GetInstructions();
|
||||
UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
|
||||
@ -2205,7 +2484,7 @@ void InterpreterAssembly::HandleSuspendGeneratorPrefV8V8(
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(state->pc);
|
||||
sp = state->base.prev;
|
||||
ASSERT(sp != nullptr);
|
||||
InterpretedFrame *prevState = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *prevState = GET_ASM_FRAME(sp);
|
||||
pc = prevState->pc;
|
||||
|
||||
// break frame
|
||||
@ -2215,10 +2494,9 @@ void InterpreterAssembly::HandleSuspendGeneratorPrefV8V8(
|
||||
return;
|
||||
}
|
||||
thread->SetCurrentSPFrame(sp);
|
||||
constpool = prevState->constpool;
|
||||
|
||||
size_t jumpSize = GetJumpSizeAfterCall(pc);
|
||||
DISPATCH_OFFSET(jumpSize);
|
||||
ASSERT(prevState->callSize == GetJumpSizeAfterCall(pc));
|
||||
DISPATCH_OFFSET(prevState->callSize);
|
||||
}
|
||||
|
||||
void InterpreterAssembly::HandleAsyncFunctionAwaitUncaughtPrefV8V8(
|
||||
@ -2652,7 +2930,7 @@ void InterpreterAssembly::HandleDefineGeneratorFuncPrefId16Imm16V8(
|
||||
JSTaggedValue env = GET_VREG_VALUE(v0);
|
||||
result->SetLexicalEnv(thread, env);
|
||||
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_ASM_FRAME(sp)->function).GetTaggedObject());
|
||||
result->SetModule(thread, currentFunc->GetModule());
|
||||
SET_ACC(JSTaggedValue(result))
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8);
|
||||
@ -2683,7 +2961,7 @@ void InterpreterAssembly::HandleDefineAsyncFuncPrefId16Imm16V8(
|
||||
JSTaggedValue env = GET_VREG_VALUE(v0);
|
||||
result->SetLexicalEnv(thread, env);
|
||||
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_ASM_FRAME(sp)->function).GetTaggedObject());
|
||||
result->SetModule(thread, currentFunc->GetModule());
|
||||
SET_ACC(JSTaggedValue(result))
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_ID16_IMM16_V8);
|
||||
@ -3495,7 +3773,7 @@ void InterpreterAssembly::HandleDefineClassWithBufferPrefId16Imm16Imm16V8V8(
|
||||
lexenv = GET_VREG_VALUE(v0); // slow runtime may gc
|
||||
cls->SetLexicalEnv(thread, lexenv);
|
||||
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_FRAME(sp)->function).GetTaggedObject());
|
||||
JSFunction *currentFunc = JSFunction::Cast((GET_ASM_FRAME(sp)->function).GetTaggedObject());
|
||||
cls->SetModule(thread, currentFunc->GetModule());
|
||||
|
||||
SlowRuntimeStub::SetClassConstructorLength(thread, res, JSTaggedValue(length));
|
||||
@ -3527,7 +3805,7 @@ void InterpreterAssembly::HandleNewLexEnvWithNameDynPrefImm16Imm16(
|
||||
INTERPRETER_RETURN_IF_ABRUPT(res);
|
||||
|
||||
SET_ACC(res);
|
||||
GET_FRAME(sp)->env = res;
|
||||
GET_ASM_FRAME(sp)->env = res;
|
||||
DISPATCH(BytecodeInstruction::Format::PREF_IMM16_IMM16);
|
||||
}
|
||||
|
||||
@ -3709,7 +3987,7 @@ void InterpreterAssembly::HandleOverflow(
|
||||
LOG(FATAL, INTERPRETER) << "opcode overflow";
|
||||
}
|
||||
|
||||
inline uint32_t InterpreterAssembly::FindCatchBlock(JSMethod *caller, uint32_t pc)
|
||||
uint32_t InterpreterAssembly::FindCatchBlock(JSMethod *caller, uint32_t pc)
|
||||
{
|
||||
auto *pandaFile = caller->GetPandaFile();
|
||||
panda_file::MethodDataAccessor mda(*pandaFile, caller->GetFileId());
|
||||
@ -3746,17 +4024,17 @@ inline void InterpreterAssembly::InterpreterFrameCopyArgs(
|
||||
}
|
||||
}
|
||||
|
||||
inline JSTaggedValue InterpreterAssembly::GetThisFunction(JSTaggedType *sp)
|
||||
JSTaggedValue InterpreterAssembly::GetThisFunction(JSTaggedType *sp)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
|
||||
AsmInterpretedFrame *state = reinterpret_cast<AsmInterpretedFrame *>(sp) - 1;
|
||||
return JSTaggedValue(state->function);
|
||||
}
|
||||
|
||||
inline JSTaggedValue InterpreterAssembly::GetNewTarget(JSTaggedType *sp)
|
||||
JSTaggedValue InterpreterAssembly::GetNewTarget(JSTaggedType *sp)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
|
||||
AsmInterpretedFrame *state = reinterpret_cast<AsmInterpretedFrame *>(sp) - 1;
|
||||
JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
|
||||
uint64_t callField = method->GetCallField();
|
||||
ASSERT(JSMethod::HaveNewTargetBit::Decode(callField));
|
||||
@ -3765,10 +4043,10 @@ inline JSTaggedValue InterpreterAssembly::GetNewTarget(JSTaggedType *sp)
|
||||
return JSTaggedValue(sp[numVregs + haveFunc]);
|
||||
}
|
||||
|
||||
inline uint32_t InterpreterAssembly::GetNumArgs(JSTaggedType *sp, uint32_t restIdx, uint32_t &startIdx)
|
||||
uint32_t InterpreterAssembly::GetNumArgs(JSTaggedType *sp, uint32_t restIdx, uint32_t &startIdx)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
InterpretedFrame *state = reinterpret_cast<InterpretedFrame *>(sp) - 1;
|
||||
AsmInterpretedFrame *state = reinterpret_cast<AsmInterpretedFrame *>(sp) - 1;
|
||||
JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
|
||||
uint64_t callField = method->GetCallField();
|
||||
ASSERT(JSMethod::HaveExtraBit::Decode(callField));
|
||||
@ -3822,18 +4100,50 @@ inline size_t InterpreterAssembly::GetJumpSizeAfterCall(const uint8_t *prevPc)
|
||||
|
||||
inline JSTaggedValue InterpreterAssembly::UpdateHotnessCounter(JSThread* thread, TaggedType *sp)
|
||||
{
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
thread->CheckSafepoint();
|
||||
if (state->profileTypeInfo == JSTaggedValue::Undefined()) {
|
||||
auto thisFunc = state->function;
|
||||
auto method = ECMAObject::Cast(thisFunc.GetTaggedObject())->GetCallTarget();
|
||||
auto res = SlowRuntimeStub::NotifyInlineCache(
|
||||
thread, JSFunction::Cast(thisFunc.GetHeapObject()), method);
|
||||
state->profileTypeInfo = res;
|
||||
JSFunction* function = JSFunction::Cast(state->function.GetTaggedObject());
|
||||
JSTaggedValue profileTypeInfo = function->GetProfileTypeInfo();
|
||||
if (profileTypeInfo == JSTaggedValue::Undefined()) {
|
||||
auto method = function->GetMethod();
|
||||
auto res = SlowRuntimeStub::NotifyInlineCache(thread, function, method);
|
||||
function->SetProfileTypeInfo(res);
|
||||
return res;
|
||||
}
|
||||
return state->profileTypeInfo;
|
||||
return profileTypeInfo;
|
||||
}
|
||||
#undef LOG_INST
|
||||
#undef ADVANCE_PC
|
||||
#undef GOTO_NEXT
|
||||
#undef DISPATCH_OFFSET
|
||||
#undef GET_ASM_FRAME
|
||||
#undef SAVE_PC
|
||||
#undef SAVE_ACC
|
||||
#undef RESTORE_ACC
|
||||
#undef INTERPRETER_GOTO_EXCEPTION_HANDLER
|
||||
#undef UPDATE_HOTNESS_COUNTER
|
||||
#undef GET_VREG
|
||||
#undef GET_VREG_VALUE
|
||||
#undef SET_VREG
|
||||
#undef GET_ACC
|
||||
#undef SET_ACC
|
||||
#undef CALL_INITIALIZE
|
||||
#undef CALL_PUSH_UNDEFINED
|
||||
#undef CALL_PUSH_ARGS_0
|
||||
#undef CALL_PUSH_ARGS_1
|
||||
#undef CALL_PUSH_ARGS_2
|
||||
#undef CALL_PUSH_ARGS_3
|
||||
#undef CALL_PUSH_ARGS_I
|
||||
#undef CALL_PUSH_ARGS_I_THIS
|
||||
#undef CALL_PUSH_ARGS_0_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_1_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_2_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_3_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_I_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS_I_THIS_NO_EXTRA
|
||||
#undef CALL_PUSH_ARGS
|
||||
#undef SET_VREGS_AND_FRAME_NATIVE
|
||||
#undef SET_VREGS_AND_FRAME_NOT_NATIVE
|
||||
#if defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#elif defined(__GNUC__)
|
||||
|
@ -32,20 +32,28 @@ using AsmDispatchEntryPoint =
|
||||
class ConstantPool;
|
||||
class ECMAObject;
|
||||
class GeneratorContext;
|
||||
struct CallParams;
|
||||
|
||||
class InterpreterAssembly {
|
||||
public:
|
||||
static const uint32_t METHOD_HOTNESS_THRESHOLD = 512;
|
||||
enum ActualNumArgsOfCall : uint8_t { CALLARG0 = 0, CALLARG1, CALLARGS2, CALLARGS3 };
|
||||
static void RunInternal(JSThread *thread, ConstantPool *constpool, const uint8_t *pc, JSTaggedType *sp);
|
||||
static inline uint32_t FindCatchBlock(JSMethod *caller, uint32_t pc);
|
||||
static void InitStackFrame(JSThread *thread);
|
||||
static JSTaggedValue Execute(JSThread *thread, const CallParams& params);
|
||||
static JSTaggedValue ExecuteNative(JSThread *thread, const CallParams& params);
|
||||
static JSTaggedValue GeneratorReEnterInterpreter(JSThread *thread, JSHandle<GeneratorContext> context);
|
||||
static void ChangeGenContext(JSThread *thread, JSHandle<GeneratorContext> context);
|
||||
static void ResumeContext(JSThread *thread);
|
||||
static uint32_t FindCatchBlock(JSMethod *caller, uint32_t pc);
|
||||
static inline size_t GetJumpSizeAfterCall(const uint8_t *prevPc);
|
||||
|
||||
static inline JSTaggedValue UpdateHotnessCounter(JSThread* thread, TaggedType *sp);
|
||||
static inline void InterpreterFrameCopyArgs(JSTaggedType *newSp, uint32_t numVregs, uint32_t numActualArgs,
|
||||
uint32_t numDeclaredArgs, bool haveExtraArgs = true);
|
||||
static inline JSTaggedValue GetThisFunction(JSTaggedType *sp);
|
||||
static inline JSTaggedValue GetNewTarget(JSTaggedType *sp);
|
||||
static inline uint32_t GetNumArgs(JSTaggedType *sp, uint32_t restIdx, uint32_t &startIdx);
|
||||
static JSTaggedValue GetThisFunction(JSTaggedType *sp);
|
||||
static JSTaggedValue GetNewTarget(JSTaggedType *sp);
|
||||
static uint32_t GetNumArgs(JSTaggedType *sp, uint32_t restIdx, uint32_t &startIdx);
|
||||
|
||||
static void HandleOverflow(JSThread *thread, const uint8_t *pc, JSTaggedType *sp,
|
||||
JSTaggedValue constpool, JSTaggedValue profileTypeInfo,
|
||||
|
@ -36,7 +36,8 @@ static constexpr size_t STORAGE_PTR_NUM = 3;
|
||||
V(SHORTY, CODEID, sizeof(uint32_t), sizeof(uint32_t)) \
|
||||
V(PROFILINGDATA, SHORTY, sizeof(uint32_t), sizeof(uint64_t)) \
|
||||
V(CALLFIELD, PROFILINGDATA, sizeof(uint32_t), sizeof(uint64_t)) \
|
||||
V(BYTECODEARRAY, CALLFIELD, sizeof(uint64_t), sizeof(uint64_t)) \
|
||||
V(JSPANDAFILE, CALLFIELD, sizeof(uint64_t), sizeof(uint64_t)) \
|
||||
V(BYTECODEARRAY, JSPANDAFILE, sizeof(uint32_t), sizeof(uint64_t)) \
|
||||
V(BYTECODEARRAYSIZE, BYTECODEARRAY, sizeof(uint32_t), sizeof(uint64_t)) \
|
||||
V(SLOTSIZE, BYTECODEARRAYSIZE, sizeof(uint32_t), sizeof(uint32_t)) \
|
||||
|
||||
|
@ -75,6 +75,9 @@ JSTaggedType RuntimeStubs::name(uintptr_t argGlue, uint32_t argc, uintptr_t argv
|
||||
ASSERT((index) < argc); \
|
||||
type name = reinterpret_cast<type>(*(reinterpret_cast<JSTaggedType *>(argv) + (index)))
|
||||
|
||||
#define GET_ASM_FRAME(CurrentSp) \
|
||||
(reinterpret_cast<AsmInterpretedFrame *>(CurrentSp) - 1) // NOLINT(cppcoreguidelines-pro-bounds-pointer-arithmetic)
|
||||
|
||||
DEF_RUNTIME_STUBS(AddElementInternal)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(AddElementInternal);
|
||||
@ -556,7 +559,7 @@ DEF_RUNTIME_STUBS(SuperCallSpread)
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, func, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, array, 1);
|
||||
auto sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
JSTaggedValue function = EcmaInterpreter::GetNewTarget(sp);
|
||||
JSTaggedValue function = InterpreterAssembly::GetNewTarget(sp);
|
||||
return RuntimeSuperCallSpread(thread, func, JSHandle<JSTaggedValue>(thread, function), array).GetRawData();
|
||||
}
|
||||
|
||||
@ -683,7 +686,7 @@ DEF_RUNTIME_STUBS(LdSuperByValue)
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, obj, 0);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, key, 1);
|
||||
auto sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
JSTaggedValue thisFunc = EcmaInterpreter::GetThisFunction(sp);
|
||||
JSTaggedValue thisFunc = InterpreterAssembly::GetThisFunction(sp);
|
||||
return RuntimeLdSuperByValue(thread, obj, key, thisFunc).GetRawData();
|
||||
}
|
||||
|
||||
@ -694,7 +697,7 @@ DEF_RUNTIME_STUBS(StSuperByValue)
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, key, 1);
|
||||
CONVERT_ARG_HANDLE_CHECKED(JSTaggedValue, value, 2);
|
||||
auto sp = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
|
||||
JSTaggedValue thisFunc = EcmaInterpreter::GetThisFunction(sp);
|
||||
JSTaggedValue thisFunc = InterpreterAssembly::GetThisFunction(sp);
|
||||
return RuntimeStSuperByValue(thread, obj, key, value, thisFunc).GetRawData();
|
||||
}
|
||||
|
||||
@ -842,7 +845,7 @@ DEF_RUNTIME_STUBS(SetClassConstructorLength)
|
||||
DEF_RUNTIME_STUBS(UpdateHotnessCounter)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(UpdateHotnessCounter);
|
||||
InterpretedFrame *state = GET_FRAME(const_cast<JSTaggedType *>(thread->GetCurrentSPFrame()));
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(const_cast<JSTaggedType *>(thread->GetCurrentSPFrame()));
|
||||
thread->CheckSafepoint();
|
||||
auto thisFunc = JSFunction::Cast(state->function.GetTaggedObject());
|
||||
if (thisFunc->GetProfileTypeInfo() == JSTaggedValue::Undefined()) {
|
||||
@ -945,7 +948,7 @@ DEF_RUNTIME_STUBS(UpFrame)
|
||||
return JSTaggedValue(static_cast<uint64_t>(0)).GetRawData();
|
||||
}
|
||||
auto method = frameHandler.GetMethod();
|
||||
pcOffset = EcmaInterpreter::FindCatchBlock(method, frameHandler.GetBytecodeOffset());
|
||||
pcOffset = InterpreterAssembly::FindCatchBlock(method, frameHandler.GetBytecodeOffset());
|
||||
if (pcOffset != panda_file::INVALID_OFFSET) {
|
||||
thread->SetCurrentSPFrame(frameHandler.GetSp());
|
||||
uintptr_t pc = reinterpret_cast<uintptr_t>(method->GetBytecodeArray() + pcOffset);
|
||||
@ -1266,7 +1269,7 @@ DEF_RUNTIME_STUBS(CallArg0Dyn)
|
||||
{
|
||||
RUNTIME_STUBS_HEADER(CallArg0Dyn);
|
||||
CONVERT_ARG_TAGGED_CHECKED(func, 0);
|
||||
uint32_t actualNumArgs = EcmaInterpreter::ActualNumArgsOfCall::CALLARG0;
|
||||
uint32_t actualNumArgs = InterpreterAssembly::ActualNumArgsOfCall::CALLARG0;
|
||||
bool callThis = false;
|
||||
std::vector<JSTaggedType> actualArgs;
|
||||
return RuntimeNativeCall(thread, func, callThis, actualNumArgs, actualArgs);
|
||||
@ -1277,7 +1280,7 @@ DEF_RUNTIME_STUBS(CallArg1Dyn)
|
||||
RUNTIME_STUBS_HEADER(CallArg1Dyn);
|
||||
CONVERT_ARG_TAGGED_CHECKED(func, 0);
|
||||
CONVERT_ARG_TAGGED_TYPE_CHECKED(arg0, 1);
|
||||
uint32_t actualNumArgs = EcmaInterpreter::ActualNumArgsOfCall::CALLARG1;
|
||||
uint32_t actualNumArgs = InterpreterAssembly::ActualNumArgsOfCall::CALLARG1;
|
||||
bool callThis = false;
|
||||
std::vector<JSTaggedType> actualArgs;
|
||||
actualArgs.emplace_back(arg0);
|
||||
@ -1290,7 +1293,7 @@ DEF_RUNTIME_STUBS(CallArgs2Dyn)
|
||||
CONVERT_ARG_TAGGED_CHECKED(func, 0);
|
||||
CONVERT_ARG_TAGGED_TYPE_CHECKED(arg0, 1);
|
||||
CONVERT_ARG_TAGGED_TYPE_CHECKED(arg1, 2);
|
||||
uint32_t actualNumArgs = EcmaInterpreter::ActualNumArgsOfCall::CALLARGS2;
|
||||
uint32_t actualNumArgs = InterpreterAssembly::ActualNumArgsOfCall::CALLARGS2;
|
||||
bool callThis = false;
|
||||
std::vector<JSTaggedType> actualArgs;
|
||||
actualArgs.emplace_back(arg0);
|
||||
@ -1305,7 +1308,7 @@ DEF_RUNTIME_STUBS(CallArgs3Dyn)
|
||||
CONVERT_ARG_TAGGED_TYPE_CHECKED(arg0, 1);
|
||||
CONVERT_ARG_TAGGED_TYPE_CHECKED(arg1, 2);
|
||||
CONVERT_ARG_TAGGED_TYPE_CHECKED(arg2, 3);
|
||||
uint32_t actualNumArgs = EcmaInterpreter::ActualNumArgsOfCall::CALLARGS3;
|
||||
uint32_t actualNumArgs = InterpreterAssembly::ActualNumArgsOfCall::CALLARGS3;
|
||||
bool callThis = false;
|
||||
std::vector<JSTaggedType> actualArgs;
|
||||
actualArgs.emplace_back(arg0);
|
||||
@ -1351,12 +1354,12 @@ DEF_RUNTIME_STUBS(JumpToCInterpreter)
|
||||
CONVERT_ARG_TAGGED_CHECKED(hotnessCounter, 3);
|
||||
|
||||
auto sp = const_cast<JSTaggedType*>(thread->GetCurrentSPFrame());
|
||||
const uint8_t* currentPc = reinterpret_cast<const uint8_t*>(GET_FRAME(sp)->pc);
|
||||
const uint8_t* currentPc = reinterpret_cast<const uint8_t*>(GET_ASM_FRAME(sp)->pc);
|
||||
|
||||
uint8_t opcode = currentPc[0];
|
||||
asmDispatchTable[opcode](thread, currentPc, sp, constpool, profileTypeInfo, acc, hotnessCounter.GetInt());
|
||||
sp = const_cast<JSTaggedType*>(thread->GetCurrentSPFrame());
|
||||
InterpretedFrame *frame = GET_FRAME(sp);
|
||||
AsmInterpretedFrame *frame = GET_ASM_FRAME(sp);
|
||||
uintptr_t framePc = reinterpret_cast<uintptr_t>(frame->pc);
|
||||
return JSTaggedValue(static_cast<uint64_t>(framePc)).GetRawData();
|
||||
}
|
||||
@ -1392,7 +1395,7 @@ DEF_RUNTIME_STUBS(GetUnmapedArgs)
|
||||
RUNTIME_STUBS_HEADER(GetUnmapedArgs);
|
||||
auto sp = const_cast<JSTaggedType*>(thread->GetCurrentSPFrame());
|
||||
uint32_t startIdx = 0;
|
||||
uint32_t actualNumArgs = EcmaInterpreter::GetNumArgs(sp, 0, startIdx);
|
||||
uint32_t actualNumArgs = InterpreterAssembly::GetNumArgs(sp, 0, startIdx);
|
||||
return RuntimeGetUnmapedArgs(thread, sp, actualNumArgs, startIdx).GetRawData();
|
||||
}
|
||||
|
||||
@ -1402,7 +1405,7 @@ DEF_RUNTIME_STUBS(CopyRestArgs)
|
||||
CONVERT_ARG_TAGGED_CHECKED(restIdx, 0);
|
||||
auto sp = const_cast<JSTaggedType*>(thread->GetCurrentSPFrame());
|
||||
uint32_t startIdx = 0;
|
||||
uint32_t restNumArgs = EcmaInterpreter::GetNumArgs(sp, restIdx.GetInt(), startIdx);
|
||||
uint32_t restNumArgs = InterpreterAssembly::GetNumArgs(sp, restIdx.GetInt(), startIdx);
|
||||
return RuntimeCopyRestArgs(thread, sp, restNumArgs, startIdx).GetRawData();
|
||||
}
|
||||
|
||||
@ -1543,7 +1546,7 @@ DEF_RUNTIME_STUBS(SuperCall)
|
||||
CONVERT_ARG_TAGGED_CHECKED(firstVRegIdx, 1);
|
||||
CONVERT_ARG_TAGGED_CHECKED(length, 2);
|
||||
auto sp = const_cast<JSTaggedType*>(thread->GetCurrentSPFrame());
|
||||
JSTaggedValue newTarget = EcmaInterpreter::GetNewTarget(sp);
|
||||
JSTaggedValue newTarget = InterpreterAssembly::GetNewTarget(sp);
|
||||
return RuntimeSuperCall(thread, func, JSHandle<JSTaggedValue>(thread, newTarget),
|
||||
static_cast<uint16_t>(firstVRegIdx.GetInt()),
|
||||
static_cast<uint16_t>(length.GetInt())).GetRawData();
|
||||
|
Loading…
Reference in New Issue
Block a user