[codegen] Add static interface descriptors
Add a new CRTP StaticCallInterfaceDescriptor class, which provides static constexpr getters for a descriptor's registers, parameter counts, and so on. Each CallInterfaceDescriptor subclass is changed to extend StaticCallInterfaceDescriptor, with StaticCallInterfaceDescriptor itself extending CallInterfaceDescriptor to still provide a dynamic lookup where needed. StaticCallInterfaceDescriptor provides a couple of customisation points, where it reads its CRTP derived descriptor's static fields and functions, with default fallbacks where appropriate. With these customisation points, the definition of CallInterfaceDescriptor subclasses is simplified to: a) Providing parameter names (as before) b) Providing parameter types (as before) c) Optionally setting flags (like kNoContext or kAllowVarArgs) as static booleans on the class. d) Optionally providing a `registers()` method that returns a std::array<Register, N> of registers that may be used for parameters (if not provided, this defaults to the implementation specific default register set). Parameter registers (and register count) are automagically set based on the number of parameters and number of given registers, with extra magic to ignore no_reg registers (to reduce ia32 special casing). The CallInterfaceDescriptorData is initialized based on these static functions, rather than manual per-descriptor initializers. This allows us to skip loading descriptors dynamically for CallBuiltin in Sparkplug, and instead lets us use a bit of template magic to statically set up arguments for the calls. Any other users of statically known descriptors will also benefit, thanks to C++ picking the static methods over the dynamic methods on the base class when available. Because we can remove various virtual functions and trigger heavier inlining of constantly known values, binary size slightly decreases with this change. Note that torque-generated descriptors are changed to use the same magic, rather than having Torque-specific magic, for consistency. Bug: v8:11420 Change-Id: Icc5e238b6313a08734feb564204a13226b450c22 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2814518 Auto-Submit: Leszek Swirski <leszeks@chromium.org> Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Reviewed-by: Clemens Backes <clemensb@chromium.org> Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Jakob Gruber <jgruber@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Cr-Commit-Position: refs/heads/master@{#73996}
This commit is contained in:
parent
abe4858b0a
commit
ae0752df1b
9
BUILD.gn
9
BUILD.gn
@ -2337,6 +2337,7 @@ v8_header_set("v8_internal_headers") {
|
||||
"src/codegen/external-reference.h",
|
||||
"src/codegen/flush-instruction-cache.h",
|
||||
"src/codegen/handler-table.h",
|
||||
"src/codegen/interface-descriptors-inl.h",
|
||||
"src/codegen/interface-descriptors.h",
|
||||
"src/codegen/label.h",
|
||||
"src/codegen/machine-type.h",
|
||||
@ -4057,7 +4058,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
sources += [ ### gcmole(arch:ia32) ###
|
||||
"src/codegen/ia32/assembler-ia32.cc",
|
||||
"src/codegen/ia32/cpu-ia32.cc",
|
||||
"src/codegen/ia32/interface-descriptors-ia32.cc",
|
||||
"src/codegen/ia32/interface-descriptors-ia32-inl.h",
|
||||
"src/codegen/ia32/macro-assembler-ia32.cc",
|
||||
"src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.cc",
|
||||
"src/compiler/backend/ia32/code-generator-ia32.cc",
|
||||
@ -4075,7 +4076,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.cc",
|
||||
"src/codegen/x64/assembler-x64.cc",
|
||||
"src/codegen/x64/cpu-x64.cc",
|
||||
"src/codegen/x64/interface-descriptors-x64.cc",
|
||||
"src/codegen/x64/interface-descriptors-x64-inl.h",
|
||||
"src/codegen/x64/macro-assembler-x64.cc",
|
||||
"src/compiler/backend/x64/code-generator-x64.cc",
|
||||
"src/compiler/backend/x64/instruction-scheduler-x64.cc",
|
||||
@ -4110,7 +4111,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/codegen/arm/assembler-arm.cc",
|
||||
"src/codegen/arm/constants-arm.cc",
|
||||
"src/codegen/arm/cpu-arm.cc",
|
||||
"src/codegen/arm/interface-descriptors-arm.cc",
|
||||
"src/codegen/arm/interface-descriptors-arm-inl.h",
|
||||
"src/codegen/arm/macro-assembler-arm.cc",
|
||||
"src/compiler/backend/arm/code-generator-arm.cc",
|
||||
"src/compiler/backend/arm/instruction-scheduler-arm.cc",
|
||||
@ -4132,7 +4133,7 @@ v8_source_set("v8_base_without_compiler") {
|
||||
"src/codegen/arm64/decoder-arm64.cc",
|
||||
"src/codegen/arm64/instructions-arm64-constants.cc",
|
||||
"src/codegen/arm64/instructions-arm64.cc",
|
||||
"src/codegen/arm64/interface-descriptors-arm64.cc",
|
||||
"src/codegen/arm64/interface-descriptors-arm64-inl.h",
|
||||
"src/codegen/arm64/macro-assembler-arm64.cc",
|
||||
"src/codegen/arm64/register-arm64.cc",
|
||||
"src/codegen/arm64/utils-arm64.cc",
|
||||
|
@ -19,9 +19,9 @@ void BaselineCompiler::Prologue() {
|
||||
__ masm()->EnterFrame(StackFrame::BASELINE);
|
||||
DCHECK_EQ(kJSFunctionRegister, kJavaScriptCallTargetRegister);
|
||||
int max_frame_size = bytecode_->frame_size() + max_call_args_;
|
||||
CallBuiltin(Builtins::kBaselineOutOfLinePrologue, kContextRegister,
|
||||
kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
CallBuiltin<Builtins::kBaselineOutOfLinePrologue>(
|
||||
kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
|
||||
PrologueFillFrame();
|
||||
}
|
||||
|
@ -18,9 +18,9 @@ void BaselineCompiler::Prologue() {
|
||||
__ masm()->EnterFrame(StackFrame::BASELINE);
|
||||
DCHECK_EQ(kJSFunctionRegister, kJavaScriptCallTargetRegister);
|
||||
int max_frame_size = bytecode_->frame_size() + max_call_args_;
|
||||
CallBuiltin(Builtins::kBaselineOutOfLinePrologue, kContextRegister,
|
||||
kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
CallBuiltin<Builtins::kBaselineOutOfLinePrologue>(
|
||||
kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
|
||||
__ masm()->AssertSpAligned();
|
||||
PrologueFillFrame();
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "src/baseline/baseline-assembler.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/interpreter/bytecode-register.h"
|
||||
#include "src/objects/feedback-cell.h"
|
||||
#include "src/objects/js-function.h"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -126,26 +126,16 @@ class BaselineCompiler {
|
||||
Label::Distance distance = Label::kFar);
|
||||
|
||||
// Call helpers.
|
||||
template <typename... Args>
|
||||
void CallBuiltin(Builtins::Name builtin, Args... args);
|
||||
template <Builtins::Name kBuiltin, typename... Args>
|
||||
void CallBuiltin(Args... args);
|
||||
template <typename... Args>
|
||||
void CallRuntime(Runtime::FunctionId function, Args... args);
|
||||
|
||||
template <typename... Args>
|
||||
void TailCallBuiltin(Builtins::Name builtin, Args... args);
|
||||
template <Builtins::Name kBuiltin, typename... Args>
|
||||
void TailCallBuiltin(Args... args);
|
||||
|
||||
void BuildBinop(
|
||||
Builtins::Name builtin_name, bool fast_path = false,
|
||||
bool check_overflow = false,
|
||||
std::function<void(Register, Register)> instruction = [](Register,
|
||||
Register) {});
|
||||
void BuildUnop(Builtins::Name builtin_name);
|
||||
void BuildCompare(Builtins::Name builtin_name);
|
||||
void BuildBinopWithConstant(Builtins::Name builtin_name);
|
||||
|
||||
template <typename... Args>
|
||||
void BuildCall(ConvertReceiverMode mode, uint32_t slot, uint32_t arg_count,
|
||||
Args... args);
|
||||
template <ConvertReceiverMode kMode, typename... Args>
|
||||
void BuildCall(uint32_t slot, uint32_t arg_count, Args... args);
|
||||
|
||||
#ifdef V8_TRACE_UNOPTIMIZED
|
||||
void TraceBytecode(Runtime::FunctionId function_id);
|
||||
|
@ -18,9 +18,9 @@ namespace baseline {
|
||||
void BaselineCompiler::Prologue() {
|
||||
DCHECK_EQ(kJSFunctionRegister, kJavaScriptCallTargetRegister);
|
||||
int max_frame_size = bytecode_->frame_size() + max_call_args_;
|
||||
CallBuiltin(Builtins::kBaselineOutOfLinePrologue, kContextRegister,
|
||||
kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
CallBuiltin<Builtins::kBaselineOutOfLinePrologue>(
|
||||
kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
|
||||
PrologueFillFrame();
|
||||
}
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include "src/base/macros.h"
|
||||
#include "src/baseline/baseline-assembler.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/x64/register-x64.h"
|
||||
|
||||
namespace v8 {
|
||||
|
@ -18,9 +18,9 @@ namespace baseline {
|
||||
void BaselineCompiler::Prologue() {
|
||||
DCHECK_EQ(kJSFunctionRegister, kJavaScriptCallTargetRegister);
|
||||
int max_frame_size = bytecode_->frame_size() + max_call_args_;
|
||||
CallBuiltin(Builtins::kBaselineOutOfLinePrologue, kContextRegister,
|
||||
kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
CallBuiltin<Builtins::kBaselineOutOfLinePrologue>(
|
||||
kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
max_frame_size, kJavaScriptCallNewTargetRegister, bytecode_);
|
||||
|
||||
PrologueFillFrame();
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/api/api-arguments.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
// For interpreter_entry_return_pc_offset. TODO(jkummerow): Drop.
|
||||
#include "src/codegen/macro-assembler-inl.h"
|
||||
#include "src/codegen/register-configuration.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/api/api-arguments.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
// For interpreter_entry_return_pc_offset. TODO(jkummerow): Drop.
|
||||
#include "src/codegen/macro-assembler-inl.h"
|
||||
#include "src/codegen/register-configuration.h"
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "src/builtins/builtins-utils-gen.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/codegen/code-stub-assembler.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/execution/frame-constants.h"
|
||||
#include "src/heap/factory-inl.h"
|
||||
#include "src/objects/allocation-site-inl.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/builtins/builtins-utils-gen.h"
|
||||
#include "src/builtins/builtins.h"
|
||||
#include "src/codegen/code-stub-assembler.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/macro-assembler.h"
|
||||
#include "src/execution/frame-constants.h"
|
||||
#include "src/heap/memory-chunk.h"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/base/bits-iterator.h"
|
||||
#include "src/base/iterator.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
// For interpreter_entry_return_pc_offset. TODO(jkummerow): Drop.
|
||||
#include "src/codegen/macro-assembler-inl.h"
|
||||
#include "src/codegen/register-configuration.h"
|
||||
@ -1458,7 +1459,7 @@ void Builtins::Generate_InterpreterPushArgsThenConstructImpl(
|
||||
// and edi are used as scratch registers.
|
||||
Generate_InterpreterPushZeroAndArgsAndReturnAddress(
|
||||
masm, eax, ecx, edx, edi,
|
||||
InterpreterPushArgsThenConstructDescriptor::kStackArgumentsCount,
|
||||
InterpreterPushArgsThenConstructDescriptor::GetStackParameterCount(),
|
||||
&stack_overflow);
|
||||
|
||||
// Call the appropriate constructor. eax and ecx already contain intended
|
||||
|
@ -8,18 +8,19 @@
|
||||
#include "src/base/bits-iterator.h"
|
||||
#include "src/base/iterator.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/objects/code.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
// For interpreter_entry_return_pc_offset. TODO(jkummerow): Drop.
|
||||
#include "src/codegen/macro-assembler-inl.h"
|
||||
#include "src/codegen/register-configuration.h"
|
||||
#include "src/codegen/x64/assembler-x64.h"
|
||||
#include "src/common/globals.h"
|
||||
#include "src/deoptimizer/deoptimizer.h"
|
||||
#include "src/execution/frame-constants.h"
|
||||
#include "src/execution/frames.h"
|
||||
#include "src/heap/heap-inl.h"
|
||||
#include "src/logging/counters.h"
|
||||
#include "src/objects/cell.h"
|
||||
#include "src/objects/code.h"
|
||||
#include "src/objects/debug-objects.h"
|
||||
#include "src/objects/foreign.h"
|
||||
#include "src/objects/heap-number.h"
|
||||
|
261
src/codegen/arm/interface-descriptors-arm-inl.h
Normal file
261
src/codegen/arm/interface-descriptors-arm-inl.h
Normal file
@ -0,0 +1,261 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_CODEGEN_ARM_INTERFACE_DESCRIPTORS_ARM_INL_H_
|
||||
#define V8_CODEGEN_ARM_INTERFACE_DESCRIPTORS_ARM_INL_H_
|
||||
|
||||
#if V8_TARGET_ARCH_ARM
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/execution/frames.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
|
||||
auto registers = RegisterArray(r0, r1, r2, r3, r4);
|
||||
STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
|
||||
return registers;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RecordWriteDescriptor::registers() {
|
||||
return RegisterArray(r0, r1, r2, r3, r4, kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto DynamicCheckMapsDescriptor::registers() {
|
||||
return RegisterArray(r0, r1, r2, r3, cp);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
|
||||
return RegisterArray(r0, r1, r2, r3, r4, kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register LoadDescriptor::ReceiverRegister() { return r1; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::NameRegister() { return r2; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::SlotRegister() { return r0; }
|
||||
|
||||
// static
|
||||
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
|
||||
|
||||
// static
|
||||
constexpr Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return r4;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ReceiverRegister() { return r1; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::NameRegister() { return r2; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ValueRegister() { return r0; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::SlotRegister() { return r4; }
|
||||
|
||||
// static
|
||||
constexpr Register StoreWithVectorDescriptor::VectorRegister() { return r3; }
|
||||
|
||||
// static
|
||||
constexpr Register StoreTransitionDescriptor::MapRegister() { return r5; }
|
||||
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::HolderRegister() { return r0; }
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::CallbackRegister() { return r3; }
|
||||
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }
|
||||
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
|
||||
return r3;
|
||||
}
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() { return r4; }
|
||||
|
||||
// static
|
||||
// static
|
||||
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return r0; }
|
||||
|
||||
// static
|
||||
constexpr auto TypeofDescriptor::registers() { return RegisterArray(r3); }
|
||||
|
||||
// static
|
||||
constexpr auto CallTrampolineDescriptor::registers() {
|
||||
// r0 : number of arguments
|
||||
// r1 : the target to call
|
||||
return RegisterArray(r1, r0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallVarargsDescriptor::registers() {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r4 : arguments list length (untagged)
|
||||
// r2 : arguments list (FixedArray)
|
||||
return RegisterArray(r1, r0, r4, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallForwardVarargsDescriptor::registers() {
|
||||
// r0 : number of arguments
|
||||
// r2 : start index (to support rest parameters)
|
||||
// r1 : the target to call
|
||||
return RegisterArray(r1, r0, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallFunctionTemplateDescriptor::registers() {
|
||||
// r1 : function template info
|
||||
// r2 : number of arguments (on the stack, not including receiver)
|
||||
return RegisterArray(r1, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithSpreadDescriptor::registers() {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r2 : the object to spread
|
||||
return RegisterArray(r1, r0, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithArrayLikeDescriptor::registers() {
|
||||
// r1 : the target to call
|
||||
// r2 : the arguments list
|
||||
return RegisterArray(r1, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructVarargsDescriptor::registers() {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r4 : arguments list length (untagged)
|
||||
// r2 : arguments list (FixedArray)
|
||||
return RegisterArray(r1, r3, r0, r4, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructForwardVarargsDescriptor::registers() {
|
||||
// r0 : number of arguments
|
||||
// r3 : the new target
|
||||
// r2 : start index (to support rest parameters)
|
||||
// r1 : the target to call
|
||||
return RegisterArray(r1, r3, r0, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithSpreadDescriptor::registers() {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r2 : the object to spread
|
||||
return RegisterArray(r1, r3, r0, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r2 : the arguments list
|
||||
return RegisterArray(r1, r3, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructStubDescriptor::registers() {
|
||||
// r0 : number of arguments
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r2 : allocation site or undefined
|
||||
return RegisterArray(r1, r3, r0, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto AbortDescriptor::registers() { return RegisterArray(r1); }
|
||||
|
||||
// static
|
||||
constexpr auto CompareDescriptor::registers() { return RegisterArray(r1, r0); }
|
||||
|
||||
// static
|
||||
constexpr auto Compare_BaselineDescriptor::registers() {
|
||||
// r1: left operand
|
||||
// r0: right operand
|
||||
// r2: feedback slot
|
||||
return RegisterArray(r1, r0, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOpDescriptor::registers() { return RegisterArray(r1, r0); }
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOp_BaselineDescriptor::registers() {
|
||||
// r1: left operand
|
||||
// r0: right operand
|
||||
// r2: feedback slot
|
||||
return RegisterArray(r1, r0, r2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ApiCallbackDescriptor::registers() {
|
||||
return RegisterArray(r1, // kApiFunctionAddress
|
||||
r2, // kArgc
|
||||
r3, // kCallData
|
||||
r0); // kHolder
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterDispatchDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
|
||||
return RegisterArray(r0, // argument count (not including receiver)
|
||||
r2, // address of first argument
|
||||
r1); // the target callable to be call
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
r0, // argument count (not including receiver)
|
||||
r4, // address of the first argument
|
||||
r1, // constructor to call
|
||||
r3, // new target
|
||||
r2); // allocation site feedback if available, undefined otherwise
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ResumeGeneratorDescriptor::registers() {
|
||||
return RegisterArray(r0, // the value to pass to the generator
|
||||
r1); // the JSGeneratorObject to resume
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto FrameDropperTrampolineDescriptor::registers() {
|
||||
return RegisterArray(r1); // loaded new FP
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RunMicrotasksEntryDescriptor::registers() {
|
||||
return RegisterArray(r0, r1);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_ARM
|
||||
|
||||
#endif // V8_CODEGEN_ARM_INTERFACE_DESCRIPTORS_ARM_INL_H_
|
@ -1,306 +0,0 @@
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#if V8_TARGET_ARCH_ARM
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
|
||||
#include "src/execution/frames.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
|
||||
|
||||
void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data, int register_parameter_count) {
|
||||
const Register default_stub_registers[] = {r0, r1, r2, r3, r4};
|
||||
CHECK_LE(static_cast<size_t>(register_parameter_count),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(register_parameter_count,
|
||||
default_stub_registers);
|
||||
}
|
||||
|
||||
void RecordWriteDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
const Register default_stub_registers[] = {r0, r1, r2, r3, r4};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void DynamicCheckMapsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register default_stub_registers[] = {r0, r1, r2, r3, cp};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void EphemeronKeyBarrierDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
const Register default_stub_registers[] = {r0, r1, r2, r3, r4};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
const Register LoadDescriptor::ReceiverRegister() { return r1; }
|
||||
const Register LoadDescriptor::NameRegister() { return r2; }
|
||||
const Register LoadDescriptor::SlotRegister() { return r0; }
|
||||
|
||||
const Register LoadWithVectorDescriptor::VectorRegister() { return r3; }
|
||||
|
||||
const Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return r4;
|
||||
}
|
||||
|
||||
const Register StoreDescriptor::ReceiverRegister() { return r1; }
|
||||
const Register StoreDescriptor::NameRegister() { return r2; }
|
||||
const Register StoreDescriptor::ValueRegister() { return r0; }
|
||||
const Register StoreDescriptor::SlotRegister() { return r4; }
|
||||
|
||||
const Register StoreWithVectorDescriptor::VectorRegister() { return r3; }
|
||||
|
||||
const Register StoreTransitionDescriptor::SlotRegister() { return r4; }
|
||||
const Register StoreTransitionDescriptor::VectorRegister() { return r3; }
|
||||
const Register StoreTransitionDescriptor::MapRegister() { return r5; }
|
||||
|
||||
const Register ApiGetterDescriptor::HolderRegister() { return r0; }
|
||||
const Register ApiGetterDescriptor::CallbackRegister() { return r3; }
|
||||
|
||||
const Register GrowArrayElementsDescriptor::ObjectRegister() { return r0; }
|
||||
const Register GrowArrayElementsDescriptor::KeyRegister() { return r3; }
|
||||
|
||||
const Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() { return r3; }
|
||||
const Register BaselineLeaveFrameDescriptor::WeightRegister() { return r4; }
|
||||
|
||||
// static
|
||||
const Register TypeConversionDescriptor::ArgumentRegister() { return r0; }
|
||||
|
||||
void TypeofDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {r3};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments
|
||||
// r1 : the target to call
|
||||
Register registers[] = {r1, r0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r4 : arguments list length (untagged)
|
||||
// r2 : arguments list (FixedArray)
|
||||
Register registers[] = {r1, r0, r4, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments
|
||||
// r2 : start index (to support rest parameters)
|
||||
// r1 : the target to call
|
||||
Register registers[] = {r1, r0, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallFunctionTemplateDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r1 : function template info
|
||||
// r2 : number of arguments (on the stack, not including receiver)
|
||||
Register registers[] = {r1, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r2 : the object to spread
|
||||
Register registers[] = {r1, r0, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r1 : the target to call
|
||||
// r2 : the arguments list
|
||||
Register registers[] = {r1, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r4 : arguments list length (untagged)
|
||||
// r2 : arguments list (FixedArray)
|
||||
Register registers[] = {r1, r3, r0, r4, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments
|
||||
// r3 : the new target
|
||||
// r2 : start index (to support rest parameters)
|
||||
// r1 : the target to call
|
||||
Register registers[] = {r1, r3, r0, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments (on the stack, not including receiver)
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r2 : the object to spread
|
||||
Register registers[] = {r1, r3, r0, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r2 : the arguments list
|
||||
Register registers[] = {r1, r3, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructStubDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r0 : number of arguments
|
||||
// r1 : the target to call
|
||||
// r3 : the new target
|
||||
// r2 : allocation site or undefined
|
||||
Register registers[] = {r1, r3, r0, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void AbortDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {r1};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CompareDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {r1, r0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void Compare_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r1: left operand
|
||||
// r0: right operand
|
||||
// r2: feedback slot
|
||||
Register registers[] = {r1, r0, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {r1, r0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOp_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// r1: left operand
|
||||
// r0: right operand
|
||||
// r2: feedback slot
|
||||
Register registers[] = {r1, r0, r2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r1, // kApiFunctionAddress
|
||||
r2, // kArgc
|
||||
r3, // kCallData
|
||||
r0, // kHolder
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r0, // argument count (not including receiver)
|
||||
r2, // address of first argument
|
||||
r1 // the target callable to be call
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r0, // argument count (not including receiver)
|
||||
r4, // address of the first argument
|
||||
r1, // constructor to call
|
||||
r3, // new target
|
||||
r2, // allocation site feedback if available, undefined otherwise
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r0, // the value to pass to the generator
|
||||
r1 // the JSGeneratorObject to resume
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
r1, // loaded new FP
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void RunMicrotasksEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {r0, r1};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_ARM
|
@ -13,6 +13,7 @@
|
||||
#include "src/codegen/callable.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/external-reference-table.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/macro-assembler.h"
|
||||
#include "src/codegen/register-configuration.h"
|
||||
#include "src/debug/debug.h"
|
||||
|
270
src/codegen/arm64/interface-descriptors-arm64-inl.h
Normal file
270
src/codegen/arm64/interface-descriptors-arm64-inl.h
Normal file
@ -0,0 +1,270 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_CODEGEN_ARM64_INTERFACE_DESCRIPTORS_ARM64_INL_H_
|
||||
#define V8_CODEGEN_ARM64_INTERFACE_DESCRIPTORS_ARM64_INL_H_
|
||||
|
||||
#if V8_TARGET_ARCH_ARM64
|
||||
|
||||
#include "src/base/template-utils.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/execution/frames.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
|
||||
auto registers = RegisterArray(x0, x1, x2, x3, x4);
|
||||
STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
|
||||
return registers;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RecordWriteDescriptor::registers() {
|
||||
return RegisterArray(x0, x1, x2, x3, x4, kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto DynamicCheckMapsDescriptor::registers() {
|
||||
return RegisterArray(x0, x1, x2, x3, cp);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
|
||||
return RegisterArray(x0, x1, x2, x3, x4, kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register LoadDescriptor::ReceiverRegister() { return x1; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::NameRegister() { return x2; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::SlotRegister() { return x0; }
|
||||
|
||||
// static
|
||||
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return x3; }
|
||||
|
||||
// static
|
||||
constexpr Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return x4;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ReceiverRegister() { return x1; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::NameRegister() { return x2; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ValueRegister() { return x0; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::SlotRegister() { return x4; }
|
||||
|
||||
// static
|
||||
constexpr Register StoreWithVectorDescriptor::VectorRegister() { return x3; }
|
||||
|
||||
// static
|
||||
constexpr Register StoreTransitionDescriptor::MapRegister() { return x5; }
|
||||
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::HolderRegister() { return x0; }
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::CallbackRegister() { return x3; }
|
||||
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; }
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return x3; }
|
||||
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
|
||||
return x3;
|
||||
}
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() { return x4; }
|
||||
|
||||
// static
|
||||
// static
|
||||
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return x0; }
|
||||
|
||||
// static
|
||||
constexpr auto TypeofDescriptor::registers() { return RegisterArray(x3); }
|
||||
|
||||
// static
|
||||
constexpr auto CallTrampolineDescriptor::registers() {
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
return RegisterArray(x1, x0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallVarargsDescriptor::registers() {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x4 : arguments list length (untagged)
|
||||
// x2 : arguments list (FixedArray)
|
||||
return RegisterArray(x1, x0, x4, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallForwardVarargsDescriptor::registers() {
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
// x2: start index (to supported rest parameters)
|
||||
return RegisterArray(x1, x0, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallFunctionTemplateDescriptor::registers() {
|
||||
// x1 : function template info
|
||||
// x2 : number of arguments (on the stack, not including receiver)
|
||||
return RegisterArray(x1, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithSpreadDescriptor::registers() {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x2 : the object to spread
|
||||
return RegisterArray(x1, x0, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithArrayLikeDescriptor::registers() {
|
||||
// x1 : the target to call
|
||||
// x2 : the arguments list
|
||||
return RegisterArray(x1, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructVarargsDescriptor::registers() {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x3 : the new target
|
||||
// x4 : arguments list length (untagged)
|
||||
// x2 : arguments list (FixedArray)
|
||||
return RegisterArray(x1, x3, x0, x4, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructForwardVarargsDescriptor::registers() {
|
||||
// x3: new target
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
// x2: start index (to supported rest parameters)
|
||||
return RegisterArray(x1, x3, x0, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithSpreadDescriptor::registers() {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x3 : the new target
|
||||
// x2 : the object to spread
|
||||
return RegisterArray(x1, x3, x0, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
|
||||
// x1 : the target to call
|
||||
// x3 : the new target
|
||||
// x2 : the arguments list
|
||||
return RegisterArray(x1, x3, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructStubDescriptor::registers() {
|
||||
// x3: new target
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
// x2: allocation site or undefined
|
||||
return RegisterArray(x1, x3, x0, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto AbortDescriptor::registers() { return RegisterArray(x1); }
|
||||
|
||||
// static
|
||||
constexpr auto CompareDescriptor::registers() {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
return RegisterArray(x1, x0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto Compare_BaselineDescriptor::registers() {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
// x2: feedback slot
|
||||
return RegisterArray(x1, x0, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOpDescriptor::registers() {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
return RegisterArray(x1, x0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOp_BaselineDescriptor::registers() {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
// x2: feedback slot
|
||||
return RegisterArray(x1, x0, x2);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ApiCallbackDescriptor::registers() {
|
||||
return RegisterArray(x1, // kApiFunctionAddress
|
||||
x2, // kArgc
|
||||
x3, // kCallData
|
||||
x0); // kHolder
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterDispatchDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
|
||||
return RegisterArray(x0, // argument count (not including receiver)
|
||||
x2, // address of first argument
|
||||
x1); // the target callable to be call
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
x0, // argument count (not including receiver)
|
||||
x4, // address of the first argument
|
||||
x1, // constructor to call
|
||||
x3, // new target
|
||||
x2); // allocation site feedback if available, undefined otherwise
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ResumeGeneratorDescriptor::registers() {
|
||||
return RegisterArray(x0, // the value to pass to the generator
|
||||
x1); // the JSGeneratorObject to resume
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto FrameDropperTrampolineDescriptor::registers() {
|
||||
return RegisterArray(x1); // loaded new FP
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RunMicrotasksEntryDescriptor::registers() {
|
||||
return RegisterArray(x0, x1);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_ARM64
|
||||
|
||||
#endif // V8_CODEGEN_ARM64_INTERFACE_DESCRIPTORS_ARM64_INL_H_
|
@ -1,310 +0,0 @@
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#if V8_TARGET_ARCH_ARM64
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
|
||||
#include "src/execution/frames.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
const Register CallInterfaceDescriptor::ContextRegister() { return cp; }
|
||||
|
||||
void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data, int register_parameter_count) {
|
||||
const Register default_stub_registers[] = {x0, x1, x2, x3, x4};
|
||||
CHECK_LE(static_cast<size_t>(register_parameter_count),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(register_parameter_count,
|
||||
default_stub_registers);
|
||||
}
|
||||
|
||||
void RecordWriteDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
const Register default_stub_registers[] = {x0, x1, x2, x3, x4};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void DynamicCheckMapsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register default_stub_registers[] = {x0, x1, x2, x3, cp};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void EphemeronKeyBarrierDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
const Register default_stub_registers[] = {x0, x1, x2, x3, x4};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
const Register LoadDescriptor::ReceiverRegister() { return x1; }
|
||||
const Register LoadDescriptor::NameRegister() { return x2; }
|
||||
const Register LoadDescriptor::SlotRegister() { return x0; }
|
||||
|
||||
const Register LoadWithVectorDescriptor::VectorRegister() { return x3; }
|
||||
|
||||
const Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return x4;
|
||||
}
|
||||
|
||||
const Register StoreDescriptor::ReceiverRegister() { return x1; }
|
||||
const Register StoreDescriptor::NameRegister() { return x2; }
|
||||
const Register StoreDescriptor::ValueRegister() { return x0; }
|
||||
const Register StoreDescriptor::SlotRegister() { return x4; }
|
||||
|
||||
const Register StoreWithVectorDescriptor::VectorRegister() { return x3; }
|
||||
|
||||
const Register StoreTransitionDescriptor::SlotRegister() { return x4; }
|
||||
const Register StoreTransitionDescriptor::VectorRegister() { return x3; }
|
||||
const Register StoreTransitionDescriptor::MapRegister() { return x5; }
|
||||
|
||||
const Register ApiGetterDescriptor::HolderRegister() { return x0; }
|
||||
const Register ApiGetterDescriptor::CallbackRegister() { return x3; }
|
||||
|
||||
const Register GrowArrayElementsDescriptor::ObjectRegister() { return x0; }
|
||||
const Register GrowArrayElementsDescriptor::KeyRegister() { return x3; }
|
||||
|
||||
const Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() { return x3; }
|
||||
const Register BaselineLeaveFrameDescriptor::WeightRegister() { return x4; }
|
||||
|
||||
// static
|
||||
const Register TypeConversionDescriptor::ArgumentRegister() { return x0; }
|
||||
|
||||
void TypeofDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {x3};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
Register registers[] = {x1, x0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x4 : arguments list length (untagged)
|
||||
// x2 : arguments list (FixedArray)
|
||||
Register registers[] = {x1, x0, x4, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
// x2: start index (to supported rest parameters)
|
||||
Register registers[] = {x1, x0, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallFunctionTemplateDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1 : function template info
|
||||
// x2 : number of arguments (on the stack, not including receiver)
|
||||
Register registers[] = {x1, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x2 : the object to spread
|
||||
Register registers[] = {x1, x0, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1 : the target to call
|
||||
// x2 : the arguments list
|
||||
Register registers[] = {x1, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x3 : the new target
|
||||
// x4 : arguments list length (untagged)
|
||||
// x2 : arguments list (FixedArray)
|
||||
Register registers[] = {x1, x3, x0, x4, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x3: new target
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
// x2: start index (to supported rest parameters)
|
||||
Register registers[] = {x1, x3, x0, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x0 : number of arguments (on the stack, not including receiver)
|
||||
// x1 : the target to call
|
||||
// x3 : the new target
|
||||
// x2 : the object to spread
|
||||
Register registers[] = {x1, x3, x0, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1 : the target to call
|
||||
// x3 : the new target
|
||||
// x2 : the arguments list
|
||||
Register registers[] = {x1, x3, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructStubDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x3: new target
|
||||
// x1: target
|
||||
// x0: number of arguments
|
||||
// x2: allocation site or undefined
|
||||
Register registers[] = {x1, x3, x0, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void AbortDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {x1};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CompareDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
Register registers[] = {x1, x0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void Compare_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
// x2: feedback slot
|
||||
Register registers[] = {x1, x0, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
Register registers[] = {x1, x0};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOp_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// x1: left operand
|
||||
// x0: right operand
|
||||
// x2: feedback slot
|
||||
Register registers[] = {x1, x0, x2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
x1, // kApiFunctionAddress
|
||||
x2, // kArgc
|
||||
x3, // kCallData
|
||||
x0, // kHolder
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
x0, // argument count (not including receiver)
|
||||
x2, // address of first argument
|
||||
x1 // the target callable to be call
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
x0, // argument count (not including receiver)
|
||||
x4, // address of the first argument
|
||||
x1, // constructor to call
|
||||
x3, // new target
|
||||
x2, // allocation site feedback if available, undefined otherwise
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
x0, // the value to pass to the generator
|
||||
x1 // the JSGeneratorObject to resume
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
x1, // loaded new FP
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void RunMicrotasksEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {x0, x1};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_ARM64
|
@ -10,6 +10,7 @@
|
||||
#include "src/codegen/callable.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/external-reference-table.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/macro-assembler-inl.h"
|
||||
#include "src/codegen/register-configuration.h"
|
||||
#include "src/codegen/reloc-info.h"
|
||||
|
272
src/codegen/ia32/interface-descriptors-ia32-inl.h
Normal file
272
src/codegen/ia32/interface-descriptors-ia32-inl.h
Normal file
@ -0,0 +1,272 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_
|
||||
#define V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
|
||||
auto registers = RegisterArray(eax, ecx, edx, edi);
|
||||
STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
|
||||
return registers;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RecordWriteDescriptor::registers() {
|
||||
return RegisterArray(ecx, edx, esi, edi, kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto DynamicCheckMapsDescriptor::registers() {
|
||||
return RegisterArray(eax, ecx, edx, edi, esi);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
|
||||
return RegisterArray(ecx, edx, esi, edi, kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register LoadDescriptor::ReceiverRegister() { return edx; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::NameRegister() { return ecx; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::SlotRegister() { return eax; }
|
||||
|
||||
// static
|
||||
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return no_reg; }
|
||||
|
||||
// static
|
||||
constexpr Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return edi;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ReceiverRegister() { return edx; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::NameRegister() { return ecx; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ValueRegister() { return no_reg; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::SlotRegister() { return no_reg; }
|
||||
|
||||
// static
|
||||
constexpr Register StoreWithVectorDescriptor::VectorRegister() {
|
||||
return no_reg;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register StoreTransitionDescriptor::MapRegister() { return edi; }
|
||||
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::HolderRegister() { return ecx; }
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::CallbackRegister() { return eax; }
|
||||
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return ecx; }
|
||||
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
|
||||
return esi;
|
||||
}
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
|
||||
return edi;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return eax; }
|
||||
|
||||
// static
|
||||
constexpr auto TypeofDescriptor::registers() { return RegisterArray(ecx); }
|
||||
|
||||
// static
|
||||
constexpr auto CallTrampolineDescriptor::registers() {
|
||||
// eax : number of arguments
|
||||
// edi : the target to call
|
||||
return RegisterArray(edi, eax);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallVarargsDescriptor::registers() {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// ecx : arguments list length (untagged)
|
||||
// On the stack : arguments list (FixedArray)
|
||||
return RegisterArray(edi, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallForwardVarargsDescriptor::registers() {
|
||||
// eax : number of arguments
|
||||
// ecx : start index (to support rest parameters)
|
||||
// edi : the target to call
|
||||
return RegisterArray(edi, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallFunctionTemplateDescriptor::registers() {
|
||||
// edx : function template info
|
||||
// ecx : number of arguments (on the stack, not including receiver)
|
||||
return RegisterArray(edx, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithSpreadDescriptor::registers() {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// ecx : the object to spread
|
||||
return RegisterArray(edi, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithArrayLikeDescriptor::registers() {
|
||||
// edi : the target to call
|
||||
// edx : the arguments list
|
||||
return RegisterArray(edi, edx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructVarargsDescriptor::registers() {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// edx : the new target
|
||||
// ecx : arguments list length (untagged)
|
||||
// On the stack : arguments list (FixedArray)
|
||||
return RegisterArray(edi, edx, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructForwardVarargsDescriptor::registers() {
|
||||
// eax : number of arguments
|
||||
// edx : the new target
|
||||
// ecx : start index (to support rest parameters)
|
||||
// edi : the target to call
|
||||
return RegisterArray(edi, edx, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithSpreadDescriptor::registers() {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// edx : the new target
|
||||
// ecx : the object to spread
|
||||
return RegisterArray(edi, edx, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
|
||||
// edi : the target to call
|
||||
// edx : the new target
|
||||
// ecx : the arguments list
|
||||
return RegisterArray(edi, edx, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructStubDescriptor::registers() {
|
||||
// eax : number of arguments
|
||||
// edx : the new target
|
||||
// edi : the target to call
|
||||
// ecx : allocation site or undefined
|
||||
// TODO(jgruber): Remove the unused allocation site parameter.
|
||||
return RegisterArray(edi, edx, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto AbortDescriptor::registers() { return RegisterArray(edx); }
|
||||
|
||||
// static
|
||||
constexpr auto CompareDescriptor::registers() {
|
||||
return RegisterArray(edx, eax);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto Compare_BaselineDescriptor::registers() {
|
||||
return RegisterArray(edx, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOpDescriptor::registers() {
|
||||
return RegisterArray(edx, eax);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOp_BaselineDescriptor::registers() {
|
||||
return RegisterArray(edx, eax, ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ApiCallbackDescriptor::registers() {
|
||||
return RegisterArray(edx, // kApiFunctionAddress
|
||||
ecx, // kArgc
|
||||
eax, // kCallData
|
||||
edi); // kHolder
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterDispatchDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
|
||||
return RegisterArray(eax, // argument count (not including receiver)
|
||||
ecx, // address of first argument
|
||||
edi); // the target callable to be call
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
|
||||
return RegisterArray(eax, // argument count (not including receiver)
|
||||
ecx); // address of first argument
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ResumeGeneratorDescriptor::registers() {
|
||||
return RegisterArray(eax, // the value to pass to the generator
|
||||
edx); // the JSGeneratorObject to resume
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto FrameDropperTrampolineDescriptor::registers() {
|
||||
return RegisterArray(eax); // loaded new FP
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RunMicrotasksEntryDescriptor::registers() {
|
||||
return RegisterArray();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto WasmFloat32ToNumberDescriptor::registers() {
|
||||
// Work around using eax, whose register code is 0, and leads to the FP
|
||||
// parameter being passed via xmm0, which is not allocatable on ia32.
|
||||
return RegisterArray(ecx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto WasmFloat64ToNumberDescriptor::registers() {
|
||||
// Work around using eax, whose register code is 0, and leads to the FP
|
||||
// parameter being passed via xmm0, which is not allocatable on ia32.
|
||||
return RegisterArray(ecx);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_IA32
|
||||
|
||||
#endif // V8_CODEGEN_IA32_INTERFACE_DESCRIPTORS_IA32_INL_H_
|
@ -1,318 +0,0 @@
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
|
||||
#include "src/execution/frames.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
const Register CallInterfaceDescriptor::ContextRegister() { return esi; }
|
||||
|
||||
void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data, int register_parameter_count) {
|
||||
constexpr Register default_stub_registers[] = {eax, ecx, edx, edi};
|
||||
STATIC_ASSERT(arraysize(default_stub_registers) == kMaxBuiltinRegisterParams);
|
||||
CHECK_LE(static_cast<size_t>(register_parameter_count),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(register_parameter_count,
|
||||
default_stub_registers);
|
||||
}
|
||||
|
||||
void RecordWriteDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
static const Register default_stub_registers[] = {ecx, edx, esi, edi,
|
||||
kReturnRegister0};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void DynamicCheckMapsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register default_stub_registers[] = {eax, ecx, edx, edi, esi};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void EphemeronKeyBarrierDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
static const Register default_stub_registers[] = {ecx, edx, esi, edi,
|
||||
kReturnRegister0};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
const Register LoadDescriptor::ReceiverRegister() { return edx; }
|
||||
const Register LoadDescriptor::NameRegister() { return ecx; }
|
||||
const Register LoadDescriptor::SlotRegister() { return eax; }
|
||||
|
||||
const Register LoadWithVectorDescriptor::VectorRegister() { return no_reg; }
|
||||
|
||||
const Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return edi;
|
||||
}
|
||||
|
||||
const Register StoreDescriptor::ReceiverRegister() { return edx; }
|
||||
const Register StoreDescriptor::NameRegister() { return ecx; }
|
||||
const Register StoreDescriptor::ValueRegister() { return no_reg; }
|
||||
const Register StoreDescriptor::SlotRegister() { return no_reg; }
|
||||
|
||||
const Register StoreWithVectorDescriptor::VectorRegister() { return no_reg; }
|
||||
|
||||
const Register StoreTransitionDescriptor::SlotRegister() { return no_reg; }
|
||||
const Register StoreTransitionDescriptor::VectorRegister() { return no_reg; }
|
||||
const Register StoreTransitionDescriptor::MapRegister() { return edi; }
|
||||
|
||||
const Register ApiGetterDescriptor::HolderRegister() { return ecx; }
|
||||
const Register ApiGetterDescriptor::CallbackRegister() { return eax; }
|
||||
|
||||
const Register GrowArrayElementsDescriptor::ObjectRegister() { return eax; }
|
||||
const Register GrowArrayElementsDescriptor::KeyRegister() { return ecx; }
|
||||
|
||||
const Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
|
||||
return esi;
|
||||
}
|
||||
const Register BaselineLeaveFrameDescriptor::WeightRegister() { return edi; }
|
||||
|
||||
// static
|
||||
const Register TypeConversionDescriptor::ArgumentRegister() { return eax; }
|
||||
|
||||
void TypeofDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments
|
||||
// edi : the target to call
|
||||
Register registers[] = {edi, eax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// ecx : arguments list length (untagged)
|
||||
// On the stack : arguments list (FixedArray)
|
||||
Register registers[] = {edi, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments
|
||||
// ecx : start index (to support rest parameters)
|
||||
// edi : the target to call
|
||||
Register registers[] = {edi, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallFunctionTemplateDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// edx : function template info
|
||||
// ecx : number of arguments (on the stack, not including receiver)
|
||||
Register registers[] = {edx, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// ecx : the object to spread
|
||||
Register registers[] = {edi, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// edi : the target to call
|
||||
// edx : the arguments list
|
||||
Register registers[] = {edi, edx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// edx : the new target
|
||||
// ecx : arguments list length (untagged)
|
||||
// On the stack : arguments list (FixedArray)
|
||||
Register registers[] = {edi, edx, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments
|
||||
// edx : the new target
|
||||
// ecx : start index (to support rest parameters)
|
||||
// edi : the target to call
|
||||
Register registers[] = {edi, edx, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments (on the stack, not including receiver)
|
||||
// edi : the target to call
|
||||
// edx : the new target
|
||||
// ecx : the object to spread
|
||||
Register registers[] = {edi, edx, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// edi : the target to call
|
||||
// edx : the new target
|
||||
// ecx : the arguments list
|
||||
Register registers[] = {edi, edx, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructStubDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// eax : number of arguments
|
||||
// edx : the new target
|
||||
// edi : the target to call
|
||||
// ecx : allocation site or undefined
|
||||
// TODO(jgruber): Remove the unused allocation site parameter.
|
||||
Register registers[] = {edi, edx, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void AbortDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {edx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CompareDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {edx, eax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void Compare_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {edx, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {edx, eax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOp_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {edx, eax, ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
edx, // kApiFunctionAddress
|
||||
ecx, // kArgc
|
||||
eax, // kCallData
|
||||
edi, // kHolder
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
eax, // argument count (not including receiver)
|
||||
ecx, // address of first argument
|
||||
edi // the target callable to be call
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
eax, // argument count (not including receiver)
|
||||
ecx, // address of first argument
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
eax, // the value to pass to the generator
|
||||
edx // the JSGeneratorObject to resume
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
eax, // loaded new FP
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void RunMicrotasksEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
void WasmFloat32ToNumberDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// Work around using eax, whose register code is 0, and leads to the FP
|
||||
// parameter being passed via xmm0, which is not allocatable on ia32.
|
||||
Register registers[] = {ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void WasmFloat64ToNumberDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// Work around using eax, whose register code is 0, and leads to the FP
|
||||
// parameter being passed via xmm0, which is not allocatable on ia32.
|
||||
Register registers[] = {ecx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_IA32
|
@ -19,7 +19,7 @@
|
||||
#include "src/codegen/external-reference.h"
|
||||
#include "src/codegen/ia32/assembler-ia32.h"
|
||||
#include "src/codegen/ia32/register-ia32.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/label.h"
|
||||
#include "src/codegen/macro-assembler.h"
|
||||
#include "src/codegen/register.h"
|
||||
|
471
src/codegen/interface-descriptors-inl.h
Normal file
471
src/codegen/interface-descriptors-inl.h
Normal file
@ -0,0 +1,471 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_CODEGEN_INTERFACE_DESCRIPTORS_INL_H_
|
||||
#define V8_CODEGEN_INTERFACE_DESCRIPTORS_INL_H_
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/register-arch.h"
|
||||
|
||||
#if V8_TARGET_ARCH_X64
|
||||
#include "src/codegen/x64/interface-descriptors-x64-inl.h"
|
||||
#elif V8_TARGET_ARCH_ARM64
|
||||
#include "src/codegen/arm64/interface-descriptors-arm64-inl.h"
|
||||
#elif V8_TARGET_ARCH_IA32
|
||||
#include "src/codegen/ia32/interface-descriptors-ia32-inl.h"
|
||||
#elif V8_TARGET_ARCH_ARM
|
||||
#include "src/codegen/arm/interface-descriptors-arm-inl.h"
|
||||
#else
|
||||
#error Unsupported target architecture.
|
||||
#endif
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
// static
|
||||
constexpr std::array<Register, kJSBuiltinRegisterParams>
|
||||
CallInterfaceDescriptor::DefaultJSRegisterArray() {
|
||||
return RegisterArray(
|
||||
kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
|
||||
kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register);
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename DerivedDescriptor>
|
||||
constexpr auto StaticCallInterfaceDescriptor<DerivedDescriptor>::registers() {
|
||||
return CallInterfaceDescriptor::DefaultRegisterArray();
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename DerivedDescriptor>
|
||||
constexpr auto StaticJSCallInterfaceDescriptor<DerivedDescriptor>::registers() {
|
||||
return CallInterfaceDescriptor::DefaultJSRegisterArray();
|
||||
}
|
||||
|
||||
template <typename DerivedDescriptor>
|
||||
void StaticCallInterfaceDescriptor<DerivedDescriptor>::Initialize(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// Static local copy of the Registers array, for platform-specific
|
||||
// initialization
|
||||
static auto registers = DerivedDescriptor::registers();
|
||||
|
||||
// The passed pointer should be a modifiable pointer to our own data.
|
||||
DCHECK_EQ(data, this->data());
|
||||
DCHECK(!data->IsInitialized());
|
||||
|
||||
if (DerivedDescriptor::kRestrictAllocatableRegisters) {
|
||||
data->RestrictAllocatableRegisters(registers.data(), registers.size());
|
||||
}
|
||||
|
||||
data->InitializeRegisters(
|
||||
DerivedDescriptor::flags(), DerivedDescriptor::kReturnCount,
|
||||
DerivedDescriptor::GetParameterCount(),
|
||||
DerivedDescriptor::kStackArgumentOrder,
|
||||
DerivedDescriptor::GetRegisterParameterCount(), registers.data());
|
||||
|
||||
// InitializeTypes is customizable by the DerivedDescriptor subclass.
|
||||
DerivedDescriptor::InitializeTypes(data);
|
||||
|
||||
DCHECK(data->IsInitialized());
|
||||
DCHECK(this->CheckFloatingPointParameters(data));
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename DerivedDescriptor>
|
||||
constexpr int
|
||||
StaticCallInterfaceDescriptor<DerivedDescriptor>::GetReturnCount() {
|
||||
static_assert(
|
||||
DerivedDescriptor::kReturnCount >= 0,
|
||||
"DerivedDescriptor subclass should override return count with a value "
|
||||
"that is greater than 0");
|
||||
|
||||
return DerivedDescriptor::kReturnCount;
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename DerivedDescriptor>
|
||||
constexpr int
|
||||
StaticCallInterfaceDescriptor<DerivedDescriptor>::GetParameterCount() {
|
||||
static_assert(
|
||||
DerivedDescriptor::kParameterCount >= 0,
|
||||
"DerivedDescriptor subclass should override parameter count with a "
|
||||
"value that is greater than 0");
|
||||
|
||||
return DerivedDescriptor::kParameterCount;
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Helper trait for statically checking if a type is a std::array<Register,N>.
|
||||
template <typename T>
|
||||
struct IsRegisterArray : std::false_type {};
|
||||
template <int i>
|
||||
struct IsRegisterArray<std::array<Register, i>> : std::true_type {};
|
||||
template <>
|
||||
struct IsRegisterArray<EmptyRegisterArray> : std::true_type {};
|
||||
|
||||
// Helper for finding the index of the first invalid register in a register
|
||||
// array.
|
||||
template <size_t N, size_t Index>
|
||||
struct FirstInvalidRegisterHelper {
|
||||
static constexpr int Call(std::array<Register, N> regs) {
|
||||
if (!std::get<Index>(regs).is_valid()) {
|
||||
// All registers after the first invalid one have to also be invalid (this
|
||||
// DCHECK will be checked recursively).
|
||||
CONSTEXPR_DCHECK((FirstInvalidRegisterHelper<N, Index + 1>::Call(regs)) ==
|
||||
Index + 1);
|
||||
return Index;
|
||||
}
|
||||
return FirstInvalidRegisterHelper<N, Index + 1>::Call(regs);
|
||||
}
|
||||
};
|
||||
template <size_t N>
|
||||
struct FirstInvalidRegisterHelper<N, N> {
|
||||
static constexpr int Call(std::array<Register, N> regs) { return N; }
|
||||
};
|
||||
template <size_t N, size_t Index = 0>
|
||||
constexpr size_t FirstInvalidRegister(std::array<Register, N> regs) {
|
||||
return FirstInvalidRegisterHelper<N, 0>::Call(regs);
|
||||
}
|
||||
constexpr size_t FirstInvalidRegister(EmptyRegisterArray regs) { return 0; }
|
||||
|
||||
} // namespace detail
|
||||
|
||||
// static
|
||||
template <typename DerivedDescriptor>
|
||||
constexpr int
|
||||
StaticCallInterfaceDescriptor<DerivedDescriptor>::GetRegisterParameterCount() {
|
||||
static_assert(
|
||||
detail::IsRegisterArray<decltype(DerivedDescriptor::registers())>::value,
|
||||
"DerivedDescriptor subclass should define a registers() function "
|
||||
"returning a std::array<Register>");
|
||||
|
||||
// The register parameter count is the minimum of:
|
||||
// 1. The number of named parameters in the descriptor, and
|
||||
// 2. The number of valid registers the descriptor provides with its
|
||||
// registers() function, e.g. for {rax, rbx, no_reg} this number is 2.
|
||||
// 3. The maximum number of register parameters allowed (
|
||||
// kMaxBuiltinRegisterParams for most builtins,
|
||||
// kMaxTFSBuiltinRegisterParams for TFS builtins, customizable by the
|
||||
// subclass otherwise).
|
||||
return std::min<int>({DerivedDescriptor::GetParameterCount(),
|
||||
static_cast<int>(detail::FirstInvalidRegister(
|
||||
DerivedDescriptor::registers())),
|
||||
DerivedDescriptor::kMaxRegisterParams});
|
||||
}
|
||||
|
||||
// static
|
||||
template <typename DerivedDescriptor>
|
||||
constexpr int
|
||||
StaticCallInterfaceDescriptor<DerivedDescriptor>::GetStackParameterCount() {
|
||||
return DerivedDescriptor::GetParameterCount() -
|
||||
DerivedDescriptor::GetRegisterParameterCount();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register FastNewObjectDescriptor::TargetRegister() {
|
||||
return kJSFunctionRegister;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register FastNewObjectDescriptor::NewTargetRegister() {
|
||||
return kJavaScriptCallNewTargetRegister;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::ReceiverRegister() {
|
||||
return LoadDescriptor::ReceiverRegister();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register LoadGlobalNoFeedbackDescriptor::ICKindRegister() {
|
||||
return LoadDescriptor::SlotRegister();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register LoadNoFeedbackDescriptor::ICKindRegister() {
|
||||
return LoadGlobalNoFeedbackDescriptor::ICKindRegister();
|
||||
}
|
||||
|
||||
#if V8_TARGET_ARCH_IA32
|
||||
// On ia32, LoadWithVectorDescriptor passes vector on the stack and thus we
|
||||
// need to choose a new register here.
|
||||
// static
|
||||
constexpr Register LoadGlobalWithVectorDescriptor::VectorRegister() {
|
||||
STATIC_ASSERT(!LoadWithVectorDescriptor::VectorRegister().is_valid());
|
||||
return LoadDescriptor::ReceiverRegister();
|
||||
}
|
||||
#else
|
||||
// static
|
||||
constexpr Register LoadGlobalWithVectorDescriptor::VectorRegister() {
|
||||
return LoadWithVectorDescriptor::VectorRegister();
|
||||
}
|
||||
#endif
|
||||
|
||||
// static
|
||||
constexpr auto LoadDescriptor::registers() {
|
||||
return RegisterArray(ReceiverRegister(), NameRegister(), SlotRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadBaselineDescriptor::registers() {
|
||||
return LoadDescriptor::registers();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadGlobalDescriptor::registers() {
|
||||
return RegisterArray(LoadDescriptor::NameRegister(),
|
||||
LoadDescriptor::SlotRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadGlobalBaselineDescriptor::registers() {
|
||||
return LoadGlobalDescriptor::registers();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto StoreDescriptor::registers() {
|
||||
return RegisterArray(ReceiverRegister(), NameRegister(), ValueRegister(),
|
||||
SlotRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto StoreBaselineDescriptor::registers() {
|
||||
return StoreDescriptor::registers();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto StoreGlobalDescriptor::registers() {
|
||||
return RegisterArray(StoreDescriptor::NameRegister(),
|
||||
StoreDescriptor::ValueRegister(),
|
||||
StoreDescriptor::SlotRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto StoreGlobalBaselineDescriptor::registers() {
|
||||
return StoreGlobalDescriptor::registers();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadWithReceiverBaselineDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
LoadDescriptor::ReceiverRegister(),
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister(),
|
||||
LoadDescriptor::NameRegister(), LoadDescriptor::SlotRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BaselineOutOfLinePrologueDescriptor::registers() {
|
||||
// TODO(v8:11421): Implement on other platforms.
|
||||
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 || \
|
||||
V8_TARGET_ARCH_ARM
|
||||
return RegisterArray(
|
||||
kContextRegister, kJSFunctionRegister, kJavaScriptCallArgCountRegister,
|
||||
kJavaScriptCallExtraArg1Register, kJavaScriptCallNewTargetRegister,
|
||||
kInterpreterBytecodeArrayRegister);
|
||||
#else
|
||||
return DefaultRegisterArray();
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BaselineLeaveFrameDescriptor::registers() {
|
||||
// TODO(v8:11421): Implement on other platforms.
|
||||
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || \
|
||||
V8_TARGET_ARCH_ARM
|
||||
return RegisterArray(ParamsSizeRegister(), WeightRegister());
|
||||
#else
|
||||
return DefaultRegisterArray();
|
||||
#endif
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto VoidDescriptor::registers() { return RegisterArray(); }
|
||||
|
||||
// static
|
||||
constexpr auto AllocateDescriptor::registers() {
|
||||
return RegisterArray(kAllocateSizeRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CEntry1ArgvOnStackDescriptor::registers() {
|
||||
return RegisterArray(kRuntimeCallArgCountRegister,
|
||||
kRuntimeCallFunctionRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterCEntry1Descriptor::registers() {
|
||||
return RegisterArray(kRuntimeCallArgCountRegister, kRuntimeCallArgvRegister,
|
||||
kRuntimeCallFunctionRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterCEntry2Descriptor::registers() {
|
||||
return RegisterArray(kRuntimeCallArgCountRegister, kRuntimeCallArgvRegister,
|
||||
kRuntimeCallFunctionRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto FastNewObjectDescriptor::registers() {
|
||||
return RegisterArray(TargetRegister(), NewTargetRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto TailCallOptimizedCodeSlotDescriptor::registers() {
|
||||
return RegisterArray(kJavaScriptCallCodeStartRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadNoFeedbackDescriptor::registers() {
|
||||
return RegisterArray(LoadDescriptor::ReceiverRegister(),
|
||||
LoadDescriptor::NameRegister(), ICKindRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadGlobalNoFeedbackDescriptor::registers() {
|
||||
return RegisterArray(LoadDescriptor::NameRegister(), ICKindRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadGlobalWithVectorDescriptor::registers() {
|
||||
return RegisterArray(LoadDescriptor::NameRegister(),
|
||||
LoadDescriptor::SlotRegister(), VectorRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadWithReceiverAndVectorDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
LoadDescriptor::ReceiverRegister(), LookupStartObjectRegister(),
|
||||
LoadDescriptor::NameRegister(), LoadDescriptor::SlotRegister(),
|
||||
LoadWithVectorDescriptor::VectorRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto StoreGlobalWithVectorDescriptor::registers() {
|
||||
return RegisterArray(StoreDescriptor::NameRegister(),
|
||||
StoreDescriptor::ValueRegister(),
|
||||
StoreDescriptor::SlotRegister(),
|
||||
StoreWithVectorDescriptor::VectorRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto StoreTransitionDescriptor::registers() {
|
||||
return RegisterArray(StoreDescriptor::ReceiverRegister(),
|
||||
StoreDescriptor::NameRegister(), MapRegister(),
|
||||
StoreDescriptor::ValueRegister(),
|
||||
StoreDescriptor::SlotRegister(),
|
||||
StoreWithVectorDescriptor::VectorRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto TypeConversionDescriptor::registers() {
|
||||
return RegisterArray(ArgumentRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto TypeConversionNoContextDescriptor::registers() {
|
||||
return RegisterArray(TypeConversionDescriptor::ArgumentRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto SingleParameterOnStackDescriptor::registers() {
|
||||
return RegisterArray();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto AsyncFunctionStackParameterDescriptor::registers() {
|
||||
return RegisterArray();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto GetIteratorStackParameterDescriptor::registers() {
|
||||
return RegisterArray();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto LoadWithVectorDescriptor::registers() {
|
||||
return RegisterArray(LoadDescriptor::ReceiverRegister(),
|
||||
LoadDescriptor::NameRegister(),
|
||||
LoadDescriptor::SlotRegister(), VectorRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto StoreWithVectorDescriptor::registers() {
|
||||
return RegisterArray(StoreDescriptor::ReceiverRegister(),
|
||||
StoreDescriptor::NameRegister(),
|
||||
StoreDescriptor::ValueRegister(),
|
||||
StoreDescriptor::SlotRegister(), VectorRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ApiGetterDescriptor::registers() {
|
||||
return RegisterArray(ReceiverRegister(), HolderRegister(),
|
||||
CallbackRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ContextOnlyDescriptor::registers() { return RegisterArray(); }
|
||||
|
||||
// static
|
||||
constexpr auto NoContextDescriptor::registers() { return RegisterArray(); }
|
||||
|
||||
// static
|
||||
constexpr auto GrowArrayElementsDescriptor::registers() {
|
||||
return RegisterArray(ObjectRegister(), KeyRegister());
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ArrayNArgumentsConstructorDescriptor::registers() {
|
||||
// Keep the arguments on the same registers as they were in
|
||||
// ArrayConstructorDescriptor to avoid unnecessary register moves.
|
||||
// kFunction, kAllocationSite, kActualArgumentsCount
|
||||
return RegisterArray(kJavaScriptCallTargetRegister,
|
||||
kJavaScriptCallExtraArg1Register,
|
||||
kJavaScriptCallArgCountRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ArrayNoArgumentConstructorDescriptor::registers() {
|
||||
// This descriptor must use the same set of registers as the
|
||||
// ArrayNArgumentsConstructorDescriptor.
|
||||
return ArrayNArgumentsConstructorDescriptor::registers();
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ArraySingleArgumentConstructorDescriptor::registers() {
|
||||
// This descriptor must use the same set of registers as the
|
||||
// ArrayNArgumentsConstructorDescriptor.
|
||||
return ArrayNArgumentsConstructorDescriptor::registers();
|
||||
}
|
||||
|
||||
// static
|
||||
// static
|
||||
constexpr Register RunMicrotasksDescriptor::MicrotaskQueueRegister() {
|
||||
return GetRegisterParameter(0);
|
||||
}
|
||||
|
||||
#define DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER(Name, DescriptorName) \
|
||||
template <> \
|
||||
struct CallInterfaceDescriptorFor<Builtins::k##Name> { \
|
||||
using type = DescriptorName##Descriptor; \
|
||||
};
|
||||
BUILTIN_LIST(IGNORE_BUILTIN, IGNORE_BUILTIN,
|
||||
/*TFC*/ DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER, IGNORE_BUILTIN,
|
||||
/*TFH*/ DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER, IGNORE_BUILTIN,
|
||||
/*ASM*/ DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER)
|
||||
#undef DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER
|
||||
#define DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER(Name, ...) \
|
||||
template <> \
|
||||
struct CallInterfaceDescriptorFor<Builtins::k##Name> { \
|
||||
using type = Name##Descriptor; \
|
||||
};
|
||||
BUILTIN_LIST_TFS(DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER)
|
||||
#undef DEFINE_STATIC_BUILTIN_DESCRIPTOR_GETTER
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_CODEGEN_INTERFACE_DESCRIPTORS_INL_H_
|
@ -4,49 +4,48 @@
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/macro-assembler.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
void CallInterfaceDescriptorData::InitializePlatformSpecific(
|
||||
int register_parameter_count, const Register* registers) {
|
||||
DCHECK(!IsInitializedPlatformIndependent());
|
||||
|
||||
register_param_count_ = register_parameter_count;
|
||||
|
||||
// UBSan doesn't like creating zero-length arrays.
|
||||
if (register_parameter_count == 0) return;
|
||||
|
||||
// InterfaceDescriptor owns a copy of the registers array.
|
||||
register_params_ = NewArray<Register>(register_parameter_count, no_reg);
|
||||
for (int i = 0; i < register_parameter_count; i++) {
|
||||
// The value of the root register must be reserved, thus any uses
|
||||
// within the calling convention are disallowed.
|
||||
#ifdef DEBUG
|
||||
CHECK_NE(registers[i], kRootRegister);
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
CHECK_NE(registers[i], kPtrComprCageBaseRegister);
|
||||
#endif
|
||||
// Check for duplicated registers.
|
||||
for (int j = i + 1; j < register_parameter_count; j++) {
|
||||
CHECK_NE(registers[i], registers[j]);
|
||||
}
|
||||
#endif
|
||||
register_params_[i] = registers[i];
|
||||
}
|
||||
}
|
||||
|
||||
void CallInterfaceDescriptorData::InitializePlatformIndependent(
|
||||
void CallInterfaceDescriptorData::InitializeRegisters(
|
||||
Flags flags, int return_count, int parameter_count,
|
||||
const MachineType* machine_types, int machine_types_length,
|
||||
StackArgumentOrder stack_order) {
|
||||
DCHECK(IsInitializedPlatformSpecific());
|
||||
StackArgumentOrder stack_order, int register_parameter_count,
|
||||
const Register* registers) {
|
||||
DCHECK(!IsInitializedTypes());
|
||||
|
||||
#ifdef DEBUG
|
||||
{
|
||||
// Make sure that the registers are all valid, and don't alias each other.
|
||||
RegList reglist = 0;
|
||||
for (int i = 0; i < register_parameter_count; ++i) {
|
||||
Register reg = registers[i];
|
||||
DCHECK(reg.is_valid());
|
||||
DCHECK_EQ(reglist & reg.bit(), 0);
|
||||
DCHECK_NE(reg, kRootRegister);
|
||||
#ifdef V8_COMPRESS_POINTERS_IN_SHARED_CAGE
|
||||
DCHECK_NE(reg, kPtrComprCageBaseRegister);
|
||||
#endif
|
||||
reglist = CombineRegLists(reglist, reg.bit());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
flags_ = flags;
|
||||
stack_order_ = stack_order;
|
||||
return_count_ = return_count;
|
||||
param_count_ = parameter_count;
|
||||
register_param_count_ = register_parameter_count;
|
||||
|
||||
// The caller owns the the registers array, so we just set the pointer.
|
||||
register_params_ = registers;
|
||||
}
|
||||
|
||||
void CallInterfaceDescriptorData::InitializeTypes(
|
||||
const MachineType* machine_types, int machine_types_length) {
|
||||
DCHECK(IsInitializedRegisters());
|
||||
const int types_length = return_count_ + param_count_;
|
||||
|
||||
// Machine types are either fully initialized or null.
|
||||
@ -77,7 +76,6 @@ bool CallInterfaceDescriptorData::AllStackParametersAreTagged() const {
|
||||
void CallInterfaceDescriptorData::Reset() {
|
||||
delete[] machine_types_;
|
||||
machine_types_ = nullptr;
|
||||
delete[] register_params_;
|
||||
register_params_ = nullptr;
|
||||
}
|
||||
|
||||
@ -105,27 +103,6 @@ void CallDescriptors::TearDown() {
|
||||
}
|
||||
}
|
||||
|
||||
void CallInterfaceDescriptor::JSDefaultInitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data, int non_js_register_parameter_count) {
|
||||
DCHECK_LE(static_cast<unsigned>(non_js_register_parameter_count), 1);
|
||||
|
||||
// 3 is for kTarget, kNewTarget and kActualArgumentsCount
|
||||
int register_parameter_count = 3 + non_js_register_parameter_count;
|
||||
|
||||
DCHECK(!AreAliased(
|
||||
kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
|
||||
kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register));
|
||||
|
||||
const Register default_js_stub_registers[] = {
|
||||
kJavaScriptCallTargetRegister, kJavaScriptCallNewTargetRegister,
|
||||
kJavaScriptCallArgCountRegister, kJavaScriptCallExtraArg1Register};
|
||||
|
||||
CHECK_LE(static_cast<size_t>(register_parameter_count),
|
||||
arraysize(default_js_stub_registers));
|
||||
data->InitializePlatformSpecific(register_parameter_count,
|
||||
default_js_stub_registers);
|
||||
}
|
||||
|
||||
const char* CallInterfaceDescriptor::DebugName() const {
|
||||
CallDescriptors::Key key = CallDescriptors::GetKey(data_);
|
||||
switch (key) {
|
||||
@ -146,487 +123,5 @@ bool CallInterfaceDescriptor::IsValidFloatParameterRegister(Register reg) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void VoidDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
void AllocateDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {kAllocateSizeRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CEntry1ArgvOnStackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {kRuntimeCallArgCountRegister,
|
||||
kRuntimeCallFunctionRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {kRuntimeCallArgCountRegister,
|
||||
kRuntimeCallArgvRegister,
|
||||
kRuntimeCallFunctionRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
|
||||
}
|
||||
|
||||
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
|
||||
}
|
||||
|
||||
void FastNewObjectDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {TargetRegister(), NewTargetRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
const Register FastNewObjectDescriptor::TargetRegister() {
|
||||
return kJSFunctionRegister;
|
||||
}
|
||||
|
||||
const Register FastNewObjectDescriptor::NewTargetRegister() {
|
||||
return kJavaScriptCallNewTargetRegister;
|
||||
}
|
||||
|
||||
void TailCallOptimizedCodeSlotDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {kJavaScriptCallCodeStartRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LoadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LoadBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {LoadDescriptor::ReceiverRegister(),
|
||||
LoadDescriptor::NameRegister(),
|
||||
LoadDescriptor::SlotRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LoadNoFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ReceiverRegister(), NameRegister(), ICKindRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LoadGlobalDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {NameRegister(), SlotRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LoadGlobalBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {LoadGlobalDescriptor::NameRegister(),
|
||||
LoadGlobalDescriptor::SlotRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LookupBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void LoadGlobalNoFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {NameRegister(), ICKindRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LoadGlobalWithVectorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {NameRegister(), SlotRegister(), VectorRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void LoadWithReceiverAndVectorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DCHECK(!AreAliased(ReceiverRegister(), LookupStartObjectRegister(),
|
||||
NameRegister(), SlotRegister(), VectorRegister()));
|
||||
Register registers[] = {ReceiverRegister(), LookupStartObjectRegister(),
|
||||
NameRegister(), SlotRegister(), VectorRegister()};
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void LoadWithReceiverBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
LoadWithReceiverAndVectorDescriptor::ReceiverRegister(),
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister(),
|
||||
LoadWithReceiverAndVectorDescriptor::NameRegister(),
|
||||
LoadWithReceiverAndVectorDescriptor::SlotRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void StoreGlobalDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {NameRegister(), ValueRegister(), SlotRegister()};
|
||||
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void StoreGlobalBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {StoreGlobalDescriptor::NameRegister(),
|
||||
StoreGlobalDescriptor::ValueRegister(),
|
||||
StoreGlobalDescriptor::SlotRegister()};
|
||||
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void StoreGlobalWithVectorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {NameRegister(), ValueRegister(), SlotRegister(),
|
||||
VectorRegister()};
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void StoreDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
|
||||
SlotRegister()};
|
||||
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void StoreBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
StoreDescriptor::ReceiverRegister(), StoreDescriptor::NameRegister(),
|
||||
StoreDescriptor::ValueRegister(), StoreDescriptor::SlotRegister()};
|
||||
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void StoreTransitionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
ReceiverRegister(), NameRegister(), MapRegister(),
|
||||
ValueRegister(), SlotRegister(), VectorRegister(),
|
||||
};
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void BaselineOutOfLinePrologueDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// TODO(v8:11421): Implement on other platforms.
|
||||
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_IA32 || \
|
||||
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_RISCV64
|
||||
Register registers[] = {kContextRegister,
|
||||
kJSFunctionRegister,
|
||||
kJavaScriptCallArgCountRegister,
|
||||
kJavaScriptCallExtraArg1Register,
|
||||
kJavaScriptCallNewTargetRegister,
|
||||
kInterpreterBytecodeArrayRegister};
|
||||
data->InitializePlatformSpecific(kParameterCount - kStackArgumentsCount,
|
||||
registers);
|
||||
#else
|
||||
InitializePlatformUnimplemented(data, kParameterCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
void BaselineLeaveFrameDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// TODO(v8:11421): Implement on other platforms.
|
||||
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_ARM64 || \
|
||||
V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_RISCV64
|
||||
Register registers[] = {ParamsSizeRegister(), WeightRegister()};
|
||||
data->InitializePlatformSpecific(kParameterCount, registers);
|
||||
#else
|
||||
InitializePlatformUnimplemented(data, kParameterCount);
|
||||
#endif
|
||||
}
|
||||
|
||||
void StringAtDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void StringAtAsStringDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void StringSubstringDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void TypeConversionDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ArgumentRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void TypeConversionNoContextDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {TypeConversionDescriptor::ArgumentRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void TypeConversion_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void SingleParameterOnStackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
void AsyncFunctionStackParameterDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
void GetIteratorStackParameterDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
void LoadWithVectorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ReceiverRegister(), NameRegister(), SlotRegister(),
|
||||
VectorRegister()};
|
||||
// TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
|
||||
// to allow no_reg entries.
|
||||
// DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), SlotRegister(),
|
||||
// VectorRegister(), kRootRegister));
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
void StoreWithVectorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ReceiverRegister(), NameRegister(), ValueRegister(),
|
||||
SlotRegister(), VectorRegister()};
|
||||
// TODO(jgruber): This DCHECK could be enabled if RegisterBase::ListOf were
|
||||
// to allow no_reg entries.
|
||||
// DCHECK(!AreAliased(ReceiverRegister(), NameRegister(), kRootRegister));
|
||||
int len = arraysize(registers) - kStackArgumentsCount;
|
||||
data->InitializePlatformSpecific(len, registers);
|
||||
}
|
||||
|
||||
const Register ApiGetterDescriptor::ReceiverRegister() {
|
||||
return LoadDescriptor::ReceiverRegister();
|
||||
}
|
||||
|
||||
void ApiGetterDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ReceiverRegister(), HolderRegister(),
|
||||
CallbackRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ContextOnlyDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
void NoContextDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
data->InitializePlatformSpecific(0, nullptr);
|
||||
}
|
||||
|
||||
void GrowArrayElementsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {ObjectRegister(), KeyRegister()};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ArrayNoArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// This descriptor must use the same set of registers as the
|
||||
// ArrayNArgumentsConstructorDescriptor.
|
||||
ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
|
||||
}
|
||||
|
||||
void ArraySingleArgumentConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// This descriptor must use the same set of registers as the
|
||||
// ArrayNArgumentsConstructorDescriptor.
|
||||
ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(data);
|
||||
}
|
||||
|
||||
void ArrayNArgumentsConstructorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// Keep the arguments on the same registers as they were in
|
||||
// ArrayConstructorDescriptor to avoid unnecessary register moves.
|
||||
// kFunction, kAllocationSite, kActualArgumentsCount
|
||||
Register registers[] = {kJavaScriptCallTargetRegister,
|
||||
kJavaScriptCallExtraArg1Register,
|
||||
kJavaScriptCallArgCountRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
#if !V8_TARGET_ARCH_IA32
|
||||
// We need a custom descriptor on ia32 to avoid using xmm0.
|
||||
void WasmFloat32ToNumberDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
// We need a custom descriptor on ia32 to avoid using xmm0.
|
||||
void WasmFloat64ToNumberDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
#endif // !V8_TARGET_ARCH_IA32
|
||||
|
||||
#if !defined(V8_TARGET_ARCH_MIPS) && !defined(V8_TARGET_ARCH_MIPS64) && \
|
||||
!defined(V8_TARGET_ARCH_RISCV64)
|
||||
void WasmI32AtomicWait32Descriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void WasmI64AtomicWait32Descriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data,
|
||||
kParameterCount - kStackArgumentsCount);
|
||||
}
|
||||
#endif
|
||||
|
||||
void CloneObjectWithVectorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void CloneObjectBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
// static
|
||||
Register RunMicrotasksDescriptor::MicrotaskQueueRegister() {
|
||||
return CallDescriptors::call_descriptor_data(CallDescriptors::RunMicrotasks)
|
||||
->register_param(0);
|
||||
}
|
||||
|
||||
void RunMicrotasksDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void I64ToBigIntDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void I32PairToBigIntDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void BigIntToI64Descriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void BigIntToI32PairDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void BinaryOp_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 4);
|
||||
}
|
||||
|
||||
void CallTrampoline_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void CallTrampoline_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 4);
|
||||
}
|
||||
|
||||
void CallWithArrayLike_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 4);
|
||||
}
|
||||
|
||||
void CallWithSpread_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void CallWithSpread_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 4);
|
||||
}
|
||||
|
||||
void ConstructWithArrayLike_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 4);
|
||||
}
|
||||
|
||||
void ConstructWithSpread_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data,
|
||||
kParameterCount - kStackArgumentsCount);
|
||||
}
|
||||
|
||||
void ConstructWithSpread_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 4);
|
||||
}
|
||||
|
||||
void Compare_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 4);
|
||||
}
|
||||
|
||||
void UnaryOp_WithFeedbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 3);
|
||||
}
|
||||
|
||||
void UnaryOp_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, 2);
|
||||
}
|
||||
|
||||
void ForInPrepareDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void SuspendGeneratorBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
void ResumeGeneratorBaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
DefaultInitializePlatformSpecific(data, kParameterCount);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -41,6 +41,27 @@ constexpr bool ShouldPadArguments(int argument_count) {
|
||||
return ArgumentPaddingSlots(argument_count) != 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
struct CountIfValidRegisterFunctor {
|
||||
template <typename RegType>
|
||||
constexpr int operator()(int count, RegType reg) const {
|
||||
return count + (reg.is_valid() ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RegType, typename... RegTypes,
|
||||
// All arguments must be either Register or DoubleRegister.
|
||||
typename = typename std::enable_if<
|
||||
base::is_same<Register, RegType, RegTypes...>::value ||
|
||||
base::is_same<DoubleRegister, RegType, RegTypes...>::value>::type>
|
||||
inline constexpr bool AreAliased(RegType first_reg, RegTypes... regs) {
|
||||
int num_different_regs = NumRegs(RegType::ListOf(first_reg, regs...));
|
||||
int num_given_regs =
|
||||
base::fold(CountIfValidRegisterFunctor{}, 0, first_reg, regs...);
|
||||
return num_different_regs < num_given_regs;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
@ -165,27 +165,6 @@ class V8_NODISCARD HardAbortScope {
|
||||
bool old_value_;
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
struct CountIfValidRegisterFunctor {
|
||||
template <typename RegType>
|
||||
constexpr int operator()(int count, RegType reg) const {
|
||||
return count + (reg.is_valid() ? 1 : 0);
|
||||
}
|
||||
};
|
||||
|
||||
template <typename RegType, typename... RegTypes,
|
||||
// All arguments must be either Register or DoubleRegister.
|
||||
typename = typename std::enable_if<
|
||||
base::is_same<Register, RegType, RegTypes...>::value ||
|
||||
base::is_same<DoubleRegister, RegType, RegTypes...>::value>::type>
|
||||
inline bool AreAliased(RegType first_reg, RegTypes... regs) {
|
||||
int num_different_regs = NumRegs(RegType::ListOf(first_reg, regs...));
|
||||
int num_given_regs =
|
||||
base::fold(CountIfValidRegisterFunctor{}, 0, first_reg, regs...);
|
||||
return num_different_regs < num_given_regs;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
|
263
src/codegen/x64/interface-descriptors-x64-inl.h
Normal file
263
src/codegen/x64/interface-descriptors-x64-inl.h
Normal file
@ -0,0 +1,263 @@
|
||||
// Copyright 2021 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
|
||||
#define V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
|
||||
|
||||
#if V8_TARGET_ARCH_X64
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
constexpr auto CallInterfaceDescriptor::DefaultRegisterArray() {
|
||||
auto registers = RegisterArray(rax, rbx, rcx, rdx, rdi);
|
||||
STATIC_ASSERT(registers.size() == kMaxBuiltinRegisterParams);
|
||||
return registers;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RecordWriteDescriptor::registers() {
|
||||
return RegisterArray(arg_reg_1, arg_reg_2, arg_reg_3, arg_reg_4,
|
||||
kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto DynamicCheckMapsDescriptor::registers() {
|
||||
return RegisterArray(kReturnRegister0, arg_reg_1, arg_reg_2, arg_reg_3,
|
||||
kRuntimeCallFunctionRegister, kContextRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto EphemeronKeyBarrierDescriptor::registers() {
|
||||
return RegisterArray(arg_reg_1, arg_reg_2, arg_reg_3, arg_reg_4,
|
||||
kReturnRegister0);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register LoadDescriptor::ReceiverRegister() { return rdx; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::NameRegister() { return rcx; }
|
||||
// static
|
||||
constexpr Register LoadDescriptor::SlotRegister() { return rax; }
|
||||
|
||||
// static
|
||||
constexpr Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
|
||||
|
||||
// static
|
||||
constexpr Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return rdi;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ReceiverRegister() { return rdx; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::NameRegister() { return rcx; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::ValueRegister() { return rax; }
|
||||
// static
|
||||
constexpr Register StoreDescriptor::SlotRegister() { return rdi; }
|
||||
|
||||
// static
|
||||
constexpr Register StoreWithVectorDescriptor::VectorRegister() { return rbx; }
|
||||
|
||||
// static
|
||||
constexpr Register StoreTransitionDescriptor::MapRegister() { return r11; }
|
||||
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::HolderRegister() { return rcx; }
|
||||
// static
|
||||
constexpr Register ApiGetterDescriptor::CallbackRegister() { return rbx; }
|
||||
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
|
||||
// static
|
||||
constexpr Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
|
||||
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
|
||||
return rbx;
|
||||
}
|
||||
// static
|
||||
constexpr Register BaselineLeaveFrameDescriptor::WeightRegister() {
|
||||
return rcx;
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
|
||||
|
||||
// static
|
||||
constexpr auto TypeofDescriptor::registers() { return RegisterArray(rbx); }
|
||||
|
||||
// static
|
||||
constexpr auto CallTrampolineDescriptor::registers() {
|
||||
// rax : number of arguments
|
||||
// rdi : the target to call
|
||||
return RegisterArray(rdi, rax);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallVarargsDescriptor::registers() {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rcx : arguments list length (untagged)
|
||||
// rbx : arguments list (FixedArray)
|
||||
return RegisterArray(rdi, rax, rcx, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallForwardVarargsDescriptor::registers() {
|
||||
// rax : number of arguments
|
||||
// rcx : start index (to support rest parameters)
|
||||
// rdi : the target to call
|
||||
return RegisterArray(rdi, rax, rcx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallFunctionTemplateDescriptor::registers() {
|
||||
// rdx: the function template info
|
||||
// rcx: number of arguments (on the stack, not including receiver)
|
||||
return RegisterArray(rdx, rcx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithSpreadDescriptor::registers() {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rbx : the object to spread
|
||||
return RegisterArray(rdi, rax, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto CallWithArrayLikeDescriptor::registers() {
|
||||
// rdi : the target to call
|
||||
// rbx : the arguments list
|
||||
return RegisterArray(rdi, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructVarargsDescriptor::registers() {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rdx : the new target
|
||||
// rcx : arguments list length (untagged)
|
||||
// rbx : arguments list (FixedArray)
|
||||
return RegisterArray(rdi, rdx, rax, rcx, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructForwardVarargsDescriptor::registers() {
|
||||
// rax : number of arguments
|
||||
// rdx : the new target
|
||||
// rcx : start index (to support rest parameters)
|
||||
// rdi : the target to call
|
||||
return RegisterArray(rdi, rdx, rax, rcx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithSpreadDescriptor::registers() {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rdx : the new target
|
||||
// rbx : the object to spread
|
||||
return RegisterArray(rdi, rdx, rax, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructWithArrayLikeDescriptor::registers() {
|
||||
// rdi : the target to call
|
||||
// rdx : the new target
|
||||
// rbx : the arguments list
|
||||
return RegisterArray(rdi, rdx, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ConstructStubDescriptor::registers() {
|
||||
// rax : number of arguments
|
||||
// rdx : the new target
|
||||
// rdi : the target to call
|
||||
// rbx : allocation site or undefined
|
||||
return RegisterArray(rdi, rdx, rax, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto AbortDescriptor::registers() { return RegisterArray(rdx); }
|
||||
|
||||
// static
|
||||
constexpr auto CompareDescriptor::registers() {
|
||||
return RegisterArray(rdx, rax);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOpDescriptor::registers() {
|
||||
return RegisterArray(rdx, rax);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto Compare_BaselineDescriptor::registers() {
|
||||
return RegisterArray(rdx, rax, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto BinaryOp_BaselineDescriptor::registers() {
|
||||
return RegisterArray(rdx, rax, rbx);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ApiCallbackDescriptor::registers() {
|
||||
return RegisterArray(rdx, // api function address
|
||||
rcx, // argument count (not including receiver)
|
||||
rbx, // call data
|
||||
rdi); // holder
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterDispatchDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister);
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenCallDescriptor::registers() {
|
||||
return RegisterArray(rax, // argument count (not including receiver)
|
||||
rbx, // address of first argument
|
||||
rdi); // the target callable to be call
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto InterpreterPushArgsThenConstructDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
rax, // argument count (not including receiver)
|
||||
rcx, // address of first argument
|
||||
rdi, // constructor to call
|
||||
rdx, // new target
|
||||
rbx); // allocation site feedback if available, undefined otherwise
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto ResumeGeneratorDescriptor::registers() {
|
||||
return RegisterArray(
|
||||
rax, // the value to pass to the generator
|
||||
rdx); // the JSGeneratorObject / JSAsyncGeneratorObject to resume
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto FrameDropperTrampolineDescriptor::registers() {
|
||||
return RegisterArray(rbx); // loaded new FP
|
||||
}
|
||||
|
||||
// static
|
||||
constexpr auto RunMicrotasksEntryDescriptor::registers() {
|
||||
return RegisterArray(arg_reg_1, arg_reg_2);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_X64
|
||||
|
||||
#endif // V8_CODEGEN_X64_INTERFACE_DESCRIPTORS_X64_INL_H_
|
@ -1,309 +0,0 @@
|
||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#if V8_TARGET_ARCH_X64
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
|
||||
#include "src/execution/frames.h"
|
||||
|
||||
namespace v8 {
|
||||
namespace internal {
|
||||
|
||||
const Register CallInterfaceDescriptor::ContextRegister() { return rsi; }
|
||||
|
||||
void CallInterfaceDescriptor::DefaultInitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data, int register_parameter_count) {
|
||||
const Register default_stub_registers[] = {rax, rbx, rcx, rdx, rdi};
|
||||
CHECK_LE(static_cast<size_t>(register_parameter_count),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(register_parameter_count,
|
||||
default_stub_registers);
|
||||
}
|
||||
|
||||
void RecordWriteDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
const Register default_stub_registers[] = {arg_reg_1, arg_reg_2, arg_reg_3,
|
||||
arg_reg_4, kReturnRegister0};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void DynamicCheckMapsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register default_stub_registers[] = {kReturnRegister0,
|
||||
arg_reg_1,
|
||||
arg_reg_2,
|
||||
arg_reg_3,
|
||||
kRuntimeCallFunctionRegister,
|
||||
kContextRegister};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
void EphemeronKeyBarrierDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
const Register default_stub_registers[] = {arg_reg_1, arg_reg_2, arg_reg_3,
|
||||
arg_reg_4, kReturnRegister0};
|
||||
|
||||
data->RestrictAllocatableRegisters(default_stub_registers,
|
||||
arraysize(default_stub_registers));
|
||||
|
||||
CHECK_LE(static_cast<size_t>(kParameterCount),
|
||||
arraysize(default_stub_registers));
|
||||
data->InitializePlatformSpecific(kParameterCount, default_stub_registers);
|
||||
}
|
||||
|
||||
const Register LoadDescriptor::ReceiverRegister() { return rdx; }
|
||||
const Register LoadDescriptor::NameRegister() { return rcx; }
|
||||
const Register LoadDescriptor::SlotRegister() { return rax; }
|
||||
|
||||
const Register LoadWithVectorDescriptor::VectorRegister() { return rbx; }
|
||||
|
||||
const Register
|
||||
LoadWithReceiverAndVectorDescriptor::LookupStartObjectRegister() {
|
||||
return rdi;
|
||||
}
|
||||
|
||||
const Register StoreDescriptor::ReceiverRegister() { return rdx; }
|
||||
const Register StoreDescriptor::NameRegister() { return rcx; }
|
||||
const Register StoreDescriptor::ValueRegister() { return rax; }
|
||||
const Register StoreDescriptor::SlotRegister() { return rdi; }
|
||||
|
||||
const Register StoreWithVectorDescriptor::VectorRegister() { return rbx; }
|
||||
|
||||
const Register StoreTransitionDescriptor::SlotRegister() { return rdi; }
|
||||
const Register StoreTransitionDescriptor::VectorRegister() { return rbx; }
|
||||
const Register StoreTransitionDescriptor::MapRegister() { return r11; }
|
||||
|
||||
const Register ApiGetterDescriptor::HolderRegister() { return rcx; }
|
||||
const Register ApiGetterDescriptor::CallbackRegister() { return rbx; }
|
||||
|
||||
const Register GrowArrayElementsDescriptor::ObjectRegister() { return rax; }
|
||||
const Register GrowArrayElementsDescriptor::KeyRegister() { return rbx; }
|
||||
|
||||
const Register BaselineLeaveFrameDescriptor::ParamsSizeRegister() {
|
||||
return rbx;
|
||||
}
|
||||
const Register BaselineLeaveFrameDescriptor::WeightRegister() { return rcx; }
|
||||
|
||||
void TypeofDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
// static
|
||||
const Register TypeConversionDescriptor::ArgumentRegister() { return rax; }
|
||||
|
||||
void CallTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments
|
||||
// rdi : the target to call
|
||||
Register registers[] = {rdi, rax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rcx : arguments list length (untagged)
|
||||
// rbx : arguments list (FixedArray)
|
||||
Register registers[] = {rdi, rax, rcx, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments
|
||||
// rcx : start index (to support rest parameters)
|
||||
// rdi : the target to call
|
||||
Register registers[] = {rdi, rax, rcx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallFunctionTemplateDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rdx: the function template info
|
||||
// rcx: number of arguments (on the stack, not including receiver)
|
||||
Register registers[] = {rdx, rcx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rbx : the object to spread
|
||||
Register registers[] = {rdi, rax, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CallWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rdi : the target to call
|
||||
// rbx : the arguments list
|
||||
Register registers[] = {rdi, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rdx : the new target
|
||||
// rcx : arguments list length (untagged)
|
||||
// rbx : arguments list (FixedArray)
|
||||
Register registers[] = {rdi, rdx, rax, rcx, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructForwardVarargsDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments
|
||||
// rdx : the new target
|
||||
// rcx : start index (to support rest parameters)
|
||||
// rdi : the target to call
|
||||
Register registers[] = {rdi, rdx, rax, rcx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithSpreadDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments (on the stack, not including receiver)
|
||||
// rdi : the target to call
|
||||
// rdx : the new target
|
||||
// rbx : the object to spread
|
||||
Register registers[] = {rdi, rdx, rax, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructWithArrayLikeDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rdi : the target to call
|
||||
// rdx : the new target
|
||||
// rbx : the arguments list
|
||||
Register registers[] = {rdi, rdx, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ConstructStubDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
// rax : number of arguments
|
||||
// rdx : the new target
|
||||
// rdi : the target to call
|
||||
// rbx : allocation site or undefined
|
||||
Register registers[] = {rdi, rdx, rax, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void AbortDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {rdx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void CompareDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {rdx, rax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void Compare_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {rdx, rax, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOpDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {rdx, rax};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void BinaryOp_BaselineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {rdx, rax, rbx};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ApiCallbackDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rdx, // api function address
|
||||
rcx, // argument count (not including receiver)
|
||||
rbx, // call data
|
||||
rdi, // holder
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterDispatchDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
kInterpreterAccumulatorRegister, kInterpreterBytecodeOffsetRegister,
|
||||
kInterpreterBytecodeArrayRegister, kInterpreterDispatchTableRegister};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenCallDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rax, // argument count (not including receiver)
|
||||
rbx, // address of first argument
|
||||
rdi // the target callable to be call
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rax, // argument count (not including receiver)
|
||||
rcx, // address of first argument
|
||||
rdi, // constructor to call
|
||||
rdx, // new target
|
||||
rbx, // allocation site feedback if available, undefined otherwise
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rax, // the value to pass to the generator
|
||||
rdx // the JSGeneratorObject / JSAsyncGeneratorObject to resume
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void FrameDropperTrampolineDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {
|
||||
rbx, // loaded new FP
|
||||
};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
void RunMicrotasksEntryDescriptor::InitializePlatformSpecific(
|
||||
CallInterfaceDescriptorData* data) {
|
||||
Register registers[] = {arg_reg_1, arg_reg_2};
|
||||
data->InitializePlatformSpecific(arraysize(registers), registers);
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
||||
#endif // V8_TARGET_ARCH_X64
|
@ -12,6 +12,7 @@
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/cpu-features.h"
|
||||
#include "src/codegen/external-reference-table.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/macro-assembler.h"
|
||||
#include "src/codegen/register-configuration.h"
|
||||
#include "src/codegen/string-constants.h"
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "src/base/iterator.h"
|
||||
#include "src/base/platform/wrappers.h"
|
||||
#include "src/codegen/assembler-inl.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/tick-counter.h"
|
||||
#include "src/compiler/backend/instruction-selector-impl.h"
|
||||
#include "src/compiler/compiler-source-position-table.h"
|
||||
|
@ -8,7 +8,7 @@
|
||||
|
||||
#include "src/base/bits.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/codegen/macro-assembler.h"
|
||||
#include "src/compiler/backend/instruction-selector.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "include/v8-fast-api-calls.h"
|
||||
#include "src/base/bits.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/common/ptr-compr-inl.h"
|
||||
#include "src/compiler/access-builder.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/ast/ast.h"
|
||||
#include "src/builtins/builtins-constructor.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/compiler/access-builder.h"
|
||||
#include "src/compiler/common-operator.h"
|
||||
#include "src/compiler/js-graph.h"
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "src/ast/modules.h"
|
||||
#include "src/builtins/builtins-utils.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/compiler/access-builder.h"
|
||||
#include "src/compiler/allocation-builder.h"
|
||||
#include "src/compiler/graph-assembler.h"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "src/compiler/memory-lowering.h"
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/common/external-pointer.h"
|
||||
#include "src/compiler/access-builder.h"
|
||||
#include "src/compiler/js-graph.h"
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include "src/codegen/assembler.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/compiler.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/codegen/optimized-compilation-info.h"
|
||||
#include "src/compiler/backend/code-generator.h"
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "src/base/optional.h"
|
||||
#include "src/builtins/builtins-constructor-gen.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/ic/handler-configuration.h"
|
||||
#include "src/ic/ic.h"
|
||||
#include "src/ic/keyed-store-generic.h"
|
||||
@ -1507,7 +1508,6 @@ void AccessorAssembler::HandleStoreAccessor(const StoreICParameters* p,
|
||||
LoadObjectField(accessor_pair, AccessorPair::kSetterOffset);
|
||||
CSA_ASSERT(this, Word32BinaryNot(IsTheHole(setter)));
|
||||
|
||||
Callable callable = CodeFactory::Call(isolate());
|
||||
Return(Call(p->context(), setter, p->receiver(), p->value()));
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@
|
||||
#include <ostream>
|
||||
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/execution/frames.h"
|
||||
#include "src/interpreter/bytecodes.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "src/codegen/assembler-inl.h"
|
||||
#include "src/codegen/callable.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
#include "src/snapshot/snapshot-utils.h"
|
||||
#include "src/snapshot/snapshot.h"
|
||||
@ -187,14 +188,15 @@ bool BuiltinAliasesOffHeapTrampolineRegister(Isolate* isolate, Code code) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (CallInterfaceDescriptor::ContextRegister() ==
|
||||
kOffHeapTrampolineRegister) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Callable callable = Builtins::CallableFor(
|
||||
isolate, static_cast<Builtins::Name>(code.builtin_index()));
|
||||
CallInterfaceDescriptor descriptor = callable.descriptor();
|
||||
|
||||
if (descriptor.ContextRegister() == kOffHeapTrampolineRegister) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptor.GetRegisterParameterCount(); i++) {
|
||||
Register reg = descriptor.GetRegisterParameter(i);
|
||||
if (reg == kOffHeapTrampolineRegister) return true;
|
||||
|
@ -658,8 +658,8 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
|
||||
} else {
|
||||
DCHECK(builtin->IsStub());
|
||||
|
||||
bool has_context_parameter = signature.HasContextParameter();
|
||||
for (size_t i = 0; i < signature.parameter_names.size(); ++i) {
|
||||
const std::string& parameter_name = signature.parameter_names[i]->value;
|
||||
const Type* type = signature.types()[i];
|
||||
const bool mark_as_used = signature.implicit_count > i;
|
||||
std::string var = AddParameter(i, builtin, ¶meters, ¶meter_types,
|
||||
@ -667,14 +667,8 @@ void ImplementationVisitor::Visit(Builtin* builtin) {
|
||||
csa_ccfile() << " " << type->GetGeneratedTypeName() << " " << var
|
||||
<< " = "
|
||||
<< "UncheckedParameter<" << type->GetGeneratedTNodeTypeName()
|
||||
<< ">(";
|
||||
if (i == 0 && has_context_parameter) {
|
||||
csa_ccfile() << "Descriptor::kContext";
|
||||
} else {
|
||||
csa_ccfile() << "Descriptor::ParameterIndex<"
|
||||
<< (has_context_parameter ? i - 1 : i) << ">()";
|
||||
}
|
||||
csa_ccfile() << ");\n";
|
||||
<< ">(Descriptor::k" << CamelifyString(parameter_name)
|
||||
<< ");\n";
|
||||
csa_ccfile() << " USE(" << var << ");\n";
|
||||
}
|
||||
}
|
||||
@ -3437,40 +3431,40 @@ void ImplementationVisitor::GenerateBuiltinDefinitionsAndInterfaceDescriptors(
|
||||
std::string descriptor_name = builtin->ExternalName() + "Descriptor";
|
||||
bool has_context_parameter = builtin->signature().HasContextParameter();
|
||||
size_t kFirstNonContextParameter = has_context_parameter ? 1 : 0;
|
||||
size_t parameter_count =
|
||||
builtin->parameter_names().size() - kFirstNonContextParameter;
|
||||
TypeVector return_types = LowerType(builtin->signature().return_type);
|
||||
|
||||
interface_descriptors
|
||||
<< "class " << descriptor_name
|
||||
<< " : public TorqueInterfaceDescriptor<" << return_types.size()
|
||||
<< ", " << parameter_count << ", "
|
||||
<< (has_context_parameter ? "true" : "false") << "> {\n";
|
||||
interface_descriptors << " DECLARE_DESCRIPTOR_WITH_BASE("
|
||||
<< descriptor_name
|
||||
<< ", TorqueInterfaceDescriptor)\n";
|
||||
interface_descriptors << "class " << descriptor_name
|
||||
<< " : public StaticCallInterfaceDescriptor<"
|
||||
<< descriptor_name << "> {\n";
|
||||
|
||||
interface_descriptors
|
||||
<< " std::vector<MachineType> ReturnType() override {\n";
|
||||
interface_descriptors << " return {{";
|
||||
PrintCommaSeparatedList(interface_descriptors, return_types,
|
||||
MachineTypeString);
|
||||
interface_descriptors << "}};\n";
|
||||
interface_descriptors << " }\n";
|
||||
interface_descriptors << " public:\n";
|
||||
|
||||
interface_descriptors << " std::array<MachineType, " << parameter_count
|
||||
<< "> ParameterTypes() override {\n";
|
||||
interface_descriptors << " return {";
|
||||
if (has_context_parameter) {
|
||||
interface_descriptors << " DEFINE_RESULT_AND_PARAMETERS(";
|
||||
} else {
|
||||
interface_descriptors << " DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(";
|
||||
}
|
||||
interface_descriptors << return_types.size();
|
||||
for (size_t i = kFirstNonContextParameter;
|
||||
i < builtin->parameter_names().size(); ++i) {
|
||||
bool last = i + 1 == builtin->parameter_names().size();
|
||||
const Type* type = builtin->signature().parameter_types.types[i];
|
||||
interface_descriptors << MachineTypeString(type)
|
||||
<< (last ? "" : ", ");
|
||||
Identifier* parameter = builtin->parameter_names()[i];
|
||||
interface_descriptors << ", k" << CamelifyString(parameter->value);
|
||||
}
|
||||
interface_descriptors << "};\n";
|
||||
interface_descriptors << ")\n";
|
||||
|
||||
interface_descriptors << " DEFINE_RESULT_AND_PARAMETER_TYPES(";
|
||||
PrintCommaSeparatedList(interface_descriptors, return_types,
|
||||
MachineTypeString);
|
||||
for (size_t i = kFirstNonContextParameter;
|
||||
i < builtin->parameter_names().size(); ++i) {
|
||||
const Type* type = builtin->signature().parameter_types.types[i];
|
||||
interface_descriptors << ", " << MachineTypeString(type);
|
||||
}
|
||||
interface_descriptors << ")\n";
|
||||
|
||||
interface_descriptors << " DECLARE_DEFAULT_DESCRIPTOR("
|
||||
<< descriptor_name << ")\n";
|
||||
|
||||
interface_descriptors << " }\n";
|
||||
interface_descriptors << "};\n\n";
|
||||
} else {
|
||||
builtin_definitions << "TFJ(" << builtin->ExternalName();
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "src/codegen/assembler-inl.h"
|
||||
// TODO(clemensb): Remove dependences on compiler stuff.
|
||||
#include "src/codegen/external-reference.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/codegen/macro-assembler-inl.h"
|
||||
#include "src/compiler/linkage.h"
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "src/builtins/builtins-string-gen.h"
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/code-stub-assembler.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/compiler/node.h"
|
||||
#include "src/debug/debug.h"
|
||||
#include "src/execution/isolate.h"
|
||||
@ -2024,7 +2025,7 @@ TEST(PopAndReturnFromTFCBuiltinWithStackParameters) {
|
||||
// least one argument passed on stack.
|
||||
using Descriptor = FlatMapIntoArrayDescriptor;
|
||||
Descriptor descriptor;
|
||||
CHECK_LT(0, descriptor.GetStackParameterCount());
|
||||
CHECK_LT(0, Descriptor::GetStackParameterCount());
|
||||
|
||||
CodeAssemblerTester asm_tester(isolate, Descriptor());
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "test/unittests/codegen/code-stub-assembler-unittest.h"
|
||||
|
||||
#include "src/codegen/code-factory.h"
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/compiler/node.h"
|
||||
#include "src/execution/isolate.h"
|
||||
#include "src/objects/objects-inl.h"
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
#include "src/compiler/int64-lowering.h"
|
||||
|
||||
#include "src/codegen/interface-descriptors.h"
|
||||
#include "src/codegen/interface-descriptors-inl.h"
|
||||
#include "src/codegen/machine-type.h"
|
||||
#include "src/codegen/signature.h"
|
||||
#include "src/compiler/common-operator.h"
|
||||
@ -1063,20 +1063,20 @@ TEST_F(Int64LoweringTest, WasmBigIntSpecialCaseBigIntToI64) {
|
||||
|
||||
CallDescriptor* bigint_to_i64_call_descriptor =
|
||||
Linkage::GetStubCallDescriptor(
|
||||
zone(), // zone
|
||||
BigIntToI64Descriptor(), // descriptor
|
||||
BigIntToI64Descriptor()
|
||||
.GetStackParameterCount(), // stack parameter count
|
||||
CallDescriptor::kNoFlags, // flags
|
||||
Operator::kNoProperties, // properties
|
||||
StubCallMode::kCallCodeObject); // stub call mode
|
||||
zone(), // zone
|
||||
BigIntToI64Descriptor(), // descriptor
|
||||
BigIntToI64Descriptor::GetStackParameterCount(), // stack parameter
|
||||
// count
|
||||
CallDescriptor::kNoFlags, // flags
|
||||
Operator::kNoProperties, // properties
|
||||
StubCallMode::kCallCodeObject); // stub call mode
|
||||
|
||||
CallDescriptor* bigint_to_i32_pair_call_descriptor =
|
||||
Linkage::GetStubCallDescriptor(
|
||||
zone(), // zone
|
||||
BigIntToI32PairDescriptor(), // descriptor
|
||||
BigIntToI32PairDescriptor()
|
||||
.GetStackParameterCount(), // stack parameter count
|
||||
BigIntToI32PairDescriptor::
|
||||
GetStackParameterCount(), // stack parameter count
|
||||
CallDescriptor::kNoFlags, // flags
|
||||
Operator::kNoProperties, // properties
|
||||
StubCallMode::kCallCodeObject); // stub call mode
|
||||
@ -1109,20 +1109,20 @@ TEST_F(Int64LoweringTest, WasmBigIntSpecialCaseI64ToBigInt) {
|
||||
|
||||
CallDescriptor* i64_to_bigint_call_descriptor =
|
||||
Linkage::GetStubCallDescriptor(
|
||||
zone(), // zone
|
||||
I64ToBigIntDescriptor(), // descriptor
|
||||
I64ToBigIntDescriptor()
|
||||
.GetStackParameterCount(), // stack parameter count
|
||||
CallDescriptor::kNoFlags, // flags
|
||||
Operator::kNoProperties, // properties
|
||||
StubCallMode::kCallCodeObject); // stub call mode
|
||||
zone(), // zone
|
||||
I64ToBigIntDescriptor(), // descriptor
|
||||
I64ToBigIntDescriptor::GetStackParameterCount(), // stack parameter
|
||||
// count
|
||||
CallDescriptor::kNoFlags, // flags
|
||||
Operator::kNoProperties, // properties
|
||||
StubCallMode::kCallCodeObject); // stub call mode
|
||||
|
||||
CallDescriptor* i32_pair_to_bigint_call_descriptor =
|
||||
Linkage::GetStubCallDescriptor(
|
||||
zone(), // zone
|
||||
I32PairToBigIntDescriptor(), // descriptor
|
||||
I32PairToBigIntDescriptor()
|
||||
.GetStackParameterCount(), // stack parameter count
|
||||
I32PairToBigIntDescriptor::
|
||||
GetStackParameterCount(), // stack parameter count
|
||||
CallDescriptor::kNoFlags, // flags
|
||||
Operator::kNoProperties, // properties
|
||||
StubCallMode::kCallCodeObject); // stub call mode
|
||||
|
Loading…
Reference in New Issue
Block a user