2021-09-07 14:24:16 +00:00
|
|
|
/*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
2022-03-09 09:53:59 +00:00
|
|
|
#ifndef ECMASCRIPT_FRAMES_H
|
|
|
|
#define ECMASCRIPT_FRAMES_H
|
|
|
|
|
|
|
|
#include "ecmascript/js_tagged_value.h"
|
|
|
|
#include "ecmascript/trampoline/asm_defines.h"
|
2021-10-10 02:44:14 +00:00
|
|
|
|
|
|
|
// Frame Layout
|
|
|
|
// Interpreter Frame(alias **iframe** ) Layout as follow:
|
|
|
|
// ```
|
2021-12-17 09:18:10 +00:00
|
|
|
// +----------------------------------+-------------------+
|
|
|
|
// | argv[n-1] | ^
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | ...... | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | thisArg [maybe not exist] | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | newTarget [maybe not exist] | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | callTarget [deleted] | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | ...... | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | Vregs [not exist in native] | |
|
|
|
|
// +----------------------------------+--------+ interpreter frame
|
|
|
|
// | base.frameType | ^ |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | base.prev(pre stack pointer) | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | numActualArgs [deleted] | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | env | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | acc | | |
|
2021-12-31 07:51:09 +00:00
|
|
|
// |----------------------------------|InterpretedFrame |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | profileTypeInfo | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | constantpool | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | method [changed to function] | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | sp(current stack point) | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | pc(bytecode addr) | v v
|
2021-10-10 02:44:14 +00:00
|
|
|
// +----------------------------------+--------+----------+
|
2022-01-22 08:07:03 +00:00
|
|
|
|
2022-03-01 02:57:53 +00:00
|
|
|
// Optimized Leave Frame(alias OptimizedLeaveFrame) layout
|
2022-01-22 08:07:03 +00:00
|
|
|
// +--------------------------+
|
Implement Proxy Lowering on x86
when function need call another js function, it will lowering to call "JSCall" trampoline function
JSCall trampoline function will check calltarget function, then correct the arguments, finally jump
the native or optimized code address of the target function.
JSCall(glue, argc, calltarget, ....)
then proxy call(glue, argc, callTarget, argv[])
if proxy->GetHandler is function
tail call JSCall(glue, argc, callTarget, argv); // consider performance
else
//Call(trap, handler, «target, thisArgument, argArray»)
call CreateArrayFromList(glue, argc, argv[]) ---> arrHandle // maybe trigger GC, construct OptimizedWithArgvLeaveFrame, visitor argv[0]..argv[argc-1]
call JSCall(glue, argc, method, argv[])
issue:https://gitee.com/openharmony/ark_js_runtime/issues/I52T6B?from=project-issue
Signed-off-by: songzhengchao <songzhengchao@huawei.com>
Change-Id: I994aae1eb9cbf51982348ae6e203c24c326f617e
2022-04-14 13:54:03 +00:00
|
|
|
// | argv[argc-1] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | .......... |
|
|
|
|
// +--------------------------+
|
|
|
|
// | argv[1] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | argv[0] |
|
|
|
|
// +--------------------------+ ---
|
|
|
|
// | argc | ^
|
|
|
|
// |--------------------------| Fixed
|
|
|
|
// | RuntimeId | OptimizedLeaveFrame
|
|
|
|
// |--------------------------| |
|
|
|
|
// | returnAddr | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | callsiteFp | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | frameType | v
|
|
|
|
// +--------------------------+ ---
|
|
|
|
// | callee save registers |
|
|
|
|
// +--------------------------+
|
|
|
|
|
|
|
|
// Optimized Leave Frame with Argv(alias OptimizedWithArgvLeaveFrame) layout
|
|
|
|
// +--------------------------+
|
2022-03-08 06:22:03 +00:00
|
|
|
// | argv[] |
|
2022-03-01 02:57:53 +00:00
|
|
|
// +--------------------------+ ---
|
|
|
|
// | argc | ^
|
2022-03-08 06:22:03 +00:00
|
|
|
// |--------------------------| Fixed
|
2022-04-24 07:14:09 +00:00
|
|
|
// | RuntimeId | OptimizedWithArgvLeaveFrame
|
2022-03-01 02:57:53 +00:00
|
|
|
// |--------------------------| |
|
|
|
|
// | returnAddr | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | callsiteFp | |
|
|
|
|
// |--------------------------| |
|
2022-03-08 06:22:03 +00:00
|
|
|
// | frameType | v
|
2022-03-01 02:57:53 +00:00
|
|
|
// +--------------------------+ ---
|
|
|
|
// | callee save registers |
|
2022-01-22 08:07:03 +00:00
|
|
|
// +--------------------------+
|
|
|
|
|
|
|
|
// Optimized Frame(alias OptimizedFrame) layout
|
|
|
|
// +--------------------------+
|
|
|
|
// | calleesave registers | ^
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| |
|
2022-01-22 08:07:03 +00:00
|
|
|
// | returnaddress | Fixed
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| OptimizedFrame
|
2022-01-24 12:31:38 +00:00
|
|
|
// | prevFp | |
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| |
|
2022-01-22 08:07:03 +00:00
|
|
|
// | frameType | |
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| |
|
2022-04-25 03:17:47 +00:00
|
|
|
// | callSiteSp | v
|
2022-01-22 08:07:03 +00:00
|
|
|
// +--------------------------+
|
|
|
|
|
|
|
|
// Optimized Entry Frame(alias OptimizedEntryFrame) layout
|
|
|
|
// +--------------------------+
|
2022-03-01 02:57:53 +00:00
|
|
|
// | returnaddress | ^
|
|
|
|
// |----------------------| |
|
|
|
|
// |calleesave registers | Fixed
|
|
|
|
// |----------------------| OptimizedEntryFrame
|
|
|
|
// | prevFp | |
|
|
|
|
// |----------------------| |
|
|
|
|
// | frameType | |
|
|
|
|
// |----------------------| |
|
|
|
|
// | prevLeaveFrameFp | v
|
2022-01-22 08:07:03 +00:00
|
|
|
// +--------------------------+
|
|
|
|
|
2022-04-06 11:22:08 +00:00
|
|
|
// Interpreted Entry Frame(alias InterpretedEntryFrame) layout
|
|
|
|
// +--------------------------+
|
|
|
|
// | base.type | ^
|
|
|
|
// |----------------------| |
|
|
|
|
// | base.prev | InterpretedEntryFrame
|
|
|
|
// |----------------------| |
|
|
|
|
// | pc | v
|
|
|
|
// +--------------------------+
|
|
|
|
|
2021-10-10 02:44:14 +00:00
|
|
|
// ```
|
|
|
|
// address space grow from high address to low address.we add new field **FrameType** ,
|
|
|
|
// the field's value is INTERPRETER_FRAME(represent interpreter frame).
|
|
|
|
// **currentsp** is pointer to callTarget field address, sp field 's value is **currentsp** ,
|
|
|
|
// pre field pointer pre stack frame point. fill JSthread's sp field with iframe sp field
|
|
|
|
// by calling JSThread->SetCurrentSPFrame and save pre Frame address to iframe pre field.
|
|
|
|
|
|
|
|
// For Example:
|
|
|
|
// ```
|
2022-01-22 08:07:03 +00:00
|
|
|
// call call
|
|
|
|
// foo -----------------> bar ----------------------->baz ---------------------> rtfunc
|
2022-03-01 02:57:53 +00:00
|
|
|
// (interpret frame) (OptimizedEntryFrame) (OptimizedFrame) (OptimizedLeaveFrame + Runtime Frame)
|
2021-10-10 02:44:14 +00:00
|
|
|
// ```
|
|
|
|
|
|
|
|
// Frame Layout as follow:
|
|
|
|
// ```
|
2021-12-17 09:18:10 +00:00
|
|
|
// +----------------------------------+-------------------+
|
|
|
|
// | argv[n-1] | ^
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | ...... | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | thisArg [maybe not exist] | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | newTarget [maybe not exist] | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | ...... | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | Vregs | |
|
|
|
|
// +----------------------------------+--------+ foo's frame
|
|
|
|
// | base.frameType | ^ |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | base.prev(pre stack pointer) | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | env | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | acc | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-31 07:51:09 +00:00
|
|
|
// | profileTypeInfo |InterpretedFrame |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | constantpool | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | function | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | sp(current stack point) | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2021-12-17 09:18:10 +00:00
|
|
|
// | pc(bytecode addr) | v v
|
2021-10-10 02:44:14 +00:00
|
|
|
// +----------------------------------+--------+----------+
|
|
|
|
// | ............. |
|
|
|
|
// +--------------------------+---------------------------+
|
2022-03-01 02:57:53 +00:00
|
|
|
// | returnaddress | ^ ^
|
|
|
|
// |----------------------| | |
|
|
|
|
// |calleesave registers | Fixed |
|
|
|
|
// |----------------------| OptimizedEntryFrame bar's frame
|
|
|
|
// | prevFp | | |
|
|
|
|
// |----------------------| | |
|
|
|
|
// | frameType | | |
|
|
|
|
// |----------------------| | |
|
|
|
|
// | prevLeaveFrameFp | v |
|
|
|
|
// +--------------------------+ V
|
2022-01-22 08:07:03 +00:00
|
|
|
// +--------------------------+---------------------------+
|
|
|
|
// | ............. |
|
|
|
|
// +--------------------------+---------------------------+
|
|
|
|
// +--------------------------+---------------------------+
|
|
|
|
// | calleesave registers | ^ ^
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| | |
|
2022-01-22 08:07:03 +00:00
|
|
|
// | returnaddress | Fixed |
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| OptimizedFrame |
|
2022-01-24 07:36:24 +00:00
|
|
|
// | prevFp | | |
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| | baz's frame Header
|
2022-01-22 08:07:03 +00:00
|
|
|
// | frameType | | |
|
2022-03-01 02:57:53 +00:00
|
|
|
// |----------------------| | |
|
2022-01-24 07:36:24 +00:00
|
|
|
// | callsitesp | v V
|
2022-01-22 08:07:03 +00:00
|
|
|
// +--------------------------+---------------------------+
|
|
|
|
// | ............. |
|
|
|
|
// +--------------------------+---------------------------+
|
2022-03-08 06:22:03 +00:00
|
|
|
// +--------------------------+---------------------------+
|
|
|
|
// | argv[] | ^
|
|
|
|
// +--------------------------+---- |
|
2022-03-01 02:57:53 +00:00
|
|
|
// | argc | ^ |
|
2022-03-08 06:22:03 +00:00
|
|
|
// |--------------------------| Fixed |
|
|
|
|
// | RuntimeId | OptimizedLeaveFrame |
|
|
|
|
// |--------------------------| | OptimizedLeaveFrame
|
2022-03-01 02:57:53 +00:00
|
|
|
// | returnAddr | | |
|
|
|
|
// |--------------------------| | |
|
|
|
|
// | callsiteFp | | |
|
|
|
|
// |--------------------------| | |
|
2022-03-08 06:22:03 +00:00
|
|
|
// | frameType | V |
|
2022-03-01 02:57:53 +00:00
|
|
|
// +--------------------------+ ---- |
|
|
|
|
// | callee save registers | V
|
2021-12-31 07:51:09 +00:00
|
|
|
// +--------------------------+---------------------------+
|
2021-10-10 02:44:14 +00:00
|
|
|
// | ............. |
|
|
|
|
// +--------------------------+---------------------------+
|
|
|
|
// | |
|
|
|
|
// | rtfunc's Frame |
|
|
|
|
// | |
|
|
|
|
// +------------------------------------------------------+
|
|
|
|
// ```
|
|
|
|
// Iterator:
|
2022-03-01 02:57:53 +00:00
|
|
|
// rtfunc get OptimizedLeaveFrame by calling GetCurrentSPFrame.
|
|
|
|
// get baz's Frame by OptimizedLeaveFrame.prev field.
|
2022-01-22 08:07:03 +00:00
|
|
|
// get bar's Frame by baz's frame fp field
|
|
|
|
// get foo's Frame by bar's Frame prev field
|
2021-10-10 02:44:14 +00:00
|
|
|
|
2022-03-10 11:24:49 +00:00
|
|
|
#include "ecmascript/base/aligned_struct.h"
|
|
|
|
|
2021-09-07 14:24:16 +00:00
|
|
|
namespace panda::ecmascript {
|
2022-03-12 09:29:12 +00:00
|
|
|
enum class FrameType: uintptr_t {
|
2021-09-07 14:24:16 +00:00
|
|
|
OPTIMIZED_FRAME = 0,
|
|
|
|
OPTIMIZED_ENTRY_FRAME = 1,
|
|
|
|
INTERPRETER_FRAME = 2,
|
2022-04-24 01:07:45 +00:00
|
|
|
LEAVE_FRAME = 3,
|
2022-03-01 11:19:40 +00:00
|
|
|
INTERPRETER_FAST_NEW_FRAME = 4,
|
2022-04-24 01:07:45 +00:00
|
|
|
INTERPRETER_ENTRY_FRAME = 5,
|
|
|
|
LEAVE_FRAME_WITH_ARGV = 6,
|
2021-09-07 14:24:16 +00:00
|
|
|
};
|
|
|
|
|
2022-01-13 08:26:00 +00:00
|
|
|
class FrameConstants {
|
2021-09-07 14:24:16 +00:00
|
|
|
public:
|
2022-01-13 08:26:00 +00:00
|
|
|
#ifdef PANDA_TARGET_AMD64
|
|
|
|
static constexpr int SP_DWARF_REG_NUM = 7;
|
|
|
|
static constexpr int FP_DWARF_REG_NUM = 6;
|
|
|
|
#else
|
|
|
|
#ifdef PANDA_TARGET_ARM64
|
|
|
|
static constexpr int SP_DWARF_REG_NUM = 31; /* x31 */
|
|
|
|
static constexpr int FP_DWARF_REG_NUM = 29; /* x29 */
|
|
|
|
#else
|
|
|
|
#ifdef PANDA_TARGET_ARM32
|
|
|
|
static constexpr int SP_DWARF_REG_NUM = 13;
|
|
|
|
static constexpr int FP_DWARF_REG_NUM = 11;
|
|
|
|
#else
|
|
|
|
static constexpr int SP_DWARF_REG_NUM = 0;
|
|
|
|
static constexpr int FP_DWARF_REG_NUM = 0;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
static constexpr int AARCH64_SLOT_SIZE = sizeof(uint64_t);
|
|
|
|
static constexpr int AMD64_SLOT_SIZE = sizeof(uint64_t);
|
|
|
|
static constexpr int ARM32_SLOT_SIZE = sizeof(uint32_t);
|
2021-09-07 14:24:16 +00:00
|
|
|
};
|
|
|
|
|
2022-04-25 03:17:47 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
|
|
struct OptimizedFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
2021-10-09 10:49:19 +00:00
|
|
|
public:
|
2022-04-25 03:17:47 +00:00
|
|
|
enum class Index : size_t {
|
|
|
|
CallSiteSpIndex = 0,
|
|
|
|
TypeIndex,
|
|
|
|
PrevFpIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
2022-03-01 02:57:53 +00:00
|
|
|
|
2022-04-29 09:32:24 +00:00
|
|
|
static OptimizedFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2022-01-13 08:26:00 +00:00
|
|
|
{
|
2022-03-01 02:57:53 +00:00
|
|
|
return reinterpret_cast<OptimizedFrame *>(reinterpret_cast<uintptr_t>(sp)
|
2022-04-25 03:17:47 +00:00
|
|
|
- MEMBER_OFFSET(OptimizedFrame, prevFp));
|
2022-03-01 02:57:53 +00:00
|
|
|
}
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
2022-04-25 03:17:47 +00:00
|
|
|
return prevFp;
|
|
|
|
}
|
|
|
|
inline uintptr_t GetCallSiteSp() const
|
|
|
|
{
|
|
|
|
return callSiteSp;
|
|
|
|
}
|
|
|
|
static int32_t GetCallSiteFpToSpDelta(bool isArch32)
|
|
|
|
{
|
|
|
|
auto prevFpOffset = GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
|
|
|
auto callSiteSpOffset = GetOffset<static_cast<size_t>(Index::CallSiteSpIndex)>(isArch32);
|
|
|
|
return prevFpOffset - callSiteSpOffset;
|
2022-01-13 08:26:00 +00:00
|
|
|
}
|
2022-04-25 03:17:47 +00:00
|
|
|
|
|
|
|
alignas(EAS) uintptr_t callSiteSp {0};
|
|
|
|
alignas(EAS) FrameType type {0};
|
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
2021-10-09 10:49:19 +00:00
|
|
|
};
|
2022-04-25 03:17:47 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedFrame), OptimizedFrame::SizeArch32, OptimizedFrame::SizeArch64);
|
2021-10-09 10:49:19 +00:00
|
|
|
|
2022-04-25 03:17:47 +00:00
|
|
|
struct OptimizedEntryFrame {
|
2021-09-07 14:24:16 +00:00
|
|
|
public:
|
2021-12-31 07:51:09 +00:00
|
|
|
OptimizedEntryFrame() = default;
|
|
|
|
~OptimizedEntryFrame() = default;
|
2022-03-01 02:57:53 +00:00
|
|
|
JSTaggedType *preLeaveFrameFp;
|
2022-04-25 03:17:47 +00:00
|
|
|
FrameType type;
|
|
|
|
JSTaggedType *prevFp;
|
2022-03-01 02:57:53 +00:00
|
|
|
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
2022-01-24 07:36:24 +00:00
|
|
|
{
|
2022-03-01 02:57:53 +00:00
|
|
|
return preLeaveFrameFp;
|
2022-01-24 07:36:24 +00:00
|
|
|
}
|
2022-03-01 02:57:53 +00:00
|
|
|
|
2022-04-29 09:32:24 +00:00
|
|
|
static OptimizedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2021-12-31 07:51:09 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<OptimizedEntryFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
2022-04-25 03:17:47 +00:00
|
|
|
MEMBER_OFFSET(OptimizedEntryFrame, prevFp));
|
2021-12-31 07:51:09 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-01-13 08:26:00 +00:00
|
|
|
class InterpretedFrameBase {
|
|
|
|
public:
|
|
|
|
InterpretedFrameBase() = default;
|
|
|
|
~InterpretedFrameBase() = default;
|
|
|
|
JSTaggedType *prev; // for llvm :c-fp ; for interrupt: thread-fp for gc
|
|
|
|
FrameType type;
|
2022-03-12 10:47:21 +00:00
|
|
|
static constexpr size_t TYPE_OFFSET_32 = sizeof(uint32_t);
|
|
|
|
static constexpr size_t TYPE_OFFSET_64 = sizeof(uint64_t);
|
|
|
|
static constexpr size_t SizeArch32 = TYPE_OFFSET_32 + sizeof(FrameType);
|
|
|
|
static constexpr size_t SizeArch64 = TYPE_OFFSET_64 + sizeof(FrameType);
|
2022-01-13 08:26:00 +00:00
|
|
|
};
|
|
|
|
|
2021-12-31 07:51:09 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
2022-03-10 11:24:49 +00:00
|
|
|
struct InterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
|
|
|
JSTaggedValue,
|
|
|
|
JSTaggedValue,
|
|
|
|
JSTaggedValue,
|
|
|
|
JSTaggedValue,
|
|
|
|
JSTaggedValue,
|
2022-04-21 02:16:04 +00:00
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
2022-03-10 11:24:49 +00:00
|
|
|
InterpretedFrameBase> {
|
|
|
|
enum class Index : size_t {
|
2022-04-21 02:16:04 +00:00
|
|
|
ConstPoolIndex = 0,
|
2022-03-10 11:24:49 +00:00
|
|
|
FunctionIndex,
|
|
|
|
ProFileTypeInfoIndex,
|
|
|
|
AccIndex,
|
|
|
|
EnvIndex,
|
2022-04-21 02:16:04 +00:00
|
|
|
SpIndex,
|
|
|
|
PcIndex,
|
2022-03-10 11:24:49 +00:00
|
|
|
BaseIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
2022-03-01 02:57:53 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return base.prev;
|
|
|
|
}
|
2022-02-19 02:09:52 +00:00
|
|
|
|
2022-04-29 09:32:24 +00:00
|
|
|
static InterpretedFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2021-12-31 07:51:09 +00:00
|
|
|
{
|
2022-04-29 09:32:24 +00:00
|
|
|
return reinterpret_cast<InterpretedFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
2021-12-31 07:51:09 +00:00
|
|
|
}
|
2022-02-19 02:09:52 +00:00
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
alignas(EAS) JSTaggedValue constpool {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) JSTaggedValue profileTypeInfo {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) JSTaggedValue acc {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
2022-04-21 02:16:04 +00:00
|
|
|
alignas(EAS) JSTaggedType *sp {nullptr};
|
|
|
|
alignas(EAS) const uint8_t *pc {nullptr};
|
2022-03-18 07:17:30 +00:00
|
|
|
alignas(EAS) InterpretedFrameBase base;
|
|
|
|
};
|
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedFrame), InterpretedFrame::SizeArch32, InterpretedFrame::SizeArch64);
|
2022-02-19 02:09:52 +00:00
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
|
|
struct AsmInterpretedFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
|
|
|
JSTaggedValue,
|
|
|
|
JSTaggedValue,
|
|
|
|
JSTaggedValue,
|
2022-04-25 03:17:47 +00:00
|
|
|
base::AlignedPointer,
|
2022-04-14 02:57:58 +00:00
|
|
|
base::AlignedPointer,
|
2022-05-06 07:51:52 +00:00
|
|
|
base::AlignedPointer,
|
2022-03-18 07:17:30 +00:00
|
|
|
InterpretedFrameBase> {
|
|
|
|
enum class Index : size_t {
|
2022-04-14 02:57:58 +00:00
|
|
|
FunctionIndex = 0,
|
2022-03-18 07:17:30 +00:00
|
|
|
AccIndex,
|
|
|
|
EnvIndex,
|
2022-04-25 03:17:47 +00:00
|
|
|
CallSizeOrCallSiteSpIndex,
|
2022-05-06 07:51:52 +00:00
|
|
|
FpIndex,
|
2022-04-14 02:57:58 +00:00
|
|
|
PcIndex,
|
2022-03-18 07:17:30 +00:00
|
|
|
BaseIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
2022-04-14 02:57:58 +00:00
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
2022-05-06 07:51:52 +00:00
|
|
|
inline const JSTaggedType* GetCurrentFramePointer() const
|
|
|
|
{
|
|
|
|
return fp;
|
|
|
|
}
|
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
2022-03-22 03:30:26 +00:00
|
|
|
{
|
2022-03-18 07:17:30 +00:00
|
|
|
return base.prev;
|
2022-03-22 03:30:26 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 09:32:24 +00:00
|
|
|
static AsmInterpretedFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2022-02-19 02:09:52 +00:00
|
|
|
{
|
2022-04-29 09:32:24 +00:00
|
|
|
return reinterpret_cast<AsmInterpretedFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-05-06 07:51:52 +00:00
|
|
|
static size_t GetFpOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::FpIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
static size_t GetCallSizeOffset(bool isArch32)
|
2022-02-19 02:09:52 +00:00
|
|
|
{
|
2022-04-25 03:17:47 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::CallSizeOrCallSiteSpIndex)>(isArch32);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
static size_t GetFunctionOffset(bool isArch32)
|
2022-02-19 02:09:52 +00:00
|
|
|
{
|
2022-03-18 07:17:30 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::FunctionIndex)>(isArch32);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
static size_t GetAccOffset(bool isArch32)
|
2022-02-19 02:09:52 +00:00
|
|
|
{
|
2022-03-10 11:24:49 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::AccIndex)>(isArch32);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
static size_t GetEnvOffset(bool isArch32)
|
2022-02-19 02:09:52 +00:00
|
|
|
{
|
2022-03-10 11:24:49 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::EnvIndex)>(isArch32);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
2022-03-18 07:17:30 +00:00
|
|
|
|
|
|
|
static size_t GetBaseOffset(bool isArch32)
|
2022-02-19 02:09:52 +00:00
|
|
|
{
|
2022-03-10 11:24:49 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32);
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-04-14 02:57:58 +00:00
|
|
|
static size_t GetPcOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::PcIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
2022-03-18 07:17:30 +00:00
|
|
|
static constexpr size_t GetSize(bool isArch32)
|
2022-02-19 02:09:52 +00:00
|
|
|
{
|
2022-03-18 07:17:30 +00:00
|
|
|
return isArch32 ? AsmInterpretedFrame::SizeArch32 : AsmInterpretedFrame::SizeArch64;
|
2022-02-19 02:09:52 +00:00
|
|
|
}
|
|
|
|
|
2022-04-25 03:17:47 +00:00
|
|
|
inline uintptr_t GetCallSiteSp() const
|
|
|
|
{
|
|
|
|
return callSizeOrCallSiteSp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int32_t GetCallSiteFpToSpDelta(bool isArch32)
|
|
|
|
{
|
|
|
|
auto fpOffset = GetSize(isArch32);
|
|
|
|
auto callSiteSpOffset = GetOffset<static_cast<size_t>(Index::CallSizeOrCallSiteSpIndex)>(isArch32);
|
|
|
|
return fpOffset - callSiteSpOffset;
|
|
|
|
}
|
|
|
|
|
2022-03-10 11:24:49 +00:00
|
|
|
alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) JSTaggedValue acc {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
2022-04-25 03:17:47 +00:00
|
|
|
alignas(EAS) uintptr_t callSizeOrCallSiteSp {0};
|
2022-05-06 07:51:52 +00:00
|
|
|
alignas(EAS) JSTaggedType *fp {nullptr};
|
2022-04-14 02:57:58 +00:00
|
|
|
alignas(EAS) const uint8_t *pc {nullptr};
|
2022-03-10 11:24:49 +00:00
|
|
|
alignas(EAS) InterpretedFrameBase base;
|
2021-12-31 07:51:09 +00:00
|
|
|
};
|
2022-03-18 07:17:30 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(AsmInterpretedFrame), AsmInterpretedFrame::SizeArch32, AsmInterpretedFrame::SizeArch64);
|
2022-01-13 08:26:00 +00:00
|
|
|
|
2022-04-21 02:16:04 +00:00
|
|
|
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
|
|
struct InterpretedEntryFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
|
|
|
base::AlignedPointer,
|
|
|
|
InterpretedFrameBase> {
|
|
|
|
enum class Index : size_t {
|
|
|
|
PcIndex = 0,
|
|
|
|
BaseIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
2022-04-06 11:22:08 +00:00
|
|
|
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return base.prev;
|
|
|
|
}
|
|
|
|
|
2022-04-29 09:32:24 +00:00
|
|
|
static InterpretedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2022-04-06 11:22:08 +00:00
|
|
|
{
|
2022-04-29 09:32:24 +00:00
|
|
|
return reinterpret_cast<InterpretedEntryFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
2022-04-06 11:22:08 +00:00
|
|
|
}
|
2022-04-21 02:16:04 +00:00
|
|
|
|
|
|
|
alignas(EAS) const uint8_t *pc {nullptr};
|
|
|
|
alignas(EAS) InterpretedFrameBase base;
|
2022-04-06 11:22:08 +00:00
|
|
|
};
|
2022-04-21 02:16:04 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedEntryFrame),
|
|
|
|
InterpretedEntryFrame::SizeArch32,
|
|
|
|
InterpretedEntryFrame::SizeArch64);
|
2022-04-06 11:22:08 +00:00
|
|
|
|
2022-03-01 02:57:53 +00:00
|
|
|
struct OptimizedLeaveFrame {
|
2022-02-18 07:04:19 +00:00
|
|
|
FrameType type;
|
2022-03-01 02:57:53 +00:00
|
|
|
uintptr_t callsiteFp; // thread sp set here
|
2022-02-21 09:13:33 +00:00
|
|
|
uintptr_t returnAddr;
|
2022-03-08 03:01:20 +00:00
|
|
|
#ifndef PANDA_TARGET_32
|
2022-02-21 08:21:09 +00:00
|
|
|
uint64_t argRuntimeId;
|
2022-03-08 03:01:20 +00:00
|
|
|
#endif
|
2022-02-21 08:21:09 +00:00
|
|
|
uint64_t argc;
|
Implement Proxy Lowering on x86
when function need call another js function, it will lowering to call "JSCall" trampoline function
JSCall trampoline function will check calltarget function, then correct the arguments, finally jump
the native or optimized code address of the target function.
JSCall(glue, argc, calltarget, ....)
then proxy call(glue, argc, callTarget, argv[])
if proxy->GetHandler is function
tail call JSCall(glue, argc, callTarget, argv); // consider performance
else
//Call(trap, handler, «target, thisArgument, argArray»)
call CreateArrayFromList(glue, argc, argv[]) ---> arrHandle // maybe trigger GC, construct OptimizedWithArgvLeaveFrame, visitor argv[0]..argv[argc-1]
call JSCall(glue, argc, method, argv[])
issue:https://gitee.com/openharmony/ark_js_runtime/issues/I52T6B?from=project-issue
Signed-off-by: songzhengchao <songzhengchao@huawei.com>
Change-Id: I994aae1eb9cbf51982348ae6e203c24c326f617e
2022-04-14 13:54:03 +00:00
|
|
|
// argv[0]...argv[argc-1] dynamic according to agc
|
2022-04-29 09:32:24 +00:00
|
|
|
static OptimizedLeaveFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2022-03-01 02:57:53 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<OptimizedLeaveFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(OptimizedLeaveFrame, callsiteFp));
|
|
|
|
}
|
|
|
|
uintptr_t GetCallSiteSp()
|
2021-10-28 12:59:19 +00:00
|
|
|
{
|
2022-03-08 03:01:20 +00:00
|
|
|
#ifndef PANDA_TARGET_32
|
2022-03-01 02:57:53 +00:00
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedLeaveFrame, argRuntimeId);
|
2022-03-08 03:01:20 +00:00
|
|
|
#else
|
2022-03-14 03:50:02 +00:00
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedLeaveFrame, argc) + argc * sizeof(JSTaggedType);
|
2022-03-08 03:01:20 +00:00
|
|
|
#endif
|
2021-10-28 12:59:19 +00:00
|
|
|
}
|
2021-09-07 14:24:16 +00:00
|
|
|
};
|
|
|
|
|
Implement Proxy Lowering on x86
when function need call another js function, it will lowering to call "JSCall" trampoline function
JSCall trampoline function will check calltarget function, then correct the arguments, finally jump
the native or optimized code address of the target function.
JSCall(glue, argc, calltarget, ....)
then proxy call(glue, argc, callTarget, argv[])
if proxy->GetHandler is function
tail call JSCall(glue, argc, callTarget, argv); // consider performance
else
//Call(trap, handler, «target, thisArgument, argArray»)
call CreateArrayFromList(glue, argc, argv[]) ---> arrHandle // maybe trigger GC, construct OptimizedWithArgvLeaveFrame, visitor argv[0]..argv[argc-1]
call JSCall(glue, argc, method, argv[])
issue:https://gitee.com/openharmony/ark_js_runtime/issues/I52T6B?from=project-issue
Signed-off-by: songzhengchao <songzhengchao@huawei.com>
Change-Id: I994aae1eb9cbf51982348ae6e203c24c326f617e
2022-04-14 13:54:03 +00:00
|
|
|
struct OptimizedWithArgvLeaveFrame {
|
|
|
|
FrameType type;
|
|
|
|
uintptr_t callsiteFp; // thread sp set here
|
|
|
|
uintptr_t returnAddr;
|
|
|
|
#ifndef PANDA_TARGET_32
|
|
|
|
uint64_t argRuntimeId;
|
|
|
|
#endif
|
|
|
|
uint64_t argc;
|
|
|
|
// uintptr_t argv[]
|
2022-04-29 09:32:24 +00:00
|
|
|
static OptimizedWithArgvLeaveFrame* GetFrameFromSp(const JSTaggedType *sp)
|
Implement Proxy Lowering on x86
when function need call another js function, it will lowering to call "JSCall" trampoline function
JSCall trampoline function will check calltarget function, then correct the arguments, finally jump
the native or optimized code address of the target function.
JSCall(glue, argc, calltarget, ....)
then proxy call(glue, argc, callTarget, argv[])
if proxy->GetHandler is function
tail call JSCall(glue, argc, callTarget, argv); // consider performance
else
//Call(trap, handler, «target, thisArgument, argArray»)
call CreateArrayFromList(glue, argc, argv[]) ---> arrHandle // maybe trigger GC, construct OptimizedWithArgvLeaveFrame, visitor argv[0]..argv[argc-1]
call JSCall(glue, argc, method, argv[])
issue:https://gitee.com/openharmony/ark_js_runtime/issues/I52T6B?from=project-issue
Signed-off-by: songzhengchao <songzhengchao@huawei.com>
Change-Id: I994aae1eb9cbf51982348ae6e203c24c326f617e
2022-04-14 13:54:03 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<OptimizedWithArgvLeaveFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, callsiteFp));
|
|
|
|
}
|
|
|
|
uintptr_t GetCallSiteSp()
|
|
|
|
{
|
|
|
|
#ifndef PANDA_TARGET_32
|
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, argRuntimeId);
|
|
|
|
#else
|
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, argc) + argc * sizeof(JSTaggedType);
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-03-01 02:57:53 +00:00
|
|
|
static_assert(static_cast<uint64_t>(FrameType::OPTIMIZED_FRAME) == OPTIMIZE_FRAME_TYPE);
|
|
|
|
static_assert(static_cast<uint64_t>(FrameType::OPTIMIZED_ENTRY_FRAME) == JS_ENTRY_FRAME_TYPE);
|
2022-04-24 01:07:45 +00:00
|
|
|
static_assert(static_cast<uint64_t>(FrameType::LEAVE_FRAME) == LEAVE_FRAME_TYPE);
|
2021-09-07 14:24:16 +00:00
|
|
|
} // namespace panda::ecmascript
|
2022-04-24 01:07:45 +00:00
|
|
|
#endif // ECMASCRIPT_FRAMES_H
|