Files
ark_js_runtime/ecmascript/interpreter/frame_handler.cpp
T
guobingbing 99e4839e8f solve the issue of 32bit-64bit not the same
Signed-off-by: guobingbing <guobingbing3@huawei.com>
Change-Id: Iee2cb3b39ad8d8a073dc2e617102d8833c91095c
2021-10-27 14:19:15 +08:00

264 lines
9.5 KiB
C++

/*
* Copyright (c) 2021 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecmascript/interpreter/frame_handler.h"
#include "ecmascript/interpreter/interpreter.h"
#include "ecmascript/js_thread.h"
#include "libpandafile/bytecode_instruction-inl.h"
#include "ecmascript/compiler/llvm/llvm_stackmap_parser.h"
namespace panda::ecmascript {
InterpretedFrameHandler::InterpretedFrameHandler(const JSThread *thread)
{
sp_ = const_cast<JSTaggedType *>(thread->GetCurrentSPFrame());
}
bool InterpretedFrameHandler::HasFrame() const
{
// Breakframe also is a frame
return sp_ != nullptr;
}
bool InterpretedFrameHandler::IsBreakFrame() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return state->sp == nullptr;
}
void InterpretedFrameHandler::PrevFrame()
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
sp_ = state->base.prev;
}
InterpretedFrameHandler InterpretedFrameHandler::GetPrevFrame() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return InterpretedFrameHandler(state->base.prev);
}
JSTaggedValue InterpretedFrameHandler::GetVRegValue(size_t index) const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
return JSTaggedValue(sp_[index]);
}
void InterpretedFrameHandler::SetVRegValue(size_t index, JSTaggedValue value)
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
sp_[index] = value.GetRawData();
}
JSTaggedValue InterpretedFrameHandler::GetAcc() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return state->acc;
}
uint32_t InterpretedFrameHandler::GetSize() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
JSTaggedType *prevSp = state->base.prev;
ASSERT(prevSp != nullptr);
auto size = (prevSp - sp_) - FRAME_STATE_SIZE;
return static_cast<uint32_t>(size);
}
uint32_t InterpretedFrameHandler::GetBytecodeOffset() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
auto offset = state->pc - JSMethod::Cast(state->method)->GetBytecodeArray();
return static_cast<uint32_t>(offset);
}
JSMethod *InterpretedFrameHandler::GetMethod() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return state->method;
}
JSTaggedValue InterpretedFrameHandler::GetFunction() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
uint32_t numVregs = state->method->GetNumVregs();
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
auto func = JSTaggedValue(sp_[numVregs]);
return func;
}
const uint8_t *InterpretedFrameHandler::GetPc() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return state->pc;
}
JSTaggedType *InterpretedFrameHandler::GetSp() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return state->sp;
}
ConstantPool *InterpretedFrameHandler::GetConstpool() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return state->constpool;
}
JSTaggedValue InterpretedFrameHandler::GetEnv() const
{
ASSERT(HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(sp_) - 1;
return state->env;
}
void InterpretedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1)
{
JSTaggedType *current = sp_;
if (current != nullptr) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *state = reinterpret_cast<FrameState *>(current) - 1;
if (state->sp != nullptr) {
uintptr_t start = ToUintPtr(current);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
FrameState *prev_state = reinterpret_cast<FrameState *>(state->base.prev) - 1;
uintptr_t end = ToUintPtr(prev_state);
v1(Root::ROOT_FRAME, ObjectSlot(start), ObjectSlot(end));
if (state->pc != nullptr) {
// interpreter frame
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&state->acc)));
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&state->constpool)));
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&state->env)));
v0(Root::ROOT_FRAME, ObjectSlot(ToUintPtr(&state->profileTypeInfo)));
}
}
}
}
void InterpretedFrameHandler::DumpStack(std::ostream &os) const
{
size_t i = 0;
InterpretedFrameHandler frameHandler(sp_);
for (; frameHandler.HasFrame(); frameHandler.PrevFrame()) {
os << "[" << i++
<< "]:" << frameHandler.GetMethod()->ParseFunctionName()
<< "\n";
}
}
void InterpretedFrameHandler::DumpPC(std::ostream &os, const uint8_t *pc) const
{
InterpretedFrameHandler frameHandler(sp_);
ASSERT(frameHandler.HasFrame());
// NOLINTNEXTLINE(cppcoreguidelines-narrowing-conversions, bugprone-narrowing-conversions)
int offset = pc - JSMethod::Cast(frameHandler.GetMethod())->GetBytecodeArray();
os << "offset: " << offset << "\n";
}
void OptimizedFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const
{
uintptr_t *current = fp_;
if (current != nullptr) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
std::vector<uintptr_t> slotAddrs;
auto returnAddr = reinterpret_cast<uintptr_t>(*(current + 1));
bool ret = kungfu::LLVMStackMapParser::GetInstance().StackMapByFuncAddrFp(
returnAddr,
reinterpret_cast<uintptr_t>(fp_),
slotAddrs);
if (ret == false) {
return;
}
for (auto &address: slotAddrs) {
v0(Root::ROOT_FRAME, ObjectSlot(address));
}
}
}
void OptimizedEntryFrameHandler::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const
{
uintptr_t *current = fp_;
if (current != nullptr) {
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
std::vector<uintptr_t> slotAddrs;
auto returnAddr = *(current + 1);
bool ret = kungfu::LLVMStackMapParser::GetInstance().StackMapByFuncAddrFp(
reinterpret_cast<uintptr_t>(returnAddr),
reinterpret_cast<uintptr_t>(fp_),
slotAddrs);
if (ret == false) {
return;
}
for (auto &address: slotAddrs) {
v0(Root::ROOT_FRAME, ObjectSlot(address));
}
}
}
void FrameIterator::Iterate(const RootVisitor &v0, const RootRangeVisitor &v1) const
{
JSTaggedType *current = fp_;
while (current) {
FrameType type = *(reinterpret_cast<FrameType*>(
reinterpret_cast<intptr_t>(current) + FrameConst::FRAME_TYPE_OFFSET));
if (type == FrameType::INTERPRETER_FRAME) {
FrameState *state = reinterpret_cast<FrameState *>(current) - 1;
InterpretedFrameHandler(current).Iterate(v0, v1);
current = state->base.prev;
} else if (type == FrameType::OPTIMIZED_FRAME) {
OptimizedFrameStateBase *state = reinterpret_cast<OptimizedFrameStateBase *>(
reinterpret_cast<intptr_t>(current) -
MEMBER_OFFSET(OptimizedFrameStateBase, prev));
OptimizedFrameHandler(reinterpret_cast<uintptr_t *>(current)).Iterate(v0, v1);
current = reinterpret_cast<JSTaggedType *>(state->prev);
} else {
ASSERT(type == FrameType::OPTIMIZED_ENTRY_FRAME);
OptimizedEntryFrameState *state = reinterpret_cast<OptimizedEntryFrameState *>(
reinterpret_cast<intptr_t>(current) -
MEMBER_OFFSET(OptimizedEntryFrameState, base.prev));
OptimizedEntryFrameHandler(reinterpret_cast<uintptr_t *>(current)).Iterate(v0, v1);
current = reinterpret_cast<JSTaggedType *>(state->threadFp);
}
}
}
} // namespace panda::ecmascript