Add AsmInterpreterFrame

Add AsmInterpreterFrame for ASM.

Issue: #I4YF9X

Signed-off-by: lichenshuai <lichenshuai@huawei.com>
Change-Id: I4efc781a9fca90de4a0aed5b6a91a8122cfa16ab
This commit is contained in:
lichenshuai 2022-03-18 15:17:30 +08:00
parent 1789e38335
commit cfc0b0b12f
13 changed files with 702 additions and 227 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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);

View File

@ -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";

View File

@ -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;

View File

@ -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) {

View File

@ -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();

View File

@ -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__)

View File

@ -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;

View File

@ -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__)

View File

@ -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,

View File

@ -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)) \

View File

@ -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();