Fix cpuprofile crash of aot calendar app

1. deopt frames are on thread sp now and adapt it
2. exchange function and env in OptimizedJSFunctionFrame

Issue:https://gitee.com/openharmony/arkcompiler_ets_runtime/issues/I64012?from=project-issue

Signed-off-by: zhangyukun8 <zhangyukun8@huawei.com>
Change-Id: I2ab531a50f104396929629cf5ff1e1610ba65936
This commit is contained in:
zhangyukun8 2022-12-02 15:00:28 +08:00
parent 306aa119d4
commit 9b81809f4f
8 changed files with 36 additions and 12 deletions

View File

@ -333,7 +333,7 @@ void LLVMIRBuilder::GenPrologue()
std::to_string(reservedSlotsSize).c_str());
SaveFrameTypeOnFrame(frameType);
} else if (frameType == FrameType::OPTIMIZED_JS_FUNCTION_FRAME) {
reservedSlotsSize = OptimizedJSFunctionFrame::ComputeReservedJSFuncOffset(slotSize_);
reservedSlotsSize = OptimizedJSFunctionFrame::ComputeReservedEnvOffset(slotSize_);
LLVMAddTargetDependentFunctionAttr(function_, "frame-reserved-slots",
std::to_string(reservedSlotsSize).c_str());
auto ArgList = circuit_->GetRoot(OpCode::ARG_LIST);

View File

@ -346,9 +346,9 @@ void OptimizedCall::CallBuiltinTrampoline(ExtendedAssembler *assembler)
// |--------------------------| OptimizedJSFunctionFrame
// | frameType | |
// |--------------------------| |
// | lexEnv | |
// | call-target | |
// |--------------------------| |
// | call-target | v
// | lexEnv | v
// +--------------------------+ ---------------
void OptimizedCall::GenJSCall(ExtendedAssembler *assembler, bool isNew)

View File

@ -532,9 +532,9 @@ void OptimizedCall::JSProxyCallInternalWithArgV(ExtendedAssembler *assembler)
// |--------------------------| OptimizedJSFunctionFrame
// | frameType | |
// |--------------------------| |
// | lexEnv | |
// | call-target | |
// |--------------------------| |
// | call-target | v
// | lexEnv | v
// +--------------------------+ ---------------
void OptimizedCall::JSCallNew(ExtendedAssembler *assembler)
{

View File

@ -568,7 +568,7 @@ bool CpuProfiler::CheckFrameType(JSThread *thread, JSTaggedType *sp)
if (preSp == nullptr) {
return true;
}
if (!thread->IsLegalAsmSp(reinterpret_cast<uintptr_t>(preSp))) {
if (!thread->IsLegalSp(reinterpret_cast<uintptr_t>(preSp))) {
return false;
}
type = FrameHandler::GetFrameType(preSp);

View File

@ -424,7 +424,7 @@ JSTaggedValue EcmaVM::InvokeEcmaAotEntrypoint(JSHandle<JSFunction> mainFunc, JSH
std::vector<JSTaggedType> args(argsNum, JSTaggedValue::Undefined().GetRawData());
args[0] = mainFunc.GetTaggedValue().GetRawData();
args[2] = thisArg.GetTaggedValue().GetRawData(); // 2: this
const JSTaggedType *prevFp = thread_->GetCurrentSPFrame();
const JSTaggedType *prevFp = thread_->GetLastLeaveFrame();
JSTaggedValue res = ExecuteAot(actualNumArgs, args.data(), prevFp, OptimizedEntryFrame::CallType::CALL_FUNC);
if (thread_->HasPendingException()) {
return thread_->GetException();

View File

@ -359,9 +359,9 @@ STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionArgConfigFrame),
// |--------------------------| OptimizedJSFunctionFrame
// | frameType | |
// |--------------------------| |
// | lexEnv | |
// | call-target | |
// |--------------------------| |
// | call-target | v
// | lexEnv | v
// +--------------------------+ ---------------
//
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
@ -374,8 +374,8 @@ struct OptimizedJSFunctionFrame : public base::AlignedStruct<JSTaggedValue::Tagg
public:
static constexpr size_t ENV_SLOT_DIFF = 2;
enum class Index : size_t {
JSFuncIndex = 0,
EnvIndex,
EnvIndex = 0,
JSFuncIndex,
TypeIndex,
PrevFpIndex,
ReturnAddrIndex,
@ -383,6 +383,11 @@ public:
};
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
static constexpr size_t GetFunctionDeltaReturnAddr()
{
return static_cast<size_t>(Index::ReturnAddrIndex) - static_cast<size_t>(Index::JSFuncIndex);
}
inline JSTaggedType* GetPrevFrameFp()
{
return prevFp;
@ -466,8 +471,8 @@ private:
}
// dynamic callee saveregisters for x86-64
alignas(EAS) JSTaggedValue jsFunc {JSTaggedValue::Undefined()};
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
alignas(EAS) JSTaggedValue jsFunc {JSTaggedValue::Undefined()};
[[maybe_unused]] alignas(EAS) FrameType type {0};
alignas(EAS) JSTaggedType *prevFp {nullptr};
alignas(EAS) uintptr_t returnAddr {0};
@ -476,6 +481,8 @@ private:
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionFrame),
OptimizedJSFunctionFrame::SizeArch32,
OptimizedJSFunctionFrame::SizeArch64);
// 2: return addr & prevFp, type and js function should be pairs to update type and js function at the same time.
static_assert((OptimizedJSFunctionFrame::GetFunctionDeltaReturnAddr() % 2) == 1);
// * The JSFunctionEntry Frame's structure is illustrated as the following:
// +--------------------------+

View File

@ -461,4 +461,17 @@ bool JSThread::IsLegalAsmSp(uintptr_t sp) const
uint64_t top = GetStackStart();
return (bottom <= sp && sp <= top);
}
bool JSThread::IsLegalThreadSp(uintptr_t sp) const
{
uintptr_t bottom = reinterpret_cast<uintptr_t>(glueData_.frameBase_);
size_t maxStackSize = vm_->GetEcmaParamConfiguration().GetMaxStackSize();
uintptr_t top = bottom + maxStackSize;
return (bottom <= sp && sp <= top);
}
bool JSThread::IsLegalSp(uintptr_t sp) const
{
return IsLegalAsmSp(sp) || IsLegalThreadSp(sp);
}
} // namespace panda::ecmascript

View File

@ -538,6 +538,10 @@ public:
bool IsLegalAsmSp(uintptr_t sp) const;
bool IsLegalThreadSp(uintptr_t sp) const;
bool IsLegalSp(uintptr_t sp) const;
bool IsPrintBCOffset() const
{
return enablePrintBCOffset_;