From febf84a3331282b163939acfd9f66a20dcc27a08 Mon Sep 17 00:00:00 2001 From: "mvstanton@chromium.org" Date: Thu, 11 Sep 2014 07:11:10 +0000 Subject: [PATCH] Added CallInterfaceDescriptors to all code stubs. A handful of code stubs are too complex to be described this way, and they are encoded with the macro DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(). Along the way: * allowed inheritance of CallInterfaceDescriptors. * Defined static Register methods for some of the new CallInterfaceDescriptors. We could go a lot further here, but it doesn't have to be done immediately. * Added Representation arrays to some CallInterfaceDescriptors, especially where future hydrogen versions of the stubs could benefit from this knowledge. R=yangguo@chromium.org Review URL: https://codereview.chromium.org/551043005 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23854 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/code-stubs-arm.cc | 8 +- src/arm/code-stubs-arm.h | 5 + src/arm/interface-descriptors-arm.cc | 51 ++++++---- src/arm/lithium-arm.cc | 7 +- src/arm/lithium-codegen-arm.cc | 8 +- src/arm64/code-stubs-arm64.cc | 15 ++- src/arm64/code-stubs-arm64.h | 6 ++ src/arm64/interface-descriptors-arm64.cc | 55 +++++----- src/arm64/lithium-arm64.cc | 13 ++- src/arm64/lithium-codegen-arm64.cc | 15 +-- src/code-stubs.h | 65 +++++++++++- src/ia32/code-stubs-ia32.cc | 6 +- src/ia32/code-stubs-ia32.h | 3 + src/ia32/interface-descriptors-ia32.cc | 53 ++++++---- src/ia32/lithium-codegen-ia32.cc | 8 +- src/ia32/lithium-ia32.cc | 7 +- src/ic/arm/handler-compiler-arm.cc | 2 +- src/ic/ia32/handler-compiler-ia32.cc | 2 +- src/ic/x64/handler-compiler-x64.cc | 2 +- src/interface-descriptors.cc | 45 ++++++++ src/interface-descriptors.h | 170 ++++++++++++++++++++++--------- src/x64/code-stubs-x64.cc | 9 +- src/x64/code-stubs-x64.h | 3 + src/x64/interface-descriptors-x64.cc | 53 ++++++---- src/x64/lithium-codegen-x64.cc | 8 +- src/x64/lithium-x64.cc | 6 +- 26 files changed, 440 insertions(+), 185 deletions(-) diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index 3391686..311d0b7 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -762,7 +762,8 @@ void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { void MathPowStub::Generate(MacroAssembler* masm) { const Register base = r1; - const Register exponent = r2; + const Register exponent = MathPowTaggedDescriptor::exponent(); + DCHECK(exponent.is(r2)); const Register heapnumbermap = r5; const Register heapnumber = r0; const DwVfpRegister double_base = d0; @@ -1506,6 +1507,8 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { // relative to the frame pointer. const int kDisplacement = StandardFrameConstants::kCallerSPOffset - kPointerSize; + DCHECK(r1.is(ArgumentsAccessReadDescriptor::index())); + DCHECK(r0.is(ArgumentsAccessReadDescriptor::parameter_count())); // Check that the key is a smi. Label slow; @@ -4620,7 +4623,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { // -- r2 : api_function_address // ----------------------------------- - Register api_function_address = r2; + Register api_function_address = ApiGetterDescriptor::function_address(); + DCHECK(api_function_address.is(r2)); __ mov(r0, sp); // r0 = Handle __ add(r1, r0, Operand(1 * kPointerSize)); // r1 = PCA diff --git a/src/arm/code-stubs-arm.h b/src/arm/code-stubs-arm.h index e7f6610..727bb1b 100644 --- a/src/arm/code-stubs-arm.h +++ b/src/arm/code-stubs-arm.h @@ -79,6 +79,7 @@ class WriteInt32ToHeapNumberStub : public PlatformCodeStub { class HeapNumberRegisterBits: public BitField {}; class ScratchRegisterBits: public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(WriteInt32ToHeapNumber, PlatformCodeStub); }; @@ -168,6 +169,8 @@ class RecordWriteStub: public PlatformCodeStub { 2 * Assembler::kInstrSize); } + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + private: // This is a helper class for freeing up 3 scratch registers. The input is // two registers that must be preserved and one scratch register provided by @@ -292,6 +295,7 @@ class DirectCEntryStub: public PlatformCodeStub { private: bool NeedsImmovableCode() { return true; } + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub); }; @@ -339,6 +343,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub { class LookupModeBits: public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); }; diff --git a/src/arm/interface-descriptors-arm.cc b/src/arm/interface-descriptors-arm.cc index 3b0e54d..9bbc1f5 100644 --- a/src/arm/interface-descriptors-arm.cc +++ b/src/arm/interface-descriptors-arm.cc @@ -18,17 +18,9 @@ const Register LoadDescriptor::ReceiverRegister() { return r1; } const Register LoadDescriptor::NameRegister() { return r2; } -const Register VectorLoadICDescriptor::ReceiverRegister() { - return LoadDescriptor::ReceiverRegister(); -} - - -const Register VectorLoadICDescriptor::NameRegister() { - return LoadDescriptor::NameRegister(); -} +const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return r0; } -const Register VectorLoadICDescriptor::SlotRegister() { return r0; } const Register VectorLoadICDescriptor::VectorRegister() { return r3; } @@ -37,26 +29,26 @@ const Register StoreDescriptor::NameRegister() { return r2; } const Register StoreDescriptor::ValueRegister() { return r0; } -const Register ElementTransitionAndStoreDescriptor::ReceiverRegister() { - return StoreDescriptor::ReceiverRegister(); -} +const Register ElementTransitionAndStoreDescriptor::MapRegister() { return r3; } -const Register ElementTransitionAndStoreDescriptor::NameRegister() { - return StoreDescriptor::NameRegister(); -} +const Register InstanceofDescriptor::left() { return r0; } +const Register InstanceofDescriptor::right() { return r1; } -const Register ElementTransitionAndStoreDescriptor::ValueRegister() { - return StoreDescriptor::ValueRegister(); -} +const Register ArgumentsAccessReadDescriptor::index() { return r1; } +const Register ArgumentsAccessReadDescriptor::parameter_count() { return r0; } -const Register ElementTransitionAndStoreDescriptor::MapRegister() { return r3; } +const Register ApiGetterDescriptor::function_address() { return r2; } -const Register InstanceofDescriptor::left() { return r0; } -const Register InstanceofDescriptor::right() { return r1; } +const Register MathPowTaggedDescriptor::exponent() { return r2; } + + +const Register MathPowIntegerDescriptor::exponent() { + return MathPowTaggedDescriptor::exponent(); +} void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { @@ -107,12 +99,29 @@ void CreateAllocationSiteDescriptor::Initialize( } +void StoreArrayLiteralElementDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {cp, r3, r0}; + data->Initialize(arraysize(registers), registers, NULL); +} + + void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { Register registers[] = {cp, r1}; data->Initialize(arraysize(registers), registers, NULL); } +void CallFunctionWithFeedbackDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {cp, r1, r3}; + Representation representations[] = {Representation::Tagged(), + Representation::Tagged(), + Representation::Smi()}; + data->Initialize(arraysize(registers), registers, representations); +} + + void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) { // r0 : number of arguments // r1 : the function to call diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 05b1535..7b97cb8 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1691,9 +1691,10 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { Representation exponent_type = instr->right()->representation(); DCHECK(instr->left()->representation().IsDouble()); LOperand* left = UseFixedDouble(instr->left(), d0); - LOperand* right = exponent_type.IsDouble() ? - UseFixedDouble(instr->right(), d1) : - UseFixed(instr->right(), r2); + LOperand* right = + exponent_type.IsDouble() + ? UseFixedDouble(instr->right(), d1) + : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent()); LPower* result = new(zone()) LPower(left, right); return MarkAsCall(DefineFixedDouble(result, d2), instr, diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 377d38b..d5c0468 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -3888,10 +3888,11 @@ void LCodeGen::DoPower(LPower* instr) { Representation exponent_type = instr->hydrogen()->right()->representation(); // Having marked this as a call, we can use any registers. // Just make sure that the input/output registers are the expected ones. + Register tagged_exponent = MathPowTaggedDescriptor::exponent(); DCHECK(!instr->right()->IsDoubleRegister() || ToDoubleRegister(instr->right()).is(d1)); DCHECK(!instr->right()->IsRegister() || - ToRegister(instr->right()).is(r2)); + ToRegister(instr->right()).is(tagged_exponent)); DCHECK(ToDoubleRegister(instr->left()).is(d0)); DCHECK(ToDoubleRegister(instr->result()).is(d2)); @@ -3900,8 +3901,9 @@ void LCodeGen::DoPower(LPower* instr) { __ CallStub(&stub); } else if (exponent_type.IsTagged()) { Label no_deopt; - __ JumpIfSmi(r2, &no_deopt); - __ ldr(r6, FieldMemOperand(r2, HeapObject::kMapOffset)); + __ JumpIfSmi(tagged_exponent, &no_deopt); + DCHECK(!r6.is(tagged_exponent)); + __ ldr(r6, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); __ cmp(r6, Operand(ip)); DeoptimizeIf(ne, instr->environment()); diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index 6cd7043..39fec09 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -726,8 +726,10 @@ void MathPowStub::Generate(MacroAssembler* masm) { Register result_tagged = x0; Register base_tagged = x10; - Register exponent_tagged = x11; - Register exponent_integer = x12; + Register exponent_tagged = MathPowTaggedDescriptor::exponent(); + DCHECK(exponent_tagged.is(x11)); + Register exponent_integer = MathPowIntegerDescriptor::exponent(); + DCHECK(exponent_integer.is(x12)); Register scratch1 = x14; Register scratch0 = x15; Register saved_lr = x19; @@ -1606,8 +1608,10 @@ void InstanceofStub::Generate(MacroAssembler* masm) { void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { - Register arg_count = x0; - Register key = x1; + Register arg_count = ArgumentsAccessReadDescriptor::parameter_count(); + Register key = ArgumentsAccessReadDescriptor::index(); + DCHECK(arg_count.is(x0)); + DCHECK(key.is(x1)); // The displacement is the offset of the last parameter (if any) relative // to the frame pointer. @@ -5008,7 +5012,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { // -- x2 : api_function_address // ----------------------------------- - Register api_function_address = x2; + Register api_function_address = ApiGetterDescriptor::function_address(); + DCHECK(api_function_address.is(x2)); __ Mov(x0, masm->StackPointer()); // x0 = Handle __ Add(x1, x0, 1 * kPointerSize); // x1 = PCA diff --git a/src/arm64/code-stubs-arm64.h b/src/arm64/code-stubs-arm64.h index c2e15e0..03dab5b 100644 --- a/src/arm64/code-stubs-arm64.h +++ b/src/arm64/code-stubs-arm64.h @@ -45,6 +45,7 @@ class StoreRegistersStateStub: public PlatformCodeStub { static void GenerateAheadOfTime(Isolate* isolate); private: + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(StoreRegistersState, PlatformCodeStub); }; @@ -57,6 +58,7 @@ class RestoreRegistersStateStub: public PlatformCodeStub { static void GenerateAheadOfTime(Isolate* isolate); private: + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, PlatformCodeStub); }; @@ -160,6 +162,8 @@ class RecordWriteStub: public PlatformCodeStub { DCHECK(GetMode(stub) == mode); } + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + private: // This is a helper class to manage the registers associated with the stub. // The 'object' and 'address' registers must be preserved. @@ -326,6 +330,7 @@ class DirectCEntryStub: public PlatformCodeStub { private: bool NeedsImmovableCode() { return true; } + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub); }; @@ -373,6 +378,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub { class LookupModeBits: public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); }; diff --git a/src/arm64/interface-descriptors-arm64.cc b/src/arm64/interface-descriptors-arm64.cc index e7d2d4a..690c8c2 100644 --- a/src/arm64/interface-descriptors-arm64.cc +++ b/src/arm64/interface-descriptors-arm64.cc @@ -18,17 +18,9 @@ const Register LoadDescriptor::ReceiverRegister() { return x1; } const Register LoadDescriptor::NameRegister() { return x2; } -const Register VectorLoadICDescriptor::ReceiverRegister() { - return LoadDescriptor::ReceiverRegister(); -} - +const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return x0; } -const Register VectorLoadICDescriptor::NameRegister() { - return LoadDescriptor::NameRegister(); -} - -const Register VectorLoadICDescriptor::SlotRegister() { return x0; } const Register VectorLoadICDescriptor::VectorRegister() { return x3; } @@ -37,21 +29,6 @@ const Register StoreDescriptor::NameRegister() { return x2; } const Register StoreDescriptor::ValueRegister() { return x0; } -const Register ElementTransitionAndStoreDescriptor::ReceiverRegister() { - return StoreDescriptor::ReceiverRegister(); -} - - -const Register ElementTransitionAndStoreDescriptor::NameRegister() { - return StoreDescriptor::NameRegister(); -} - - -const Register ElementTransitionAndStoreDescriptor::ValueRegister() { - return StoreDescriptor::ValueRegister(); -} - - const Register ElementTransitionAndStoreDescriptor::MapRegister() { return x3; } @@ -67,6 +44,19 @@ const Register InstanceofDescriptor::right() { } +const Register ArgumentsAccessReadDescriptor::index() { return x1; } +const Register ArgumentsAccessReadDescriptor::parameter_count() { return x0; } + + +const Register ApiGetterDescriptor::function_address() { return x2; } + + +const Register MathPowTaggedDescriptor::exponent() { return x11; } + + +const Register MathPowIntegerDescriptor::exponent() { return x12; } + + void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { // cp: context // x2: function info @@ -135,6 +125,13 @@ void CreateAllocationSiteDescriptor::Initialize( } +void StoreArrayLiteralElementDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {cp, x3, x0}; + data->Initialize(arraysize(registers), registers, NULL); +} + + void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { // x1 function the function to call Register registers[] = {cp, x1}; @@ -142,6 +139,16 @@ void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { } +void CallFunctionWithFeedbackDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {cp, x1, x3}; + Representation representations[] = {Representation::Tagged(), + Representation::Tagged(), + Representation::Smi()}; + data->Initialize(arraysize(registers), registers, representations); +} + + void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) { // x0 : number of arguments // x1 : the function to call diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 7f5e2a3..b15b414 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -2017,11 +2017,14 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { Representation exponent_type = instr->right()->representation(); DCHECK(instr->left()->representation().IsDouble()); LOperand* left = UseFixedDouble(instr->left(), d0); - LOperand* right = exponent_type.IsInteger32() - ? UseFixed(instr->right(), x12) - : exponent_type.IsDouble() - ? UseFixedDouble(instr->right(), d1) - : UseFixed(instr->right(), x11); + LOperand* right; + if (exponent_type.IsInteger32()) { + right = UseFixed(instr->right(), MathPowIntegerDescriptor::exponent()); + } else if (exponent_type.IsDouble()) { + right = UseFixedDouble(instr->right(), d1); + } else { + right = UseFixed(instr->right(), MathPowTaggedDescriptor::exponent()); + } LPower* result = new(zone()) LPower(left, right); return MarkAsCall(DefineFixedDouble(result, d0), instr, diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index da237a6..fdfec41 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -4086,11 +4086,14 @@ void LCodeGen::DoPower(LPower* instr) { Representation exponent_type = instr->hydrogen()->right()->representation(); // Having marked this as a call, we can use any registers. // Just make sure that the input/output registers are the expected ones. + Register tagged_exponent = MathPowTaggedDescriptor::exponent(); + Register integer_exponent = MathPowIntegerDescriptor::exponent(); DCHECK(!instr->right()->IsDoubleRegister() || ToDoubleRegister(instr->right()).is(d1)); DCHECK(exponent_type.IsInteger32() || !instr->right()->IsRegister() || - ToRegister(instr->right()).is(x11)); - DCHECK(!exponent_type.IsInteger32() || ToRegister(instr->right()).is(x12)); + ToRegister(instr->right()).is(tagged_exponent)); + DCHECK(!exponent_type.IsInteger32() || + ToRegister(instr->right()).is(integer_exponent)); DCHECK(ToDoubleRegister(instr->left()).is(d0)); DCHECK(ToDoubleRegister(instr->result()).is(d0)); @@ -4099,8 +4102,9 @@ void LCodeGen::DoPower(LPower* instr) { __ CallStub(&stub); } else if (exponent_type.IsTagged()) { Label no_deopt; - __ JumpIfSmi(x11, &no_deopt); - __ Ldr(x0, FieldMemOperand(x11, HeapObject::kMapOffset)); + __ JumpIfSmi(tagged_exponent, &no_deopt); + DCHECK(!x0.is(tagged_exponent)); + __ Ldr(x0, FieldMemOperand(tagged_exponent, HeapObject::kMapOffset)); DeoptimizeIfNotRoot(x0, Heap::kHeapNumberMapRootIndex, instr->environment()); __ Bind(&no_deopt); @@ -4109,8 +4113,7 @@ void LCodeGen::DoPower(LPower* instr) { } else if (exponent_type.IsInteger32()) { // Ensure integer exponent has no garbage in top 32-bits, as MathPowStub // supports large integer exponents. - Register exponent = ToRegister(instr->right()); - __ Sxtw(exponent, exponent); + __ Sxtw(integer_exponent, integer_exponent); MathPowStub stub(isolate(), MathPowStub::INTEGER); __ CallStub(&stub); } else { diff --git a/src/code-stubs.h b/src/code-stubs.h index 626e14e..eb858b0 100644 --- a/src/code-stubs.h +++ b/src/code-stubs.h @@ -180,10 +180,7 @@ class CodeStub BASE_EMBEDDED { // Lookup the code in the (possibly custom) cache. bool FindCodeInCache(Code** code_out); - virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() { - UNREACHABLE(); // Default returns an uninitialized descriptor. - return CallInterfaceDescriptor(); - } + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() = 0; virtual void InitializeDescriptor(CodeStubDescriptor* descriptor) {} @@ -314,6 +311,16 @@ class CodeStub BASE_EMBEDDED { return NAME##Descriptor(isolate()); \ } +// There are some code stubs we just can't describe right now with a +// CallInterfaceDescriptor. Isolate behavior for those cases with this macro. +// An attempt to retrieve a descriptor will fail. +#define DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR() \ + public: \ + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { \ + UNREACHABLE(); \ + return CallInterfaceDescriptor(); \ + } + class PlatformCodeStub : public CodeStub { public: @@ -670,6 +677,13 @@ class InstanceofStub: public PlatformCodeStub { static Register left() { return InstanceofDescriptor::left(); } static Register right() { return InstanceofDescriptor::right(); } + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (HasArgsInRegisters()) { + return InstanceofDescriptor(isolate()); + } + return ContextOnlyDescriptor(isolate()); + } + private: Flags flags() const { return FlagBits::decode(minor_key_); } @@ -687,7 +701,6 @@ class InstanceofStub: public PlatformCodeStub { class FlagBits : public BitField {}; - DEFINE_CALL_INTERFACE_DESCRIPTOR(Instanceof); DEFINE_PLATFORM_CODE_STUB(Instanceof, PlatformCodeStub); }; @@ -719,6 +732,7 @@ class ArrayConstructorStub: public PlatformCodeStub { class ArgumentCountBits : public BitField {}; + DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor); DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub); }; @@ -730,6 +744,7 @@ class InternalArrayConstructorStub: public PlatformCodeStub { private: void GenerateCase(MacroAssembler* masm, ElementsKind kind); + DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor); DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, PlatformCodeStub); }; @@ -743,6 +758,16 @@ class MathPowStub: public PlatformCodeStub { minor_key_ = ExponentTypeBits::encode(exponent_type); } + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (exponent_type() == TAGGED) { + return MathPowTaggedDescriptor(isolate()); + } else if (exponent_type() == INTEGER) { + return MathPowIntegerDescriptor(isolate()); + } + // A CallInterfaceDescriptor doesn't specify double registers (yet). + return ContextOnlyDescriptor(isolate()); + } + private: ExponentType exponent_type() const { return ExponentTypeBits::decode(minor_key_); @@ -789,6 +814,7 @@ class CallICStub: public PlatformCodeStub { private: virtual void PrintState(OStream& os) const OVERRIDE; // NOLINT + DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback); DEFINE_PLATFORM_CODE_STUB(CallIC, PlatformCodeStub); }; @@ -817,6 +843,10 @@ class FunctionPrototypeStub : public PlatformCodeStub { virtual Code::Kind GetCodeKind() const { return Code::HANDLER; } + // TODO(mvstanton): only the receiver register is accessed. When this is + // translated to a hydrogen code stub, a new CallInterfaceDescriptor + // should be created that just uses that register for more efficient code. + DEFINE_CALL_INTERFACE_DESCRIPTOR(Load); DEFINE_PLATFORM_CODE_STUB(FunctionPrototype, PlatformCodeStub); }; @@ -1009,6 +1039,7 @@ class CallApiFunctionStub : public PlatformCodeStub { class ArgumentBits: public BitField {}; STATIC_ASSERT(Code::kArgumentsBits + 2 <= kStubMinorKeyBits); + DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiFunction); DEFINE_PLATFORM_CODE_STUB(CallApiFunction, PlatformCodeStub); }; @@ -1017,6 +1048,7 @@ class CallApiGetterStub : public PlatformCodeStub { public: explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {} + DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter); DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub); }; @@ -1108,6 +1140,7 @@ class BinaryOpICWithAllocationSiteStub FINAL : public PlatformCodeStub { static void GenerateAheadOfTime(Isolate* isolate, const BinaryOpIC::State& state); + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite); DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub); }; @@ -1230,6 +1263,7 @@ class CompareICStub : public PlatformCodeStub { Handle known_map_; + DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp); DEFINE_PLATFORM_CODE_STUB(CompareIC, PlatformCodeStub); }; @@ -1353,6 +1387,7 @@ class CEntryStub : public PlatformCodeStub { class SaveDoublesBits : public BitField {}; class ResultSizeBits : public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(CEntry, PlatformCodeStub); }; @@ -1381,6 +1416,7 @@ class JSEntryStub : public PlatformCodeStub { int handler_offset_; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(JSEntry, PlatformCodeStub); }; @@ -1398,6 +1434,13 @@ class ArgumentsAccessStub: public PlatformCodeStub { minor_key_ = TypeBits::encode(type); } + virtual CallInterfaceDescriptor GetCallInterfaceDescriptor() OVERRIDE { + if (type() == READ_ELEMENT) { + return ArgumentsAccessReadDescriptor(isolate()); + } + return ContextOnlyDescriptor(isolate()); + } + private: Type type() const { return TypeBits::decode(minor_key_); } @@ -1418,6 +1461,7 @@ class RegExpExecStub: public PlatformCodeStub { public: explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { } + DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly); DEFINE_PLATFORM_CODE_STUB(RegExpExec, PlatformCodeStub); }; @@ -1716,6 +1760,7 @@ class LoadICTrampolineStub : public PlatformCodeStub { return LoadIC::State(static_cast(minor_key_)); } + DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadICTrampoline); DEFINE_PLATFORM_CODE_STUB(LoadICTrampoline, PlatformCodeStub); }; @@ -1836,6 +1881,7 @@ class DoubleToIStub : public PlatformCodeStub { class SSE3Bits: public BitField {}; // NOLINT + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub); }; @@ -2102,6 +2148,7 @@ class StoreElementStub : public PlatformCodeStub { class ElementsKindBits : public BitField {}; + DEFINE_CALL_INTERFACE_DESCRIPTOR(Store); DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub); }; @@ -2252,6 +2299,7 @@ class StoreArrayLiteralElementStub : public PlatformCodeStub { explicit StoreArrayLiteralElementStub(Isolate* isolate) : PlatformCodeStub(isolate) { } + DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreArrayLiteralElement); DEFINE_PLATFORM_CODE_STUB(StoreArrayLiteralElement, PlatformCodeStub); }; @@ -2272,6 +2320,7 @@ class StubFailureTrampolineStub : public PlatformCodeStub { class FunctionModeField : public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, PlatformCodeStub); }; @@ -2291,6 +2340,9 @@ class ProfileEntryHookStub : public PlatformCodeStub { intptr_t stack_pointer, Isolate* isolate); + // ProfileEntryHookStub is called at the start of a function, so it has the + // same register set. + DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunction) DEFINE_PLATFORM_CODE_STUB(ProfileEntryHook, PlatformCodeStub); }; @@ -2310,6 +2362,7 @@ class StoreBufferOverflowStub : public PlatformCodeStub { class SaveDoublesBits : public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub); }; @@ -2318,6 +2371,7 @@ class SubStringStub : public PlatformCodeStub { public: explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {} + DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly); DEFINE_PLATFORM_CODE_STUB(SubString, PlatformCodeStub); }; @@ -2326,6 +2380,7 @@ class StringCompareStub : public PlatformCodeStub { public: explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) {} + DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly); DEFINE_PLATFORM_CODE_STUB(StringCompare, PlatformCodeStub); }; diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index e92254d..ef507b5 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -380,7 +380,8 @@ void FloatingPointHelper::CheckFloatOperands(MacroAssembler* masm, void MathPowStub::Generate(MacroAssembler* masm) { Factory* factory = isolate()->factory(); - const Register exponent = eax; + const Register exponent = MathPowTaggedDescriptor::exponent(); + DCHECK(exponent.is(eax)); const Register base = edx; const Register scratch = ecx; const XMMRegister double_result = xmm3; @@ -659,6 +660,8 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) { void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { // The key is in edx and the parameter count is in eax. + DCHECK(edx.is(ArgumentsAccessReadDescriptor::index())); + DCHECK(eax.is(ArgumentsAccessReadDescriptor::parameter_count())); // The displacement is used for skipping the frame pointer on the // stack. It is the offset of the last parameter (if any) relative @@ -4634,6 +4637,7 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { // -- ... // -- edx : api_function_address // ----------------------------------- + DCHECK(edx.is(ApiGetterDescriptor::function_address())); // array for v8::Arguments::values_, handler for name and pointer // to the values (it considered as smi in GC). diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h index 7943f26..eabb5a5 100644 --- a/src/ia32/code-stubs-ia32.h +++ b/src/ia32/code-stubs-ia32.h @@ -109,6 +109,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub { class IndexBits: public BitField {}; class LookupModeBits: public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); }; @@ -190,6 +191,8 @@ class RecordWriteStub: public PlatformCodeStub { CpuFeatures::FlushICache(stub->instruction_start(), 7); } + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + private: // This is a helper class for freeing up 3 scratch registers, where the third // is always ecx (needed for shift operations). The input is two registers diff --git a/src/ia32/interface-descriptors-ia32.cc b/src/ia32/interface-descriptors-ia32.cc index f97c64c..3a0d526 100644 --- a/src/ia32/interface-descriptors-ia32.cc +++ b/src/ia32/interface-descriptors-ia32.cc @@ -18,17 +18,9 @@ const Register LoadDescriptor::ReceiverRegister() { return edx; } const Register LoadDescriptor::NameRegister() { return ecx; } -const Register VectorLoadICDescriptor::ReceiverRegister() { - return LoadDescriptor::ReceiverRegister(); -} - - -const Register VectorLoadICDescriptor::NameRegister() { - return LoadDescriptor::NameRegister(); -} +const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return eax; } -const Register VectorLoadICDescriptor::SlotRegister() { return eax; } const Register VectorLoadICDescriptor::VectorRegister() { return ebx; } @@ -37,28 +29,28 @@ const Register StoreDescriptor::NameRegister() { return ecx; } const Register StoreDescriptor::ValueRegister() { return eax; } -const Register ElementTransitionAndStoreDescriptor::ReceiverRegister() { - return StoreDescriptor::ReceiverRegister(); +const Register ElementTransitionAndStoreDescriptor::MapRegister() { + return ebx; } -const Register ElementTransitionAndStoreDescriptor::NameRegister() { - return StoreDescriptor::NameRegister(); -} +const Register InstanceofDescriptor::left() { return eax; } +const Register InstanceofDescriptor::right() { return edx; } -const Register ElementTransitionAndStoreDescriptor::ValueRegister() { - return StoreDescriptor::ValueRegister(); -} +const Register ArgumentsAccessReadDescriptor::index() { return edx; } +const Register ArgumentsAccessReadDescriptor::parameter_count() { return eax; } -const Register ElementTransitionAndStoreDescriptor::MapRegister() { - return ebx; -} +const Register ApiGetterDescriptor::function_address() { return edx; } -const Register InstanceofDescriptor::left() { return eax; } -const Register InstanceofDescriptor::right() { return edx; } +const Register MathPowTaggedDescriptor::exponent() { return eax; } + + +const Register MathPowIntegerDescriptor::exponent() { + return MathPowTaggedDescriptor::exponent(); +} void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { @@ -110,12 +102,29 @@ void CreateAllocationSiteDescriptor::Initialize( } +void StoreArrayLiteralElementDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {esi, ecx, eax}; + data->Initialize(arraysize(registers), registers, NULL); +} + + void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { Register registers[] = {esi, edi}; data->Initialize(arraysize(registers), registers, NULL); } +void CallFunctionWithFeedbackDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {esi, edi, edx}; + Representation representations[] = {Representation::Tagged(), + Representation::Tagged(), + Representation::Smi()}; + data->Initialize(arraysize(registers), registers, representations); +} + + void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) { // eax : number of arguments // ebx : feedback vector diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index d9504c7..27952f3 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -3797,10 +3797,11 @@ void LCodeGen::DoPower(LPower* instr) { Representation exponent_type = instr->hydrogen()->right()->representation(); // Having marked this as a call, we can use any registers. // Just make sure that the input/output registers are the expected ones. + Register tagged_exponent = MathPowTaggedDescriptor::exponent(); DCHECK(!instr->right()->IsDoubleRegister() || ToDoubleRegister(instr->right()).is(xmm1)); DCHECK(!instr->right()->IsRegister() || - ToRegister(instr->right()).is(eax)); + ToRegister(instr->right()).is(tagged_exponent)); DCHECK(ToDoubleRegister(instr->left()).is(xmm2)); DCHECK(ToDoubleRegister(instr->result()).is(xmm3)); @@ -3809,8 +3810,9 @@ void LCodeGen::DoPower(LPower* instr) { __ CallStub(&stub); } else if (exponent_type.IsTagged()) { Label no_deopt; - __ JumpIfSmi(eax, &no_deopt); - __ CmpObjectType(eax, HEAP_NUMBER_TYPE, ecx); + __ JumpIfSmi(tagged_exponent, &no_deopt); + DCHECK(!ecx.is(tagged_exponent)); + __ CmpObjectType(tagged_exponent, HEAP_NUMBER_TYPE, ecx); DeoptimizeIf(not_equal, instr->environment()); __ bind(&no_deopt); MathPowStub stub(isolate(), MathPowStub::TAGGED); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index b5eeff4..0db3d9c 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -1652,9 +1652,10 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { Representation exponent_type = instr->right()->representation(); DCHECK(instr->left()->representation().IsDouble()); LOperand* left = UseFixedDouble(instr->left(), xmm2); - LOperand* right = exponent_type.IsDouble() ? - UseFixedDouble(instr->right(), xmm1) : - UseFixed(instr->right(), eax); + LOperand* right = + exponent_type.IsDouble() + ? UseFixedDouble(instr->right(), xmm1) + : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent()); LPower* result = new(zone()) LPower(left, right); return MarkAsCall(DefineFixedDouble(result, xmm3), instr, CAN_DEOPTIMIZE_EAGERLY); diff --git a/src/ic/arm/handler-compiler-arm.cc b/src/ic/arm/handler-compiler-arm.cc index fb50985..e49abf2 100644 --- a/src/ic/arm/handler-compiler-arm.cc +++ b/src/ic/arm/handler-compiler-arm.cc @@ -678,7 +678,7 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback( __ push(name()); // Abi for CallApiGetter - Register getter_address_reg = r2; + Register getter_address_reg = ApiGetterDescriptor::function_address(); Address getter_address = v8::ToCData
(callback->getter()); ApiFunction fun(getter_address); diff --git a/src/ic/ia32/handler-compiler-ia32.cc b/src/ic/ia32/handler-compiler-ia32.cc index fd77944..815a5d0 100644 --- a/src/ic/ia32/handler-compiler-ia32.cc +++ b/src/ic/ia32/handler-compiler-ia32.cc @@ -665,7 +665,7 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback( __ push(scratch3()); // Restore return address. // Abi for CallApiGetter - Register getter_address = edx; + Register getter_address = ApiGetterDescriptor::function_address(); Address function_address = v8::ToCData
(callback->getter()); __ mov(getter_address, Immediate(function_address)); diff --git a/src/ic/x64/handler-compiler-x64.cc b/src/ic/x64/handler-compiler-x64.cc index 399b96f..c4d6ecf 100644 --- a/src/ic/x64/handler-compiler-x64.cc +++ b/src/ic/x64/handler-compiler-x64.cc @@ -660,7 +660,7 @@ void NamedLoadHandlerCompiler::GenerateLoadCallback( __ PushReturnAddressFrom(scratch4()); // Abi for CallApiGetter - Register api_function_address = r8; + Register api_function_address = ApiGetterDescriptor::function_address(); Address getter_address = v8::ToCData
(callback->getter()); __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE); diff --git a/src/interface-descriptors.cc b/src/interface-descriptors.cc index eb2d737..62d7105 100644 --- a/src/interface-descriptors.cc +++ b/src/interface-descriptors.cc @@ -88,9 +88,54 @@ void InstanceofDescriptor::Initialize(CallInterfaceDescriptorData* data) { } +void MathPowTaggedDescriptor::Initialize(CallInterfaceDescriptorData* data) { + Register registers[] = {ContextRegister(), exponent()}; + data->Initialize(arraysize(registers), registers, NULL); +} + + +void MathPowIntegerDescriptor::Initialize(CallInterfaceDescriptorData* data) { + Register registers[] = {ContextRegister(), exponent()}; + data->Initialize(arraysize(registers), registers, NULL); +} + + +void VectorLoadICTrampolineDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {ContextRegister(), ReceiverRegister(), NameRegister(), + SlotRegister()}; + data->Initialize(arraysize(registers), registers, NULL); +} + + void VectorLoadICDescriptor::Initialize(CallInterfaceDescriptorData* data) { Register registers[] = {ContextRegister(), ReceiverRegister(), NameRegister(), SlotRegister(), VectorRegister()}; + Representation representations[] = { + Representation::Tagged(), Representation::Tagged(), + Representation::Tagged(), Representation::Smi(), + Representation::Tagged()}; + data->Initialize(arraysize(registers), registers, representations); +} + + +void ApiGetterDescriptor::Initialize(CallInterfaceDescriptorData* data) { + Register registers[] = {ContextRegister(), function_address()}; + Representation representations[] = {Representation::Tagged(), + Representation::External()}; + data->Initialize(arraysize(registers), registers, representations); +} + + +void ArgumentsAccessReadDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {ContextRegister(), index(), parameter_count()}; + data->Initialize(arraysize(registers), registers, NULL); +} + + +void ContextOnlyDescriptor::Initialize(CallInterfaceDescriptorData* data) { + Register registers[] = {ContextRegister()}; data->Initialize(arraysize(registers), registers, NULL); } diff --git a/src/interface-descriptors.h b/src/interface-descriptors.h index 4475900..b773c91 100644 --- a/src/interface-descriptors.h +++ b/src/interface-descriptors.h @@ -18,6 +18,7 @@ class PlatformInterfaceDescriptor; V(Store) \ V(ElementTransitionAndStore) \ V(Instanceof) \ + V(VectorLoadICTrampoline) \ V(VectorLoadIC) \ V(FastNewClosure) \ V(FastNewContext) \ @@ -27,6 +28,7 @@ class PlatformInterfaceDescriptor; V(FastCloneShallowObject) \ V(CreateAllocationSite) \ V(CallFunction) \ + V(CallFunctionWithFeedback) \ V(CallConstruct) \ V(RegExpConstructResult) \ V(TransitionElementsKind) \ @@ -43,7 +45,13 @@ class PlatformInterfaceDescriptor; V(Named) \ V(CallHandler) \ V(ArgumentAdaptor) \ - V(ApiFunction) + V(ApiGetter) \ + V(ApiFunction) \ + V(ArgumentsAccessRead) \ + V(StoreArrayLiteralElement) \ + V(MathPowTagged) \ + V(MathPowInteger) \ + V(ContextOnly) class CallInterfaceDescriptorData { @@ -164,18 +172,24 @@ class CallInterfaceDescriptor { }; -#define DECLARE_DESCRIPTOR(name) \ - explicit name(Isolate* isolate) : CallInterfaceDescriptor(isolate, key()) { \ - if (!data()->IsInitialized()) \ - Initialize(isolate->call_descriptor_data(key())); \ - } \ - static inline CallDescriptors::Key key(); \ - void Initialize(CallInterfaceDescriptorData* data); +#define DECLARE_DESCRIPTOR(name, base) \ + explicit name(Isolate* isolate) : base(isolate, key()) { \ + if (!data()->IsInitialized()) \ + Initialize(isolate->call_descriptor_data(key())); \ + } \ + \ + protected: \ + void Initialize(CallInterfaceDescriptorData* data); \ + name(Isolate* isolate, CallDescriptors::Key key) : base(isolate, key) {} \ + \ + public: \ + static inline CallDescriptors::Key key(); +// LoadDescriptor is used by all stubs that implement Load/KeyedLoad ICs. class LoadDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(LoadDescriptor) + DECLARE_DESCRIPTOR(LoadDescriptor, CallInterfaceDescriptor) enum ParameterIndices { kReceiverIndex, kNameIndex }; static const Register ReceiverRegister(); @@ -185,7 +199,7 @@ class LoadDescriptor : public CallInterfaceDescriptor { class StoreDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(StoreDescriptor) + DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor) enum ParameterIndices { kReceiverIndex, @@ -199,20 +213,17 @@ class StoreDescriptor : public CallInterfaceDescriptor { }; -class ElementTransitionAndStoreDescriptor : public CallInterfaceDescriptor { +class ElementTransitionAndStoreDescriptor : public StoreDescriptor { public: - DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor) + DECLARE_DESCRIPTOR(ElementTransitionAndStoreDescriptor, StoreDescriptor) - static const Register ReceiverRegister(); - static const Register NameRegister(); - static const Register ValueRegister(); static const Register MapRegister(); }; class InstanceofDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(InstanceofDescriptor) + DECLARE_DESCRIPTOR(InstanceofDescriptor, CallInterfaceDescriptor) enum ParameterIndices { kLeftIndex, kRightIndex, kParameterCount }; static const Register left(); @@ -220,174 +231,237 @@ class InstanceofDescriptor : public CallInterfaceDescriptor { }; -class VectorLoadICDescriptor : public CallInterfaceDescriptor { +class VectorLoadICTrampolineDescriptor : public LoadDescriptor { + public: + DECLARE_DESCRIPTOR(VectorLoadICTrampolineDescriptor, LoadDescriptor) + + enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex }; + + static const Register SlotRegister(); +}; + + +class VectorLoadICDescriptor : public VectorLoadICTrampolineDescriptor { public: - DECLARE_DESCRIPTOR(VectorLoadICDescriptor) + DECLARE_DESCRIPTOR(VectorLoadICDescriptor, VectorLoadICTrampolineDescriptor) enum ParameterIndices { kReceiverIndex, kNameIndex, kSlotIndex, - kVectorIndex, - kParameterCount + kVectorIndex }; - static const Register ReceiverRegister(); - static const Register NameRegister(); - static const Register SlotRegister(); static const Register VectorRegister(); }; class FastNewClosureDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(FastNewClosureDescriptor) + DECLARE_DESCRIPTOR(FastNewClosureDescriptor, CallInterfaceDescriptor) }; class FastNewContextDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(FastNewContextDescriptor) + DECLARE_DESCRIPTOR(FastNewContextDescriptor, CallInterfaceDescriptor) }; class ToNumberDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(ToNumberDescriptor) + DECLARE_DESCRIPTOR(ToNumberDescriptor, CallInterfaceDescriptor) }; class NumberToStringDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(NumberToStringDescriptor) + DECLARE_DESCRIPTOR(NumberToStringDescriptor, CallInterfaceDescriptor) }; class FastCloneShallowArrayDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor) + DECLARE_DESCRIPTOR(FastCloneShallowArrayDescriptor, CallInterfaceDescriptor) }; class FastCloneShallowObjectDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor) + DECLARE_DESCRIPTOR(FastCloneShallowObjectDescriptor, CallInterfaceDescriptor) }; class CreateAllocationSiteDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor) + DECLARE_DESCRIPTOR(CreateAllocationSiteDescriptor, CallInterfaceDescriptor) }; class CallFunctionDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(CallFunctionDescriptor) + DECLARE_DESCRIPTOR(CallFunctionDescriptor, CallInterfaceDescriptor) +}; + + +class CallFunctionWithFeedbackDescriptor : public CallInterfaceDescriptor { + public: + DECLARE_DESCRIPTOR(CallFunctionWithFeedbackDescriptor, + CallInterfaceDescriptor) }; class CallConstructDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(CallConstructDescriptor) + DECLARE_DESCRIPTOR(CallConstructDescriptor, CallInterfaceDescriptor) }; class RegExpConstructResultDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor) + DECLARE_DESCRIPTOR(RegExpConstructResultDescriptor, CallInterfaceDescriptor) }; class TransitionElementsKindDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor) + DECLARE_DESCRIPTOR(TransitionElementsKindDescriptor, CallInterfaceDescriptor) }; class ArrayConstructorConstantArgCountDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor) + DECLARE_DESCRIPTOR(ArrayConstructorConstantArgCountDescriptor, + CallInterfaceDescriptor) }; class ArrayConstructorDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(ArrayConstructorDescriptor) + DECLARE_DESCRIPTOR(ArrayConstructorDescriptor, CallInterfaceDescriptor) }; class InternalArrayConstructorConstantArgCountDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor) + DECLARE_DESCRIPTOR(InternalArrayConstructorConstantArgCountDescriptor, + CallInterfaceDescriptor) }; class InternalArrayConstructorDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor) + DECLARE_DESCRIPTOR(InternalArrayConstructorDescriptor, + CallInterfaceDescriptor) }; class CompareNilDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(CompareNilDescriptor) + DECLARE_DESCRIPTOR(CompareNilDescriptor, CallInterfaceDescriptor) }; class ToBooleanDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(ToBooleanDescriptor) + DECLARE_DESCRIPTOR(ToBooleanDescriptor, CallInterfaceDescriptor) }; class BinaryOpDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(BinaryOpDescriptor) + DECLARE_DESCRIPTOR(BinaryOpDescriptor, CallInterfaceDescriptor) }; class BinaryOpWithAllocationSiteDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor) + DECLARE_DESCRIPTOR(BinaryOpWithAllocationSiteDescriptor, + CallInterfaceDescriptor) }; class StringAddDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(StringAddDescriptor) + DECLARE_DESCRIPTOR(StringAddDescriptor, CallInterfaceDescriptor) }; class KeyedDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(KeyedDescriptor) + DECLARE_DESCRIPTOR(KeyedDescriptor, CallInterfaceDescriptor) }; class NamedDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(NamedDescriptor) + DECLARE_DESCRIPTOR(NamedDescriptor, CallInterfaceDescriptor) }; class CallHandlerDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(CallHandlerDescriptor) + DECLARE_DESCRIPTOR(CallHandlerDescriptor, CallInterfaceDescriptor) }; class ArgumentAdaptorDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor) + DECLARE_DESCRIPTOR(ArgumentAdaptorDescriptor, CallInterfaceDescriptor) }; class ApiFunctionDescriptor : public CallInterfaceDescriptor { public: - DECLARE_DESCRIPTOR(ApiFunctionDescriptor) + DECLARE_DESCRIPTOR(ApiFunctionDescriptor, CallInterfaceDescriptor) +}; + + +class ApiGetterDescriptor : public CallInterfaceDescriptor { + public: + DECLARE_DESCRIPTOR(ApiGetterDescriptor, CallInterfaceDescriptor) + + static const Register function_address(); +}; + + +class ArgumentsAccessReadDescriptor : public CallInterfaceDescriptor { + public: + DECLARE_DESCRIPTOR(ArgumentsAccessReadDescriptor, CallInterfaceDescriptor) + + static const Register index(); + static const Register parameter_count(); +}; + + +class StoreArrayLiteralElementDescriptor : public CallInterfaceDescriptor { + public: + DECLARE_DESCRIPTOR(StoreArrayLiteralElementDescriptor, + CallInterfaceDescriptor) +}; + + +class MathPowTaggedDescriptor : public CallInterfaceDescriptor { + public: + DECLARE_DESCRIPTOR(MathPowTaggedDescriptor, CallInterfaceDescriptor) + + static const Register exponent(); +}; + + +class MathPowIntegerDescriptor : public CallInterfaceDescriptor { + public: + DECLARE_DESCRIPTOR(MathPowIntegerDescriptor, CallInterfaceDescriptor) + + static const Register exponent(); +}; + + +class ContextOnlyDescriptor : public CallInterfaceDescriptor { + public: + DECLARE_DESCRIPTOR(ContextOnlyDescriptor, CallInterfaceDescriptor) }; #undef DECLARE_DESCRIPTOR diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index a76c5cd..dfa74e0 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -259,7 +259,8 @@ void FloatingPointHelper::LoadSSE2UnknownOperands(MacroAssembler* masm, void MathPowStub::Generate(MacroAssembler* masm) { - const Register exponent = rdx; + const Register exponent = MathPowTaggedDescriptor::exponent(); + DCHECK(exponent.is(rdx)); const Register base = rax; const Register scratch = rcx; const XMMRegister double_result = xmm3; @@ -531,6 +532,8 @@ void FunctionPrototypeStub::Generate(MacroAssembler* masm) { void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) { // The key is in rdx and the parameter count is in rax. + DCHECK(rdx.is(ArgumentsAccessReadDescriptor::index())); + DCHECK(rax.is(ArgumentsAccessReadDescriptor::parameter_count())); // Check that the key is a smi. Label slow; @@ -2022,7 +2025,6 @@ void CallIC_ArrayStub::Generate(MacroAssembler* masm) { void CallICStub::Generate(MacroAssembler* masm) { // rdi - function - // rbx - vector // rdx - slot id Isolate* isolate = masm->isolate(); Label extra_checks_or_miss, slow_start; @@ -4590,7 +4592,8 @@ void CallApiGetterStub::Generate(MacroAssembler* masm) { Register accessor_info_arg = rsi; Register name_arg = rdi; #endif - Register api_function_address = r8; + Register api_function_address = ApiGetterDescriptor::function_address(); + DCHECK(api_function_address.is(r8)); Register scratch = rax; // v8::Arguments::values_ and handler for name. diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h index 7d174e5..d17fa1b 100644 --- a/src/x64/code-stubs-x64.h +++ b/src/x64/code-stubs-x64.h @@ -104,6 +104,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub { class IndexBits: public BitField {}; class LookupModeBits: public BitField {}; + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub); }; @@ -182,6 +183,8 @@ class RecordWriteStub: public PlatformCodeStub { CpuFeatures::FlushICache(stub->instruction_start(), 7); } + DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR(); + private: // This is a helper class for freeing up 3 scratch registers, where the third // is always rcx (needed for shift operations). The input is two registers diff --git a/src/x64/interface-descriptors-x64.cc b/src/x64/interface-descriptors-x64.cc index d0e24dd..84fdca4 100644 --- a/src/x64/interface-descriptors-x64.cc +++ b/src/x64/interface-descriptors-x64.cc @@ -18,17 +18,9 @@ const Register LoadDescriptor::ReceiverRegister() { return rdx; } const Register LoadDescriptor::NameRegister() { return rcx; } -const Register VectorLoadICDescriptor::ReceiverRegister() { - return LoadDescriptor::ReceiverRegister(); -} - - -const Register VectorLoadICDescriptor::NameRegister() { - return LoadDescriptor::NameRegister(); -} +const Register VectorLoadICTrampolineDescriptor::SlotRegister() { return rax; } -const Register VectorLoadICDescriptor::SlotRegister() { return rax; } const Register VectorLoadICDescriptor::VectorRegister() { return rbx; } @@ -37,28 +29,28 @@ const Register StoreDescriptor::NameRegister() { return rcx; } const Register StoreDescriptor::ValueRegister() { return rax; } -const Register ElementTransitionAndStoreDescriptor::ReceiverRegister() { - return StoreDescriptor::ReceiverRegister(); +const Register ElementTransitionAndStoreDescriptor::MapRegister() { + return rbx; } -const Register ElementTransitionAndStoreDescriptor::NameRegister() { - return StoreDescriptor::NameRegister(); -} +const Register InstanceofDescriptor::left() { return rax; } +const Register InstanceofDescriptor::right() { return rdx; } -const Register ElementTransitionAndStoreDescriptor::ValueRegister() { - return StoreDescriptor::ValueRegister(); -} +const Register ArgumentsAccessReadDescriptor::index() { return rdx; } +const Register ArgumentsAccessReadDescriptor::parameter_count() { return rax; } -const Register ElementTransitionAndStoreDescriptor::MapRegister() { - return rbx; -} +const Register ApiGetterDescriptor::function_address() { return r8; } -const Register InstanceofDescriptor::left() { return rax; } -const Register InstanceofDescriptor::right() { return rdx; } +const Register MathPowTaggedDescriptor::exponent() { return rdx; } + + +const Register MathPowIntegerDescriptor::exponent() { + return MathPowTaggedDescriptor::exponent(); +} void FastNewClosureDescriptor::Initialize(CallInterfaceDescriptorData* data) { @@ -110,12 +102,29 @@ void CreateAllocationSiteDescriptor::Initialize( } +void StoreArrayLiteralElementDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {rsi, rcx, rax}; + data->Initialize(arraysize(registers), registers, NULL); +} + + void CallFunctionDescriptor::Initialize(CallInterfaceDescriptorData* data) { Register registers[] = {rsi, rdi}; data->Initialize(arraysize(registers), registers, NULL); } +void CallFunctionWithFeedbackDescriptor::Initialize( + CallInterfaceDescriptorData* data) { + Register registers[] = {rsi, rdi, rdx}; + Representation representations[] = {Representation::Tagged(), + Representation::Tagged(), + Representation::Smi()}; + data->Initialize(arraysize(registers), registers, representations); +} + + void CallConstructDescriptor::Initialize(CallInterfaceDescriptorData* data) { // rax : number of arguments // rbx : feedback vector diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index c59d9e0..3f3ee8f 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -3891,9 +3891,9 @@ void LCodeGen::DoPower(LPower* instr) { // Having marked this as a call, we can use any registers. // Just make sure that the input/output registers are the expected ones. - Register exponent = rdx; + Register tagged_exponent = MathPowTaggedDescriptor::exponent(); DCHECK(!instr->right()->IsRegister() || - ToRegister(instr->right()).is(exponent)); + ToRegister(instr->right()).is(tagged_exponent)); DCHECK(!instr->right()->IsDoubleRegister() || ToDoubleRegister(instr->right()).is(xmm1)); DCHECK(ToDoubleRegister(instr->left()).is(xmm2)); @@ -3904,8 +3904,8 @@ void LCodeGen::DoPower(LPower* instr) { __ CallStub(&stub); } else if (exponent_type.IsTagged()) { Label no_deopt; - __ JumpIfSmi(exponent, &no_deopt, Label::kNear); - __ CmpObjectType(exponent, HEAP_NUMBER_TYPE, rcx); + __ JumpIfSmi(tagged_exponent, &no_deopt, Label::kNear); + __ CmpObjectType(tagged_exponent, HEAP_NUMBER_TYPE, rcx); DeoptimizeIf(not_equal, instr->environment()); __ bind(&no_deopt); MathPowStub stub(isolate(), MathPowStub::TAGGED); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 0ab6c1d..b7b1386 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1635,8 +1635,10 @@ LInstruction* LChunkBuilder::DoPower(HPower* instr) { Representation exponent_type = instr->right()->representation(); DCHECK(instr->left()->representation().IsDouble()); LOperand* left = UseFixedDouble(instr->left(), xmm2); - LOperand* right = exponent_type.IsDouble() ? - UseFixedDouble(instr->right(), xmm1) : UseFixed(instr->right(), rdx); + LOperand* right = + exponent_type.IsDouble() + ? UseFixedDouble(instr->right(), xmm1) + : UseFixed(instr->right(), MathPowTaggedDescriptor::exponent()); LPower* result = new(zone()) LPower(left, right); return MarkAsCall(DefineFixedDouble(result, xmm3), instr, CAN_DEOPTIMIZE_EAGERLY); -- 2.7.4