Refactoring InterfaceDescriptors away from code-stubs.h

Clean up and create seperation between the concept of a call descriptor and a
code stub interface descriptor. The former is just concerned with how to call,
but the latter has many extra hints related to code generation and
deoptimization for the implementation of a particular code stub.

R=yangguo@chromium.org

Review URL: https://codereview.chromium.org/517993002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23515 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mvstanton@chromium.org 2014-08-29 10:40:02 +00:00
parent fb7e3c8f95
commit 9514d34e14
21 changed files with 667 additions and 516 deletions

View File

@ -732,6 +732,8 @@ source_set("v8_base") {
"src/ic/stub-cache.h",
"src/interface.cc",
"src/interface.h",
"src/interface-descriptors.cc",
"src/interface-descriptors.h",
"src/interpreter-irregexp.cc",
"src/interpreter-irregexp.h",
"src/isolate.cc",
@ -889,6 +891,7 @@ source_set("v8_base") {
"src/ia32/frames-ia32.cc",
"src/ia32/frames-ia32.h",
"src/ia32/full-codegen-ia32.cc",
"src/ia32/interface-descriptors-ia32.cc",
"src/ia32/lithium-codegen-ia32.cc",
"src/ia32/lithium-codegen-ia32.h",
"src/ia32/lithium-gap-resolver-ia32.cc",
@ -925,6 +928,7 @@ source_set("v8_base") {
"src/x64/frames-x64.cc",
"src/x64/frames-x64.h",
"src/x64/full-codegen-x64.cc",
"src/x64/interface-descriptors-x64.cc",
"src/x64/lithium-codegen-x64.cc",
"src/x64/lithium-codegen-x64.h",
"src/x64/lithium-gap-resolver-x64.cc",
@ -965,6 +969,8 @@ source_set("v8_base") {
"src/arm/frames-arm.cc",
"src/arm/frames-arm.h",
"src/arm/full-codegen-arm.cc",
"src/arm/interface-descriptors-arm.cc",
"src/arm/interface-descriptors-arm.h",
"src/arm/lithium-arm.cc",
"src/arm/lithium-arm.h",
"src/arm/lithium-codegen-arm.cc",
@ -1013,6 +1019,8 @@ source_set("v8_base") {
"src/arm64/instructions-arm64.h",
"src/arm64/instrument-arm64.cc",
"src/arm64/instrument-arm64.h",
"src/arm64/interface-descriptors-arm64.cc",
"src/arm64/interface-descriptors-arm64.h",
"src/arm64/lithium-arm64.cc",
"src/arm64/lithium-arm64.h",
"src/arm64/lithium-codegen-arm64.cc",

View File

@ -133,9 +133,6 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
}
const Register InterfaceDescriptor::ContextRegister() { return cp; }
static void InitializeArrayConstructorDescriptor(
CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
@ -270,91 +267,6 @@ void StringAddStub::InitializeInterfaceDescriptor(
}
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
static PlatformInterfaceDescriptor noInlineDescriptor =
PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ArgumentAdaptorCall);
Register registers[] = { cp, // context
r1, // JSFunction
r0, // actual number of arguments
r2, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers,
representations, &default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::KeyedCall);
Register registers[] = { cp, // context
r2, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers,
representations, &noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::NamedCall);
Register registers[] = { cp, // context
r2, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers,
representations, &noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::CallHandler);
Register registers[] = { cp, // context
r0, // receiver
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers,
representations, &default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ApiFunctionCall);
Register registers[] = { cp, // context
r0, // callee
r4, // call_data
r2, // holder
r1, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers,
representations, &default_descriptor);
}
}
#define __ ACCESS_MASM(masm)

View File

@ -402,20 +402,6 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
LookupMode mode_;
};
class PlatformInterfaceDescriptor {
public:
explicit PlatformInterfaceDescriptor(
TargetAddressStorageMode storage_mode)
: storage_mode_(storage_mode) { }
TargetAddressStorageMode storage_mode() { return storage_mode_; }
private:
TargetAddressStorageMode storage_mode_;
};
} } // namespace v8::internal
#endif // V8_ARM_CODE_STUBS_ARM_H_

View File

@ -0,0 +1,108 @@
// 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.
#include "src/v8.h"
#if V8_TARGET_ARCH_ARM
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
const Register InterfaceDescriptor::ContextRegister() { return cp; }
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
static PlatformInterfaceDescriptor noInlineDescriptor =
PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
Register registers[] = {
cp, // context
r1, // JSFunction
r0, // actual number of arguments
r2, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers, representations,
&default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::KeyedCall);
Register registers[] = {
cp, // context
r2, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers, representations,
&noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NamedCall);
Register registers[] = {
cp, // context
r2, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers, representations,
&noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallHandler);
Register registers[] = {
cp, // context
r0, // receiver
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers, representations,
&default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ApiFunctionCall);
Register registers[] = {
cp, // context
r0, // callee
r4, // call_data
r2, // holder
r1, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers, representations,
&default_descriptor);
}
}
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_ARM

View File

@ -0,0 +1,26 @@
// 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.
#ifndef V8_ARM_INTERFACE_DESCRIPTORS_ARM_H_
#define V8_ARM_INTERFACE_DESCRIPTORS_ARM_H_
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
class PlatformInterfaceDescriptor {
public:
explicit PlatformInterfaceDescriptor(TargetAddressStorageMode storage_mode)
: storage_mode_(storage_mode) {}
TargetAddressStorageMode storage_mode() { return storage_mode_; }
private:
TargetAddressStorageMode storage_mode_;
};
}
} // namespace v8::internal
#endif // V8_ARM_INTERFACE_DESCRIPTORS_ARM_H_

View File

@ -160,9 +160,6 @@ void CompareNilICStub::InitializeInterfaceDescriptor(
}
const Register InterfaceDescriptor::ContextRegister() { return cp; }
static void InitializeArrayConstructorDescriptor(
CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
@ -307,91 +304,6 @@ void StringAddStub::InitializeInterfaceDescriptor(
}
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
static PlatformInterfaceDescriptor noInlineDescriptor =
PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ArgumentAdaptorCall);
Register registers[] = { cp, // context
x1, // JSFunction
x0, // actual number of arguments
x2, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers,
representations, &default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::KeyedCall);
Register registers[] = { cp, // context
x2, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers,
representations, &noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::NamedCall);
Register registers[] = { cp, // context
x2, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers,
representations, &noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::CallHandler);
Register registers[] = { cp, // context
x0, // receiver
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers,
representations, &default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ApiFunctionCall);
Register registers[] = { cp, // context
x0, // callee
x4, // call_data
x2, // holder
x1, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers,
representations, &default_descriptor);
}
}
#define __ ACCESS_MASM(masm)

View File

@ -454,20 +454,6 @@ class StringCompareStub: public PlatformCodeStub {
Label* chars_not_equal);
};
class PlatformInterfaceDescriptor {
public:
explicit PlatformInterfaceDescriptor(
TargetAddressStorageMode storage_mode)
: storage_mode_(storage_mode) { }
TargetAddressStorageMode storage_mode() { return storage_mode_; }
private:
TargetAddressStorageMode storage_mode_;
};
} } // namespace v8::internal
#endif // V8_ARM64_CODE_STUBS_ARM64_H_

View File

@ -0,0 +1,108 @@
// 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.
#include "src/v8.h"
#if V8_TARGET_ARCH_ARM64
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
const Register InterfaceDescriptor::ContextRegister() { return cp; }
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
static PlatformInterfaceDescriptor default_descriptor =
PlatformInterfaceDescriptor(CAN_INLINE_TARGET_ADDRESS);
static PlatformInterfaceDescriptor noInlineDescriptor =
PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
Register registers[] = {
cp, // context
x1, // JSFunction
x0, // actual number of arguments
x2, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers, representations,
&default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::KeyedCall);
Register registers[] = {
cp, // context
x2, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers, representations,
&noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NamedCall);
Register registers[] = {
cp, // context
x2, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers, representations,
&noInlineDescriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallHandler);
Register registers[] = {
cp, // context
x0, // receiver
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers, representations,
&default_descriptor);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ApiFunctionCall);
Register registers[] = {
cp, // context
x0, // callee
x4, // call_data
x2, // holder
x1, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers, representations,
&default_descriptor);
}
}
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_ARM64

View File

@ -0,0 +1,26 @@
// 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.
#ifndef V8_ARM64_INTERFACE_DESCRIPTORS_ARM64_H_
#define V8_ARM64_INTERFACE_DESCRIPTORS_ARM64_H_
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
class PlatformInterfaceDescriptor {
public:
explicit PlatformInterfaceDescriptor(TargetAddressStorageMode storage_mode)
: storage_mode_(storage_mode) {}
TargetAddressStorageMode storage_mode() { return storage_mode_; }
private:
TargetAddressStorageMode storage_mode_;
};
}
} // namespace v8::internal
#endif // V8_ARM64_INTERFACE_DESCRIPTORS_ARM64_H_

View File

@ -16,10 +16,6 @@ namespace v8 {
namespace internal {
InterfaceDescriptor::InterfaceDescriptor()
: register_param_count_(-1) { }
CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor()
: stack_parameter_count_(no_reg),
hint_stack_parameter_count_(-1),
@ -30,38 +26,6 @@ CodeStubInterfaceDescriptor::CodeStubInterfaceDescriptor()
has_miss_handler_(false) { }
void InterfaceDescriptor::Initialize(
int register_parameter_count,
Register* registers,
Representation* register_param_representations,
PlatformInterfaceDescriptor* platform_descriptor) {
platform_specific_descriptor_ = platform_descriptor;
register_param_count_ = register_parameter_count;
// An interface descriptor must have a context register.
DCHECK(register_parameter_count > 0 && registers[0].is(ContextRegister()));
// InterfaceDescriptor owns a copy of the registers array.
register_params_.Reset(NewArray<Register>(register_parameter_count));
for (int i = 0; i < register_parameter_count; i++) {
register_params_[i] = registers[i];
}
// If a representations array is specified, then the descriptor owns that as
// well.
if (register_param_representations != NULL) {
register_param_representations_.Reset(
NewArray<Representation>(register_parameter_count));
for (int i = 0; i < register_parameter_count; i++) {
// If there is a context register, the representation must be tagged.
DCHECK(i != 0 || register_param_representations[i].Equals(
Representation::Tagged()));
register_param_representations_[i] = register_param_representations[i];
}
}
}
void CodeStubInterfaceDescriptor::Initialize(
CodeStub::Major major, int register_parameter_count, Register* registers,
Address deoptimization_handler,
@ -92,16 +56,6 @@ void CodeStubInterfaceDescriptor::Initialize(
}
void CallInterfaceDescriptor::Initialize(
int register_parameter_count,
Register* registers,
Representation* param_representations,
PlatformInterfaceDescriptor* platform_descriptor) {
InterfaceDescriptor::Initialize(register_parameter_count, registers,
param_representations, platform_descriptor);
}
bool CodeStub::FindCodeInCache(Code** code_out) {
UnseededNumberDictionary* stubs = isolate()->heap()->code_stubs();
int index = stubs->FindEntry(GetKey());

View File

@ -11,6 +11,7 @@
#include "src/globals.h"
#include "src/ic/ic.h"
#include "src/ic/ic-conventions.h"
#include "src/interface-descriptors.h"
#include "src/macro-assembler.h"
#include "src/ostreams.h"
@ -280,79 +281,6 @@ enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS };
class PlatformInterfaceDescriptor;
class InterfaceDescriptor {
public:
bool IsInitialized() const { return register_param_count_ >= 0; }
int GetEnvironmentLength() const { return register_param_count_; }
int GetRegisterParameterCount() const { return register_param_count_; }
Register GetParameterRegister(int index) const {
return register_params_[index];
}
Representation GetParameterRepresentation(int index) const {
DCHECK(index < register_param_count_);
if (register_param_representations_.get() == NULL) {
return Representation::Tagged();
}
return register_param_representations_[index];
}
// "Environment" versions of parameter functions. The first register
// parameter (context) is not included.
int GetEnvironmentParameterCount() const {
return GetEnvironmentLength() - 1;
}
Register GetEnvironmentParameterRegister(int index) const {
return GetParameterRegister(index + 1);
}
Representation GetEnvironmentParameterRepresentation(int index) const {
return GetParameterRepresentation(index + 1);
}
// Some platforms have extra information to associate with the descriptor.
PlatformInterfaceDescriptor* platform_specific_descriptor() const {
return platform_specific_descriptor_;
}
static const Register ContextRegister();
protected:
InterfaceDescriptor();
virtual ~InterfaceDescriptor() {}
void Initialize(int register_parameter_count, Register* registers,
Representation* register_param_representations,
PlatformInterfaceDescriptor* platform_descriptor = NULL);
private:
int register_param_count_;
// 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.
SmartArrayPointer<Register> register_params_;
// Specifies Representations for the stub's parameter. Points to an array of
// Representations of the same length of the numbers of parameters to the
// stub, or if NULL (the default value), Representation of each parameter
// assumed to be Tagged().
SmartArrayPointer<Representation> register_param_representations_;
PlatformInterfaceDescriptor* platform_specific_descriptor_;
DISALLOW_COPY_AND_ASSIGN(InterfaceDescriptor);
};
class CodeStubInterfaceDescriptor: public InterfaceDescriptor {
public:
CodeStubInterfaceDescriptor();
@ -421,23 +349,6 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor {
};
class CallInterfaceDescriptor: public InterfaceDescriptor {
public:
CallInterfaceDescriptor() { }
// A copy of the passed in registers and param_representations is made
// and owned by the CallInterfaceDescriptor.
// TODO(mvstanton): Instead of taking parallel arrays register and
// param_representations, how about a struct that puts the representation
// and register side by side (eg, RegRep(r1, Representation::Tagged()).
// The same should go for the CodeStubInterfaceDescriptor class.
void Initialize(int register_parameter_count, Register* registers,
Representation* param_representations,
PlatformInterfaceDescriptor* platform_descriptor = NULL);
};
class HydrogenCodeStub : public CodeStub {
public:
enum InitializationState {
@ -2660,11 +2571,6 @@ class ProfileEntryHookStub : public PlatformCodeStub {
};
class CallDescriptors {
public:
static void InitializeForIsolate(Isolate* isolate);
};
} } // namespace v8::internal
#endif // V8_CODE_STUBS_H_

View File

@ -7393,7 +7393,7 @@ HInstruction* HOptimizedGraphBuilder::NewArgumentAdaptorCall(
HValue* fun, HValue* context,
int argument_count, HValue* expected_param_count) {
CallInterfaceDescriptor* descriptor =
isolate()->call_descriptor(Isolate::ArgumentAdaptorCall);
isolate()->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
HValue* arity = Add<HConstant>(argument_count - 1);
@ -8644,7 +8644,7 @@ bool HOptimizedGraphBuilder::TryInlineApiCall(Handle<JSFunction> function,
};
CallInterfaceDescriptor* descriptor =
isolate()->call_descriptor(Isolate::ApiFunctionCall);
isolate()->call_descriptor(CallDescriptorKey::ApiFunctionCall);
CallApiFunctionStub stub(isolate(), is_store, call_data_is_undefined, argc);
Handle<Code> code = stub.GetCode();

View File

@ -123,9 +123,6 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
}
const Register InterfaceDescriptor::ContextRegister() { return esi; }
static void InitializeArrayConstructorDescriptor(
Isolate* isolate, CodeStub::Major major,
CodeStubInterfaceDescriptor* descriptor,
@ -268,80 +265,6 @@ void StringAddStub::InitializeInterfaceDescriptor(
}
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ArgumentAdaptorCall);
Register registers[] = { esi, // context
edi, // JSFunction
eax, // actual number of arguments
ebx, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::KeyedCall);
Register registers[] = { esi, // context
ecx, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::NamedCall);
Register registers[] = { esi, // context
ecx, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::CallHandler);
Register registers[] = { esi, // context
edx, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ApiFunctionCall);
Register registers[] = { esi, // context
eax, // callee
ebx, // call_data
ecx, // holder
edx, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
}
#define __ ACCESS_MASM(masm)

View File

@ -0,0 +1,97 @@
// 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.
#include "src/v8.h"
#if V8_TARGET_ARCH_IA32
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
const Register InterfaceDescriptor::ContextRegister() { return esi; }
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
Register registers[] = {
esi, // context
edi, // JSFunction
eax, // actual number of arguments
ebx, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::KeyedCall);
Register registers[] = {
esi, // context
ecx, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NamedCall);
Register registers[] = {
esi, // context
ecx, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallHandler);
Register registers[] = {
esi, // context
edx, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ApiFunctionCall);
Register registers[] = {
esi, // context
eax, // callee
ebx, // call_data
ecx, // holder
edx, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
}
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_IA32

View File

@ -0,0 +1,55 @@
// 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.
#include "src/v8.h"
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
InterfaceDescriptor::InterfaceDescriptor() : register_param_count_(-1) {}
void InterfaceDescriptor::Initialize(
int register_parameter_count, Register* registers,
Representation* register_param_representations,
PlatformInterfaceDescriptor* platform_descriptor) {
platform_specific_descriptor_ = platform_descriptor;
register_param_count_ = register_parameter_count;
// An interface descriptor must have a context register.
DCHECK(register_parameter_count > 0 && registers[0].is(ContextRegister()));
// InterfaceDescriptor owns a copy of the registers array.
register_params_.Reset(NewArray<Register>(register_parameter_count));
for (int i = 0; i < register_parameter_count; i++) {
register_params_[i] = registers[i];
}
// If a representations array is specified, then the descriptor owns that as
// well.
if (register_param_representations != NULL) {
register_param_representations_.Reset(
NewArray<Representation>(register_parameter_count));
for (int i = 0; i < register_parameter_count; i++) {
// If there is a context register, the representation must be tagged.
DCHECK(
i != 0 ||
register_param_representations[i].Equals(Representation::Tagged()));
register_param_representations_[i] = register_param_representations[i];
}
}
}
void CallInterfaceDescriptor::Initialize(
int register_parameter_count, Register* registers,
Representation* param_representations,
PlatformInterfaceDescriptor* platform_descriptor) {
InterfaceDescriptor::Initialize(register_parameter_count, registers,
param_representations, platform_descriptor);
}
}
} // namespace v8::internal

126
src/interface-descriptors.h Normal file
View File

@ -0,0 +1,126 @@
// Copyright 2014 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_CALL_INTERFACE_DESCRIPTOR_H_
#define V8_CALL_INTERFACE_DESCRIPTOR_H_
#include "src/assembler.h"
#include "src/macro-assembler.h"
namespace v8 {
namespace internal {
class PlatformInterfaceDescriptor;
class InterfaceDescriptor {
public:
bool IsInitialized() const { return register_param_count_ >= 0; }
int GetEnvironmentLength() const { return register_param_count_; }
int GetRegisterParameterCount() const { return register_param_count_; }
Register GetParameterRegister(int index) const {
return register_params_[index];
}
Representation GetParameterRepresentation(int index) const {
DCHECK(index < register_param_count_);
if (register_param_representations_.get() == NULL) {
return Representation::Tagged();
}
return register_param_representations_[index];
}
// "Environment" versions of parameter functions. The first register
// parameter (context) is not included.
int GetEnvironmentParameterCount() const {
return GetEnvironmentLength() - 1;
}
Register GetEnvironmentParameterRegister(int index) const {
return GetParameterRegister(index + 1);
}
Representation GetEnvironmentParameterRepresentation(int index) const {
return GetParameterRepresentation(index + 1);
}
// Some platforms have extra information to associate with the descriptor.
PlatformInterfaceDescriptor* platform_specific_descriptor() const {
return platform_specific_descriptor_;
}
static const Register ContextRegister();
protected:
InterfaceDescriptor();
virtual ~InterfaceDescriptor() {}
void Initialize(int register_parameter_count, Register* registers,
Representation* register_param_representations,
PlatformInterfaceDescriptor* platform_descriptor = NULL);
private:
int register_param_count_;
// 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.
SmartArrayPointer<Register> register_params_;
// Specifies Representations for the stub's parameter. Points to an array of
// Representations of the same length of the numbers of parameters to the
// stub, or if NULL (the default value), Representation of each parameter
// assumed to be Tagged().
SmartArrayPointer<Representation> register_param_representations_;
PlatformInterfaceDescriptor* platform_specific_descriptor_;
DISALLOW_COPY_AND_ASSIGN(InterfaceDescriptor);
};
enum CallDescriptorKey {
KeyedCall,
NamedCall,
CallHandler,
ArgumentAdaptorCall,
ApiFunctionCall,
NUMBER_OF_CALL_DESCRIPTORS
};
class CallInterfaceDescriptor : public InterfaceDescriptor {
public:
CallInterfaceDescriptor() {}
// A copy of the passed in registers and param_representations is made
// and owned by the CallInterfaceDescriptor.
// TODO(mvstanton): Instead of taking parallel arrays register and
// param_representations, how about a struct that puts the representation
// and register side by side (eg, RegRep(r1, Representation::Tagged()).
// The same should go for the CodeStubInterfaceDescriptor class.
void Initialize(int register_parameter_count, Register* registers,
Representation* param_representations,
PlatformInterfaceDescriptor* platform_descriptor = NULL);
};
class CallDescriptors {
public:
static void InitializeForIsolate(Isolate* isolate);
};
}
} // namespace v8::internal
#if V8_TARGET_ARCH_ARM64
#include "src/arm64/interface-descriptors-arm64.h"
#elif V8_TARGET_ARCH_ARM
#include "src/arm/interface-descriptors-arm.h"
#endif
#endif // V8_CALL_INTERFACE_DESCRIPTOR_H_

View File

@ -2030,6 +2030,8 @@ bool Isolate::Init(Deserializer* des) {
kDeoptTableSerializeEntryCount - 1);
}
CallDescriptors::InitializeForIsolate(this);
if (!serializer_enabled()) {
// Ensure that all stubs which need to be generated ahead of time, but
// cannot be serialized into the snapshot have been generated.
@ -2057,8 +2059,6 @@ bool Isolate::Init(Deserializer* des) {
LoadFastElementStub::InstallDescriptors(this);
}
CallDescriptors::InitializeForIsolate(this);
initialized_from_snapshot_ = (des != NULL);
return true;
@ -2242,9 +2242,8 @@ CodeStubInterfaceDescriptor*
}
CallInterfaceDescriptor*
Isolate::call_descriptor(CallDescriptorKey index) {
DCHECK(0 <= index && index < NUMBER_OF_CALL_DESCRIPTORS);
CallInterfaceDescriptor* Isolate::call_descriptor(int index) {
DCHECK(0 <= index && index < CallDescriptorKey::NUMBER_OF_CALL_DESCRIPTORS);
return &call_descriptors_[index];
}

View File

@ -1022,16 +1022,7 @@ class Isolate {
CodeStubInterfaceDescriptor*
code_stub_interface_descriptor(int index);
enum CallDescriptorKey {
KeyedCall,
NamedCall,
CallHandler,
ArgumentAdaptorCall,
ApiFunctionCall,
NUMBER_OF_CALL_DESCRIPTORS
};
CallInterfaceDescriptor* call_descriptor(CallDescriptorKey index);
CallInterfaceDescriptor* call_descriptor(int index);
void IterateDeferredHandles(ObjectVisitor* visitor);
void LinkDeferredHandles(DeferredHandles* deferred_handles);

View File

@ -122,9 +122,6 @@ void TransitionElementsKindStub::InitializeInterfaceDescriptor(
}
const Register InterfaceDescriptor::ContextRegister() { return rsi; }
static void InitializeArrayConstructorDescriptor(
CodeStub::Major major, CodeStubInterfaceDescriptor* descriptor,
int constant_stack_parameter_count) {
@ -268,80 +265,6 @@ void StringAddStub::InitializeInterfaceDescriptor(
}
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ArgumentAdaptorCall);
Register registers[] = { rsi, // context
rdi, // JSFunction
rax, // actual number of arguments
rbx, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::KeyedCall);
Register registers[] = { rsi, // context
rcx, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::NamedCall);
Register registers[] = { rsi, // context
rcx, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::CallHandler);
Register registers[] = { rsi, // context
rdx, // receiver
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(Isolate::ApiFunctionCall);
Register registers[] = { rsi, // context
rax, // callee
rbx, // call_data
rcx, // holder
rdx, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
}
#define __ ACCESS_MASM(masm)

View File

@ -0,0 +1,97 @@
// 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.
#include "src/v8.h"
#if V8_TARGET_ARCH_X64
#include "src/interface-descriptors.h"
namespace v8 {
namespace internal {
const Register InterfaceDescriptor::ContextRegister() { return rsi; }
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
Register registers[] = {
rsi, // context
rdi, // JSFunction
rax, // actual number of arguments
rbx, // expected number of arguments
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // JSFunction
Representation::Integer32(), // actual number of arguments
Representation::Integer32(), // expected number of arguments
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::KeyedCall);
Register registers[] = {
rsi, // context
rcx, // key
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // key
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NamedCall);
Register registers[] = {
rsi, // context
rcx, // name
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // name
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallHandler);
Register registers[] = {
rsi, // context
rdx, // receiver
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // receiver
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ApiFunctionCall);
Register registers[] = {
rsi, // context
rax, // callee
rbx, // call_data
rcx, // holder
rdx, // api_function_address
};
Representation representations[] = {
Representation::Tagged(), // context
Representation::Tagged(), // callee
Representation::Tagged(), // call_data
Representation::Tagged(), // holder
Representation::External(), // api_function_address
};
descriptor->Initialize(arraysize(registers), registers, representations);
}
}
}
} // namespace v8::internal
#endif // V8_TARGET_ARCH_X64

View File

@ -613,6 +613,8 @@
'../../src/ic/ic-conventions.h',
'../../src/interface.cc',
'../../src/interface.h',
'../../src/interface-descriptors.cc',
'../../src/interface-descriptors.h',
'../../src/interpreter-irregexp.cc',
'../../src/interpreter-irregexp.h',
'../../src/isolate.cc',
@ -781,6 +783,8 @@
'../../src/arm/frames-arm.cc',
'../../src/arm/frames-arm.h',
'../../src/arm/full-codegen-arm.cc',
'../../src/arm/interface-descriptors-arm.cc',
'../../src/arm/interface-descriptors-arm.h',
'../../src/arm/lithium-arm.cc',
'../../src/arm/lithium-arm.h',
'../../src/arm/lithium-codegen-arm.cc',
@ -833,6 +837,8 @@
'../../src/arm64/instructions-arm64.h',
'../../src/arm64/instrument-arm64.cc',
'../../src/arm64/instrument-arm64.h',
'../../src/arm64/interface-descriptors-arm64.cc',
'../../src/arm64/interface-descriptors-arm64.h',
'../../src/arm64/lithium-arm64.cc',
'../../src/arm64/lithium-arm64.h',
'../../src/arm64/lithium-codegen-arm64.cc',
@ -877,6 +883,7 @@
'../../src/ia32/frames-ia32.cc',
'../../src/ia32/frames-ia32.h',
'../../src/ia32/full-codegen-ia32.cc',
'../../src/ia32/interface-descriptors-ia32.cc',
'../../src/ia32/lithium-codegen-ia32.cc',
'../../src/ia32/lithium-codegen-ia32.h',
'../../src/ia32/lithium-gap-resolver-ia32.cc',
@ -1027,6 +1034,7 @@
'../../src/x64/frames-x64.cc',
'../../src/x64/frames-x64.h',
'../../src/x64/full-codegen-x64.cc',
'../../src/x64/interface-descriptors-x64.cc',
'../../src/x64/lithium-codegen-x64.cc',
'../../src/x64/lithium-codegen-x64.h',
'../../src/x64/lithium-gap-resolver-x64.cc',