mirror of
https://gitee.com/openharmony/arkcompiler_ets_runtime
synced 2025-02-17 10:18:13 +00:00
refactor jsMethod
1. Move necessary fileds in jsMethod 2. Make jsMethod inherit aligned struct 3. Change some function names for easy reading Signed-off-by: xiongluo <xiongluo@huawei.com>
This commit is contained in:
parent
4978eb99a4
commit
727b20b57e
@ -93,5 +93,15 @@ struct AlignedUint64 {
|
||||
static constexpr size_t SizeArch32 = sizeof(uint64_t);
|
||||
static constexpr size_t SizeArch64 = sizeof(uint64_t);
|
||||
};
|
||||
|
||||
struct AlignedUint32 {
|
||||
static constexpr size_t SizeArch32 = sizeof(uint32_t);
|
||||
static constexpr size_t SizeArch64 = sizeof(uint32_t);
|
||||
};
|
||||
|
||||
struct AlignedUint8 {
|
||||
static constexpr size_t SizeArch32 = sizeof(uint8_t);
|
||||
static constexpr size_t SizeArch64 = sizeof(uint8_t);
|
||||
};
|
||||
}
|
||||
#endif // ECMASCRIPT_BASE_ALIGNED_STRUCT_H
|
||||
|
@ -198,14 +198,14 @@ CString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread)
|
||||
continue;
|
||||
}
|
||||
auto method = frameHandler.GetMethod();
|
||||
if (!method->IsNative()) {
|
||||
if (!method->IsNativeWithCallField()) {
|
||||
data.append(" at ");
|
||||
data += DecodeFunctionName(method->ParseFunctionName());
|
||||
data.append(" (");
|
||||
// source file
|
||||
tooling::JSPtExtractor *debugExtractor =
|
||||
JSPandaFileManager::GetInstance()->GetJSPtExtractor(method->GetJSPandaFile());
|
||||
const CString &sourceFile = debugExtractor->GetSourceFile(method->GetFileId());
|
||||
const CString &sourceFile = debugExtractor->GetSourceFile(method->GetMethodId());
|
||||
if (sourceFile.empty()) {
|
||||
data.push_back('?');
|
||||
} else {
|
||||
@ -219,7 +219,8 @@ CString ErrorHelper::BuildNativeEcmaStackTrace(JSThread *thread)
|
||||
data += ToCString(column + 1);
|
||||
return true;
|
||||
};
|
||||
if (!debugExtractor->MatchWithOffset(callbackFunc, method->GetFileId(), frameHandler.GetBytecodeOffset())) {
|
||||
if (!debugExtractor->MatchWithOffset(callbackFunc, method->GetMethodId(),
|
||||
frameHandler.GetBytecodeOffset())) {
|
||||
data.push_back('?');
|
||||
}
|
||||
data.push_back(')');
|
||||
|
@ -150,7 +150,7 @@ std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> BytecodeCircui
|
||||
// try contains many catch
|
||||
const panda_file::File *file = file_->GetPandaFile();
|
||||
std::map<std::pair<uint8_t *, uint8_t *>, std::vector<uint8_t *>> byteCodeException;
|
||||
panda_file::MethodDataAccessor mda(*file, method_->GetFileId());
|
||||
panda_file::MethodDataAccessor mda(*file, method_->GetMethodId());
|
||||
panda_file::CodeDataAccessor cda(*file, mda.GetCodeId().value());
|
||||
cda.EnumerateTryBlocks([this, &byteCodeCurPrePc, &bytecodeBlockInfos, &byteCodeException](
|
||||
panda_file::CodeDataAccessor::TryBlock &try_block) {
|
||||
|
@ -1496,7 +1496,7 @@ DECLARE_ASM_HANDLER(SingleStepDebugging)
|
||||
GateRef method = Load(VariableType::NATIVE_POINTER(), function,
|
||||
IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varHotnessCounter = Load(VariableType::INT32(), method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET));
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())));
|
||||
}
|
||||
Dispatch(glue, *varPc, *varSp, *varConstpool, *varProfileTypeInfo, *varAcc,
|
||||
*varHotnessCounter, IntPtr(0));
|
||||
@ -4105,7 +4105,7 @@ DECLARE_ASM_HANDLER(HandleReturnDyn)
|
||||
GateRef offset = Int32Not(TruncPtrToInt32(IntPtrSub(*varPc, fistPC)));
|
||||
UPDATE_HOTNESS(*varSp);
|
||||
Store(VariableType::INT32(), glue, method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET), *varHotnessCounter);
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())), *varHotnessCounter);
|
||||
Jump(&tryContinue);
|
||||
}
|
||||
|
||||
@ -4133,7 +4133,7 @@ DECLARE_ASM_HANDLER(HandleReturnDyn)
|
||||
GateRef method = Load(VariableType::NATIVE_POINTER(), function,
|
||||
IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varHotnessCounter = Load(VariableType::INT32(), method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET));
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())));
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
#if ECMASCRIPT_ENABLE_ASM_INTERPRETER_RSP_STACK
|
||||
DispatchCommonCall<RTSTUB_ID(ResumeRspAndDispatch)>(glue, *varPc, *varSp, *varConstpool, *varProfileTypeInfo,
|
||||
@ -4174,7 +4174,7 @@ DECLARE_ASM_HANDLER(HandleReturnUndefinedPref)
|
||||
GateRef offset = Int32Not(TruncPtrToInt32(IntPtrSub(*varPc, fistPC)));
|
||||
UPDATE_HOTNESS(*varSp);
|
||||
Store(VariableType::INT32(), glue, method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET), *varHotnessCounter);
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())), *varHotnessCounter);
|
||||
Jump(&tryContinue);
|
||||
}
|
||||
|
||||
@ -4203,7 +4203,7 @@ DECLARE_ASM_HANDLER(HandleReturnUndefinedPref)
|
||||
GateRef method = Load(VariableType::NATIVE_POINTER(), function,
|
||||
IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varHotnessCounter = Load(VariableType::INT32(), method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET));
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())));
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
#if ECMASCRIPT_ENABLE_ASM_INTERPRETER_RSP_STACK
|
||||
DispatchCommonCall<RTSTUB_ID(ResumeRspAndDispatch)>(glue, *varPc, *varSp, *varConstpool, *varProfileTypeInfo,
|
||||
@ -4256,7 +4256,7 @@ DECLARE_ASM_HANDLER(HandleSuspendGeneratorPrefV8V8)
|
||||
GateRef offset = Int32Not(TruncPtrToInt32(IntPtrSub(*varPc, fistPC)));
|
||||
UPDATE_HOTNESS(*varSp);
|
||||
Store(VariableType::INT32(), glue, method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET), *varHotnessCounter);
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())), *varHotnessCounter);
|
||||
Jump(&tryContinue);
|
||||
}
|
||||
|
||||
@ -4280,7 +4280,7 @@ DECLARE_ASM_HANDLER(HandleSuspendGeneratorPrefV8V8)
|
||||
GateRef method = Load(VariableType::NATIVE_POINTER(), function,
|
||||
IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varHotnessCounter = Load(VariableType::INT32(), method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET));
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())));
|
||||
GateRef jumpSize = GetCallSizeFromFrame(prevState);
|
||||
Dispatch(glue, *varPc, *varSp, *varConstpool, *varProfileTypeInfo, *varAcc,
|
||||
*varHotnessCounter, jumpSize);
|
||||
@ -4319,7 +4319,7 @@ DECLARE_ASM_HANDLER(ExceptionHandler)
|
||||
GateRef method = Load(VariableType::NATIVE_POINTER(), function,
|
||||
IntPtr(JSFunctionBase::METHOD_OFFSET));
|
||||
varHotnessCounter = Load(VariableType::INT32(), method,
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET));
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit())));
|
||||
Dispatch(glue, *varPc, *varSp, *varConstpool, *varProfileTypeInfo, *varAcc,
|
||||
*varHotnessCounter, IntPtr(0));
|
||||
}
|
||||
@ -5083,7 +5083,7 @@ DECLARE_ASM_HANDLER(HandleSub2DynPrefV8)
|
||||
GateRef newConstpool = GetConstpoolFromFunction(func); \
|
||||
GateRef newProfileTypeInfo = GetProfileTypeInfoFromFunction(func); \
|
||||
GateRef newHotnessCounter = Load(VariableType::INT32(), method, \
|
||||
IntPtr(JSMethod::HOTNESS_COUNTER_OFFSET)); \
|
||||
IntPtr(JSMethod::GetHotnessCounterOffset(env->IsArch32Bit()))); \
|
||||
Dispatch(glue, bytecodeArray, *newSp, newConstpool, newProfileTypeInfo, \
|
||||
Hole(VariableType::JS_ANY()), newHotnessCounter, IntPtr(0)); \
|
||||
}
|
||||
|
@ -2097,12 +2097,7 @@ inline GateRef Stub::IsBoundFunction(GateRef obj)
|
||||
|
||||
inline GateRef Stub::IsNativeMethod(GateRef method)
|
||||
{
|
||||
GateRef callFieldOffset;
|
||||
if (env_.Is32Bit()) {
|
||||
callFieldOffset = IntPtr(JS_METHOD_CALLFIELD_OFFSET_32);
|
||||
} else {
|
||||
callFieldOffset = IntPtr(JS_METHOD_CALLFIELD_OFFSET_64);
|
||||
}
|
||||
GateRef callFieldOffset = IntPtr(JSMethod::GetCallFieldOffset(env_.Is32Bit()));
|
||||
GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
|
||||
return Int64NotEqual(
|
||||
Int64And(
|
||||
@ -2113,12 +2108,7 @@ inline GateRef Stub::IsNativeMethod(GateRef method)
|
||||
|
||||
inline GateRef Stub::HasAotCode(GateRef method)
|
||||
{
|
||||
GateRef callFieldOffset;
|
||||
if (env_.Is32Bit()) {
|
||||
callFieldOffset = IntPtr(JS_METHOD_CALLFIELD_OFFSET_32);
|
||||
} else {
|
||||
callFieldOffset = IntPtr(JS_METHOD_CALLFIELD_OFFSET_64);
|
||||
}
|
||||
GateRef callFieldOffset = IntPtr(JSMethod::GetCallFieldOffset(env_.Is32Bit()));
|
||||
GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
|
||||
return Int64NotEqual(
|
||||
Int64And(
|
||||
@ -2129,12 +2119,7 @@ inline GateRef Stub::HasAotCode(GateRef method)
|
||||
|
||||
inline GateRef Stub::GetExpectedNumOfArgs(GateRef method)
|
||||
{
|
||||
GateRef callFieldOffset;
|
||||
if (env_.Is32Bit()) {
|
||||
callFieldOffset = IntPtr(JS_METHOD_CALLFIELD_OFFSET_32);
|
||||
} else {
|
||||
callFieldOffset = IntPtr(JS_METHOD_CALLFIELD_OFFSET_64);
|
||||
}
|
||||
GateRef callFieldOffset = IntPtr(JSMethod::GetCallFieldOffset(env_.Is32Bit()));
|
||||
GateRef callfield = Load(VariableType::INT64(), method, callFieldOffset);
|
||||
return TruncInt64ToInt32(Int64And(
|
||||
UInt64LSR(callfield, Int32(JSMethod::NumArgsBits::START_BIT)),
|
||||
|
@ -199,7 +199,7 @@ void CpuProfiler::GetFrameStack(JSThread *thread)
|
||||
void CpuProfiler::ParseMethodInfo(JSMethod *method, InterpretedFrameHandler frameHandler)
|
||||
{
|
||||
struct StackInfo codeEntry;
|
||||
if (method != nullptr && method->IsNative()) {
|
||||
if (method != nullptr && method->IsNativeWithCallField()) {
|
||||
codeEntry.codeType = "other";
|
||||
codeEntry.functionName = "native";
|
||||
staticStackInfo_.insert(std::make_pair(method, codeEntry));
|
||||
@ -214,7 +214,7 @@ void CpuProfiler::ParseMethodInfo(JSMethod *method, InterpretedFrameHandler fram
|
||||
// source file
|
||||
tooling::JSPtExtractor *debugExtractor =
|
||||
JSPandaFileManager::GetInstance()->GetJSPtExtractor(method->GetJSPandaFile());
|
||||
const CString &sourceFile = debugExtractor->GetSourceFile(method->GetFileId());
|
||||
const CString &sourceFile = debugExtractor->GetSourceFile(method->GetMethodId());
|
||||
if (sourceFile.empty()) {
|
||||
codeEntry.url = "";
|
||||
} else {
|
||||
@ -235,7 +235,7 @@ void CpuProfiler::ParseMethodInfo(JSMethod *method, InterpretedFrameHandler fram
|
||||
columnNumber = column + 1;
|
||||
return true;
|
||||
};
|
||||
if (!debugExtractor->MatchWithOffset(callbackFunc, method->GetFileId(), frameHandler.GetBytecodeOffset())) {
|
||||
if (!debugExtractor->MatchWithOffset(callbackFunc, method->GetMethodId(), frameHandler.GetBytecodeOffset())) {
|
||||
codeEntry.lineNumber = 0;
|
||||
codeEntry.columnNumber = 0;
|
||||
} else {
|
||||
|
@ -334,15 +334,12 @@ EcmaVM::CpuProfilingScope::~CpuProfilingScope()
|
||||
|
||||
JSMethod *EcmaVM::GetMethodForNativeFunction(const void *func)
|
||||
{
|
||||
// signature: any foo(any function_obj, any this)
|
||||
uint32_t accessFlags = ACC_PUBLIC | ACC_STATIC | ACC_FINAL | ACC_NATIVE;
|
||||
uint32_t numArgs = 2; // function object and this
|
||||
|
||||
auto method = chunk_.New<JSMethod>(nullptr, panda_file::File::EntityId(0), panda_file::File::EntityId(0),
|
||||
accessFlags, numArgs);
|
||||
auto method = chunk_.New<JSMethod>(nullptr, panda_file::File::EntityId(0));
|
||||
method->SetNativePointer(const_cast<void *>(func));
|
||||
method->SetNativeBit(true);
|
||||
|
||||
method->SetNativeBit(true);
|
||||
method->SetNumArgsWithCallField(numArgs);
|
||||
nativeMethods_.push_back(method);
|
||||
return nativeMethods_.back();
|
||||
}
|
||||
|
@ -321,7 +321,7 @@ void InterpretedFrameHandler::DumpPC(std::ostream &os, const uint8_t *pc) const
|
||||
ASSERT(frameHandler.HasFrame());
|
||||
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions)
|
||||
int offset = pc - JSMethod::Cast(frameHandler.GetMethod())->GetBytecodeArray();
|
||||
int offset = pc - frameHandler.GetMethod()->GetBytecodeArray();
|
||||
os << "offset: " << offset << "\n";
|
||||
}
|
||||
|
||||
|
@ -706,7 +706,7 @@ void EcmaInterpreter::NotifyBytecodePcChanged(JSThread *thread)
|
||||
}
|
||||
JSMethod *method = frameHandler.GetMethod();
|
||||
// Skip builtins method
|
||||
if (method->IsNative()) {
|
||||
if (method->IsNativeWithCallField()) {
|
||||
continue;
|
||||
}
|
||||
auto bcOffset = frameHandler.GetBytecodeOffset();
|
||||
@ -1010,7 +1010,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
InterpretedFrame *state = GET_FRAME(newSp);
|
||||
state->base.prev = sp;
|
||||
state->base.type = FrameType::INTERPRETER_FRAME;
|
||||
state->pc = pc = JSMethod::Cast(method)->GetBytecodeArray();
|
||||
state->pc = pc = method->GetBytecodeArray();
|
||||
state->sp = sp = newSp;
|
||||
state->function = JSTaggedValue(funcTagged);
|
||||
state->acc = JSTaggedValue::Hole();
|
||||
@ -1031,7 +1031,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(state->sp) << " "
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(state->pc);
|
||||
JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
|
||||
[[maybe_unused]] auto fistPC = method->GetInstructions();
|
||||
[[maybe_unused]] auto fistPC = method->GetBytecodeArray();
|
||||
UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
|
||||
JSTaggedType *currentSp = sp;
|
||||
sp = state->base.prev;
|
||||
@ -1084,7 +1084,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: Runtime Call " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(state->pc);
|
||||
JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
|
||||
[[maybe_unused]] auto fistPC = method->GetInstructions();
|
||||
[[maybe_unused]] auto fistPC = method->GetBytecodeArray();
|
||||
UPDATE_HOTNESS_COUNTER_NON_ACC(-(pc - fistPC));
|
||||
JSTaggedType *currentSp = sp;
|
||||
sp = state->base.prev;
|
||||
@ -2377,7 +2377,7 @@ NO_UB_SANITIZE void EcmaInterpreter::RunInternal(JSThread *thread, ConstantPool
|
||||
|
||||
InterpretedFrame *state = GET_FRAME(sp);
|
||||
JSMethod *method = JSFunction::Cast(state->function.GetTaggedObject())->GetMethod();
|
||||
[[maybe_unused]] auto fistPC = method->GetInstructions();
|
||||
[[maybe_unused]] auto fistPC = method->GetBytecodeArray();
|
||||
UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: SuspendGenerator " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(state->pc);
|
||||
@ -3667,7 +3667,7 @@ void EcmaInterpreter::InitStackFrame(JSThread *thread)
|
||||
uint32_t EcmaInterpreter::FindCatchBlock(JSMethod *caller, uint32_t pc)
|
||||
{
|
||||
auto *pandaFile = caller->GetPandaFile();
|
||||
panda_file::MethodDataAccessor mda(*pandaFile, caller->GetFileId());
|
||||
panda_file::MethodDataAccessor mda(*pandaFile, caller->GetMethodId());
|
||||
panda_file::CodeDataAccessor cda(*pandaFile, mda.GetCodeId().value());
|
||||
|
||||
uint32_t pcOffset = panda_file::INVALID_OFFSET;
|
||||
|
@ -401,7 +401,7 @@ using panda::ecmascript::kungfu::CommonStubCSigns;
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(newSp); \
|
||||
state->base.prev = sp; \
|
||||
state->base.type = FrameType::INTERPRETER_FRAME; \
|
||||
pc = JSMethod::Cast(method)->GetBytecodeArray(); /* will be stored in DISPATCH_OFFSET */ \
|
||||
pc = method->GetBytecodeArray(); /* will be stored in DISPATCH_OFFSET */ \
|
||||
sp = newSp; /* for DISPATCH_OFFSET */ \
|
||||
state->function = funcValue; \
|
||||
acc = JSTaggedValue::Hole(); /* will be stored in DISPATCH_OFFSET */ \
|
||||
@ -643,9 +643,7 @@ JSTaggedValue InterpreterAssembly::GeneratorReEnterInterpreter(JSThread *thread,
|
||||
state->env = env;
|
||||
// execute interpreter
|
||||
thread->SetCurrentSPFrame(newSp);
|
||||
|
||||
InterpreterAssembly::RunInternal(thread, ConstantPool::Cast(constpool.GetTaggedObject()), resumePc, newSp);
|
||||
|
||||
JSTaggedValue res = state->acc;
|
||||
// pop frame
|
||||
thread->SetCurrentSPFrame(currentSp);
|
||||
@ -1029,7 +1027,7 @@ void InterpreterAssembly::HandleReturnDyn(
|
||||
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();
|
||||
[[maybe_unused]] auto fistPC = method->GetBytecodeArray();
|
||||
UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
|
||||
method->SetHotnessCounter(static_cast<uint32_t>(hotnessCounter));
|
||||
JSTaggedType *currentSp = sp;
|
||||
@ -1086,7 +1084,7 @@ void InterpreterAssembly::HandleReturnUndefinedPref(
|
||||
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();
|
||||
[[maybe_unused]] auto fistPC = method->GetBytecodeArray();
|
||||
UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
|
||||
method->SetHotnessCounter(static_cast<uint32_t>(hotnessCounter));
|
||||
JSTaggedType *currentSp = sp;
|
||||
@ -2632,7 +2630,7 @@ void InterpreterAssembly::HandleSuspendGeneratorPrefV8V8(
|
||||
|
||||
AsmInterpretedFrame *state = GET_ASM_FRAME(sp);
|
||||
JSMethod *method = ECMAObject::Cast(state->function.GetTaggedObject())->GetCallTarget();
|
||||
[[maybe_unused]] auto fistPC = method->GetInstructions();
|
||||
[[maybe_unused]] auto fistPC = method->GetBytecodeArray();
|
||||
UPDATE_HOTNESS_COUNTER(-(pc - fistPC));
|
||||
LOG(DEBUG, INTERPRETER) << "Exit: SuspendGenerator " << std::hex << reinterpret_cast<uintptr_t>(sp) << " "
|
||||
<< std::hex << reinterpret_cast<uintptr_t>(state->pc);
|
||||
@ -4143,7 +4141,7 @@ void InterpreterAssembly::HandleOverflow(
|
||||
uint32_t InterpreterAssembly::FindCatchBlock(JSMethod *caller, uint32_t pc)
|
||||
{
|
||||
auto *pandaFile = caller->GetPandaFile();
|
||||
panda_file::MethodDataAccessor mda(*pandaFile, caller->GetFileId());
|
||||
panda_file::MethodDataAccessor mda(*pandaFile, caller->GetMethodId());
|
||||
panda_file::CodeDataAccessor cda(*pandaFile, mda.GetCodeId().value());
|
||||
|
||||
uint32_t pcOffset = panda_file::INVALID_OFFSET;
|
||||
|
@ -77,7 +77,7 @@ JSTaggedValue SlowRuntimeHelper::NewObject(EcmaRuntimeCallInfo *info)
|
||||
ASSERT(jsFunc->GetCallTarget() != nullptr);
|
||||
ASSERT(JSFunction::Cast(info->GetNewTarget()->GetTaggedObject())->GetCallTarget() != nullptr);
|
||||
|
||||
if (jsFunc->GetCallTarget()->IsNative()) {
|
||||
if (jsFunc->GetCallTarget()->IsNativeWithCallField()) {
|
||||
if (jsFunc->IsBuiltinsConstructor()) {
|
||||
return EcmaInterpreter::Execute(info);
|
||||
}
|
||||
|
@ -16,18 +16,24 @@
|
||||
#include "ecmascript/js_method.h"
|
||||
|
||||
#include "ecmascript/jspandafile/js_pandafile.h"
|
||||
#include "libpandafile/code_data_accessor-inl.h"
|
||||
#include "libpandafile/method_data_accessor-inl.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
JSMethod::JSMethod(const JSPandaFile *jsPandaFile, panda_file::File::EntityId fileId,
|
||||
panda_file::File::EntityId codeId, uint32_t accessFlags,
|
||||
uint32_t numArgs)
|
||||
: Method(nullptr, jsPandaFile != nullptr ? jsPandaFile->GetPandaFile() : nullptr,
|
||||
fileId, codeId, accessFlags, numArgs, nullptr)
|
||||
JSMethod::JSMethod(const JSPandaFile *jsPandaFile, panda_file::File::EntityId methodId)
|
||||
{
|
||||
bytecodeArray_ = GetInstructions();
|
||||
bytecodeArraySize_ = GetCodeSize();
|
||||
methodId_ = methodId;
|
||||
jsPandaFile_ = jsPandaFile;
|
||||
if (jsPandaFile_ != nullptr) {
|
||||
panda_file::MethodDataAccessor mda(*(jsPandaFile_->GetPandaFile()), methodId_);
|
||||
auto codeId = mda.GetCodeId().value();
|
||||
if (!codeId.IsValid()) {
|
||||
nativePointerOrBytecodeArray_ = nullptr;
|
||||
}
|
||||
panda_file::CodeDataAccessor cda(*(jsPandaFile_->GetPandaFile()), codeId);
|
||||
nativePointerOrBytecodeArray_ = cda.GetInstructions();
|
||||
}
|
||||
bytecodeArraySize_ = GetCodeSize();
|
||||
}
|
||||
|
||||
// It's not allowed '#' token appear in ECMA function(method) name, which discriminates same names in panda methods.
|
||||
@ -41,12 +47,11 @@ CString JSMethod::ParseFunctionName() const
|
||||
return CString(methodName.substr(index + 1));
|
||||
}
|
||||
|
||||
void JSMethod::InitializeCallField()
|
||||
void JSMethod::InitializeCallField(uint32_t numVregs, uint32_t numArgs)
|
||||
{
|
||||
uint32_t callType = UINT32_MAX; // UINT32_MAX means not found
|
||||
const panda_file::File *pandaFile = GetPandaFile();
|
||||
panda_file::File::EntityId fieldId = GetFileId();
|
||||
panda_file::MethodDataAccessor mda(*pandaFile, fieldId);
|
||||
const panda_file::File *pandaFile = jsPandaFile_->GetPandaFile();
|
||||
panda_file::MethodDataAccessor mda(*pandaFile, methodId_);
|
||||
mda.EnumerateAnnotations([&](panda_file::File::EntityId annotation_id) {
|
||||
panda_file::AnnotationDataAccessor ada(*pandaFile, annotation_id);
|
||||
auto *annotation_name = reinterpret_cast<const char *>(pandaFile->GetStringData(ada.GetClassId()).data);
|
||||
@ -61,17 +66,59 @@ void JSMethod::InitializeCallField()
|
||||
}
|
||||
}
|
||||
});
|
||||
// Needed info for call can be got by loading callField only once
|
||||
// Needed info for call can be got by loading callField only once.
|
||||
// Native bit will be set in GetMethodForNativeFunction();
|
||||
callField_ = (callType & CALL_TYPE_MASK) |
|
||||
NumVregsBits::Encode(GetNumVregs()) |
|
||||
NumArgsBits::Encode(GetNumArgs() - HaveFuncBit::Decode(callType) // exclude func
|
||||
- HaveNewTargetBit::Decode(callType) // exclude new target
|
||||
- HaveThisBit::Decode(callType)) | // exclude this
|
||||
IsNativeBit::Encode(IsNative());
|
||||
NumVregsBits::Encode(numVregs) |
|
||||
NumArgsBits::Encode(numArgs - HaveFuncBit::Decode(callType) // exclude func
|
||||
- HaveNewTargetBit::Decode(callType) // exclude new target
|
||||
- HaveThisBit::Decode(callType)); // exclude this
|
||||
}
|
||||
|
||||
const char *JSMethod::GetMethodName() const
|
||||
{
|
||||
return utf::Mutf8AsCString(GetName().data);
|
||||
}
|
||||
|
||||
panda_file::File::StringData JSMethod::GetName() const
|
||||
{
|
||||
panda_file::MethodDataAccessor mda(*(jsPandaFile_->GetPandaFile()), methodId_);
|
||||
return jsPandaFile_->GetPandaFile()->GetStringData(mda.GetNameId());
|
||||
}
|
||||
|
||||
uint32_t JSMethod::GetNumVregs() const
|
||||
{
|
||||
if (jsPandaFile_ == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
panda_file::MethodDataAccessor mda(*(jsPandaFile_->GetPandaFile()), methodId_);
|
||||
auto codeId = mda.GetCodeId().value();
|
||||
if (!codeId.IsValid()) {
|
||||
return 0;
|
||||
}
|
||||
panda_file::CodeDataAccessor cda(*(jsPandaFile_->GetPandaFile()), codeId);
|
||||
return cda.GetNumVregs();
|
||||
}
|
||||
|
||||
uint32_t JSMethod::GetCodeSize() const
|
||||
{
|
||||
if (jsPandaFile_ == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
panda_file::MethodDataAccessor mda(*(jsPandaFile_->GetPandaFile()), methodId_);
|
||||
auto codeId = mda.GetCodeId().value();
|
||||
if (!codeId.IsValid()) {
|
||||
return 0;
|
||||
}
|
||||
panda_file::CodeDataAccessor cda(*(jsPandaFile_->GetPandaFile()), codeId);
|
||||
return cda.GetCodeSize();
|
||||
}
|
||||
|
||||
const panda_file::File *JSMethod::GetPandaFile() const
|
||||
{
|
||||
if (jsPandaFile_ == nullptr) {
|
||||
return nullptr;
|
||||
}
|
||||
return jsPandaFile_->GetPandaFile();
|
||||
}
|
||||
} // namespace panda::ecmascript
|
@ -16,53 +16,40 @@
|
||||
#ifndef ECMASCRIPT_JS_METHOD_H
|
||||
#define ECMASCRIPT_JS_METHOD_H
|
||||
|
||||
#include "ecmascript/base/aligned_struct.h"
|
||||
#include "ecmascript/js_tagged_value.h"
|
||||
#include "ecmascript/mem/c_string.h"
|
||||
#include "include/method.h"
|
||||
#include "ecmascript/trampoline/asm_defines.h"
|
||||
#include "libpandafile/file.h"
|
||||
|
||||
namespace panda {
|
||||
class Class;
|
||||
}
|
||||
|
||||
static constexpr uint32_t CALL_TYPE_MASK = 0xF; // 0xF: the last 4 bits are used as callType
|
||||
static constexpr size_t STORAGE_32_NUM = 4;
|
||||
static constexpr size_t STORAGE_PTR_NUM = 3;
|
||||
|
||||
#define JS_METHOD_OFFSET_LIST(V) \
|
||||
V(STORPTR, STOR32, STORAGE_32_NUM * sizeof(uint32_t), STORAGE_32_NUM * sizeof(uint32_t)) \
|
||||
V(PANDAFILE, STORPTR, STORAGE_PTR_NUM * sizeof(uint32_t), STORAGE_PTR_NUM * sizeof(uint64_t)) \
|
||||
V(FILEID, PANDAFILE, sizeof(uint32_t), sizeof(uint64_t)) \
|
||||
V(CODEID, FILEID, sizeof(uint32_t), sizeof(uint32_t)) \
|
||||
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(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)) \
|
||||
|
||||
static constexpr uint32_t JS_METHOD_STOR32_OFFSET_32 = 0U;
|
||||
static constexpr uint32_t JS_METHOD_STOR32_OFFSET_64 = 0U;
|
||||
#define JS_METHOD_OFFSET_MACRO(name, lastName, lastSize32, lastSize64) \
|
||||
static constexpr uint32_t JS_METHOD_##name##_OFFSET_32 = JS_METHOD_##lastName##_OFFSET_32 + (lastSize32); \
|
||||
static constexpr uint32_t JS_METHOD_##name##_OFFSET_64 = JS_METHOD_##lastName##_OFFSET_64 + (lastSize64);
|
||||
JS_METHOD_OFFSET_LIST(JS_METHOD_OFFSET_MACRO)
|
||||
#undef JS_METHOD_OFFSET_MACRO
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class JSPandaFile;
|
||||
class JSMethod : public Method {
|
||||
public:
|
||||
struct PUBLIC_API JSMethod : public base::AlignedStruct<sizeof(uint64_t),
|
||||
base::AlignedUint64,
|
||||
base::AlignedPointer,
|
||||
base::AlignedPointer,
|
||||
base::AlignedUint32,
|
||||
base::AlignedUint32,
|
||||
base::AlignedUint32,
|
||||
base::AlignedUint8> {
|
||||
enum class Index : size_t {
|
||||
CALL_FIELD_INDEX = 0,
|
||||
NATIVE_POINTER_OR_BYTECODE_ARRAY_INDEX,
|
||||
JS_PANDA_FILE_INDEX,
|
||||
BYTECODE_ARRAY_SIZE_INDEX,
|
||||
HOTNESS_COUNTER_INDEX,
|
||||
METHOD_ID_INDEX,
|
||||
SLOT_SIZE_INDEX,
|
||||
NUM_OF_MEMBERS
|
||||
};
|
||||
|
||||
static_assert(static_cast<size_t>(Index::NUM_OF_MEMBERS) == NumOfTypes);
|
||||
|
||||
static constexpr uint8_t MAX_SLOT_SIZE = 0xFF;
|
||||
static constexpr uint32_t HOTNESS_COUNTER_OFFSET = 3 * sizeof(uint32_t); // 3: the 3th field of method
|
||||
|
||||
static JSMethod *Cast(Method *method)
|
||||
{
|
||||
return static_cast<JSMethod *>(method);
|
||||
}
|
||||
|
||||
JSMethod(const JSPandaFile *jsPandaFile, panda_file::File::EntityId fileId,
|
||||
panda_file::File::EntityId codeId, uint32_t accessFlags, uint32_t numArgs);
|
||||
JSMethod(const JSPandaFile *jsPandaFile, panda_file::File::EntityId fileId);
|
||||
JSMethod() = delete;
|
||||
~JSMethod() = default;
|
||||
JSMethod(const JSMethod &) = delete;
|
||||
@ -70,22 +57,14 @@ public:
|
||||
JSMethod &operator=(const JSMethod &) = delete;
|
||||
JSMethod &operator=(JSMethod &&) = delete;
|
||||
|
||||
static constexpr uint32_t GetBytecodeArrayOffset()
|
||||
static size_t GetBytecodeArrayOffset(bool isArch32)
|
||||
{
|
||||
return MEMBER_OFFSET(JSMethod, bytecodeArray_);
|
||||
}
|
||||
|
||||
static constexpr uint32_t GetBytecodeArrayOffset(bool isArm32)
|
||||
{
|
||||
if (isArm32) {
|
||||
return JS_METHOD_BYTECODEARRAY_OFFSET_32;
|
||||
}
|
||||
return JS_METHOD_BYTECODEARRAY_OFFSET_64;
|
||||
return GetOffset<static_cast<size_t>(Index::NATIVE_POINTER_OR_BYTECODE_ARRAY_INDEX)>(isArch32);
|
||||
}
|
||||
|
||||
const uint8_t *GetBytecodeArray() const
|
||||
{
|
||||
return bytecodeArray_;
|
||||
return reinterpret_cast<const uint8_t *>(nativePointerOrBytecodeArray_);
|
||||
}
|
||||
|
||||
uint32_t GetBytecodeArraySize() const
|
||||
@ -95,7 +74,7 @@ public:
|
||||
|
||||
void SetBytecodeArray(const uint8_t *bc)
|
||||
{
|
||||
bytecodeArray_ = bc;
|
||||
nativePointerOrBytecodeArray_ = reinterpret_cast<const void *>(bc);
|
||||
}
|
||||
|
||||
uint8_t GetSlotSize() const
|
||||
@ -113,6 +92,11 @@ public:
|
||||
slotSize_ = static_cast<uint8_t>(end);
|
||||
}
|
||||
|
||||
static size_t GetHotnessCounterOffset(bool isArch32)
|
||||
{
|
||||
return GetOffset<static_cast<size_t>(Index::HOTNESS_COUNTER_INDEX)>(isArch32);
|
||||
}
|
||||
|
||||
static constexpr size_t VREGS_ARGS_NUM_BITS = 28; // 28: maximum 268,435,455
|
||||
using HaveThisBit = BitField<bool, 0, 1>; // offset 0
|
||||
using HaveNewTargetBit = HaveThisBit::NextFlag; // offset 1
|
||||
@ -128,12 +112,9 @@ public:
|
||||
return callField_;
|
||||
}
|
||||
|
||||
static constexpr uint32_t GetCallFieldOffset(bool isArm32)
|
||||
static size_t GetCallFieldOffset(bool isArch32)
|
||||
{
|
||||
if (isArm32) {
|
||||
return JS_METHOD_CALLFIELD_OFFSET_32;
|
||||
}
|
||||
return JS_METHOD_CALLFIELD_OFFSET_64;
|
||||
return GetOffset<static_cast<size_t>(Index::CALL_FIELD_INDEX)>(isArch32);
|
||||
}
|
||||
|
||||
void SetNumArgsWithCallField(uint32_t numargs)
|
||||
@ -152,7 +133,8 @@ public:
|
||||
}
|
||||
|
||||
CString PUBLIC_API ParseFunctionName() const;
|
||||
void InitializeCallField();
|
||||
|
||||
void InitializeCallField(uint32_t numVregs, uint32_t numArgs);
|
||||
|
||||
bool HaveThisWithCallField() const
|
||||
{
|
||||
@ -194,6 +176,12 @@ public:
|
||||
return NumArgsBits::Decode(callField_);
|
||||
}
|
||||
|
||||
uint32_t GetNumArgs() const
|
||||
{
|
||||
return GetNumArgsWithCallField() + HaveFuncWithCallField() +
|
||||
HaveNewTargetWithCallField() + HaveThisWithCallField();
|
||||
}
|
||||
|
||||
const JSPandaFile *GetJSPandaFile() const
|
||||
{
|
||||
return jsPandaFile_;
|
||||
@ -201,13 +189,63 @@ public:
|
||||
|
||||
const char * PUBLIC_API GetMethodName() const;
|
||||
|
||||
private:
|
||||
uint64_t callField_ {0};
|
||||
const JSPandaFile *jsPandaFile_ {nullptr};
|
||||
const uint8_t *bytecodeArray_ {nullptr};
|
||||
uint32_t bytecodeArraySize_ {0};
|
||||
uint8_t slotSize_ {0};
|
||||
inline uint32_t GetHotnessCounter() const
|
||||
{
|
||||
return hotnessCounter_;
|
||||
}
|
||||
|
||||
inline NO_THREAD_SANITIZE void IncrementHotnessCounter()
|
||||
{
|
||||
++hotnessCounter_;
|
||||
}
|
||||
|
||||
NO_THREAD_SANITIZE void ResetHotnessCounter()
|
||||
{
|
||||
hotnessCounter_ = 0;
|
||||
}
|
||||
|
||||
inline NO_THREAD_SANITIZE void SetHotnessCounter(size_t counter)
|
||||
{
|
||||
hotnessCounter_ = counter;
|
||||
}
|
||||
|
||||
panda_file::File::EntityId GetMethodId() const
|
||||
{
|
||||
return methodId_;
|
||||
}
|
||||
|
||||
uint32_t PUBLIC_API GetNumVregs() const;
|
||||
|
||||
uint32_t GetCodeSize() const;
|
||||
|
||||
panda_file::File::StringData GetName() const;
|
||||
|
||||
const void* GetNativePointer() const
|
||||
{
|
||||
return nativePointerOrBytecodeArray_;
|
||||
}
|
||||
|
||||
void SetNativePointer(const void *nativePointer)
|
||||
{
|
||||
nativePointerOrBytecodeArray_ = nativePointer;
|
||||
}
|
||||
|
||||
const panda_file::File *GetPandaFile() const;
|
||||
|
||||
alignas(EAS) uint64_t callField_ {0};
|
||||
// Native method decides this filed is NativePointer or BytecodeArray pointer.
|
||||
alignas(EAS) const void *nativePointerOrBytecodeArray_ {nullptr};
|
||||
alignas(EAS) const JSPandaFile *jsPandaFile_ {nullptr};
|
||||
alignas(EAS) uint32_t bytecodeArraySize_ {0};
|
||||
alignas(EAS) uint32_t hotnessCounter_;
|
||||
alignas(EAS) panda_file::File::EntityId methodId_;
|
||||
alignas(EAS) uint8_t slotSize_ {0};
|
||||
};
|
||||
static_assert(MEMBER_OFFSET(JSMethod, callField_) == ASM_JS_METHOD_CALLFIELD_OFFSET);
|
||||
static_assert(MEMBER_OFFSET(JSMethod, nativePointerOrBytecodeArray_) == ASM_JS_METHOD_BYTECODEARRAY_OFFSET);
|
||||
static_assert(MEMBER_OFFSET(JSMethod, hotnessCounter_) == ASM_JS_METHOD_HOTNESS_COUNTER_OFFSET);
|
||||
static_assert(MEMBER_OFFSET(JSMethod, nativePointerOrBytecodeArray_) == ASM_JS_METHOD_NATIVE_POINTER_OFFSET);
|
||||
STATIC_ASSERT_EQ_ARCH(sizeof(JSMethod), JSMethod::SizeArch32, JSMethod::SizeArch64);
|
||||
} // namespace panda::ecmascript
|
||||
|
||||
#endif // ECMASCRIPT_JS_METHOD_H
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
void SetMethodToMap(JSMethod *method)
|
||||
{
|
||||
if (method != nullptr) {
|
||||
methodMap_.emplace(method->GetFileId().GetOffset(), method);
|
||||
methodMap_.emplace(method->GetMethodId().GetOffset(), method);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,10 +72,9 @@ void PandaFileTranslator::TranslateClasses(JSPandaFile *jsPandaFile, const CStri
|
||||
jsPandaFile->UpdateMainMethodIndex(mda.GetMethodId().GetOffset());
|
||||
}
|
||||
|
||||
InitializeMemory(method, jsPandaFile, mda.GetMethodId(), codeDataAccessor.GetCodeId(),
|
||||
mda.GetAccessFlags(), codeDataAccessor.GetNumArgs());
|
||||
InitializeMemory(method, jsPandaFile, mda.GetMethodId());
|
||||
method->SetHotnessCounter(EcmaInterpreter::METHOD_HOTNESS_THRESHOLD);
|
||||
method->InitializeCallField();
|
||||
method->InitializeCallField(codeDataAccessor.GetNumVregs(), codeDataAccessor.GetNumArgs());
|
||||
const uint8_t *insns = codeDataAccessor.GetInstructions();
|
||||
if (translatedCode.find(insns) == translatedCode.end()) {
|
||||
translatedCode.insert(insns);
|
||||
@ -469,27 +468,27 @@ void PandaFileTranslator::TranslateBytecode(JSPandaFile *jsPandaFile, uint32_t i
|
||||
uint32_t index;
|
||||
uint32_t methodId;
|
||||
case BytecodeInstruction::Opcode::ECMA_DEFINEFUNCDYN_PREF_ID16_IMM16_V8:
|
||||
methodId = pf->ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::BASE_FUNCTION, methodId);
|
||||
FixInstructionId32(bcIns, index);
|
||||
break;
|
||||
case BytecodeInstruction::Opcode::ECMA_DEFINENCFUNCDYN_PREF_ID16_IMM16_V8:
|
||||
methodId = pf->ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::NC_FUNCTION, methodId);
|
||||
FixInstructionId32(bcIns, index);
|
||||
break;
|
||||
case BytecodeInstruction::Opcode::ECMA_DEFINEGENERATORFUNC_PREF_ID16_IMM16_V8:
|
||||
methodId = pf->ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::GENERATOR_FUNCTION, methodId);
|
||||
FixInstructionId32(bcIns, index);
|
||||
break;
|
||||
case BytecodeInstruction::Opcode::ECMA_DEFINEASYNCFUNC_PREF_ID16_IMM16_V8:
|
||||
methodId = pf->ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::ASYNC_FUNCTION, methodId);
|
||||
FixInstructionId32(bcIns, index);
|
||||
break;
|
||||
case BytecodeInstruction::Opcode::ECMA_DEFINEMETHOD_PREF_ID16_IMM16_V8:
|
||||
methodId = pf->ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::METHOD, methodId);
|
||||
FixInstructionId32(bcIns, index);
|
||||
break;
|
||||
@ -509,7 +508,7 @@ void PandaFileTranslator::TranslateBytecode(JSPandaFile *jsPandaFile, uint32_t i
|
||||
break;
|
||||
}
|
||||
case BytecodeInstruction::Opcode::ECMA_DEFINECLASSWITHBUFFER_PREF_ID16_IMM16_IMM16_V8_V8: {
|
||||
methodId = pf->ResolveMethodIndex(method->GetFileId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
methodId = pf->ResolveMethodIndex(method->GetMethodId(), bcIns.GetId().AsIndex()).GetOffset();
|
||||
index = jsPandaFile->GetOrInsertConstantPool(ConstPoolType::CLASS_FUNCTION, methodId);
|
||||
FixInstructionId32(bcIns, index);
|
||||
auto imm = bcIns.GetImm<BytecodeInstruction::Format::PREF_ID16_IMM16_IMM16_V8_V8>();
|
||||
|
@ -1058,7 +1058,7 @@ bool FunctionRef::IsNative(const EcmaVM *vm)
|
||||
JSThread *thread = vm->GetJSThread();
|
||||
JSHandle<JSFunctionBase> func = JSHandle<JSFunctionBase>(thread, JSNApiHelper::ToJSTaggedValue(this));
|
||||
JSMethod *method = func->GetMethod();
|
||||
return method->IsNative();
|
||||
return method->IsNativeWithCallField();
|
||||
}
|
||||
|
||||
// ----------------------------------- ArrayRef ----------------------------------------
|
||||
|
@ -2205,16 +2205,6 @@ JSHandle<JSObject> ObjectFactory::NewEmptyJSObject()
|
||||
return NewJSObjectByConstructor(JSHandle<JSFunction>(builtinObj), builtinObj);
|
||||
}
|
||||
|
||||
EcmaString *ObjectFactory::ResolveString(uint32_t stringId)
|
||||
{
|
||||
JSMethod *caller = InterpretedFrameHandler(thread_).GetMethod();
|
||||
auto *pf = caller->GetPandaFile();
|
||||
auto id = panda_file::File::EntityId(stringId);
|
||||
auto foundStr = pf->GetStringData(id);
|
||||
|
||||
return GetRawStringFromStringTable(foundStr.data, foundStr.utf16_length, foundStr.is_ascii);
|
||||
}
|
||||
|
||||
uintptr_t ObjectFactory::NewSpaceBySnapShotAllocator(size_t size)
|
||||
{
|
||||
NewObjectHook();
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "ecmascript/tagged_array.h"
|
||||
|
||||
namespace panda::ecmascript {
|
||||
class JSMethod;
|
||||
struct JSMethod;
|
||||
class JSObject;
|
||||
class JSArray;
|
||||
class JSAPIPlainArray;
|
||||
@ -352,7 +352,6 @@ public:
|
||||
// only use for creating Function.prototype and Function
|
||||
JSHandle<JSFunction> NewJSFunctionByDynClass(JSMethod *method, const JSHandle<JSHClass> &clazz,
|
||||
FunctionKind kind = FunctionKind::NORMAL_FUNCTION);
|
||||
EcmaString *ResolveString(uint32_t stringId);
|
||||
|
||||
// used for creating jsobject by constructor
|
||||
JSHandle<JSObject> NewJSObjectByConstructor(const JSHandle<JSFunction> &constructor,
|
||||
|
@ -773,11 +773,9 @@ void SnapShotSerialize::Relocate(SnapShotType type, const JSPandaFile *jsPandaFi
|
||||
{
|
||||
SnapShotSpace *space = vm_->GetHeap()->GetSnapShotSpace();
|
||||
EcmaStringTable *stringTable = vm_->GetEcmaStringTable();
|
||||
const panda_file::File *pf = nullptr;
|
||||
uint32_t methodNums = 0;
|
||||
JSMethod *methods = nullptr;
|
||||
if (jsPandaFile) {
|
||||
pf = jsPandaFile->GetPandaFile();
|
||||
methodNums = jsPandaFile->GetNumMethods();
|
||||
methods = jsPandaFile->GetMethods();
|
||||
}
|
||||
@ -785,7 +783,7 @@ void SnapShotSerialize::Relocate(SnapShotType type, const JSPandaFile *jsPandaFi
|
||||
size_t others = 0;
|
||||
size_t objIndex = 0;
|
||||
space->EnumerateRegions([stringTable, &others, &objIndex, &rootObjSize, &type,
|
||||
this, pf, methods, &methodNums](Region *current) {
|
||||
this, methods, &methodNums](Region *current) {
|
||||
size_t allocated = current->GetAllocatedBytes();
|
||||
uintptr_t begin = current->GetBegin();
|
||||
uintptr_t end = begin + allocated;
|
||||
@ -794,8 +792,7 @@ void SnapShotSerialize::Relocate(SnapShotType type, const JSPandaFile *jsPandaFi
|
||||
for (size_t i = 0; i < others; i++) {
|
||||
pandaMethod_.emplace_back(begin);
|
||||
auto method = reinterpret_cast<JSMethod *>(begin);
|
||||
method->SetPandaFile(pf);
|
||||
method->SetBytecodeArray(method->GetInstructions());
|
||||
method->SetBytecodeArray(method->GetBytecodeArray());
|
||||
if (memcpy_s(methods + (--methodNums), METHOD_SIZE, method, METHOD_SIZE) != EOK) {
|
||||
LOG_ECMA(FATAL) << "memcpy_s failed";
|
||||
UNREACHABLE();
|
||||
@ -814,8 +811,7 @@ void SnapShotSerialize::Relocate(SnapShotType type, const JSPandaFile *jsPandaFi
|
||||
for (size_t i = 0; i < encodeBit.GetNativePointerIndex(); i++) {
|
||||
pandaMethod_.emplace_back(begin);
|
||||
auto method = reinterpret_cast<JSMethod *>(begin);
|
||||
method->SetPandaFile(pf);
|
||||
method->SetBytecodeArray(method->GetInstructions());
|
||||
method->SetBytecodeArray(method->GetBytecodeArray());
|
||||
if (memcpy_s(methods + (--methodNums), METHOD_SIZE, method, METHOD_SIZE) != EOK) {
|
||||
LOG_ECMA(FATAL) << "memcpy_s failed";
|
||||
UNREACHABLE();
|
||||
|
@ -377,7 +377,7 @@ std::optional<CString> JSBackend::EvaluateValueCmpt(CallFrameId callFrameId, con
|
||||
std::unique_ptr<RemoteObject> *result)
|
||||
{
|
||||
JSMethod *method = DebuggerApi::GetMethod(ecmaVm_);
|
||||
if (method->IsNative()) {
|
||||
if (method->IsNativeWithCallField()) {
|
||||
*result = RemoteObject::FromTagged(ecmaVm_,
|
||||
Exception::EvalError(ecmaVm_, StringRef::NewFromUtf8(ecmaVm_, "Native Frame not support.")));
|
||||
return "Native Frame not support.";
|
||||
@ -403,7 +403,7 @@ std::optional<CString> JSBackend::EvaluateValueCmpt(CallFrameId callFrameId, con
|
||||
}
|
||||
|
||||
int32_t regIndex = -1;
|
||||
auto varInfos = extractor->GetLocalVariableTable(method->GetFileId());
|
||||
auto varInfos = extractor->GetLocalVariableTable(method->GetMethodId());
|
||||
auto iter = varInfos.find(varName.c_str());
|
||||
if (iter != varInfos.end()) {
|
||||
regIndex = iter->second;
|
||||
@ -485,7 +485,7 @@ bool JSBackend::GenerateCallFrames(CVector<std::unique_ptr<CallFrame>> *callFram
|
||||
CallFrameId callFrameId = 0;
|
||||
auto walkerFunc = [this, &callFrameId, &callFrames](const InterpretedFrameHandler *frameHandler) -> StackState {
|
||||
JSMethod *method = DebuggerApi::GetMethod(frameHandler);
|
||||
if (method->IsNative()) {
|
||||
if (method->IsNativeWithCallField()) {
|
||||
LOG(INFO, DEBUGGER) << "GenerateCallFrames: Skip CFrame and Native method";
|
||||
return StackState::CONTINUE;
|
||||
}
|
||||
@ -515,7 +515,7 @@ bool JSBackend::GenerateCallFrame(CallFrame *callFrame,
|
||||
|
||||
// location
|
||||
std::unique_ptr<Location> location = std::make_unique<Location>();
|
||||
CString url = extractor->GetSourceFile(method->GetFileId());
|
||||
CString url = extractor->GetSourceFile(method->GetMethodId());
|
||||
auto scriptFunc = [&location](PtScript *script) -> bool {
|
||||
location->SetScriptId(script->GetScriptId());
|
||||
return true;
|
||||
@ -529,7 +529,8 @@ bool JSBackend::GenerateCallFrame(CallFrame *callFrame,
|
||||
location->SetColumn(column);
|
||||
return true;
|
||||
};
|
||||
if (!extractor->MatchWithOffset(callbackFunc, method->GetFileId(), DebuggerApi::GetBytecodeOffset(frameHandler))) {
|
||||
if (!extractor->MatchWithOffset(callbackFunc, method->GetMethodId(),
|
||||
DebuggerApi::GetBytecodeOffset(frameHandler))) {
|
||||
LOG(ERROR, DEBUGGER) << "GenerateCallFrame: unknown offset: " << DebuggerApi::GetBytecodeOffset(frameHandler);
|
||||
return false;
|
||||
}
|
||||
@ -572,7 +573,7 @@ std::unique_ptr<Scope> JSBackend::GetLocalScopeChain(const InterpretedFrameHandl
|
||||
LOG(ERROR, DEBUGGER) << "GetScopeChain: extractor is null";
|
||||
return localScope;
|
||||
}
|
||||
panda_file::File::EntityId methodId = DebuggerApi::GetMethod(frameHandler)->GetFileId();
|
||||
panda_file::File::EntityId methodId = DebuggerApi::GetMethod(frameHandler)->GetMethodId();
|
||||
Local<JSValueRef> name = JSValueRef::Undefined(ecmaVm_);
|
||||
Local<JSValueRef> value = JSValueRef::Undefined(ecmaVm_);
|
||||
for (const auto &var : extractor->GetLocalVariableTable(methodId)) {
|
||||
|
@ -29,7 +29,7 @@ namespace panda {
|
||||
namespace ecmascript {
|
||||
class InterpretedFrameHandler;
|
||||
class EcmaVM;
|
||||
class JSMethod;
|
||||
struct JSMethod;
|
||||
class JSThread;
|
||||
namespace tooling {
|
||||
class JSDebugger;
|
||||
|
@ -102,7 +102,7 @@ bool JSDebugger::HandleBreakpoint(const JSMethod *method, uint32_t bcOffset)
|
||||
}
|
||||
|
||||
auto *pf = method->GetPandaFile();
|
||||
JSPtLocation location {pf->GetFilename().c_str(), method->GetFileId(), bcOffset};
|
||||
JSPtLocation location {pf->GetFilename().c_str(), method->GetMethodId(), bcOffset};
|
||||
|
||||
hooks_->Breakpoint(location);
|
||||
return true;
|
||||
@ -115,7 +115,7 @@ void JSDebugger::HandleExceptionThrowEvent(const JSThread *thread, const JSMetho
|
||||
}
|
||||
|
||||
auto *pf = method->GetPandaFile();
|
||||
JSPtLocation throwLocation {pf->GetFilename().c_str(), method->GetFileId(), bcOffset};
|
||||
JSPtLocation throwLocation {pf->GetFilename().c_str(), method->GetMethodId(), bcOffset};
|
||||
|
||||
hooks_->Exception(throwLocation);
|
||||
}
|
||||
@ -127,7 +127,7 @@ bool JSDebugger::HandleStep(const JSMethod *method, uint32_t bcOffset)
|
||||
}
|
||||
|
||||
auto *pf = method->GetPandaFile();
|
||||
JSPtLocation location {pf->GetFilename().c_str(), method->GetFileId(), bcOffset};
|
||||
JSPtLocation location {pf->GetFilename().c_str(), method->GetMethodId(), bcOffset};
|
||||
|
||||
hooks_->SingleStep(location);
|
||||
return true;
|
||||
@ -138,7 +138,7 @@ std::optional<JSBreakpoint> JSDebugger::FindBreakpoint(const JSMethod *method, u
|
||||
for (const auto &bp : breakpoints_) {
|
||||
if (bp.GetBytecodeOffset() == bcOffset &&
|
||||
bp.GetMethod()->GetPandaFile()->GetFilename() == method->GetPandaFile()->GetFilename() &&
|
||||
bp.GetMethod()->GetFileId() == method->GetFileId()) {
|
||||
bp.GetMethod()->GetMethodId() == method->GetMethodId()) {
|
||||
return bp;
|
||||
}
|
||||
}
|
||||
@ -167,7 +167,7 @@ JSMethod *JSDebugger::FindMethod(const JSPtLocation &location) const
|
||||
JSMethod *methodsData = jsPandaFile->GetMethods();
|
||||
uint32_t numberMethods = jsPandaFile->GetNumMethods();
|
||||
for (uint32_t i = 0; i < numberMethods; ++i) {
|
||||
if (methodsData[i].GetFileId() == location.GetMethodId()) {
|
||||
if (methodsData[i].GetMethodId() == location.GetMethodId()) {
|
||||
method = methodsData + i;
|
||||
return false;
|
||||
}
|
||||
@ -324,7 +324,7 @@ JSTaggedValue JSDebugger::SetGlobalValue(const EcmaVM *ecmaVm, JSTaggedValue key
|
||||
|
||||
bool JSDebugger::EvaluateLocalValue(JSMethod *method, JSThread *thread, const CString &varName, int32_t ®Index)
|
||||
{
|
||||
if (method->IsNative()) {
|
||||
if (method->IsNativeWithCallField()) {
|
||||
LOG(ERROR, DEBUGGER) << "EvaluateLocalValue: native frame not support";
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "native frame not support", false);
|
||||
}
|
||||
@ -334,7 +334,7 @@ bool JSDebugger::EvaluateLocalValue(JSMethod *method, JSThread *thread, const CS
|
||||
THROW_TYPE_ERROR_AND_RETURN(thread, "extractor is null", false);
|
||||
}
|
||||
|
||||
auto varTbl = extractor->GetLocalVariableTable(method->GetFileId());
|
||||
auto varTbl = extractor->GetLocalVariableTable(method->GetMethodId());
|
||||
auto iter = varTbl.find(varName);
|
||||
if (iter == varTbl.end()) {
|
||||
return false;
|
||||
|
@ -110,7 +110,7 @@ std::unique_ptr<JSPtExtractor::SingleStepper> JSPtExtractor::GetStepper(const Ec
|
||||
return std::make_unique<SingleStepper>(ecmaVm, method, CList<JSPtStepRange> {}, type);
|
||||
}
|
||||
|
||||
CList<JSPtStepRange> ranges = GetStepRanges(method->GetFileId(), DebuggerApi::GetBytecodeOffset(ecmaVm));
|
||||
CList<JSPtStepRange> ranges = GetStepRanges(method->GetMethodId(), DebuggerApi::GetBytecodeOffset(ecmaVm));
|
||||
return std::make_unique<SingleStepper>(ecmaVm, method, std::move(ranges), type);
|
||||
}
|
||||
} // namespace panda::ecmascript::tooling
|
||||
|
@ -22,13 +22,13 @@
|
||||
#define ASM_GLUE_BC_HANDLERS_OFFSET (32)
|
||||
#define ASM_GLUE_RUNTIME_FUNCTIONS_OFFSET (2080)
|
||||
#define ASM_BASE_FUNCTION_METHOD_OFFSET (32)
|
||||
#define ASM_JS_METHOD_CALLFIELD_OFFSET (72)
|
||||
#define ASM_JS_METHOD_BYTECODEARRAY_OFFSET (88)
|
||||
#define ASM_JS_METHOD_CALLFIELD_OFFSET (0)
|
||||
#define ASM_JS_METHOD_BYTECODEARRAY_OFFSET (8)
|
||||
#define ASM_JS_FUNCTION_LEXICAL_ENV_OFFSET (48)
|
||||
#define ASM_JS_FUNCTION_CONSTANT_POOL_OFFSET (72)
|
||||
#define ASM_JF_FUNCTION_PROFILE_TYPE_INFO_OFFSET (80)
|
||||
#define ASM_JS_METHOD_HOTNESS_COUNTER_OFFSET (12)
|
||||
#define ASM_JS_METHOD_NATIVE_POINTER_OFFSET (32)
|
||||
#define ASM_JS_METHOD_HOTNESS_COUNTER_OFFSET (32)
|
||||
#define ASM_JS_METHOD_NATIVE_POINTER_OFFSET (8)
|
||||
#ifdef PANDA_TARGET_ARM64
|
||||
#define ASM_GLUE_TO_THREAD_OFFSET (136)
|
||||
#else
|
||||
@ -63,13 +63,13 @@
|
||||
#define ASM_GLUE_BC_HANDLERS_OFFSET (32)
|
||||
#define ASM_GLUE_RUNTIME_FUNCTIONS_OFFSET (1056)
|
||||
#define ASM_BASE_FUNCTION_METHOD_OFFSET (32)
|
||||
#define ASM_JS_METHOD_CALLFIELD_OFFSET (48)
|
||||
#define ASM_JS_METHOD_BYTECODEARRAY_OFFSET (60)
|
||||
#define ASM_JS_METHOD_CALLFIELD_OFFSET (0)
|
||||
#define ASM_JS_METHOD_BYTECODEARRAY_OFFSET (8)
|
||||
#define ASM_JS_FUNCTION_LEXICAL_ENV_OFFSET (48)
|
||||
#define ASM_JS_FUNCTION_CONSTANT_POOL_OFFSET (72)
|
||||
#define ASM_JF_FUNCTION_PROFILE_TYPE_INFO_OFFSET (80)
|
||||
#define ASM_JS_METHOD_HOTNESS_COUNTER_OFFSET (12)
|
||||
#define ASM_JS_METHOD_NATIVE_POINTER_OFFSET (24)
|
||||
#define ASM_JS_METHOD_HOTNESS_COUNTER_OFFSET (32)
|
||||
#define ASM_JS_METHOD_NATIVE_POINTER_OFFSET (8)
|
||||
#define ASM_GLUE_TO_THREAD_OFFSET (80)
|
||||
// ecma_runtime_callinfo struct in stack
|
||||
// -----------------------------
|
||||
|
@ -185,7 +185,7 @@ GlobalTSTypeRef TSLoader::GetGTFromPandaFile(const panda_file::File &pf, uint32_
|
||||
JSThread *thread = vm_->GetJSThread();
|
||||
ObjectFactory *factory = vm_->GetFactory();
|
||||
|
||||
panda_file::File::EntityId fieldId = method->GetFileId();
|
||||
panda_file::File::EntityId fieldId = method->GetMethodId();
|
||||
panda_file::MethodDataAccessor mda(pf, fieldId);
|
||||
|
||||
uint32_t localId = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user