Define return count and return types in CallInterfaceDescriptor.

Bug: v8:7754, v8:6600
Change-Id: I4db943d4a4a02a14bba670f89661ea98c5e306dd
Reviewed-on: https://chromium-review.googlesource.com/1107919
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#53907}
This commit is contained in:
Igor Sheludko 2018-06-21 10:47:48 +02:00 committed by Commit Bot
parent 17693fea1a
commit d7e6fbe5da
27 changed files with 270 additions and 121 deletions

View File

@ -255,7 +255,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r0, // argument count (argc)
@ -265,6 +267,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -260,7 +260,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
x0, // argument count (argc)
@ -270,6 +272,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -141,10 +141,11 @@ Code* BuildWithCodeStubAssemblerCS(Isolate* isolate, int32_t builtin_index,
// and this construction just queries the details from the descriptors table.
CallInterfaceDescriptor descriptor(interface_descriptor);
// Ensure descriptor is already initialized.
DCHECK_EQ(result_size, descriptor.GetReturnCount());
DCHECK_LE(0, descriptor.GetRegisterParameterCount());
compiler::CodeAssemblerState state(
isolate, &zone, descriptor, Code::BUILTIN, name,
PoisoningMitigationLevel::kDontPoison, result_size, 0, builtin_index);
PoisoningMitigationLevel::kDontPoison, 0, builtin_index);
generator(&state);
Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);
PostBuildProfileAndTracing(isolate, *code, name);

View File

@ -318,7 +318,12 @@ Callable CodeFactory::InterpreterCEntry(Isolate* isolate, int result_size) {
// save fpregs too.
Handle<Code> code = CodeFactory::CEntry(isolate, result_size, kDontSaveFPRegs,
kArgvInRegister);
return Callable(code, InterpreterCEntryDescriptor{});
if (result_size == 1) {
return Callable(code, InterpreterCEntry1Descriptor{});
} else {
DCHECK_EQ(result_size, 2);
return Callable(code, InterpreterCEntry2Descriptor{});
}
}
// static

View File

@ -261,7 +261,7 @@ Handle<Code> TurboFanCodeStub::GenerateCode() {
CallInterfaceDescriptor descriptor(GetCallInterfaceDescriptor());
compiler::CodeAssemblerState state(
isolate(), &zone, descriptor, Code::STUB, name,
PoisoningMitigationLevel::kDontPoison, 1, GetKey());
PoisoningMitigationLevel::kDontPoison, GetKey());
GenerateAssembly(&state);
return compiler::CodeAssembler::GenerateCode(&state);
}

View File

@ -44,15 +44,14 @@ static_assert(
CodeAssemblerState::CodeAssemblerState(
Isolate* isolate, Zone* zone, const CallInterfaceDescriptor& descriptor,
Code::Kind kind, const char* name, PoisoningMitigationLevel poisoning_level,
size_t result_size, uint32_t stub_key, int32_t builtin_index)
uint32_t stub_key, int32_t builtin_index)
// TODO(rmcilroy): Should we use Linkage::GetBytecodeDispatchDescriptor for
// bytecode handlers?
: CodeAssemblerState(
isolate, zone,
Linkage::GetStubCallDescriptor(
zone, descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size),
CallDescriptor::kNoFlags, Operator::kNoProperties),
kind, name, poisoning_level, stub_key, builtin_index) {}
CodeAssemblerState::CodeAssemblerState(Isolate* isolate, Zone* zone,
@ -1142,9 +1141,10 @@ Node* CodeAssembler::CallStubN(const CallInterfaceDescriptor& descriptor,
// Extra arguments not mentioned in the descriptor are passed on the stack.
int stack_parameter_count = argc - descriptor.GetRegisterParameterCount();
DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
DCHECK_EQ(result_size, descriptor.GetReturnCount());
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), descriptor, stack_parameter_count, CallDescriptor::kNoFlags,
Operator::kNoProperties, MachineType::AnyTagged(), result_size,
Operator::kNoProperties,
pass_context ? Linkage::kPassContext : Linkage::kNoContext);
CallPrologue();
@ -1160,11 +1160,9 @@ void CodeAssembler::TailCallStubImpl(const CallInterfaceDescriptor& descriptor,
constexpr size_t kMaxNumArgs = 11;
DCHECK_GE(kMaxNumArgs, args.size());
DCHECK_EQ(descriptor.GetParameterCount(), args.size());
size_t result_size = 1;
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
CallDescriptor::kNoFlags, Operator::kNoProperties);
NodeArray<kMaxNumArgs + 2> inputs;
inputs.Add(target);
@ -1203,7 +1201,7 @@ Node* CodeAssembler::TailCallStubThenBytecodeDispatchImpl(
DCHECK_LE(descriptor.GetStackParameterCount(), stack_parameter_count);
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), descriptor, stack_parameter_count, CallDescriptor::kNoFlags,
Operator::kNoProperties, MachineType::AnyTagged(), 0);
Operator::kNoProperties);
NodeArray<kMaxNumArgs + 2> inputs;
inputs.Add(target);
@ -1238,11 +1236,9 @@ TNode<Object> CodeAssembler::TailCallJSCode(TNode<Code> code,
TNode<Object> new_target,
TNode<Int32T> arg_count) {
JSTrampolineDescriptor descriptor;
size_t result_size = 1;
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), descriptor, descriptor.GetStackParameterCount(),
CallDescriptor::kFixedTargetRegister, Operator::kNoProperties,
MachineType::AnyTagged(), result_size);
CallDescriptor::kFixedTargetRegister, Operator::kNoProperties);
Node* nodes[] = {code, function, new_target, arg_count, context};
CHECK_EQ(descriptor.GetParameterCount() + 2, arraysize(nodes));

View File

@ -1359,7 +1359,7 @@ class V8_EXPORT_PRIVATE CodeAssemblerState {
CodeAssemblerState(Isolate* isolate, Zone* zone,
const CallInterfaceDescriptor& descriptor, Code::Kind kind,
const char* name, PoisoningMitigationLevel poisoning_level,
size_t result_size = 1, uint32_t stub_key = 0,
uint32_t stub_key = 0,
int32_t builtin_index = Builtins::kNoBuiltinId);
// Create with JSCall linkage.

View File

@ -2951,8 +2951,7 @@ Node* EffectControlLinearizer::LowerStringCodePointAt(
Operator::Properties properties = Operator::kNoThrow | Operator::kNoWrite;
CallDescriptor::Flags flags = CallDescriptor::kNoFlags;
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), callable.descriptor(), 0, flags, properties,
MachineType::TaggedSigned());
graph()->zone(), callable.descriptor(), 0, flags, properties);
return __ Call(call_descriptor, __ HeapConstant(callable.code()), receiver,
position, __ NoContextConstant());
}

View File

@ -863,8 +863,7 @@ Reduction JSCallReducer::ReduceReflectGet(Node* node) {
Builtins::CallableFor(isolate(), Builtins::kGetProperty);
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), callable.descriptor(), 0,
CallDescriptor::kNeedsFrameState, Operator::kNoProperties,
MachineType::AnyTagged(), 1);
CallDescriptor::kNeedsFrameState, Operator::kNoProperties);
Node* stub_code = jsgraph()->HeapConstant(callable.code());
vtrue = etrue = if_true =
graph()->NewNode(common()->Call(call_descriptor), stub_code, target,
@ -2912,7 +2911,7 @@ Reduction JSCallReducer::ReduceCallApiFunction(
graph()->zone(), cid,
cid.GetStackParameterCount() + argc + 1 /* implicit receiver */,
CallDescriptor::kNeedsFrameState, Operator::kNoProperties,
MachineType::AnyTagged(), 1, Linkage::kNoContext);
Linkage::kNoContext);
ApiFunction api_function(v8::ToCData<Address>(call_handler_info->callback()));
Node* holder = lookup == CallOptimization::kHolderFound
? jsgraph()->HeapConstant(api_holder)

View File

@ -101,12 +101,11 @@ void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
void JSGenericLowering::ReplaceWithStubCall(Node* node, Callable callable,
CallDescriptor::Flags flags,
Operator::Properties properties,
int result_size) {
Operator::Properties properties) {
const CallInterfaceDescriptor& descriptor = callable.descriptor();
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), descriptor, descriptor.GetStackParameterCount(), flags,
properties, MachineType::AnyTagged(), result_size);
properties);
Node* stub_code = jsgraph()->HeapConstant(callable.code());
node->InsertInput(zone(), 0, stub_code);
NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
@ -362,8 +361,7 @@ void JSGenericLowering::LowerJSCreateArray(Node* node) {
Handle<AllocationSite> const site = p.site();
auto call_descriptor = Linkage::GetStubCallDescriptor(
zone(), ArrayConstructorDescriptor{}, arity + 1,
CallDescriptor::kNeedsFrameState, node->op()->properties(),
MachineType::AnyTagged());
CallDescriptor::kNeedsFrameState, node->op()->properties());
Node* stub_code = jsgraph()->ArrayConstructorStubConstant();
Node* stub_arity = jsgraph()->Int32Constant(arity);
Node* type_info = site.is_null() ? jsgraph()->UndefinedConstant()

View File

@ -39,8 +39,7 @@ class JSGenericLowering final : public Reducer {
// Helpers to replace existing nodes with a generic call.
void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags);
void ReplaceWithStubCall(Node* node, Callable c, CallDescriptor::Flags flags,
Operator::Properties properties,
int result_size = 1);
Operator::Properties properties);
void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1);
Zone* zone() const;

View File

@ -1767,7 +1767,7 @@ Node* JSNativeContextSpecialization::InlineApiCall(
call_interface_descriptor.GetStackParameterCount() + argc +
1 /* implicit receiver */,
CallDescriptor::kNeedsFrameState, Operator::kNoProperties,
MachineType::AnyTagged(), 1, Linkage::kNoContext);
Linkage::kNoContext);
Node* data = jsgraph()->Constant(call_data_object);
ApiFunction function(v8::ToCData<Address>(call_handler_info->callback()));

View File

@ -346,8 +346,7 @@ CallDescriptor* Linkage::GetJSCallDescriptor(Zone* zone, bool is_osr,
CallDescriptor* Linkage::GetStubCallDescriptor(
Zone* zone, const CallInterfaceDescriptor& descriptor,
int stack_parameter_count, CallDescriptor::Flags flags,
Operator::Properties properties, MachineType return_type,
size_t return_count, Linkage::ContextSpecification context_spec,
Operator::Properties properties, Linkage::ContextSpecification context_spec,
StubCallMode stub_mode) {
const int register_parameter_count = descriptor.GetRegisterParameterCount();
const int js_parameter_count =
@ -356,17 +355,18 @@ CallDescriptor* Linkage::GetStubCallDescriptor(
const size_t parameter_count =
static_cast<size_t>(js_parameter_count + context_count);
size_t return_count = descriptor.GetReturnCount();
LocationSignature::Builder locations(zone, return_count, parameter_count);
// Add returns.
if (locations.return_count_ > 0) {
locations.AddReturn(regloc(kReturnRegister0, return_type));
locations.AddReturn(regloc(kReturnRegister0, descriptor.GetReturnType(0)));
}
if (locations.return_count_ > 1) {
locations.AddReturn(regloc(kReturnRegister1, return_type));
locations.AddReturn(regloc(kReturnRegister1, descriptor.GetReturnType(1)));
}
if (locations.return_count_ > 2) {
locations.AddReturn(regloc(kReturnRegister2, return_type));
locations.AddReturn(regloc(kReturnRegister2, descriptor.GetReturnType(2)));
}
// Add parameters in registers and on the stack.
@ -417,7 +417,10 @@ CallDescriptor* Linkage::GetBytecodeDispatchCallDescriptor(
const int register_parameter_count = descriptor.GetRegisterParameterCount();
const int parameter_count = register_parameter_count + stack_parameter_count;
LocationSignature::Builder locations(zone, 0, parameter_count);
DCHECK_EQ(descriptor.GetReturnCount(), 1);
LocationSignature::Builder locations(zone, 1, parameter_count);
locations.AddReturn(regloc(kReturnRegister0, descriptor.GetReturnType(0)));
// Add parameters in registers and on the stack.
for (int i = 0; i < parameter_count; i++) {

View File

@ -393,8 +393,7 @@ class V8_EXPORT_PRIVATE Linkage : public NON_EXPORTED_BASE(ZoneObject) {
Zone* zone, const CallInterfaceDescriptor& descriptor,
int stack_parameter_count, CallDescriptor::Flags flags,
Operator::Properties properties = Operator::kNoProperties,
MachineType return_type = MachineType::AnyTagged(),
size_t return_count = 1, ContextSpecification context_spec = kPassContext,
ContextSpecification context_spec = kPassContext,
StubCallMode stub_mode = StubCallMode::kCallOnHeapBuiltin);
static CallDescriptor* GetBytecodeDispatchCallDescriptor(

View File

@ -239,7 +239,7 @@ void MemoryOptimizer::VisitAllocateRaw(Node* node,
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), AllocateDescriptor{}, 0,
CallDescriptor::kCanUseRoots, Operator::kNoThrow,
MachineType::AnyTagged(), 1, Linkage::kNoContext);
Linkage::kNoContext);
allocate_operator_.set(common()->Call(call_descriptor));
}
Node* vfalse = __ Call(allocate_operator_.get(), target, size);
@ -296,7 +296,7 @@ void MemoryOptimizer::VisitAllocateRaw(Node* node,
auto call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), AllocateDescriptor{}, 0,
CallDescriptor::kCanUseRoots, Operator::kNoThrow,
MachineType::AnyTagged(), 1, Linkage::kNoContext);
Linkage::kNoContext);
allocate_operator_.set(common()->Call(call_descriptor));
}
__ Goto(&done, __ Call(allocate_operator_.get(), target, size));

View File

@ -270,8 +270,6 @@ void WasmGraphBuilder::StackCheck(wasm::WasmCodePosition position,
0, // stack parameter count
CallDescriptor::kNoFlags, // flags
Operator::kNoProperties, // properties
MachineType::None(), // return type
0, // return count
Linkage::kNoContext, // context specification
StubCallMode::kCallWasmRuntimeStub); // stub call mode
// A direct call to a wasm runtime stub defined in this module.
@ -4034,8 +4032,8 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
if (!allocate_heap_number_operator_.is_set()) {
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), AllocateHeapNumberDescriptor(), 0,
CallDescriptor::kNoFlags, Operator::kNoThrow,
MachineType::AnyTagged(), 1, Linkage::kNoContext, stub_mode_);
CallDescriptor::kNoFlags, Operator::kNoThrow, Linkage::kNoContext,
stub_mode_);
allocate_heap_number_operator_.set(common->Call(call_descriptor));
}
Node* heap_number = graph()->NewNode(allocate_heap_number_operator_.get(),
@ -4197,7 +4195,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
auto call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), TypeConversionDescriptor(), 0,
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), 1, Linkage::kPassContext, stub_mode_);
Linkage::kPassContext, stub_mode_);
Node* stub_code =
(stub_mode_ == StubCallMode::kCallWasmRuntimeStub)
? mcgraph()->RelocatableIntPtrConstant(
@ -4517,8 +4515,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
call_descriptor = Linkage::GetStubCallDescriptor(
mcgraph()->zone(), ArgumentAdaptorDescriptor{}, 1 + wasm_count,
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), 1, Linkage::kPassContext,
StubCallMode::kCallWasmRuntimeStub);
Linkage::kPassContext, StubCallMode::kCallWasmRuntimeStub);
// Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_);
@ -4543,8 +4540,7 @@ class WasmWrapperGraphBuilder : public WasmGraphBuilder {
call_descriptor = Linkage::GetStubCallDescriptor(
graph()->zone(), CallTrampolineDescriptor{}, wasm_count + 1,
CallDescriptor::kNoFlags, Operator::kNoProperties,
MachineType::AnyTagged(), 1, Linkage::kPassContext,
StubCallMode::kCallWasmRuntimeStub);
Linkage::kPassContext, StubCallMode::kCallWasmRuntimeStub);
// Convert wasm numbers to JS values.
pos = AddArgumentNodes(args, pos, wasm_count, sig_);

View File

@ -247,7 +247,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
eax, // argument count (argc)
@ -257,6 +259,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -22,14 +22,16 @@ void CallInterfaceDescriptorData::InitializePlatformSpecific(
}
void CallInterfaceDescriptorData::InitializePlatformIndependent(
int parameter_count, int extra_parameter_count,
const MachineType* machine_types) {
int return_count, int parameter_count, const MachineType* machine_types,
int machine_types_length) {
// InterfaceDescriptor owns a copy of the MachineType array.
// We only care about parameters, not receiver and result.
param_count_ = parameter_count + extra_parameter_count;
machine_types_ = NewArray<MachineType>(param_count_);
for (int i = 0; i < param_count_; i++) {
if (machine_types == nullptr || i >= parameter_count) {
return_count_ = return_count;
param_count_ = parameter_count;
int types_length = return_count_ + param_count_;
machine_types_ = NewArray<MachineType>(types_length);
for (int i = 0; i < types_length; i++) {
if (machine_types == nullptr || i >= machine_types_length) {
machine_types_[i] = MachineType::AnyTagged();
} else {
machine_types_[i] = machine_types[i];

View File

@ -67,7 +67,8 @@ class PlatformInterfaceDescriptor;
V(InterpreterDispatch) \
V(InterpreterPushArgsThenCall) \
V(InterpreterPushArgsThenConstruct) \
V(InterpreterCEntry) \
V(InterpreterCEntry1) \
V(InterpreterCEntry2) \
V(ResumeGenerator) \
V(FrameDropperTrampoline) \
V(RunMicrotasks) \
@ -85,27 +86,37 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
PlatformInterfaceDescriptor* platform_descriptor = nullptr);
// if machine_types is null, then an array of size
// (parameter_count + extra_parameter_count) will be created with
// (return_count + parameter_count) will be created with
// MachineType::AnyTagged() for each member.
//
// if machine_types is not null, then it should be of the size
// parameter_count. Those members of the parameter array will be initialized
// from {machine_types}, and the rest initialized to MachineType::AnyTagged().
void InitializePlatformIndependent(int parameter_count,
int extra_parameter_count,
const MachineType* machine_types);
// (return_count + parameter_count). Those members of the parameter array will
// be initialized from {machine_types}, and the rest initialized to
// MachineType::AnyTagged().
void InitializePlatformIndependent(int return_count, int parameter_count,
const MachineType* machine_types,
int machine_types_length);
void Reset();
bool IsInitialized() const {
return register_param_count_ >= 0 && param_count_ >= 0;
return register_param_count_ >= 0 && return_count_ >= 0 &&
param_count_ >= 0;
}
int return_count() const { return return_count_; }
int param_count() const { return param_count_; }
int register_param_count() const { return register_param_count_; }
Register register_param(int index) const { return register_params_[index]; }
Register* register_params() const { return register_params_; }
MachineType param_type(int index) const { return machine_types_[index]; }
MachineType return_type(int index) const {
DCHECK_LT(index, return_count_);
return machine_types_[index];
}
MachineType param_type(int index) const {
DCHECK_LT(index, param_count_);
return machine_types_[return_count_ + index];
}
PlatformInterfaceDescriptor* platform_specific_descriptor() const {
return platform_specific_descriptor_;
}
@ -122,16 +133,19 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptorData {
private:
int register_param_count_ = -1;
int return_count_ = -1;
int param_count_ = -1;
// Specifying the set of registers that could be used by the register
// allocator. Currently, it's only used by RecordWrite code stub.
RegList allocatable_registers_ = 0;
// The Register params are allocated dynamically by the
// InterfaceDescriptor, and freed on destruction. This is because static
// arrays of Registers cause creation of runtime static initializers
// which we don't want.
// |registers_params_| defines registers that are used for parameter passing.
// |machine_types_| defines machine types for resulting values and incomping
// parameters.
// Both arrays are allocated dynamically by the InterfaceDescriptor and
// freed on destruction. This is because static arrays cause creation of
// runtime static initializers which we don't want.
Register* register_params_ = nullptr;
MachineType* machine_types_ = nullptr;
@ -177,6 +191,13 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
CallInterfaceDescriptor(CallDescriptors::Key key)
: data_(CallDescriptors::call_descriptor_data(key)) {}
int GetReturnCount() const { return data()->return_count(); }
MachineType GetReturnType(int index) const {
DCHECK_LT(index, data()->return_count());
return data()->return_type(index);
}
int GetParameterCount() const { return data()->param_count(); }
int GetRegisterParameterCount() const {
@ -192,7 +213,7 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
}
MachineType GetParameterType(int index) const {
DCHECK(index < data()->param_count());
DCHECK_LT(index, data()->param_count());
return data()->param_type(index);
}
@ -218,8 +239,10 @@ class V8_EXPORT_PRIVATE CallInterfaceDescriptor {
virtual void InitializePlatformIndependent(
CallInterfaceDescriptorData* data) {
data->InitializePlatformIndependent(data->register_param_count(), 0,
nullptr);
// Default descriptor configuration: one result, all parameters are passed
// in registers and all parameters have MachineType::AnyTagged() type.
data->InitializePlatformIndependent(1, data->register_param_count(),
nullptr, 0);
}
// Initializes |data| using the platform dependent default set of registers.
@ -271,8 +294,8 @@ constexpr int kMaxBuiltinRegisterParams = 5;
} \
void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
override { \
data->InitializePlatformIndependent(kRegisterParams, kStackParams, \
nullptr); \
data->InitializePlatformIndependent(kReturnCount, parameter_count, \
nullptr, 0); \
} \
name(CallDescriptors::Key key) : base(key) {} \
\
@ -290,7 +313,8 @@ constexpr int kMaxBuiltinRegisterParams = 5;
\
public:
#define DEFINE_PARAMETERS(...) \
#define DEFINE_RESULT_AND_PARAMETERS(return_count, ...) \
static constexpr int kReturnCount = return_count; \
enum ParameterIndices { \
__dummy = -1, /* to be able to pass zero arguments */ \
##__VA_ARGS__, \
@ -299,27 +323,34 @@ constexpr int kMaxBuiltinRegisterParams = 5;
kContext = kParameterCount /* implicit parameter */ \
};
#define DEFINE_PARAMETERS_NO_CONTEXT(...) \
enum ParameterIndices { \
__dummy = -1, /* to be able to pass zero arguments */ \
##__VA_ARGS__, \
\
kParameterCount \
#define DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(return_count, ...) \
static constexpr int kReturnCount = return_count; \
enum ParameterIndices { \
__dummy = -1, /* to be able to pass zero arguments */ \
##__VA_ARGS__, \
\
kParameterCount \
};
#define DEFINE_PARAMETER_TYPES(...) \
#define DEFINE_PARAMETERS(...) DEFINE_RESULT_AND_PARAMETERS(1, ##__VA_ARGS__)
#define DEFINE_RESULT_AND_PARAMETER_TYPES(...) \
void InitializePlatformIndependent(CallInterfaceDescriptorData* data) \
override { \
/* First element is here to workaround empty __VA_ARGS__ case */ \
MachineType machine_types[] = {MachineType::None(), ##__VA_ARGS__}; \
MachineType machine_types[] = {__VA_ARGS__}; \
static_assert( \
kParameterCount == arraysize(machine_types) - 1, \
kReturnCount + kParameterCount == arraysize(machine_types), \
"Parameter names definition is not consistent with parameter types"); \
data->InitializePlatformIndependent(kParameterCount, 0, \
&machine_types[1]); \
data->InitializePlatformIndependent(kReturnCount, kParameterCount, \
machine_types, \
arraysize(machine_types)); \
}
#define DEFINE_PARAMETER_TYPES(...) \
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged() /* result */, \
##__VA_ARGS__)
#define DEFINE_JS_PARAMETERS(...) \
static constexpr int kReturnCount = 1; \
enum ParameterIndices { \
kTarget, \
kNewTarget, \
@ -353,8 +384,9 @@ class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
class AllocateDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS_NO_CONTEXT(kRequestedSize)
DEFINE_PARAMETER_TYPES(MachineType::Int32())
DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT(1, kRequestedSize)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedPointer(), // result 0
MachineType::Int32()) // kRequestedSize
DECLARE_DESCRIPTOR(AllocateDescriptor, CallInterfaceDescriptor)
};
@ -781,9 +813,10 @@ class BinaryOpDescriptor : public CallInterfaceDescriptor {
class StringAtDescriptor final : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kReceiver, kPosition)
// TODO(turbofan): Allow builtins to return untagged values.
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kReceiver
MachineType::IntPtr()) // kPosition
// TODO(turbofan): Return untagged value here.
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::TaggedSigned(), // result 0
MachineType::AnyTagged(), // kReceiver
MachineType::IntPtr()) // kPosition
DECLARE_DESCRIPTOR(StringAtDescriptor, CallInterfaceDescriptor)
};
@ -852,8 +885,8 @@ class NewArgumentsElementsDescriptor final : public CallInterfaceDescriptor {
class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
: public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kAccumulator, kBytecodeOffset, kBytecodeArray,
kDispatchTable)
DEFINE_RESULT_AND_PARAMETERS(1, kAccumulator, kBytecodeOffset, kBytecodeArray,
kDispatchTable)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kAccumulator
MachineType::IntPtr(), // kBytecodeOffset
MachineType::AnyTagged(), // kBytecodeArray
@ -863,7 +896,7 @@ class V8_EXPORT_PRIVATE InterpreterDispatchDescriptor
class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunction)
DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument, kFunction)
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
MachineType::Pointer(), // kFirstArgument
MachineType::AnyTagged()) // kFunction
@ -874,8 +907,8 @@ class InterpreterPushArgsThenCallDescriptor : public CallInterfaceDescriptor {
class InterpreterPushArgsThenConstructDescriptor
: public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kNumberOfArguments, kNewTarget, kConstructor,
kFeedbackElement, kFirstArgument)
DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kNewTarget, kConstructor,
kFeedbackElement, kFirstArgument)
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
MachineType::AnyTagged(), // kNewTarget
MachineType::AnyTagged(), // kConstructor
@ -885,13 +918,27 @@ class InterpreterPushArgsThenConstructDescriptor
CallInterfaceDescriptor)
};
class InterpreterCEntryDescriptor : public CallInterfaceDescriptor {
class InterpreterCEntry1Descriptor : public CallInterfaceDescriptor {
public:
DEFINE_PARAMETERS(kNumberOfArguments, kFirstArgument, kFunctionEntry)
DEFINE_PARAMETER_TYPES(MachineType::Int32(), // kNumberOfArguments
MachineType::Pointer(), // kFirstArgument
MachineType::Pointer()) // kFunctionEntry
DECLARE_DESCRIPTOR(InterpreterCEntryDescriptor, CallInterfaceDescriptor)
DEFINE_RESULT_AND_PARAMETERS(1, kNumberOfArguments, kFirstArgument,
kFunctionEntry)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 0
MachineType::Int32(), // kNumberOfArguments
MachineType::Pointer(), // kFirstArgument
MachineType::Pointer()) // kFunctionEntry
DECLARE_DESCRIPTOR(InterpreterCEntry1Descriptor, CallInterfaceDescriptor)
};
class InterpreterCEntry2Descriptor : public CallInterfaceDescriptor {
public:
DEFINE_RESULT_AND_PARAMETERS(2, kNumberOfArguments, kFirstArgument,
kFunctionEntry)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::AnyTagged(), // result 0
MachineType::AnyTagged(), // result 1
MachineType::Int32(), // kNumberOfArguments
MachineType::Pointer(), // kFirstArgument
MachineType::Pointer()) // kFunctionEntry
DECLARE_DESCRIPTOR(InterpreterCEntry2Descriptor, CallInterfaceDescriptor)
};
class ResumeGeneratorDescriptor final : public CallInterfaceDescriptor {
@ -930,8 +977,10 @@ BUILTIN_LIST_TFS(DEFINE_TFS_BUILTIN_DESCRIPTOR)
#undef DECLARE_DESCRIPTOR_WITH_BASE
#undef DECLARE_DESCRIPTOR
#undef DECLARE_JS_COMPATIBLE_DESCRIPTOR
#undef DEFINE_RESULT_AND_PARAMETERS
#undef DEFINE_RESULT_AND_PARAMETERS_NO_CONTEXT
#undef DEFINE_PARAMETERS
#undef DEFINE_PARAMETERS_NO_CONTEXT
#undef DEFINE_RESULT_AND_PARAMETER_TYPES
#undef DEFINE_PARAMETER_TYPES
#undef DEFINE_JS_PARAMETERS
#undef DEFINE_JS_PARAMETER_TYPES

View File

@ -695,11 +695,6 @@ class V8_EXPORT_PRIVATE Bytecodes final : public AllStatic {
#undef OR_BYTECODE
}
// Returns the number of values which |bytecode| returns.
static constexpr size_t ReturnCount(Bytecode bytecode) {
return Returns(bytecode) ? 1 : 0;
}
// Returns the number of operands expected by |bytecode|.
static int NumberOfOperands(Bytecode bytecode) {
DCHECK_LE(bytecode, Bytecode::kLast);

View File

@ -3112,8 +3112,7 @@ Handle<Code> GenerateBytecodeHandler(Isolate* isolate, Bytecode bytecode,
Bytecodes::ToString(bytecode),
FLAG_untrusted_code_mitigations
? PoisoningMitigationLevel::kPoisonCriticalOnly
: PoisoningMitigationLevel::kDontPoison,
Bytecodes::ReturnCount(bytecode));
: PoisoningMitigationLevel::kDontPoison);
switch (bytecode) {
#define CALL_GENERATOR(Name, ...) \
@ -3173,7 +3172,6 @@ class DeserializeLazyAssembler : public InterpreterAssembler {
Handle<Code> GenerateDeserializeLazyHandler(Isolate* isolate,
OperandScale operand_scale) {
Zone zone(isolate->allocator(), ZONE_NAME);
const size_t return_count = 0;
std::string debug_name = std::string("DeserializeLazy");
if (operand_scale > OperandScale::kSingle) {
@ -3187,8 +3185,7 @@ Handle<Code> GenerateDeserializeLazyHandler(Isolate* isolate,
debug_name.c_str(),
FLAG_untrusted_code_mitigations
? PoisoningMitigationLevel::kPoisonCriticalOnly
: PoisoningMitigationLevel::kDontPoison,
return_count);
: PoisoningMitigationLevel::kDontPoison);
DeserializeLazyAssembler::Generate(&state, operand_scale);
Handle<Code> code = compiler::CodeAssembler::GenerateCode(&state);

View File

@ -246,7 +246,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // argument count (argc)
@ -256,6 +258,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -246,7 +246,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
a0, // argument count (argc)
@ -256,6 +258,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -246,7 +246,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r3, // argument count (argc)
@ -256,6 +258,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -244,7 +244,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
r2, // argument count (argc)
@ -254,6 +256,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -247,7 +247,9 @@ void InterpreterPushArgsThenConstructDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
void InterpreterCEntryDescriptor::InitializePlatformSpecific(
namespace {
void InterpreterCEntryDescriptor_InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {
rax, // argument count (argc)
@ -257,6 +259,18 @@ void InterpreterCEntryDescriptor::InitializePlatformSpecific(
data->InitializePlatformSpecific(arraysize(registers), registers);
}
} // namespace
void InterpreterCEntry1Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void InterpreterCEntry2Descriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
InterpreterCEntryDescriptor_InitializePlatformSpecific(data);
}
void ResumeGeneratorDescriptor::InitializePlatformSpecific(
CallInterfaceDescriptorData* data) {
Register registers[] = {

View File

@ -27,8 +27,7 @@ InterpreterAssemblerTestState::InterpreterAssemblerTestState(
: compiler::CodeAssemblerState(
test->isolate(), test->zone(), InterpreterDispatchDescriptor{},
Code::BYTECODE_HANDLER, Bytecodes::ToString(bytecode),
PoisoningMitigationLevel::kPoisonCriticalOnly,
Bytecodes::ReturnCount(bytecode)) {}
PoisoningMitigationLevel::kPoisonCriticalOnly) {}
const interpreter::Bytecode kBytecodes[] = {
#define DEFINE_BYTECODE(Name, ...) interpreter::Bytecode::k##Name,