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
|
|
|
// | ...... | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | Vregs [not exist in native] | |
|
|
|
|
// +----------------------------------+--------+ interpreter frame
|
|
|
|
// | base.frameType | ^ |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2022-05-12 02:22:18 +00:00
|
|
|
// | base.prev(prev stack pointer) | | |
|
|
|
|
// |----------------------------------| | |
|
|
|
|
// | pc(bytecode addr) | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2022-05-12 02:22:18 +00:00
|
|
|
// | sp(current 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-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
|
|
|
// |----------------------------------| | |
|
2022-05-12 02:22:18 +00:00
|
|
|
// | function | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2022-05-12 02:22:18 +00:00
|
|
|
// | constpool | 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
|
|
|
// |----------------------------------| | |
|
2022-05-12 02:22:18 +00:00
|
|
|
// | base.prev(prev stack pointer) | | |
|
|
|
|
// |----------------------------------| | |
|
|
|
|
// | pc(bytecode addr) | | |
|
|
|
|
// +----------------------------------| | |
|
|
|
|
// | sp(current 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
|
|
|
// | function | | |
|
2021-10-10 02:44:14 +00:00
|
|
|
// |----------------------------------| | |
|
2022-05-12 02:22:18 +00:00
|
|
|
// | constpool | 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,
|
2022-05-07 08:06:38 +00:00
|
|
|
LEAVE_FRAME = 2,
|
|
|
|
LEAVE_FRAME_WITH_ARGV = 3,
|
|
|
|
INTERPRETER_FRAME = 4,
|
|
|
|
ASM_INTERPRETER_FRAME = 5,
|
|
|
|
INTERPRETER_CONSTRUCTOR_FRAME = 6,
|
|
|
|
BUILTIN_FRAME = 7,
|
2022-05-13 04:58:21 +00:00
|
|
|
BUILTIN_FRAME_WITH_ARGV = 8,
|
|
|
|
BUILTIN_ENTRY_FRAME = 9,
|
|
|
|
INTERPRETER_FAST_NEW_FRAME = 10,
|
|
|
|
INTERPRETER_ENTRY_FRAME = 11,
|
|
|
|
ASM_INTERPRETER_ENTRY_FRAME = 12,
|
2022-05-07 08:06:38 +00:00
|
|
|
|
|
|
|
INTERPRETER_BEGIN = INTERPRETER_FRAME,
|
|
|
|
INTERPRETER_END = INTERPRETER_FAST_NEW_FRAME,
|
2022-05-13 04:58:21 +00:00
|
|
|
BUILTIN_BEGIN = BUILTIN_FRAME,
|
|
|
|
BUILTIN_END = BUILTIN_ENTRY_FRAME,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum class JSCallMode : uintptr_t {
|
|
|
|
CALL_ARG0,
|
|
|
|
CALL_ARG1,
|
|
|
|
CALL_ARG2,
|
|
|
|
CALL_ARG3,
|
|
|
|
CALL_WITH_ARGV,
|
|
|
|
CALL_THIS_WITH_ARGV,
|
|
|
|
CALL_CONSTRUCTOR_WITH_ARGV,
|
|
|
|
CALL_FROM_AOT,
|
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-04-26 01:06:56 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
|
|
struct InterpretedFrameBase : public base::AlignedStruct<base::AlignedPointer::Size(),
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedSize> {
|
|
|
|
enum class Index : size_t {
|
|
|
|
PrevIndex = 0,
|
|
|
|
TypeIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
2022-05-16 02:00:35 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
static InterpretedFrameBase* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<InterpretedFrameBase *>(const_cast<JSTaggedType *>(sp)) - 1;
|
|
|
|
}
|
|
|
|
|
2022-04-26 01:06:56 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t GetTypeOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
|
|
|
alignas(EAS) JSTaggedType *prev {nullptr}; // for llvm :c-fp ; for interrupt: thread-fp for gc
|
|
|
|
alignas(EAS) FrameType type {FrameType::OPTIMIZED_FRAME}; // 0
|
2022-01-13 08:26:00 +00:00
|
|
|
};
|
2022-04-26 01:06:56 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedFrameBase),
|
|
|
|
InterpretedFrameBase::SizeArch32,
|
|
|
|
InterpretedFrameBase::SizeArch64);
|
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,
|
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
|
|
|
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-05-07 08:06:38 +00:00
|
|
|
static uint32_t NumOfMembers()
|
|
|
|
{
|
|
|
|
return sizeof(InterpretedFrame) / JSTaggedValue::TaggedTypeSize();
|
|
|
|
}
|
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) 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-12 07:50:47 +00:00
|
|
|
inline JSTaggedType* GetCurrentFramePointer()
|
2022-05-06 07:51:52 +00:00
|
|
|
{
|
|
|
|
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-05-07 08:06:38 +00:00
|
|
|
static uint32_t NumOfMembers()
|
|
|
|
{
|
|
|
|
return sizeof(AsmInterpretedFrame) / JSTaggedValue::TaggedTypeSize();
|
|
|
|
}
|
|
|
|
|
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;
|
2022-04-26 01:06:56 +00:00
|
|
|
// vregs, not exist in native
|
|
|
|
// args, may be truncated if not extra
|
|
|
|
// thisObject, used in asm constructor frame
|
|
|
|
// numArgs, used if extra or asm constructor frame
|
2022-05-12 13:57:08 +00:00
|
|
|
enum ReverseIndex : int32_t { NUM_ARGS_REVERSE_INDEX = -1, THIS_OBJECT_REVERSE_INDEX = -2 };
|
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-05-12 07:50:47 +00:00
|
|
|
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
|
|
struct AsmInterpretedEntryFrame : 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);
|
|
|
|
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return base.prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
static InterpretedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<InterpretedEntryFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
alignas(EAS) const uint8_t *pc {nullptr};
|
|
|
|
alignas(EAS) InterpretedFrameBase base;
|
|
|
|
};
|
|
|
|
|
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
|
|
|
}
|
2022-05-07 08:06:38 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
|
|
|
}
|
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-05-07 08:06:38 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
struct BuiltinFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
|
|
|
base::AlignedSize,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
|
|
|
enum class Index : size_t {
|
|
|
|
TypeIndex = 0,
|
|
|
|
PrevFpIndex,
|
|
|
|
ReturnAddrIndex,
|
|
|
|
NativeCodeIndex,
|
|
|
|
NumArgsIndex,
|
|
|
|
StackArgsIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
|
|
|
static constexpr uint32_t RESERVED_CALL_ARGCOUNT = 3;
|
2022-05-07 08:06:38 +00:00
|
|
|
|
|
|
|
static BuiltinFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<BuiltinFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(BuiltinFrame, prevFp));
|
|
|
|
}
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return prevFp;
|
|
|
|
}
|
|
|
|
uintptr_t GetCallSiteSp()
|
|
|
|
{
|
2022-05-13 04:58:21 +00:00
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(BuiltinFrame, nativeCode);
|
|
|
|
}
|
|
|
|
static size_t GetPreFpOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
static size_t GetNumArgsToFpDelta(bool isArch32)
|
|
|
|
{
|
|
|
|
auto offset = GetOffset<static_cast<size_t>(Index::NumArgsIndex)>(isArch32);
|
|
|
|
return offset - GetPreFpOffset(isArch32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t GetNativeCodeToFpDelta(bool isArch32)
|
|
|
|
{
|
|
|
|
auto offset = GetOffset<static_cast<size_t>(Index::NativeCodeIndex)>(isArch32);
|
|
|
|
return offset - GetPreFpOffset(isArch32);
|
|
|
|
}
|
|
|
|
static size_t GetStackArgsToFpDelta(bool isArch32)
|
|
|
|
{
|
|
|
|
auto offset = GetOffset<static_cast<size_t>(Index::StackArgsIndex)>(isArch32);
|
|
|
|
return offset - GetPreFpOffset(isArch32);
|
|
|
|
}
|
|
|
|
uintptr_t GetStackArgsAddress()
|
|
|
|
{
|
|
|
|
return reinterpret_cast<uintptr_t>(&stackArgs);
|
|
|
|
}
|
|
|
|
JSTaggedValue GetFunction()
|
|
|
|
{
|
|
|
|
auto functionAddress = reinterpret_cast<JSTaggedType *>(GetStackArgsAddress());
|
|
|
|
return JSTaggedValue(*functionAddress);
|
|
|
|
}
|
|
|
|
size_t GetNumArgs()
|
|
|
|
{
|
|
|
|
return numArgs;
|
|
|
|
}
|
|
|
|
|
|
|
|
alignas(EAS) FrameType type;
|
|
|
|
alignas(EAS) JSTaggedType *prevFp;
|
|
|
|
alignas(EAS) uintptr_t returnAddr;
|
|
|
|
alignas(EAS) uintptr_t nativeCode;
|
|
|
|
alignas(EAS) uintptr_t numArgs;
|
|
|
|
alignas(EAS) uintptr_t stackArgs;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct BuiltinWithArgvFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
|
|
|
base::AlignedSize,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
2022-05-25 01:09:14 +00:00
|
|
|
enum class Index : int {
|
2022-05-13 04:58:21 +00:00
|
|
|
StackArgsTopIndex = -1,
|
|
|
|
NumArgsIndex = -1,
|
|
|
|
TypeIndex = 0,
|
|
|
|
PrevFpIndex,
|
|
|
|
ReturnAddrIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
|
|
|
static BuiltinWithArgvFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<BuiltinWithArgvFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(BuiltinFrame, prevFp));
|
|
|
|
}
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return prevFp;
|
|
|
|
}
|
|
|
|
uintptr_t GetCallSiteSp()
|
|
|
|
{
|
|
|
|
return ToUintPtr(this) + sizeof(BuiltinWithArgvFrame);
|
|
|
|
}
|
|
|
|
uintptr_t GetStackArgsAddress()
|
|
|
|
{
|
|
|
|
auto topAddress = ToUintPtr(this) +
|
2022-05-20 07:22:39 +00:00
|
|
|
(static_cast<int>(Index::StackArgsTopIndex) * sizeof(uintptr_t));
|
2022-05-13 04:58:21 +00:00
|
|
|
auto numberArgs = GetNumArgs() + BuiltinFrame::RESERVED_CALL_ARGCOUNT;
|
|
|
|
return topAddress - numberArgs * sizeof(uintptr_t);
|
|
|
|
}
|
|
|
|
JSTaggedValue GetFunction()
|
|
|
|
{
|
|
|
|
auto functionAddress = reinterpret_cast<JSTaggedType *>(GetStackArgsAddress());
|
|
|
|
return JSTaggedValue(*functionAddress);
|
|
|
|
}
|
|
|
|
size_t GetNumArgs()
|
|
|
|
{
|
|
|
|
auto argcAddress = reinterpret_cast<size_t *>(
|
2022-05-20 07:22:39 +00:00
|
|
|
ToUintPtr(this) + (static_cast<int>(Index::NumArgsIndex) * sizeof(uintptr_t)));
|
2022-05-13 04:58:21 +00:00
|
|
|
return *argcAddress;
|
2022-05-07 08:06:38 +00:00
|
|
|
}
|
2022-05-13 04:58:21 +00:00
|
|
|
// argv(... this, new.target, function)
|
|
|
|
// numargs
|
|
|
|
alignas(EAS) FrameType type;
|
|
|
|
alignas(EAS) JSTaggedType *prevFp;
|
|
|
|
alignas(EAS) uintptr_t returnAddr;
|
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
|
|
|
};
|
2021-09-07 14:24:16 +00:00
|
|
|
} // namespace panda::ecmascript
|
2022-04-24 01:07:45 +00:00
|
|
|
#endif // ECMASCRIPT_FRAMES_H
|