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
|
|
|
|
|
2022-10-03 04:31:39 +00:00
|
|
|
#include "ecmascript/ark_stackmap.h"
|
2022-03-09 09:53:59 +00:00
|
|
|
#include "ecmascript/js_tagged_value.h"
|
2022-03-10 11:24:49 +00:00
|
|
|
#include "ecmascript/base/aligned_struct.h"
|
2022-08-02 06:18:16 +00:00
|
|
|
#include "ecmascript/llvm_stackmap_type.h"
|
2022-06-16 06:01:06 +00:00
|
|
|
#include "ecmascript/mem/visitor.h"
|
2022-07-21 11:14:41 +00:00
|
|
|
|
2021-09-07 14:24:16 +00:00
|
|
|
namespace panda::ecmascript {
|
2022-06-13 12:46:44 +00:00
|
|
|
class JSThread;
|
|
|
|
class EcmaVM;
|
2022-06-16 06:01:06 +00:00
|
|
|
class FrameIterator;
|
2022-06-23 08:46:13 +00:00
|
|
|
namespace kungfu {
|
2022-08-02 06:43:25 +00:00
|
|
|
class ArkStackMapParser;
|
2022-06-23 08:46:13 +00:00
|
|
|
};
|
2022-10-16 03:21:00 +00:00
|
|
|
|
|
|
|
// Here list all scenarios of calling between Runtime/CInterpreter/ASMInterpreter/AOTCompiler/CBuiltin/ASMBuitlin.
|
|
|
|
// Please note that the "[]" means a must frame while "<>" means an optional frame. Each case is from top to down.
|
|
|
|
//
|
|
|
|
// * Runtime (C++) => CInterpreter:
|
|
|
|
// 1) [INTERPRETER_FRAME]
|
|
|
|
//
|
|
|
|
// * Runtime (C++) -> AOTCompiler:
|
|
|
|
// 1) [OPTIMIZED_ENTRY_FRAME]
|
|
|
|
// <OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME>
|
|
|
|
// <OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME>
|
|
|
|
// [OPTIMIZED_JS_FUNCTION_FRAME]
|
|
|
|
//
|
|
|
|
// * Runtime (C++) => ASMInterpreter:
|
|
|
|
// 1) [INTERPRETER_ENTRY_FRAME][ASM_INTERPRETER_FRAME]
|
|
|
|
//
|
|
|
|
// * Runtime (C++) => CBuiltin:
|
|
|
|
// 1) [not supported]
|
|
|
|
//
|
|
|
|
// * Runtime (C++) => ASMBuiltin:
|
|
|
|
// 1) [not supported]
|
|
|
|
//
|
|
|
|
// * CInterpreter => CInterpreter:
|
|
|
|
// 1) [INTERPRETER_FRAME]
|
|
|
|
//
|
|
|
|
// * CInterpreter => Runtime (C++):
|
|
|
|
// 1) [INTERPRETER_FAST_NEW_FRAME]
|
|
|
|
// 2) [INTERPRETER_CONSTRUCTOR_FRAME]
|
|
|
|
//
|
|
|
|
// * CInterpreter => AOTCompiler:
|
|
|
|
// 1) [not supported]
|
|
|
|
//
|
|
|
|
// * CInterperter => CBuiltin:
|
|
|
|
// 1) [INTERPRETER_BUILTIN_FRAME]
|
|
|
|
//
|
|
|
|
// * CInterpreter => ASMBuiltin:
|
|
|
|
// 1) [not supported]
|
|
|
|
//
|
|
|
|
// * ASMInterpreter => Runtime (C++):
|
|
|
|
// 1) [LEAVE_FRAME]
|
|
|
|
// 2) [LEAVE_FRAME_WITH_ARGV]
|
|
|
|
//
|
|
|
|
// * ASMInterpreter => AOTCompiler:
|
|
|
|
// 1) [OPTIMIZED_ENTRY_FRAME]
|
|
|
|
// <OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME>
|
|
|
|
// <OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME>
|
|
|
|
// [OPTIMIZED_JS_FUNCTION_FRAME]
|
|
|
|
//
|
|
|
|
// * ASMInterpreter => ASMInterpreter:
|
|
|
|
// 1) [ASM_INTERPRETER_FRAME]
|
|
|
|
//
|
|
|
|
// * ASMInterpreter => AsmBuiltin:
|
|
|
|
// 1) [BUILTIN_ENTRY_FRAME]
|
|
|
|
// [BUILTIN_FRAME]
|
|
|
|
// 2) [BUILTIN_ENTRY_FRAME]
|
|
|
|
// [BUILTIN_FRAME_WITH_ARGV]
|
|
|
|
//
|
|
|
|
// * ASMInterpreter => CBuiltin:
|
|
|
|
// 1) [LEAVE_FRAME]
|
|
|
|
// 2) [LEAVE_FRAME_WITH_ARGV]
|
|
|
|
//
|
|
|
|
// * AOTCompiler => Runtime (C++):
|
|
|
|
// 1) [LEAVE_FRAME]
|
|
|
|
// 2) [LEAVE_FRAME_WITH_ARGV]
|
|
|
|
//
|
|
|
|
// * AOTCompiler => ASMInterpreter:
|
|
|
|
// 1) [ASM_INTERPRETER_BRIDGE_FRAME]
|
|
|
|
// 2) [ASM_INTERPRETER_FRAME]
|
|
|
|
//
|
|
|
|
// * AOTCompiler => CBuiltin:
|
|
|
|
// 1) [LEAVE_FRAME]
|
|
|
|
// 2) [LEAVE_FRAME_WITH_ARGV]
|
|
|
|
//
|
|
|
|
// * AOTCompiler => ASMBuiltin:
|
|
|
|
// 1) [BUILTIN_ENTRY_FRAME]
|
|
|
|
// [BUILTIN_FRAME]
|
|
|
|
// 2) [BUILTIN_ENTRY_FRAME]
|
|
|
|
// [BUILTIN_FRAME_WITH_ARGV]
|
|
|
|
|
|
|
|
|
2022-03-12 09:29:12 +00:00
|
|
|
enum class FrameType: uintptr_t {
|
2021-09-07 14:24:16 +00:00
|
|
|
OPTIMIZED_FRAME = 0,
|
2022-08-02 07:54:31 +00:00
|
|
|
OPTIMIZED_ENTRY_FRAME,
|
|
|
|
OPTIMIZED_JS_FUNCTION_FRAME,
|
|
|
|
LEAVE_FRAME,
|
|
|
|
LEAVE_FRAME_WITH_ARGV,
|
|
|
|
BUILTIN_CALL_LEAVE_FRAME,
|
|
|
|
INTERPRETER_FRAME,
|
|
|
|
ASM_INTERPRETER_FRAME,
|
|
|
|
INTERPRETER_CONSTRUCTOR_FRAME,
|
|
|
|
BUILTIN_FRAME,
|
|
|
|
BUILTIN_FRAME_WITH_ARGV,
|
|
|
|
BUILTIN_ENTRY_FRAME,
|
|
|
|
INTERPRETER_BUILTIN_FRAME,
|
|
|
|
INTERPRETER_FAST_NEW_FRAME,
|
|
|
|
INTERPRETER_ENTRY_FRAME,
|
|
|
|
ASM_INTERPRETER_ENTRY_FRAME,
|
|
|
|
ASM_INTERPRETER_BRIDGE_FRAME,
|
|
|
|
OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME,
|
|
|
|
OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME,
|
2022-05-07 08:06:38 +00:00
|
|
|
|
2022-08-02 07:54:31 +00:00
|
|
|
FRAME_TYPE_FIRST = OPTIMIZED_FRAME,
|
|
|
|
FRAME_TYPE_LAST = OPTIMIZED_JS_FUNCTION_ARGS_CONFIG_FRAME,
|
|
|
|
INTERPRETER_FIRST = INTERPRETER_FRAME,
|
|
|
|
INTERPRETER_LAST = INTERPRETER_FAST_NEW_FRAME,
|
|
|
|
BUILTIN_FIRST = BUILTIN_FRAME,
|
|
|
|
BUILTIN_LAST = BUILTIN_ENTRY_FRAME,
|
2022-05-13 04:58:21 +00:00
|
|
|
};
|
|
|
|
|
2022-06-02 06:35:14 +00:00
|
|
|
enum class ReservedSlots: int {
|
|
|
|
OPTIMIZED_RESERVED_SLOT = 1,
|
2022-06-29 09:09:09 +00:00
|
|
|
OPTIMIZED_JS_FUNCTION_RESERVED_SLOT = 2,
|
2022-06-02 06:35:14 +00:00
|
|
|
OPTIMIZED_ENTRY_RESERVED_SLOT = 2,
|
|
|
|
};
|
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
enum class JSCallMode : uintptr_t {
|
2022-05-30 02:41:07 +00:00
|
|
|
CALL_ARG0 = 0,
|
2022-05-13 04:58:21 +00:00
|
|
|
CALL_ARG1,
|
|
|
|
CALL_ARG2,
|
|
|
|
CALL_ARG3,
|
2022-08-26 09:36:43 +00:00
|
|
|
CALL_THIS_ARG0,
|
|
|
|
CALL_THIS_ARG1,
|
|
|
|
CALL_THIS_ARG2,
|
|
|
|
CALL_THIS_ARG3,
|
2022-05-13 04:58:21 +00:00
|
|
|
CALL_WITH_ARGV,
|
|
|
|
CALL_THIS_WITH_ARGV,
|
|
|
|
CALL_CONSTRUCTOR_WITH_ARGV,
|
2022-08-26 09:36:43 +00:00
|
|
|
DEPRECATED_CALL_ARG0,
|
|
|
|
DEPRECATED_CALL_ARG1,
|
|
|
|
DEPRECATED_CALL_ARG2,
|
|
|
|
DEPRECATED_CALL_ARG3,
|
|
|
|
DEPRECATED_CALL_WITH_ARGV,
|
|
|
|
DEPRECATED_CALL_THIS_WITH_ARGV,
|
2022-08-30 13:43:46 +00:00
|
|
|
DEPRECATED_CALL_CONSTRUCTOR_WITH_ARGV,
|
2022-05-30 02:41:07 +00:00
|
|
|
CALL_GETTER,
|
|
|
|
CALL_SETTER,
|
2022-10-13 06:44:04 +00:00
|
|
|
CALL_THIS_ARG3_WITH_RETURN,
|
2022-05-30 02:41:07 +00:00
|
|
|
CALL_ENTRY,
|
|
|
|
CALL_GENERATOR,
|
2022-05-13 04:58:21 +00:00
|
|
|
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-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
|
|
|
|
const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
2022-08-10 07:29:17 +00:00
|
|
|
|
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedFrame, type);
|
|
|
|
}
|
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedFrame, prevFp);
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
private:
|
2022-04-25 03:17:47 +00:00
|
|
|
enum class Index : size_t {
|
2022-06-02 06:35:14 +00:00
|
|
|
TypeIndex = 0,
|
2022-04-25 03:17:47 +00:00
|
|
|
PrevFpIndex,
|
2022-06-02 14:01:42 +00:00
|
|
|
ReturnAddrIndex,
|
2022-04-25 03:17:47 +00:00
|
|
|
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;
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
[[maybe_unused]] alignas(EAS) FrameType type {0};
|
2022-06-02 06:35:14 +00:00
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
2022-06-02 14:01:42 +00:00
|
|
|
alignas(EAS) uintptr_t returnAddr {0};
|
2022-06-16 06:01:06 +00:00
|
|
|
friend class FrameIterator;
|
2022-06-02 06:35:14 +00:00
|
|
|
};
|
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedFrame), OptimizedFrame::SizeArch32, OptimizedFrame::SizeArch64);
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * OptimizedUnfoldArgVFrame layout description as the following:
|
|
|
|
// sp ----> |--------------------------| ---------------
|
|
|
|
// | returnAddr | ^
|
|
|
|
// currentFp--> |--------------------------| |
|
|
|
|
// | prevFp | |
|
|
|
|
// |--------------------------| OptimizedUnfoldArgVFrame
|
|
|
|
// | frameType | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | currentFp | v
|
|
|
|
// +--------------------------+ ---------------
|
|
|
|
//
|
2022-07-19 01:38:13 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
2022-07-25 11:22:05 +00:00
|
|
|
struct OptimizedJSFunctionUnfoldArgVFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
2022-08-10 07:29:17 +00:00
|
|
|
public:
|
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedJSFunctionUnfoldArgVFrame, type);
|
|
|
|
}
|
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedJSFunctionUnfoldArgVFrame, prevFp);
|
|
|
|
}
|
2022-07-19 01:38:13 +00:00
|
|
|
private:
|
|
|
|
enum class Index : size_t {
|
|
|
|
CallSiteSpIndex = 0,
|
|
|
|
TypeIndex,
|
|
|
|
PrevFpIndex,
|
|
|
|
ReturnAddrIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
2022-07-25 11:22:05 +00:00
|
|
|
static OptimizedJSFunctionUnfoldArgVFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2022-07-19 01:38:13 +00:00
|
|
|
{
|
2022-07-25 11:22:05 +00:00
|
|
|
return reinterpret_cast<OptimizedJSFunctionUnfoldArgVFrame *>(reinterpret_cast<uintptr_t>(sp)
|
|
|
|
- MEMBER_OFFSET(OptimizedJSFunctionUnfoldArgVFrame, prevFp));
|
2022-07-19 01:38:13 +00:00
|
|
|
}
|
|
|
|
inline JSTaggedType* GetPrevFrameFp() const
|
|
|
|
{
|
|
|
|
return prevFp;
|
|
|
|
}
|
|
|
|
uintptr_t GetReturnAddr() const
|
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
|
|
|
uintptr_t GetPrevFrameSp() const
|
|
|
|
{
|
|
|
|
return callSiteSp;
|
|
|
|
}
|
|
|
|
[[maybe_unused]] alignas(EAS) uintptr_t callSiteSp {0};
|
|
|
|
[[maybe_unused]] alignas(EAS) FrameType type {0};
|
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
|
|
|
alignas(EAS) uintptr_t returnAddr {0};
|
|
|
|
friend class FrameIterator;
|
|
|
|
};
|
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedFrame), OptimizedFrame::SizeArch32, OptimizedFrame::SizeArch64);
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * The OptimizedJSFunctionArgsConfig Frame's structure is illustrated as the following:
|
|
|
|
// +--------------------------+
|
|
|
|
// | arg[N-1] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | . . . . |
|
|
|
|
// +--------------------------+
|
|
|
|
// | arg[0] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | argC |
|
|
|
|
// sp ---> +--------------------------+ -----------------
|
|
|
|
// | | ^
|
|
|
|
// | prevFP | |
|
|
|
|
// |--------------------------| OptimizedJSFunctionArgsConfigFrame
|
|
|
|
// | frameType | |
|
|
|
|
// | | V
|
|
|
|
// +--------------------------+ -----------------
|
|
|
|
//
|
2022-06-02 06:35:14 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
|
|
struct OptimizedJSFunctionArgConfigFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
2022-10-16 03:21:00 +00:00
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
2022-08-10 07:29:17 +00:00
|
|
|
public:
|
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedJSFunctionArgConfigFrame, type);
|
|
|
|
}
|
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedJSFunctionArgConfigFrame, prevFp);
|
|
|
|
}
|
2022-06-16 06:46:52 +00:00
|
|
|
private:
|
2022-06-02 06:35:14 +00:00
|
|
|
enum class Index : size_t {
|
|
|
|
TypeIndex = 0,
|
|
|
|
PrevFpIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
|
|
|
static OptimizedJSFunctionArgConfigFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2022-04-25 03:17:47 +00:00
|
|
|
{
|
2022-06-02 06:35:14 +00:00
|
|
|
return reinterpret_cast<OptimizedJSFunctionArgConfigFrame *>(reinterpret_cast<uintptr_t>(sp)
|
|
|
|
- MEMBER_OFFSET(OptimizedJSFunctionArgConfigFrame, prevFp));
|
2022-04-25 03:17:47 +00:00
|
|
|
}
|
2022-06-02 06:35:14 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
2022-04-25 03:17:47 +00:00
|
|
|
{
|
2022-06-02 06:35:14 +00:00
|
|
|
return prevFp;
|
2022-01-13 08:26:00 +00:00
|
|
|
}
|
2022-06-16 06:46:52 +00:00
|
|
|
[[maybe_unused]] alignas(EAS) FrameType type {0};
|
2022-06-02 06:35:14 +00:00
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
2022-06-16 06:46:52 +00:00
|
|
|
friend class FrameIterator;
|
2022-06-02 06:35:14 +00:00
|
|
|
};
|
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionArgConfigFrame),
|
2022-10-16 03:21:00 +00:00
|
|
|
OptimizedJSFunctionArgConfigFrame::SizeArch32,
|
|
|
|
OptimizedJSFunctionArgConfigFrame::SizeArch64);
|
|
|
|
|
|
|
|
// * OptimizedJSFunctionFrame layout description as the following:
|
|
|
|
// +--------------------------+
|
|
|
|
// | arg[N-1] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | ... |
|
|
|
|
// +--------------------------+
|
|
|
|
// | arg[1] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | arg[0] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | this |
|
|
|
|
// +--------------------------+
|
|
|
|
// | new-target |
|
|
|
|
// +--------------------------+
|
|
|
|
// | call-target |
|
|
|
|
// |--------------------------|
|
|
|
|
// | argc |
|
|
|
|
// |--------------------------|
|
|
|
|
// | lexEnv |
|
|
|
|
// sp ----> |--------------------------| ---------------
|
|
|
|
// | returnAddr | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | callsiteFp | |
|
|
|
|
// |--------------------------| OptimizedJSFunctionFrame
|
|
|
|
// | frameType | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | lexEnv | v
|
|
|
|
// +--------------------------+ ---------------
|
|
|
|
//
|
2022-06-02 06:35:14 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
2022-06-29 09:09:09 +00:00
|
|
|
struct OptimizedJSFunctionFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
2022-10-16 03:21:00 +00:00
|
|
|
JSTaggedValue,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
2022-06-02 06:35:14 +00:00
|
|
|
public:
|
2022-06-29 09:09:09 +00:00
|
|
|
static constexpr size_t ENV_SLOT_DIFF = 2;
|
2022-06-02 06:35:14 +00:00
|
|
|
enum class Index : size_t {
|
2022-06-29 09:09:09 +00:00
|
|
|
EnvIndex = 0,
|
|
|
|
TypeIndex,
|
2022-06-02 06:35:14 +00:00
|
|
|
PrevFpIndex,
|
|
|
|
ReturnAddrIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
2022-04-25 03:17:47 +00:00
|
|
|
|
2022-06-02 06:35:14 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return prevFp;
|
|
|
|
}
|
2022-06-29 09:09:09 +00:00
|
|
|
|
|
|
|
JSTaggedType* GetArgv(uintptr_t *preFrameSp) const
|
2022-06-02 06:35:14 +00:00
|
|
|
{
|
2022-06-29 09:09:09 +00:00
|
|
|
return reinterpret_cast<JSTaggedType *>(preFrameSp + ENV_SLOT_DIFF * sizeof(uint64_t) / sizeof(uintptr_t));
|
2022-06-02 06:35:14 +00:00
|
|
|
}
|
2022-06-29 09:09:09 +00:00
|
|
|
|
|
|
|
size_t GetArgc(uintptr_t *preFrameSp) const
|
2022-06-02 06:35:14 +00:00
|
|
|
{
|
2022-06-29 09:09:09 +00:00
|
|
|
return *(preFrameSp + sizeof(uint64_t) / sizeof(uintptr_t));
|
2022-06-02 06:35:14 +00:00
|
|
|
}
|
2022-06-23 02:08:12 +00:00
|
|
|
|
2022-06-23 09:35:41 +00:00
|
|
|
JSTaggedType* GetArgv(const FrameIterator &it) const;
|
2022-06-23 02:08:12 +00:00
|
|
|
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
|
|
|
|
const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
2022-08-05 07:01:17 +00:00
|
|
|
void CollectBCOffsetInfo(const FrameIterator &it, kungfu::ConstInfo &info) const;
|
2022-06-29 09:09:09 +00:00
|
|
|
|
|
|
|
inline JSTaggedValue GetEnv() const
|
|
|
|
{
|
|
|
|
return env;
|
|
|
|
}
|
|
|
|
inline void SetEnv(JSTaggedValue lexEnv)
|
|
|
|
{
|
|
|
|
env = lexEnv;
|
|
|
|
}
|
2022-08-05 06:35:14 +00:00
|
|
|
static uintptr_t ComputeArgsConfigFrameSp(JSTaggedType *fp)
|
|
|
|
{
|
|
|
|
const size_t offset = 2; // 2: skip prevFp and return address.
|
|
|
|
return reinterpret_cast<uintptr_t>(fp) + offset * sizeof(uintptr_t);
|
|
|
|
}
|
2022-08-10 07:29:17 +00:00
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedJSFunctionFrame, type);
|
|
|
|
}
|
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp);
|
|
|
|
}
|
2022-06-29 09:09:09 +00:00
|
|
|
friend class FrameIterator;
|
2022-10-03 04:31:39 +00:00
|
|
|
void GetDeoptBundleInfo(const FrameIterator &it, std::vector<kungfu::ARKDeopt>& deopts) const;
|
|
|
|
void GetFuncCalleeRegAndOffset(
|
|
|
|
const FrameIterator &it, kungfu::CalleeRegAndOffsetVec &ret) const;
|
|
|
|
uintptr_t* ComputePrevFrameSp(const FrameIterator &it) const;
|
2022-10-16 03:21:00 +00:00
|
|
|
|
2022-06-29 09:09:09 +00:00
|
|
|
private:
|
|
|
|
static OptimizedJSFunctionFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<OptimizedJSFunctionFrame *>(reinterpret_cast<uintptr_t>(sp)
|
|
|
|
- MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp));
|
|
|
|
}
|
2022-10-03 04:31:39 +00:00
|
|
|
|
2022-06-02 06:35:14 +00:00
|
|
|
// dynamic callee saveregisters for x86-64
|
2022-06-29 09:09:09 +00:00
|
|
|
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
2022-06-16 06:46:52 +00:00
|
|
|
[[maybe_unused]] alignas(EAS) FrameType type {0};
|
2022-04-25 03:17:47 +00:00
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
2022-06-02 06:35:14 +00:00
|
|
|
alignas(EAS) uintptr_t returnAddr {0};
|
|
|
|
// dynamic callee saveregisters for arm64
|
2021-10-09 10:49:19 +00:00
|
|
|
};
|
2022-10-16 03:21:00 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionFrame),
|
|
|
|
OptimizedJSFunctionFrame::SizeArch32,
|
|
|
|
OptimizedJSFunctionFrame::SizeArch64);
|
|
|
|
|
|
|
|
// * The JSFunctionEntry Frame's structure is illustrated as the following:
|
|
|
|
// +--------------------------+
|
|
|
|
// | . . . . . . |
|
|
|
|
// sp ---> +--------------------------+ -----------------
|
|
|
|
// | prevFP | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | frameType | JSFunctionEntryFrame
|
|
|
|
// |--------------------------| |
|
|
|
|
// | preLeaveFrameFp | v
|
|
|
|
// +--------------------------+ -----------------
|
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:
|
2022-11-01 06:32:39 +00:00
|
|
|
enum class CallType : size_t {
|
|
|
|
CALL_FUNC = 0,
|
|
|
|
CALL_NEW,
|
|
|
|
};
|
2021-12-31 07:51:09 +00:00
|
|
|
OptimizedEntryFrame() = default;
|
|
|
|
~OptimizedEntryFrame() = default;
|
2022-03-01 02:57:53 +00:00
|
|
|
JSTaggedType *preLeaveFrameFp;
|
2022-06-16 06:46:52 +00:00
|
|
|
[[maybe_unused]] FrameType type;
|
2022-04-25 03:17:47 +00:00
|
|
|
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-06-16 06:46:52 +00:00
|
|
|
friend class FrameIterator;
|
2022-10-16 03:21:00 +00:00
|
|
|
|
2022-06-16 06:46:52 +00:00
|
|
|
private:
|
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);
|
|
|
|
}
|
|
|
|
|
2022-10-03 04:31:39 +00:00
|
|
|
static constexpr size_t GetSize(bool isArch32)
|
|
|
|
{
|
|
|
|
return isArch32 ? InterpretedFrameBase::SizeArch32 : InterpretedFrameBase::SizeArch64;
|
|
|
|
}
|
|
|
|
|
2022-04-26 01:06:56 +00:00
|
|
|
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
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// Interpreter Frame Layout as the following:
|
|
|
|
// +----------------------------------+
|
|
|
|
// | argv[n-1] |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | ...... |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | thisArg [maybe not exist] |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | newTarget [maybe not exist] |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | ...... |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | Vregs [not exist in native] |
|
|
|
|
// +----------------------------------+--------+
|
|
|
|
// | base.frameType | ^
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | base.prev(prev stack pointer) | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | pc(bytecode addr) | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | sp(current stack pointer) | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | env | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | acc | |
|
|
|
|
// |----------------------------------| InterpretedFrame
|
|
|
|
// | profileTypeInfo | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | thisObj | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | function | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | constpool | v
|
|
|
|
// +----------------------------------+--------+
|
|
|
|
//
|
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-09-16 00:56:19 +00:00
|
|
|
JSTaggedValue,
|
2022-04-21 02:16:04 +00:00
|
|
|
base::AlignedPointer,
|
2022-03-10 11:24:49 +00:00
|
|
|
InterpretedFrameBase> {
|
2022-06-16 06:46:52 +00:00
|
|
|
public:
|
2022-03-10 11:24:49 +00:00
|
|
|
enum class Index : size_t {
|
2022-04-21 02:16:04 +00:00
|
|
|
ConstPoolIndex = 0,
|
2022-03-10 11:24:49 +00:00
|
|
|
FunctionIndex,
|
2022-09-16 00:56:19 +00:00
|
|
|
ThisObjIndex,
|
2022-03-10 11:24:49 +00:00
|
|
|
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-06-16 06:01:06 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp() const
|
2022-03-01 02:57:53 +00:00
|
|
|
{
|
|
|
|
return base.prev;
|
|
|
|
}
|
2022-02-19 02:09:52 +00:00
|
|
|
|
2022-07-04 02:08:05 +00:00
|
|
|
static InterpretedFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<InterpretedFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
|
|
|
}
|
|
|
|
|
2022-06-16 06:46:52 +00:00
|
|
|
inline const uint8_t *GetPc() const
|
2021-12-31 07:51:09 +00:00
|
|
|
{
|
2022-06-16 06:46:52 +00:00
|
|
|
return pc;
|
2021-12-31 07:51:09 +00:00
|
|
|
}
|
2022-06-16 06:46:52 +00:00
|
|
|
|
|
|
|
inline JSTaggedValue GetEnv() const
|
|
|
|
{
|
|
|
|
return env;
|
2021-12-31 07:51:09 +00:00
|
|
|
}
|
2022-06-16 06:46:52 +00:00
|
|
|
|
2022-05-07 08:06:38 +00:00
|
|
|
static uint32_t NumOfMembers()
|
|
|
|
{
|
|
|
|
return sizeof(InterpretedFrame) / JSTaggedValue::TaggedTypeSize();
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
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()};
|
2022-09-16 00:56:19 +00:00
|
|
|
alignas(EAS) JSTaggedValue thisObj {JSTaggedValue::Hole()};
|
2022-03-18 07:17:30 +00:00
|
|
|
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;
|
2022-06-16 06:46:52 +00:00
|
|
|
friend class FrameIterator;
|
2022-07-04 02:08:05 +00:00
|
|
|
};
|
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedFrame), InterpretedFrame::SizeArch32, InterpretedFrame::SizeArch64);
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * InterpretedBuiltinFrame layout description as the following:
|
|
|
|
// |--------------------------| ---------------
|
|
|
|
// | . . . . . | ^
|
|
|
|
// | InterpretedFrameBase | |
|
|
|
|
// | . . . . . | |
|
|
|
|
// |--------------------------| InterpretedBuiltinFrame
|
|
|
|
// | bytecode-PC | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | call-target | v
|
|
|
|
// +--------------------------+ ---------------
|
|
|
|
//
|
2022-07-04 02:08:05 +00:00
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
|
|
|
struct InterpretedBuiltinFrame : public base::AlignedStruct<JSTaggedValue::TaggedTypeSize(),
|
|
|
|
JSTaggedValue,
|
|
|
|
base::AlignedPointer,
|
|
|
|
InterpretedFrameBase> {
|
|
|
|
enum class Index : size_t {
|
|
|
|
FunctionIndex = 0,
|
|
|
|
PcIndex,
|
|
|
|
BaseIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
2022-06-16 06:46:52 +00:00
|
|
|
{
|
2022-07-04 02:08:05 +00:00
|
|
|
return base.prev;
|
2022-06-16 06:46:52 +00:00
|
|
|
}
|
2022-07-04 02:08:05 +00:00
|
|
|
|
|
|
|
static InterpretedBuiltinFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<InterpretedBuiltinFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static uint32_t NumOfMembers()
|
|
|
|
{
|
|
|
|
return sizeof(InterpretedBuiltinFrame) / JSTaggedValue::TaggedTypeSize();
|
|
|
|
}
|
|
|
|
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
2022-07-04 02:08:05 +00:00
|
|
|
|
|
|
|
alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) const uint8_t *pc {nullptr};
|
|
|
|
alignas(EAS) InterpretedFrameBase base;
|
2022-03-18 07:17:30 +00:00
|
|
|
};
|
2022-07-04 02:08:05 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedBuiltinFrame),
|
|
|
|
InterpretedBuiltinFrame::SizeArch32,
|
|
|
|
InterpretedBuiltinFrame::SizeArch64);
|
2022-02-19 02:09:52 +00:00
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// AsmInterpretedFrame Layout as the following:
|
|
|
|
// +----------------------------------+
|
|
|
|
// | argv[n-1] |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | ...... |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | thisArg [maybe not exist] |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | newTarget [maybe not exist] |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | ...... |
|
|
|
|
// |----------------------------------|
|
|
|
|
// | Vregs [not exist in native] |
|
|
|
|
// +----------------------------------+--------+
|
|
|
|
// | . . . . | ^
|
|
|
|
// | InterpretedFrameBase | |
|
|
|
|
// | . . . . | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | pc(bytecode addr) | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | sp(current stack pointer) | |
|
|
|
|
// |----------------------------------| AsmInterpretedFrame
|
|
|
|
// | callSize | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | env | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | acc | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | thisObj | |
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | call-target | v
|
|
|
|
// +----------------------------------+--------+
|
|
|
|
//
|
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-09-20 12:11:17 +00:00
|
|
|
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-09-20 12:11:17 +00:00
|
|
|
ThisObjIndex,
|
2022-03-18 07:17:30 +00:00
|
|
|
AccIndex,
|
|
|
|
EnvIndex,
|
2022-06-02 06:35:14 +00:00
|
|
|
CallSizeIndex,
|
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-06-02 06:35:14 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::CallSizeIndex)>(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-09-20 12:11:17 +00:00
|
|
|
static size_t GetThisOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::ThisObjIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
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-05-07 08:06:38 +00:00
|
|
|
static uint32_t NumOfMembers()
|
|
|
|
{
|
|
|
|
return sizeof(AsmInterpretedFrame) / JSTaggedValue::TaggedTypeSize();
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
|
|
|
|
const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
2022-05-07 08:06:38 +00:00
|
|
|
|
2022-06-16 06:46:52 +00:00
|
|
|
JSTaggedValue GetEnv() const
|
|
|
|
{
|
|
|
|
return env;
|
|
|
|
}
|
|
|
|
|
|
|
|
const uint8_t *GetPc()
|
|
|
|
{
|
|
|
|
return pc;
|
|
|
|
}
|
2022-05-07 08:06:38 +00:00
|
|
|
|
2022-03-10 11:24:49 +00:00
|
|
|
alignas(EAS) JSTaggedValue function {JSTaggedValue::Hole()};
|
2022-09-20 12:11:17 +00:00
|
|
|
alignas(EAS) JSTaggedValue thisObj {JSTaggedValue::Hole()};
|
2022-03-10 11:24:49 +00:00
|
|
|
alignas(EAS) JSTaggedValue acc {JSTaggedValue::Hole()};
|
|
|
|
alignas(EAS) JSTaggedValue env {JSTaggedValue::Hole()};
|
2022-06-02 06:35:14 +00:00
|
|
|
alignas(EAS) uintptr_t callSize {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
|
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-10-16 03:21:00 +00:00
|
|
|
// InterpretedEntryFrame Layout as the following:
|
|
|
|
// +----------------------------------+---------------
|
|
|
|
// | . . . . | ^
|
|
|
|
// | InterpretedFrameBase | |
|
|
|
|
// | . . . . | InterpretedEntryFrame
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | pc(bytecode addr) | v
|
|
|
|
// |----------------------------------|---------------
|
|
|
|
//
|
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-07-04 02:08:05 +00:00
|
|
|
|
|
|
|
static uint32_t NumOfMembers()
|
|
|
|
{
|
|
|
|
return sizeof(InterpretedEntryFrame) / JSTaggedValue::TaggedTypeSize();
|
|
|
|
}
|
|
|
|
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor,
|
|
|
|
const RootRangeVisitor &rangeVisitor) const;
|
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-06-10 02:58:12 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(InterpretedEntryFrame),
|
|
|
|
InterpretedEntryFrame::SizeArch32,
|
|
|
|
InterpretedEntryFrame::SizeArch64);
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
|
|
|
|
// AsmInterpretedEntryFrame Layout as the following:
|
|
|
|
// +----------------------------------+---------------
|
|
|
|
// | . . . . | ^
|
|
|
|
// | InterpretedFrameBase | |
|
|
|
|
// | . . . . | AsmInterpretedEntryFrame
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | pc(bytecode addr) | v
|
|
|
|
// |----------------------------------|---------------
|
|
|
|
//
|
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;
|
|
|
|
}
|
|
|
|
|
2022-10-03 04:31:39 +00:00
|
|
|
static size_t GetBaseOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
2022-06-08 03:57:26 +00:00
|
|
|
static AsmInterpretedEntryFrame* GetFrameFromSp(const JSTaggedType *sp)
|
2022-05-12 07:50:47 +00:00
|
|
|
{
|
2022-06-08 03:57:26 +00:00
|
|
|
return reinterpret_cast<AsmInterpretedEntryFrame *>(const_cast<JSTaggedType *>(sp)) - 1;
|
2022-05-12 07:50:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
alignas(EAS) const uint8_t *pc {nullptr};
|
|
|
|
alignas(EAS) InterpretedFrameBase base;
|
|
|
|
};
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// AsmInterpretedBridgeFrame Layout as the following:
|
|
|
|
// +----------------------------------+---------------
|
|
|
|
// | ret-address | ^
|
|
|
|
// |----------------------------------| |
|
|
|
|
// | . . . . | AsmInterpretedBridgeFrame
|
|
|
|
// | AsmInterpretedEntryFrame | |
|
|
|
|
// | . . . . | v
|
|
|
|
// |----------------------------------|---------------
|
|
|
|
//
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
2022-10-03 04:31:39 +00:00
|
|
|
struct AsmInterpretedBridgeFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
2022-06-10 02:58:12 +00:00
|
|
|
AsmInterpretedEntryFrame,
|
|
|
|
base::AlignedPointer> {
|
|
|
|
enum class Index : size_t {
|
|
|
|
EntryIndex = 0,
|
|
|
|
ReturnAddrIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
|
|
|
static AsmInterpretedBridgeFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<AsmInterpretedBridgeFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(AsmInterpretedBridgeFrame, returnAddr));
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetCallSiteSp() const
|
2022-06-10 02:58:12 +00:00
|
|
|
{
|
|
|
|
return ToUintPtr(this) + sizeof(AsmInterpretedBridgeFrame);
|
|
|
|
}
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return entry.base.prev;
|
|
|
|
}
|
|
|
|
|
2022-10-03 04:31:39 +00:00
|
|
|
static size_t GetReturnAddrOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::ReturnAddrIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
|
|
|
static constexpr size_t GetSize(bool isArch32)
|
|
|
|
{
|
|
|
|
return isArch32 ? AsmInterpretedBridgeFrame::SizeArch32 : AsmInterpretedBridgeFrame::SizeArch64;
|
|
|
|
}
|
|
|
|
|
|
|
|
AsmInterpretedEntryFrame entry;
|
2022-06-10 02:58:12 +00:00
|
|
|
alignas(EAS) uintptr_t returnAddr;
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-06-10 02:58:12 +00:00
|
|
|
};
|
2022-04-06 11:22:08 +00:00
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * Optimized-leaved-frame layout as the following:
|
|
|
|
// +--------------------------+
|
|
|
|
// | argv[N-1] |
|
|
|
|
// |--------------------------|
|
|
|
|
// | . . . . . |
|
|
|
|
// |--------------------------|
|
|
|
|
// | argv[0] |
|
|
|
|
// +--------------------------+-------------
|
|
|
|
// | argc | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | RuntimeId | |
|
|
|
|
// sp --> |--------------------------| OptimizedLeaveFrame
|
|
|
|
// | ret-addr | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | prevFp | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | frameType | v
|
|
|
|
// +--------------------------+-------------
|
|
|
|
//
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
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-02-21 08:21:09 +00:00
|
|
|
uint64_t argRuntimeId;
|
|
|
|
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));
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetCallSiteSp() const
|
2021-10-28 12:59:19 +00:00
|
|
|
{
|
2022-03-01 02:57:53 +00:00
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedLeaveFrame, argRuntimeId);
|
2021-10-28 12:59:19 +00:00
|
|
|
}
|
2022-05-16 04:08:23 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp() const
|
2022-05-07 08:06:38 +00:00
|
|
|
{
|
|
|
|
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
|
|
|
}
|
2022-05-16 04:08:23 +00:00
|
|
|
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
2021-09-07 14:24:16 +00:00
|
|
|
};
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * Optimized-leaved-frame-with-argv layout as the following:
|
|
|
|
// +--------------------------+
|
|
|
|
// | argv[] |
|
|
|
|
// +--------------------------+-------------
|
|
|
|
// | argc | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | RuntimeId | OptimizedWithArgvLeaveFrame
|
|
|
|
// sp --> |--------------------------| |
|
|
|
|
// | returnAddr | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | callsiteFp | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | frameType | v
|
|
|
|
// +--------------------------+-------------
|
|
|
|
|
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;
|
|
|
|
uint64_t argRuntimeId;
|
|
|
|
uint64_t argc;
|
2022-10-16 03:21:00 +00:00
|
|
|
|
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));
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetCallSiteSp() const
|
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 ToUintPtr(this) + MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, argRuntimeId);
|
|
|
|
}
|
2022-05-07 08:06:38 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
2022-05-07 08:06:38 +00:00
|
|
|
};
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * OptimizedBuiltinLeaveFrame layout as the following:
|
|
|
|
// +--------------------------+
|
|
|
|
// | argv[N-1] |
|
|
|
|
// |--------------------------|
|
|
|
|
// | . . . . . |
|
|
|
|
// |--------------------------|
|
|
|
|
// | argv[0] |
|
|
|
|
// +--------------------------+-------------
|
|
|
|
// | argc | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | env | |
|
|
|
|
// +--------------------------+ |
|
|
|
|
// | ret-addr | |
|
2022-10-29 00:58:50 +00:00
|
|
|
// sp --> |--------------------------| OptimizedBuiltinLeaveFrame
|
2022-10-16 03:21:00 +00:00
|
|
|
// | prevFp | |
|
|
|
|
// |--------------------------| |
|
2022-10-29 00:58:50 +00:00
|
|
|
// | frameType | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | align byte | v
|
2022-10-16 03:21:00 +00:00
|
|
|
// +--------------------------+-------------
|
|
|
|
//
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
2022-06-29 09:09:09 +00:00
|
|
|
struct OptimizedBuiltinLeaveFrame {
|
|
|
|
public:
|
|
|
|
static OptimizedBuiltinLeaveFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<OptimizedBuiltinLeaveFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, callsiteFp));
|
|
|
|
}
|
|
|
|
uintptr_t GetCallSiteSp() const
|
|
|
|
{
|
2022-10-29 00:58:50 +00:00
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, thread);
|
2022-06-29 09:09:09 +00:00
|
|
|
}
|
|
|
|
inline JSTaggedType* GetPrevFrameFp() const
|
|
|
|
{
|
|
|
|
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
|
|
|
}
|
|
|
|
uintptr_t GetReturnAddr() const
|
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
2022-08-10 07:29:17 +00:00
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, type);
|
|
|
|
}
|
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, callsiteFp);
|
|
|
|
}
|
2022-06-29 09:09:09 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
[[maybe_unused]] FrameType type;
|
|
|
|
uintptr_t callsiteFp; // thread sp set here
|
|
|
|
uintptr_t returnAddr;
|
2022-10-29 00:58:50 +00:00
|
|
|
JSTaggedValue thread;
|
2022-06-29 09:09:09 +00:00
|
|
|
uint64_t argc;
|
|
|
|
// argv[0]...argv[argc-1] dynamic according to agc
|
|
|
|
};
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * BuiltinFrame layout as the following:
|
|
|
|
// +--------------------------+
|
|
|
|
// | argV[N - 1] |
|
|
|
|
// |--------------------------|
|
|
|
|
// | . . . . |
|
|
|
|
// |--------------------------+
|
|
|
|
// | argV[2]=this |
|
|
|
|
// +--------------------------+
|
|
|
|
// | argV[1]=new-target |
|
|
|
|
// +--------------------------+
|
|
|
|
// | argV[0]=call-target |
|
|
|
|
// +--------------------------+ ---------
|
|
|
|
// | argc | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | thread | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | returnAddr | BuiltinFrame
|
|
|
|
// |--------------------------| |
|
|
|
|
// | callsiteFp | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | frameType | v
|
|
|
|
// +--------------------------+ ---------
|
|
|
|
//
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
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,
|
2022-07-04 02:08:05 +00:00
|
|
|
ThreadIndex,
|
2022-05-13 04:58:21 +00:00
|
|
|
NumArgsIndex,
|
|
|
|
StackArgsIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
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;
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetCallSiteSp() const
|
2022-05-07 08:06:38 +00:00
|
|
|
{
|
2022-07-04 02:08:05 +00:00
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(BuiltinFrame, thread);
|
2022-05-13 04:58:21 +00:00
|
|
|
}
|
|
|
|
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 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);
|
|
|
|
}
|
2022-07-04 02:08:05 +00:00
|
|
|
int32_t GetNumArgs()
|
2022-05-13 04:58:21 +00:00
|
|
|
{
|
2022-07-04 02:08:05 +00:00
|
|
|
return numArgs;
|
2022-05-13 04:58:21 +00:00
|
|
|
}
|
|
|
|
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
2022-05-13 04:58:21 +00:00
|
|
|
alignas(EAS) FrameType type;
|
|
|
|
alignas(EAS) JSTaggedType *prevFp;
|
|
|
|
alignas(EAS) uintptr_t returnAddr;
|
2022-07-04 02:08:05 +00:00
|
|
|
alignas(EAS) uintptr_t thread;
|
|
|
|
alignas(EAS) int32_t numArgs;
|
2022-05-13 04:58:21 +00:00
|
|
|
alignas(EAS) uintptr_t stackArgs;
|
|
|
|
};
|
|
|
|
|
2022-10-16 03:21:00 +00:00
|
|
|
// * BuiltinWithArgvFrame layout as the following:
|
|
|
|
// +--------------------------+ ---------
|
|
|
|
// | . . . . . | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | returnAddr | |
|
|
|
|
// |--------------------------| |
|
|
|
|
// | callsiteFp | BuiltinWithArgvFrame
|
|
|
|
// |--------------------------| |
|
|
|
|
// | frameType | |
|
|
|
|
// +--------------------------+ |
|
|
|
|
// | argc | v
|
|
|
|
// +--------------------------+ ---------
|
|
|
|
// | argV[0] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | argV[1] |
|
|
|
|
// +--------------------------+
|
|
|
|
// | . . . . |
|
|
|
|
// +--------------------------+
|
|
|
|
//
|
|
|
|
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-member-init)
|
2022-05-13 04:58:21 +00:00
|
|
|
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;
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetCallSiteSp() const
|
2022-05-13 04:58:21 +00:00
|
|
|
{
|
|
|
|
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-07-04 02:08:05 +00:00
|
|
|
auto numberArgs = GetNumArgs() + NUM_MANDATORY_JSFUNC_ARGS;
|
2022-07-07 08:14:16 +00:00
|
|
|
return topAddress - static_cast<uint32_t>(numberArgs) * sizeof(uintptr_t);
|
2022-05-13 04:58:21 +00:00
|
|
|
}
|
|
|
|
JSTaggedValue GetFunction()
|
|
|
|
{
|
|
|
|
auto functionAddress = reinterpret_cast<JSTaggedType *>(GetStackArgsAddress());
|
|
|
|
return JSTaggedValue(*functionAddress);
|
|
|
|
}
|
2022-07-04 02:08:05 +00:00
|
|
|
int32_t GetNumArgs()
|
2022-05-13 04:58:21 +00:00
|
|
|
{
|
2022-07-04 02:08:05 +00:00
|
|
|
auto argcAddress = reinterpret_cast<int32_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-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
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
|
|
|
};
|
2022-06-11 12:47:30 +00:00
|
|
|
|
2022-08-11 06:24:41 +00:00
|
|
|
enum class GCVisitedFlag : bool {
|
|
|
|
VISITED = true,
|
|
|
|
IGNORED = false,
|
|
|
|
};
|
|
|
|
|
2022-06-14 02:16:45 +00:00
|
|
|
class FrameIterator {
|
2022-06-11 12:47:30 +00:00
|
|
|
public:
|
2022-06-23 08:46:13 +00:00
|
|
|
explicit FrameIterator(JSTaggedType *sp, const JSThread *thread = nullptr);
|
2022-06-16 06:01:06 +00:00
|
|
|
FrameType GetFrameType() const
|
2022-06-11 12:47:30 +00:00
|
|
|
{
|
|
|
|
ASSERT(current_ != nullptr);
|
|
|
|
FrameType *typeAddr = reinterpret_cast<FrameType *>(
|
|
|
|
reinterpret_cast<uintptr_t>(current_) - sizeof(FrameType));
|
|
|
|
return *typeAddr;
|
|
|
|
}
|
|
|
|
|
2022-06-14 07:10:13 +00:00
|
|
|
template<class T>
|
|
|
|
T* GetFrame()
|
|
|
|
{
|
|
|
|
return T::GetFrameFromSp(current_);
|
|
|
|
}
|
2022-06-11 13:00:01 +00:00
|
|
|
|
2022-06-16 06:01:06 +00:00
|
|
|
template<class T>
|
|
|
|
const T* GetFrame() const
|
|
|
|
{
|
|
|
|
return T::GetFrameFromSp(current_);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Done() const
|
2022-06-11 12:47:30 +00:00
|
|
|
{
|
|
|
|
return current_ == nullptr;
|
|
|
|
}
|
2022-06-16 06:01:06 +00:00
|
|
|
JSTaggedType *GetSp() const
|
|
|
|
{
|
|
|
|
return current_;
|
|
|
|
}
|
2022-06-11 12:47:30 +00:00
|
|
|
JSTaggedType *GetSp()
|
|
|
|
{
|
|
|
|
return current_;
|
|
|
|
}
|
2022-10-03 04:31:39 +00:00
|
|
|
void GetCalleeRegAndOffsetVec(kungfu::CalleeRegAndOffsetVec &ret) const
|
|
|
|
{
|
|
|
|
ret = calleeRegInfo_;
|
|
|
|
}
|
2022-06-29 09:09:09 +00:00
|
|
|
int ComputeDelta() const;
|
2022-08-11 06:24:41 +00:00
|
|
|
template <GCVisitedFlag GCVisit = GCVisitedFlag::IGNORED>
|
2022-06-11 12:47:30 +00:00
|
|
|
void Advance();
|
2022-08-02 06:18:16 +00:00
|
|
|
uintptr_t GetPrevFrameCallSiteSp([[maybe_unused]] uintptr_t curPc = 0) const;
|
2022-07-04 02:08:05 +00:00
|
|
|
uintptr_t GetPrevFrame() const;
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetCallSiteSp() const
|
|
|
|
{
|
|
|
|
return optimizedCallSiteSp_;
|
|
|
|
}
|
|
|
|
uintptr_t GetOptimizedReturnAddr() const
|
|
|
|
{
|
|
|
|
return optimizedReturnAddr_;
|
|
|
|
}
|
|
|
|
const JSThread *GetThread() const
|
|
|
|
{
|
|
|
|
return thread_;
|
|
|
|
}
|
2022-08-05 07:01:17 +00:00
|
|
|
bool IteratorStackMap(const RootVisitor &visitor, const RootBaseAndDerivedVisitor &derivedVisitor) const;
|
|
|
|
void CollectBCOffsetInfo(kungfu::ConstInfo &info) const;
|
2022-10-03 04:31:39 +00:00
|
|
|
void CollectArkDeopt(std::vector<kungfu::ARKDeopt>& deopts) const;
|
|
|
|
std::tuple<uint64_t, uint8_t *, int, kungfu::CalleeRegAndOffsetVec> CalCallSiteInfo(uintptr_t retAddr) const;
|
2022-08-05 07:01:17 +00:00
|
|
|
int GetCallSiteDelta(uintptr_t retAddr) const;
|
2022-10-16 03:21:00 +00:00
|
|
|
|
2022-06-11 12:47:30 +00:00
|
|
|
private:
|
2022-06-13 12:46:44 +00:00
|
|
|
JSTaggedType *current_ {nullptr};
|
|
|
|
const JSThread *thread_ {nullptr};
|
2022-08-02 06:43:25 +00:00
|
|
|
const kungfu::ArkStackMapParser *arkStackMapParser_ {nullptr};
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t optimizedCallSiteSp_ {0};
|
|
|
|
uintptr_t optimizedReturnAddr_ {0};
|
2022-08-02 06:18:16 +00:00
|
|
|
uint8_t *stackMapAddr_ {nullptr};
|
2022-08-02 06:43:25 +00:00
|
|
|
int fpDeltaPrevFrameSp_ {0};
|
2022-10-03 04:31:39 +00:00
|
|
|
kungfu::CalleeRegAndOffsetVec calleeRegInfo_;
|
2022-06-11 12:47:30 +00:00
|
|
|
};
|
2021-09-07 14:24:16 +00:00
|
|
|
} // namespace panda::ecmascript
|
2022-08-10 07:29:17 +00:00
|
|
|
extern "C" int step_ark_managed_native_frame(
|
|
|
|
int pid, uintptr_t *pc, uintptr_t *fp, uintptr_t *sp, char *buf, size_t buf_sz);
|
2022-07-30 08:29:50 +00:00
|
|
|
#endif // ECMASCRIPT_FRAMES_H
|