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-03-10 11:24:49 +00:00
|
|
|
#include "ecmascript/base/aligned_struct.h"
|
2022-11-28 04:30:50 +00:00
|
|
|
#include "ecmascript/js_tagged_value.h"
|
2022-06-16 06:01:06 +00:00
|
|
|
#include "ecmascript/mem/visitor.h"
|
2022-11-21 11:09:52 +00:00
|
|
|
#include "ecmascript/method.h"
|
2022-11-28 04:30:50 +00:00
|
|
|
#include "ecmascript/stackmap/ark_stackmap.h"
|
|
|
|
#include "ecmascript/stackmap/llvm_stackmap_type.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,
|
2023-05-18 11:13:51 +00:00
|
|
|
OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME,
|
2023-03-17 07:02:11 +00:00
|
|
|
ASM_BRIDGE_FRAME,
|
2022-08-02 07:54:31 +00:00
|
|
|
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,
|
2023-04-23 09:42:26 +00:00
|
|
|
BUILTIN_FRAME_WITH_ARGV_STACK_OVER_FLOW_FRAME,
|
2022-05-07 08:06:38 +00:00
|
|
|
|
2022-08-02 07:54:31 +00:00
|
|
|
FRAME_TYPE_FIRST = OPTIMIZED_FRAME,
|
2022-11-28 04:30:50 +00:00
|
|
|
FRAME_TYPE_LAST = OPTIMIZED_JS_FUNCTION_UNFOLD_ARGV_FRAME,
|
2022-08-02 07:54:31 +00:00
|
|
|
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
|
|
|
};
|
|
|
|
|
|
|
|
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,
|
2023-04-23 09:42:26 +00:00
|
|
|
CALL_THIS_ARGV_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
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-11-24 03:35:05 +00:00
|
|
|
static size_t ComputeReservedSize(size_t slotSize)
|
|
|
|
{
|
|
|
|
size_t slotOffset = static_cast<size_t>(Index::PrevFpIndex) - static_cast<size_t>(Index::TypeIndex);
|
|
|
|
return slotSize * slotOffset;
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2023-03-08 01:32:05 +00:00
|
|
|
FrameType GetType() const
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
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-11-25 09:08:52 +00:00
|
|
|
return reinterpret_cast<OptimizedFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
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;
|
|
|
|
}
|
2023-03-08 01:32:05 +00:00
|
|
|
|
|
|
|
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);
|
|
|
|
|
2023-03-17 07:02:11 +00:00
|
|
|
struct AsmBridgeFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
|
|
|
public:
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-03-17 07:02:11 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2023-03-17 07:02:11 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-03-17 07:02:11 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
2023-03-17 07:02:11 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
uintptr_t GetCallSiteSp() const
|
|
|
|
{
|
|
|
|
return ToUintPtr(this) + sizeof(AsmBridgeFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
FrameType GetType() const
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum class Index : size_t {
|
|
|
|
TypeIndex = 0,
|
|
|
|
PrevFpIndex,
|
|
|
|
ReturnAddrIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
static_assert(static_cast<size_t>(Index::NumOfMembers) == NumOfTypes);
|
|
|
|
|
|
|
|
static AsmBridgeFrame* GetFrameFromSp(const JSTaggedType *sp)
|
|
|
|
{
|
|
|
|
return reinterpret_cast<AsmBridgeFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(AsmBridgeFrame, prevFp));
|
|
|
|
}
|
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return prevFp;
|
|
|
|
}
|
|
|
|
uintptr_t GetReturnAddr() const
|
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
|
|
|
alignas(EAS) FrameType type {0};
|
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
|
|
|
alignas(EAS) uintptr_t returnAddr {0};
|
|
|
|
friend class FrameIterator;
|
|
|
|
};
|
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(AsmBridgeFrame), AsmBridgeFrame::SizeArch32, AsmBridgeFrame::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:
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2023-03-08 01:32:05 +00:00
|
|
|
FrameType GetType() const
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
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-11-25 09:08:52 +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;
|
|
|
|
}
|
2023-01-04 02:55:29 +00:00
|
|
|
alignas(EAS) uintptr_t callSiteSp {0};
|
2023-03-08 01:32:05 +00:00
|
|
|
alignas(EAS) FrameType type {0};
|
2022-07-19 01:38:13 +00:00
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
|
|
|
alignas(EAS) uintptr_t returnAddr {0};
|
|
|
|
friend class FrameIterator;
|
|
|
|
};
|
2023-03-17 07:02:11 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedJSFunctionUnfoldArgVFrame),
|
|
|
|
OptimizedJSFunctionUnfoldArgVFrame::SizeArch32, OptimizedJSFunctionUnfoldArgVFrame::SizeArch64);
|
2022-07-19 01:38:13 +00:00
|
|
|
|
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:
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2023-03-08 01:32:05 +00:00
|
|
|
FrameType GetType() const
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
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-11-25 09:08:52 +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
|
|
|
}
|
2023-03-08 01:32:05 +00:00
|
|
|
|
|
|
|
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 |
|
|
|
|
// sp ----> |--------------------------| ---------------
|
|
|
|
// | returnAddr | ^
|
|
|
|
// |--------------------------| |
|
|
|
|
// | callsiteFp | |
|
|
|
|
// |--------------------------| OptimizedJSFunctionFrame
|
|
|
|
// | frameType | |
|
|
|
|
// |--------------------------| |
|
2023-02-22 03:11:36 +00:00
|
|
|
// | call-target | v
|
2022-10-16 03:21:00 +00:00
|
|
|
// +--------------------------+ ---------------
|
|
|
|
//
|
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:
|
2023-03-20 01:26:31 +00:00
|
|
|
using ConstInfo = kungfu::LLVMStackMapType::ConstInfo;
|
2022-06-02 06:35:14 +00:00
|
|
|
enum class Index : size_t {
|
2023-02-22 03:11:36 +00:00
|
|
|
JSFuncIndex = 0,
|
2022-06-29 09:09:09 +00:00
|
|
|
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-12-02 07:00:28 +00:00
|
|
|
static constexpr size_t GetFunctionDeltaReturnAddr()
|
|
|
|
{
|
|
|
|
return static_cast<size_t>(Index::ReturnAddrIndex) - static_cast<size_t>(Index::JSFuncIndex);
|
|
|
|
}
|
|
|
|
|
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
|
|
|
{
|
2023-03-30 12:39:26 +00:00
|
|
|
return reinterpret_cast<JSTaggedType *>(preFrameSp + 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
|
|
|
{
|
2023-03-30 12:39:26 +00:00
|
|
|
return *preFrameSp;
|
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-11-28 04:30:50 +00:00
|
|
|
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor,
|
2023-05-18 11:13:51 +00:00
|
|
|
const RootBaseAndDerivedVisitor &derivedVisitor, FrameType frameType) const;
|
2023-03-20 01:26:31 +00:00
|
|
|
void CollectPcOffsetInfo(const FrameIterator &it, ConstInfo &info) const;
|
2022-06-29 09:09:09 +00:00
|
|
|
|
2022-11-28 04:30:50 +00:00
|
|
|
inline JSTaggedValue GetFunction() const
|
|
|
|
{
|
|
|
|
return jsFunc;
|
|
|
|
}
|
|
|
|
|
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-11-28 04:30:50 +00:00
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2022-11-28 04:30:50 +00:00
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2022-08-10 07:29:17 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
2022-08-10 07:29:17 +00:00
|
|
|
}
|
2022-11-28 04:30:50 +00:00
|
|
|
|
2022-11-24 03:35:05 +00:00
|
|
|
static size_t ComputeReservedJSFuncOffset(size_t slotSize)
|
|
|
|
{
|
|
|
|
size_t slotOffset = static_cast<size_t>(Index::PrevFpIndex) - static_cast<size_t>(Index::JSFuncIndex);
|
|
|
|
return slotSize * slotOffset;
|
|
|
|
}
|
2022-11-28 04:30:50 +00:00
|
|
|
|
2023-03-08 01:32:05 +00:00
|
|
|
FrameType GetType() const
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2022-06-29 09:09:09 +00:00
|
|
|
friend class FrameIterator;
|
2023-01-16 06:20:58 +00:00
|
|
|
friend class FrameHandler;
|
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)
|
|
|
|
{
|
2022-11-25 09:08:52 +00:00
|
|
|
return reinterpret_cast<OptimizedJSFunctionFrame *>(reinterpret_cast<uintptr_t>(sp) -
|
|
|
|
MEMBER_OFFSET(OptimizedJSFunctionFrame, prevFp));
|
2022-06-29 09:09:09 +00:00
|
|
|
}
|
2022-10-03 04:31:39 +00:00
|
|
|
|
2022-06-02 06:35:14 +00:00
|
|
|
// dynamic callee saveregisters for x86-64
|
2022-12-02 07:00:28 +00:00
|
|
|
alignas(EAS) JSTaggedValue jsFunc {JSTaggedValue::Undefined()};
|
2023-03-08 01:32:05 +00:00
|
|
|
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);
|
2022-12-02 07:00:28 +00:00
|
|
|
// 2: return addr & prevFp, type and js function should be pairs to update type and js function at the same time.
|
|
|
|
static_assert((OptimizedJSFunctionFrame::GetFunctionDeltaReturnAddr() % 2) == 1);
|
2022-10-16 03:21:00 +00:00
|
|
|
|
|
|
|
// * 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-11-24 03:35:05 +00:00
|
|
|
struct OptimizedEntryFrame : public base::AlignedStruct<base::AlignedPointer::Size(),
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer,
|
|
|
|
base::AlignedPointer> {
|
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,
|
|
|
|
};
|
2022-11-24 03:35:05 +00:00
|
|
|
|
|
|
|
enum class Index : size_t {
|
|
|
|
PreLeaveFrameFpIndex = 0,
|
|
|
|
TypeIndex,
|
|
|
|
PrevFpIndex,
|
|
|
|
NumOfMembers
|
|
|
|
};
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2022-11-24 03:35:05 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2022-11-24 03:35:05 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetLeaveFrameFpOffset(bool isArch32 = false)
|
2022-11-24 03:35:05 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PreLeaveFrameFpIndex)>(isArch32);
|
2022-11-24 03:35:05 +00:00
|
|
|
}
|
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-11-24 03:35:05 +00:00
|
|
|
|
|
|
|
static size_t ComputeReservedSize(size_t slotSize)
|
|
|
|
{
|
|
|
|
size_t slotOffset = static_cast<size_t>(Index::PrevFpIndex) - static_cast<size_t>(Index::PreLeaveFrameFpIndex);
|
|
|
|
return slotSize * slotOffset;
|
|
|
|
}
|
2023-03-08 01:32:05 +00:00
|
|
|
|
|
|
|
FrameType GetType() const
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
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) -
|
2023-03-08 01:32:05 +00:00
|
|
|
MEMBER_OFFSET(OptimizedEntryFrame, prevFp));
|
|
|
|
}
|
|
|
|
|
|
|
|
JSTaggedType* GetLeaveFp() const
|
|
|
|
{
|
|
|
|
return preLeaveFrameFp;
|
|
|
|
}
|
|
|
|
|
|
|
|
JSTaggedType* GetPrevFp() const
|
|
|
|
{
|
|
|
|
return prevFp;
|
2021-12-31 07:51:09 +00:00
|
|
|
}
|
2023-03-08 01:32:05 +00:00
|
|
|
|
|
|
|
alignas(EAS) JSTaggedType *preLeaveFrameFp {nullptr};
|
|
|
|
alignas(EAS) FrameType type {0};
|
|
|
|
alignas(EAS) JSTaggedType *prevFp {nullptr};
|
2021-12-31 07:51:09 +00:00
|
|
|
};
|
2022-11-24 03:35:05 +00:00
|
|
|
STATIC_ASSERT_EQ_ARCH(sizeof(OptimizedEntryFrame), OptimizedEntryFrame::SizeArch32, OptimizedEntryFrame::SizeArch64);
|
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;
|
|
|
|
}
|
|
|
|
|
2023-07-05 02:27:10 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2022-04-26 01:06:56 +00:00
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevIndex)>(isArch32);
|
|
|
|
}
|
|
|
|
|
2023-07-05 02:27:10 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2022-04-26 01:06:56 +00:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
}
|
2023-04-27 12:03:12 +00:00
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetTypeOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetPrevOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetTypeOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetPrevOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2022-12-29 08:19:39 +00:00
|
|
|
const uint8_t *GetPc() const
|
2022-06-16 06:46:52 +00:00
|
|
|
{
|
|
|
|
return pc;
|
|
|
|
}
|
2022-05-07 08:06:38 +00:00
|
|
|
|
2023-04-27 12:03:12 +00:00
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(AsmInterpretedFrame, base) + MEMBER_OFFSET(InterpretedFrameBase, type);
|
|
|
|
}
|
|
|
|
|
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(AsmInterpretedFrame, base) + MEMBER_OFFSET(InterpretedFrameBase, prev);
|
|
|
|
}
|
|
|
|
|
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();
|
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetTypeOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetPrevOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
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
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetTypeOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::BaseIndex)>(isArch32) +
|
|
|
|
InterpretedFrameBase::GetPrevOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::EntryIndex)>(isArch32) +
|
|
|
|
AsmInterpretedEntryFrame::GetBaseOffset(isArch32) +
|
|
|
|
InterpretedFrameBase::GetTypeOffset(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::EntryIndex)>(isArch32) +
|
|
|
|
AsmInterpretedEntryFrame::GetBaseOffset(isArch32) +
|
|
|
|
InterpretedFrameBase::GetPrevOffset(isArch32);
|
2023-04-27 12:03: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;
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
AsmInterpretedEntryFrame entry;
|
|
|
|
alignas(EAS) uintptr_t 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;
|
2023-06-06 06:27:28 +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[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));
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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
|
|
|
}
|
2023-06-06 06:27:28 +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;
|
|
|
|
}
|
2023-04-27 12:03:12 +00:00
|
|
|
|
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedLeaveFrame, type);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2023-04-27 12:03:12 +00:00
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedLeaveFrame, callsiteFp);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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));
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-07 08:06:38 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2023-04-27 12:03:12 +00:00
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, type);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2023-04-27 12:03:12 +00:00
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedWithArgvLeaveFrame, callsiteFp);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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 | ^
|
|
|
|
// |--------------------------| |
|
2023-03-30 12:39:26 +00:00
|
|
|
// | thread | |
|
2022-10-16 03:21:00 +00:00
|
|
|
// +--------------------------+ |
|
|
|
|
// | 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));
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-06-29 09:09:09 +00:00
|
|
|
uintptr_t GetCallSiteSp() const
|
|
|
|
{
|
2023-03-30 12:39:26 +00:00
|
|
|
return ToUintPtr(this) + MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, argc);
|
2022-06-29 09:09:09 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-06-29 09:09:09 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp() const
|
|
|
|
{
|
|
|
|
return reinterpret_cast<JSTaggedType*>(callsiteFp);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-06-29 09:09:09 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-08-10 07:29:17 +00:00
|
|
|
static size_t GetTypeOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, type);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-08-10 07:29:17 +00:00
|
|
|
static size_t GetPrevOffset()
|
|
|
|
{
|
|
|
|
return MEMBER_OFFSET(OptimizedBuiltinLeaveFrame, callsiteFp);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-12-07 04:57:12 +00:00
|
|
|
const JSTaggedType* GetArgv() const
|
|
|
|
{
|
|
|
|
return reinterpret_cast<const JSTaggedType *>(&argc + 1);
|
|
|
|
}
|
2022-06-29 09:09:09 +00:00
|
|
|
|
2023-03-08 01:32:05 +00:00
|
|
|
FrameType GetType() const
|
|
|
|
{
|
|
|
|
return type;
|
|
|
|
}
|
|
|
|
|
2022-06-29 09:09:09 +00:00
|
|
|
private:
|
2023-03-08 01:32:05 +00:00
|
|
|
FrameType type;
|
2022-06-29 09:09:09 +00:00
|
|
|
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));
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-07 08:06:38 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return prevFp;
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
static size_t GetPreFpOffset(bool isArch32)
|
|
|
|
{
|
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
static size_t GetNumArgsToFpDelta(bool isArch32)
|
|
|
|
{
|
|
|
|
auto offset = GetOffset<static_cast<size_t>(Index::NumArgsIndex)>(isArch32);
|
|
|
|
return offset - GetPreFpOffset(isArch32);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
static size_t GetStackArgsToFpDelta(bool isArch32)
|
|
|
|
{
|
|
|
|
auto offset = GetOffset<static_cast<size_t>(Index::StackArgsIndex)>(isArch32);
|
|
|
|
return offset - GetPreFpOffset(isArch32);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
uintptr_t GetStackArgsAddress()
|
|
|
|
{
|
|
|
|
return reinterpret_cast<uintptr_t>(&stackArgs);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
JSTaggedValue GetFunction()
|
|
|
|
{
|
|
|
|
auto functionAddress = reinterpret_cast<JSTaggedType *>(GetStackArgsAddress());
|
|
|
|
return JSTaggedValue(*functionAddress);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
uint32_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;
|
|
|
|
}
|
2023-04-27 12:03:12 +00:00
|
|
|
|
2023-06-06 06:27:28 +00:00
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-07-30 08:29:50 +00:00
|
|
|
void GCIterate(const FrameIterator &it, const RootVisitor &visitor, const RootRangeVisitor &rangeVisitor) const;
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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;
|
2023-06-06 06:27:28 +00:00
|
|
|
alignas(EAS) uint32_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));
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
inline JSTaggedType* GetPrevFrameFp()
|
|
|
|
{
|
|
|
|
return prevFp;
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
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
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-05-13 04:58:21 +00:00
|
|
|
JSTaggedValue GetFunction()
|
|
|
|
{
|
|
|
|
auto functionAddress = reinterpret_cast<JSTaggedType *>(GetStackArgsAddress());
|
|
|
|
return JSTaggedValue(*functionAddress);
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
2022-06-16 06:01:06 +00:00
|
|
|
uintptr_t GetReturnAddr() const
|
2022-06-13 12:46:44 +00:00
|
|
|
{
|
|
|
|
return returnAddr;
|
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
static size_t GetTypeOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::TypeIndex)>(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
|
|
|
static size_t GetPrevOffset(bool isArch32 = false)
|
2023-04-27 12:03:12 +00:00
|
|
|
{
|
2023-06-06 06:27:28 +00:00
|
|
|
return GetOffset<static_cast<size_t>(Index::PrevFpIndex)>(isArch32);
|
2023-04-27 12:03:12 +00:00
|
|
|
}
|
2023-06-06 06:27:28 +00:00
|
|
|
|
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,
|
2023-05-16 02:18:05 +00:00
|
|
|
HYBRID_STACK = true,
|
2022-08-11 06:24:41 +00:00
|
|
|
};
|
|
|
|
|
2022-06-14 02:16:45 +00:00
|
|
|
class FrameIterator {
|
2022-06-11 12:47:30 +00:00
|
|
|
public:
|
2023-03-20 01:26:31 +00:00
|
|
|
using ConstInfo = kungfu::LLVMStackMapType::ConstInfo;
|
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-12-29 08:19:39 +00:00
|
|
|
uint32_t GetBytecodeOffset() const;
|
2023-03-08 01:32:05 +00:00
|
|
|
uintptr_t GetPrevFrameCallSiteSp() 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;
|
2023-03-20 01:26:31 +00:00
|
|
|
void CollectPcOffsetInfo(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-11-21 11:09:52 +00:00
|
|
|
Method *CheckAndGetMethod() const;
|
|
|
|
JSTaggedValue GetFunction() const;
|
|
|
|
|
2023-01-09 11:54:12 +00:00
|
|
|
bool IsLeaveFrame() const
|
|
|
|
{
|
|
|
|
FrameType type = GetFrameType();
|
|
|
|
return (type == FrameType::LEAVE_FRAME) || (type == FrameType::LEAVE_FRAME_WITH_ARGV);
|
|
|
|
}
|
|
|
|
|
2023-01-11 06:12:19 +00:00
|
|
|
bool IsOptimizedFrame() const
|
|
|
|
{
|
|
|
|
FrameType type = GetFrameType();
|
|
|
|
return (type == FrameType::OPTIMIZED_FRAME);
|
|
|
|
}
|
|
|
|
|
2023-03-02 12:09:04 +00:00
|
|
|
bool IsInterpretedFrame(FrameType type) const
|
|
|
|
{
|
|
|
|
return (type >= FrameType::INTERPRETER_FIRST) && (type <= FrameType::INTERPRETER_LAST);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsJSFrame() const
|
|
|
|
{
|
|
|
|
FrameType type = GetFrameType();
|
|
|
|
return IsInterpretedFrame(type) || IsOptimizedJSFunctionFrame(type);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool IsOptimizedJSFunctionFrame(FrameType type) const
|
|
|
|
{
|
2023-05-18 11:13:51 +00:00
|
|
|
return type == FrameType::OPTIMIZED_JS_FUNCTION_FRAME ||
|
|
|
|
type == FrameType::OPTIMIZED_JS_FAST_CALL_FUNCTION_FRAME;
|
2023-03-02 12:09:04 +00:00
|
|
|
}
|
|
|
|
|
2023-01-09 11:54:12 +00:00
|
|
|
bool IsOptimizedJSFunctionFrame() const
|
|
|
|
{
|
|
|
|
FrameType type = GetFrameType();
|
2023-03-02 12:09:04 +00:00
|
|
|
return IsOptimizedJSFunctionFrame(type);
|
2023-01-09 11:54:12 +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-07-30 08:29:50 +00:00
|
|
|
#endif // ECMASCRIPT_FRAMES_H
|