Multiple stubs can point to the same calling convention.

R=yangguo@chromium.org

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

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23546 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 58a5d15b
This diff is collapsed.
......@@ -21,6 +21,156 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
static PlatformInterfaceDescriptor noInlineDescriptor =
PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
InitializeForIsolateAllPlatforms(isolate);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewClosureCall);
Register registers[] = {cp, r2};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewContextCall);
Register registers[] = {cp, r1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToNumberCall);
Register registers[] = {cp, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NumberToStringCall);
Register registers[] = {cp, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowArrayCall);
Register registers[] = {cp, r3, r2, r1};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Smi(), Representation::Tagged()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowObjectCall);
Register registers[] = {cp, r3, r2, r1, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CreateAllocationSiteCall);
Register registers[] = {cp, r2, r3};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallFunctionCall);
Register registers[] = {cp, r1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallConstructCall);
// r0 : number of arguments
// r1 : the function to call
// r2 : feedback vector
// r3 : (only if r2 is not the megamorphic symbol) slot in feedback
// vector (Smi)
// TODO(turbofan): So far we don't gather type feedback and hence skip the
// slot parameter, but ArrayConstructStub needs the vector to be undefined.
Register registers[] = {cp, r0, r1, r2};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::RegExpConstructResultCall);
Register registers[] = {cp, r2, r1, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::TransitionElementsKindCall);
Register registers[] = {cp, r0, r1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::ArrayConstructorConstantArgCountCall);
// register state
// cp -- context
// r0 -- number of arguments
// r1 -- function
// r2 -- allocation site with elements kind
Register registers[] = {cp, r1, r2};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {cp, r1, r2, r0};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Tagged(), Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorConstantArgCountCall);
// register state
// cp -- context
// r0 -- number of arguments
// r1 -- constructor function
Register registers[] = {cp, r1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {cp, r1, r0};
Representation representations[] = {Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CompareNilCall);
Register registers[] = {cp, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToBooleanCall);
Register registers[] = {cp, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::BinaryOpCall);
Register registers[] = {cp, r1, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::BinaryOpWithAllocationSiteCall);
Register registers[] = {cp, r2, r1, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::StringAddCall);
Register registers[] = {cp, r1, r0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
......
This diff is collapsed.
......@@ -21,6 +21,195 @@ void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
static PlatformInterfaceDescriptor noInlineDescriptor =
PlatformInterfaceDescriptor(NEVER_INLINE_TARGET_ADDRESS);
InitializeForIsolateAllPlatforms(isolate);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewClosureCall);
// cp: context
// x2: function info
Register registers[] = {cp, x2};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewContextCall);
// cp: context
// x1: function
Register registers[] = {cp, x1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToNumberCall);
// cp: context
// x0: value
Register registers[] = {cp, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NumberToStringCall);
// cp: context
// x0: value
Register registers[] = {cp, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowArrayCall);
// cp: context
// x3: array literals array
// x2: array literal index
// x1: constant elements
Register registers[] = {cp, x3, x2, x1};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Smi(), Representation::Tagged()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowObjectCall);
// cp: context
// x3: object literals array
// x2: object literal index
// x1: constant properties
// x0: object literal flags
Register registers[] = {cp, x3, x2, x1, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CreateAllocationSiteCall);
// cp: context
// x2: feedback vector
// x3: call feedback slot
Register registers[] = {cp, x2, x3};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallFunctionCall);
// x1 function the function to call
Register registers[] = {cp, x1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallConstructCall);
// x0 : number of arguments
// x1 : the function to call
// x2 : feedback vector
// x3 : slot in feedback vector (smi) (if r2 is not the megamorphic symbol)
// TODO(turbofan): So far we don't gather type feedback and hence skip the
// slot parameter, but ArrayConstructStub needs the vector to be undefined.
Register registers[] = {cp, x0, x1, x2};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::RegExpConstructResultCall);
// cp: context
// x2: length
// x1: index (of last match)
// x0: string
Register registers[] = {cp, x2, x1, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::TransitionElementsKindCall);
// cp: context
// x0: value (js_array)
// x1: to_map
Register registers[] = {cp, x0, x1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::ArrayConstructorConstantArgCountCall);
// cp: context
// x1: function
// x2: allocation site with elements kind
// x0: number of arguments to the constructor function
Register registers[] = {cp, x1, x2};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {cp, x1, x2, x0};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Tagged(), Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorConstantArgCountCall);
// cp: context
// x1: constructor function
// x0: number of arguments to the constructor function
Register registers[] = {cp, x1};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {cp, x1, x0};
Representation representations[] = {Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CompareNilCall);
// cp: context
// x0: value to compare
Register registers[] = {cp, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToBooleanCall);
// cp: context
// x0: value
Register registers[] = {cp, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::BinaryOpCall);
// cp: context
// x1: left operand
// x0: right operand
Register registers[] = {cp, x1, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::BinaryOpWithAllocationSiteCall);
// cp: context
// x2: allocation site
// x1: left operand
// x0: right operand
Register registers[] = {cp, x2, x1, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::StringAddCall);
// cp: context
// x1: left operand
// x0: right operand
Register registers[] = {cp, x1, x0};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
......
This diff is collapsed.
......@@ -281,19 +281,19 @@ enum StubFunctionMode { NOT_JS_FUNCTION_STUB_MODE, JS_FUNCTION_STUB_MODE };
enum HandlerArgumentsMode { DONT_PASS_ARGUMENTS, PASS_ARGUMENTS };
class CodeStubInterfaceDescriptor: public InterfaceDescriptor {
class CodeStubInterfaceDescriptor {
public:
CodeStubInterfaceDescriptor();
void Initialize(CodeStub::Major major, int register_parameter_count,
Register* registers, Address deoptimization_handler = NULL,
Representation* register_param_representations = NULL,
void Initialize(CodeStub::Major major,
CallInterfaceDescriptor* call_descriptor,
Address deoptimization_handler = NULL,
int hint_stack_parameter_count = -1,
StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE);
void Initialize(CodeStub::Major major, int register_parameter_count,
Register* registers, Register stack_parameter_count,
void Initialize(CodeStub::Major major,
CallInterfaceDescriptor* call_descriptor,
Register stack_parameter_count,
Address deoptimization_handler = NULL,
Representation* register_param_representations = NULL,
int hint_stack_parameter_count = -1,
StubFunctionMode function_mode = NOT_JS_FUNCTION_STUB_MODE,
HandlerArgumentsMode handler_mode = DONT_PASS_ARGUMENTS);
......@@ -306,6 +306,38 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor {
DCHECK(!stack_parameter_count_.is_valid());
}
bool IsInitialized() const { return call_descriptor_ != NULL; }
CallInterfaceDescriptor* call_descriptor() const { return call_descriptor_; }
int GetEnvironmentLength() const {
return call_descriptor()->GetEnvironmentLength();
}
int GetRegisterParameterCount() const {
return call_descriptor()->GetRegisterParameterCount();
}
Register GetParameterRegister(int index) const {
return call_descriptor()->GetParameterRegister(index);
}
Representation GetParameterRepresentation(int index) const {
return call_descriptor()->GetParameterRepresentation(index);
}
int GetEnvironmentParameterCount() const {
return call_descriptor()->GetEnvironmentParameterCount();
}
Register GetEnvironmentParameterRegister(int index) const {
return call_descriptor()->GetEnvironmentParameterRegister(index);
}
Representation GetEnvironmentParameterRepresentation(int index) const {
return call_descriptor()->GetEnvironmentParameterRepresentation(index);
}
ExternalReference miss_handler() const {
DCHECK(has_miss_handler_);
return miss_handler_;
......@@ -316,11 +348,12 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor {
}
bool IsEnvironmentParameterCountRegister(int index) const {
return GetEnvironmentParameterRegister(index).is(stack_parameter_count_);
return call_descriptor()->GetEnvironmentParameterRegister(index).is(
stack_parameter_count_);
}
int GetHandlerParameterCount() const {
int params = GetEnvironmentParameterCount();
int params = call_descriptor()->GetEnvironmentParameterCount();
if (handler_arguments_mode_ == PASS_ARGUMENTS) {
params += 1;
}
......@@ -334,6 +367,7 @@ class CodeStubInterfaceDescriptor: public InterfaceDescriptor {
CodeStub::Major MajorKey() const { return major_; }
private:
CallInterfaceDescriptor* call_descriptor_;
Register stack_parameter_count_;
// If hint_stack_parameter_count_ > 0, the code stub can optimize the
// return sequence. Default value is -1, which means it is ignored.
......@@ -671,8 +705,8 @@ class InstanceofStub: public PlatformCodeStub {
void Generate(MacroAssembler* masm);
static Register left();
static Register right();
static Register left() { return InstanceofConvention::left(); }
static Register right() { return InstanceofConvention::right(); }
virtual void InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor);
......
......@@ -46,10 +46,9 @@ class LoadICStubShim : public HydrogenCodeStub {
virtual void InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE {
Register registers[] = {InterfaceDescriptor::ContextRegister(),
LoadConvention::ReceiverRegister(),
LoadConvention::NameRegister()};
descriptor->Initialize(MajorKey(), arraysize(registers), registers);
CallInterfaceDescriptor* call_descriptor =
isolate()->call_descriptor(CallDescriptorKey::LoadICCall);
descriptor->Initialize(MajorKey(), call_descriptor);
}
private:
......@@ -76,10 +75,9 @@ class KeyedLoadICStubShim : public HydrogenCodeStub {
virtual void InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE {
Register registers[] = {InterfaceDescriptor::ContextRegister(),
LoadConvention::ReceiverRegister(),
LoadConvention::NameRegister()};
descriptor->Initialize(MajorKey(), arraysize(registers), registers);
CallInterfaceDescriptor* call_descriptor =
isolate()->call_descriptor(CallDescriptorKey::LoadICCall);
descriptor->Initialize(MajorKey(), call_descriptor);
}
private:
......@@ -105,11 +103,9 @@ class StoreICStubShim : public HydrogenCodeStub {
virtual void InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE {
Register registers[] = {InterfaceDescriptor::ContextRegister(),
StoreConvention::ReceiverRegister(),
StoreConvention::NameRegister(),
StoreConvention::ValueRegister()};
descriptor->Initialize(MajorKey(), arraysize(registers), registers);
CallInterfaceDescriptor* call_descriptor =
isolate()->call_descriptor(CallDescriptorKey::StoreICCall);
descriptor->Initialize(MajorKey(), call_descriptor);
}
private:
......@@ -139,11 +135,9 @@ class KeyedStoreICStubShim : public HydrogenCodeStub {
virtual void InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE {
Register registers[] = {InterfaceDescriptor::ContextRegister(),
StoreConvention::ReceiverRegister(),
StoreConvention::NameRegister(),
StoreConvention::ValueRegister()};
descriptor->Initialize(MajorKey(), arraysize(registers), registers);
CallInterfaceDescriptor* call_descriptor =
isolate()->call_descriptor(CallDescriptorKey::StoreICCall);
descriptor->Initialize(MajorKey(), call_descriptor);
}
private:
......
This diff is collapsed.
......@@ -6,6 +6,7 @@
#if V8_TARGET_ARCH_IA32
#include "src/ic/ic-conventions.h"
#include "src/interface-descriptors.h"
namespace v8 {
......@@ -15,6 +16,155 @@ const Register InterfaceDescriptor::ContextRegister() { return esi; }
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
InitializeForIsolateAllPlatforms(isolate);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewClosureCall);
Register registers[] = {esi, ebx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewContextCall);
Register registers[] = {esi, edi};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToNumberCall);
// ToNumberStub invokes a function, and therefore needs a context.
Register registers[] = {esi, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NumberToStringCall);
Register registers[] = {esi, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowArrayCall);
Register registers[] = {esi, eax, ebx, ecx};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Smi(), Representation::Tagged()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowObjectCall);
Register registers[] = {esi, eax, ebx, ecx, edx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CreateAllocationSiteCall);
Register registers[] = {esi, ebx, edx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallFunctionCall);
Register registers[] = {esi, edi};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallConstructCall);
// eax : number of arguments
// ebx : feedback vector
// edx : (only if ebx is not the megamorphic symbol) slot in feedback
// vector (Smi)
// edi : constructor function
// TODO(turbofan): So far we don't gather type feedback and hence skip the
// slot parameter, but ArrayConstructStub needs the vector to be undefined.
Register registers[] = {esi, eax, edi, ebx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::RegExpConstructResultCall);
Register registers[] = {esi, ecx, ebx, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::TransitionElementsKindCall);
Register registers[] = {esi, eax, ebx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::ArrayConstructorConstantArgCountCall);
// register state
// eax -- number of arguments
// edi -- function
// ebx -- allocation site with elements kind
Register registers[] = {esi, edi, ebx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {esi, edi, ebx, eax};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Tagged(), Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorConstantArgCountCall);
// register state
// eax -- number of arguments
// edi -- function
Register registers[] = {esi, edi};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {esi, edi, eax};
Representation representations[] = {Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CompareNilCall);
Register registers[] = {esi, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToBooleanCall);
Register registers[] = {esi, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::BinaryOpCall);
Register registers[] = {esi, edx, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::BinaryOpWithAllocationSiteCall);
Register registers[] = {esi, ecx, edx, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::StringAddCall);
Register registers[] = {esi, edx, eax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
......
......@@ -17,24 +17,20 @@ const Register LoadConvention::ReceiverRegister() { return r1; }
const Register LoadConvention::NameRegister() { return r2; }
const Register VectorLoadConvention::SlotRegister() {
DCHECK(FLAG_vector_ics);
return r0;
}
const Register VectorLoadConvention::SlotRegister() { return r0; }
const Register FullVectorLoadConvention::VectorRegister() {
DCHECK(FLAG_vector_ics);
return r3;
}
const Register FullVectorLoadConvention::VectorRegister() { return r3; }
const Register StoreConvention::ReceiverRegister() { return r1; }
const Register StoreConvention::NameRegister() { return r2; }
const Register StoreConvention::ValueRegister() { return r0; }
const Register StoreConvention::MapRegister() { return r3; }
const Register StoreConvention::MapRegister() { return r3; }
const Register InstanceofConvention::left() { return r0; }
const Register InstanceofConvention::right() { return r1; }
}
} // namespace v8::internal
......
......@@ -16,16 +16,11 @@ namespace internal {
const Register LoadConvention::ReceiverRegister() { return x1; }
const Register LoadConvention::NameRegister() { return x2; }
const Register VectorLoadConvention::SlotRegister() {
DCHECK(FLAG_vector_ics);
return x0;
}
const Register VectorLoadConvention::SlotRegister() { return x0; }
const Register FullVectorLoadConvention::VectorRegister() {
DCHECK(FLAG_vector_ics);
return x3;
}
const Register FullVectorLoadConvention::VectorRegister() { return x3; }
const Register StoreConvention::ReceiverRegister() { return x1; }
......@@ -34,6 +29,18 @@ const Register StoreConvention::ValueRegister() { return x0; }
const Register StoreConvention::MapRegister() { return x3; }
const Register InstanceofConvention::left() {
// Object to check (instanceof lhs).
return x11;
}
const Register InstanceofConvention::right() {
// Constructor function (instanceof rhs).
return x10;
}
}
} // namespace v8::internal
......
......@@ -18,22 +18,20 @@ const Register LoadConvention::ReceiverRegister() { return edx; }
const Register LoadConvention::NameRegister() { return ecx; }
const Register VectorLoadConvention::SlotRegister() {
DCHECK(FLAG_vector_ics);
return eax;
}
const Register VectorLoadConvention::SlotRegister() { return eax; }
const Register FullVectorLoadConvention::VectorRegister() {
DCHECK(FLAG_vector_ics);
return ebx;
}
const Register FullVectorLoadConvention::VectorRegister() { return ebx; }
const Register StoreConvention::ReceiverRegister() { return edx; }
const Register StoreConvention::NameRegister() { return ecx; }
const Register StoreConvention::ValueRegister() { return eax; }
const Register StoreConvention::MapRegister() { return ebx; }
const Register InstanceofConvention::left() { return eax; }
const Register InstanceofConvention::right() { return edx; }
}
} // namespace v8::internal
......
......@@ -58,6 +58,14 @@ class StoreConvention {
// stub implementations requires it to be initialized.
static const Register MapRegister();
};
class InstanceofConvention {
public:
enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount };
static const Register left();
static const Register right();
};
}
} // namespace v8::internal
......
......@@ -17,24 +17,21 @@ const Register LoadConvention::ReceiverRegister() { return rdx; }
const Register LoadConvention::NameRegister() { return rcx; }
const Register VectorLoadConvention::SlotRegister() {
DCHECK(FLAG_vector_ics);
return rax;
}
const Register VectorLoadConvention::SlotRegister() { return rax; }
const Register FullVectorLoadConvention::VectorRegister() {
DCHECK(FLAG_vector_ics);
return rbx;
}
const Register FullVectorLoadConvention::VectorRegister() { return rbx; }
const Register StoreConvention::ReceiverRegister() { return rdx; }
const Register StoreConvention::NameRegister() { return rcx; }
const Register StoreConvention::ValueRegister() { return rax; }
const Register StoreConvention::MapRegister() { return rbx; }
const Register StoreConvention::MapRegister() { return rbx; }
// Passing arguments in registers is not supported.
const Register InstanceofConvention::left() { return rax; }
const Register InstanceofConvention::right() { return rdx; }
}
} // namespace v8::internal
......
......@@ -4,6 +4,7 @@
#include "src/v8.h"
#include "src/ic/ic-conventions.h"
#include "src/interface-descriptors.h"
namespace v8 {
......@@ -51,5 +52,53 @@ void CallInterfaceDescriptor::Initialize(
InterfaceDescriptor::Initialize(register_parameter_count, registers,
param_representations, platform_descriptor);
}
void CallDescriptors::InitializeForIsolateAllPlatforms(Isolate* isolate) {
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::LoadICCall);
Register registers[] = {InterfaceDescriptor::ContextRegister(),
LoadConvention::ReceiverRegister(),
LoadConvention::NameRegister()};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::StoreICCall);
Register registers[] = {InterfaceDescriptor::ContextRegister(),
StoreConvention::ReceiverRegister(),
StoreConvention::NameRegister(),
StoreConvention::ValueRegister()};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::ElementTransitionAndStoreCall);
Register registers[] = {
InterfaceDescriptor::ContextRegister(),
StoreConvention::ValueRegister(), StoreConvention::MapRegister(),
StoreConvention::NameRegister(), StoreConvention::ReceiverRegister()};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::InstanceofCall);
Register registers[] = {InterfaceDescriptor::ContextRegister(),
InstanceofConvention::left(),
InstanceofConvention::right()};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::VectorLoadICCall);
Register registers[] = {InterfaceDescriptor::ContextRegister(),
FullVectorLoadConvention::ReceiverRegister(),
FullVectorLoadConvention::NameRegister(),
FullVectorLoadConvention::SlotRegister(),
FullVectorLoadConvention::VectorRegister()};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
}
}
} // namespace v8::internal
......@@ -84,6 +84,31 @@ class InterfaceDescriptor {
enum CallDescriptorKey {
LoadICCall,
StoreICCall,
ElementTransitionAndStoreCall,
InstanceofCall,
VectorLoadICCall,
FastNewClosureCall,
FastNewContextCall,
ToNumberCall,
NumberToStringCall,
FastCloneShallowArrayCall,
FastCloneShallowObjectCall,
CreateAllocationSiteCall,
CallFunctionCall,
CallConstructCall,
RegExpConstructResultCall,
TransitionElementsKindCall,
ArrayConstructorConstantArgCountCall,
ArrayConstructorCall,
InternalArrayConstructorConstantArgCountCall,
InternalArrayConstructorCall,
CompareNilCall,
ToBooleanCall,
BinaryOpCall,
BinaryOpWithAllocationSiteCall,
StringAddCall,
KeyedCall,
NamedCall,
CallHandler,
......@@ -113,6 +138,9 @@ class CallInterfaceDescriptor : public InterfaceDescriptor {
class CallDescriptors {
public:
static void InitializeForIsolate(Isolate* isolate);
private:
static void InitializeForIsolateAllPlatforms(Isolate* isolate);
};
}
} // namespace v8::internal
......
......@@ -1917,6 +1917,8 @@ bool Isolate::Init(Deserializer* des) {
deoptimizer_data_ = new DeoptimizerData(memory_allocator_);
CallDescriptors::InitializeForIsolate(this);
const bool create_heap_objects = (des == NULL);
if (create_heap_objects && !heap_.CreateHeapObjects()) {
V8::FatalProcessOutOfMemory("heap object creation");
......@@ -2027,8 +2029,6 @@ 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.
......
This diff is collapsed.
......@@ -15,6 +15,156 @@ const Register InterfaceDescriptor::ContextRegister() { return rsi; }
void CallDescriptors::InitializeForIsolate(Isolate* isolate) {
InitializeForIsolateAllPlatforms(isolate);
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewClosureCall);
Register registers[] = {rsi, rbx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastNewContextCall);
Register registers[] = {rsi, rdi};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToNumberCall);
// ToNumberStub invokes a function, and therefore needs a context.
Register registers[] = {rsi, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::NumberToStringCall);
Register registers[] = {rsi, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowArrayCall);
Register registers[] = {rsi, rax, rbx, rcx};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Smi(), Representation::Tagged()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::FastCloneShallowObjectCall);
Register registers[] = {rsi, rax, rbx, rcx, rdx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CreateAllocationSiteCall);
Register registers[] = {rsi, rbx, rdx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallFunctionCall);
Register registers[] = {rsi, rdi};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CallConstructCall);
// rax : number of arguments
// rbx : feedback vector
// rdx : (only if rbx is not the megamorphic symbol) slot in feedback
// vector (Smi)
// rdi : constructor function
// TODO(turbofan): So far we don't gather type feedback and hence skip the
// slot parameter, but ArrayConstructStub needs the vector to be undefined.
Register registers[] = {rsi, rax, rdi, rbx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::RegExpConstructResultCall);
Register registers[] = {rsi, rcx, rbx, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::TransitionElementsKindCall);
Register registers[] = {rsi, rax, rbx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::ArrayConstructorConstantArgCountCall);
// register state
// rax -- number of arguments
// rdi -- function
// rbx -- allocation site with elements kind
Register registers[] = {rsi, rdi, rbx};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {rsi, rdi, rbx, rax};
Representation representations[] = {
Representation::Tagged(), Representation::Tagged(),
Representation::Tagged(), Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorConstantArgCountCall);
// register state
// rsi -- context
// rax -- number of arguments
// rdi -- constructor function
Register registers[] = {rsi, rdi};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::InternalArrayConstructorCall);
// stack param count needs (constructor pointer, and single argument)
Register registers[] = {rsi, rdi, rax};
Representation representations[] = {Representation::Tagged(),
Representation::Tagged(),
Representation::Integer32()};
descriptor->Initialize(arraysize(registers), registers, representations);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::CompareNilCall);
Register registers[] = {rsi, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ToBooleanCall);
Register registers[] = {rsi, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::BinaryOpCall);
Register registers[] = {rsi, rdx, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor = isolate->call_descriptor(
CallDescriptorKey::BinaryOpWithAllocationSiteCall);
Register registers[] = {rsi, rcx, rdx, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::StringAddCall);
Register registers[] = {rsi, rdx, rax};
descriptor->Initialize(arraysize(registers), registers, NULL);
}
{
CallInterfaceDescriptor* descriptor =
isolate->call_descriptor(CallDescriptorKey::ArgumentAdaptorCall);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment