Added CallInterfaceDescriptors to all code stubs. A handful
authormvstanton@chromium.org <mvstanton@chromium.org>
Thu, 11 Sep 2014 07:11:10 +0000 (07:11 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org>
Thu, 11 Sep 2014 07:11:10 +0000 (07:11 +0000)
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

26 files changed:
src/arm/code-stubs-arm.cc
src/arm/code-stubs-arm.h
src/arm/interface-descriptors-arm.cc
src/arm/lithium-arm.cc
src/arm/lithium-codegen-arm.cc
src/arm64/code-stubs-arm64.cc
src/arm64/code-stubs-arm64.h
src/arm64/interface-descriptors-arm64.cc
src/arm64/lithium-arm64.cc
src/arm64/lithium-codegen-arm64.cc
src/code-stubs.h
src/ia32/code-stubs-ia32.cc
src/ia32/code-stubs-ia32.h
src/ia32/interface-descriptors-ia32.cc
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-ia32.cc
src/ic/arm/handler-compiler-arm.cc
src/ic/ia32/handler-compiler-ia32.cc
src/ic/x64/handler-compiler-x64.cc
src/interface-descriptors.cc
src/interface-descriptors.h
src/x64/code-stubs-x64.cc
src/x64/code-stubs-x64.h
src/x64/interface-descriptors-x64.cc
src/x64/lithium-codegen-x64.cc
src/x64/lithium-x64.cc

index 3391686..311d0b7 100644 (file)
@@ -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<Name>
   __ add(r1, r0, Operand(1 * kPointerSize));  // r1 = PCA
index e7f6610..727bb1b 100644 (file)
@@ -79,6 +79,7 @@ class WriteInt32ToHeapNumberStub : public PlatformCodeStub {
   class HeapNumberRegisterBits: public BitField<int, 4, 4> {};
   class ScratchRegisterBits: public BitField<int, 8, 4> {};
 
+  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<LookupMode, 0, 1> {};
 
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
   DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub);
 };
 
index 3b0e54d..9bbc1f5 100644 (file)
@@ -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
index 05b1535..7b97cb8 100644 (file)
@@ -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,
index 377d38b..d5c0468 100644 (file)
@@ -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());
index 6cd7043..39fec09 100644 (file)
@@ -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<Name>
   __ Add(x1, x0, 1 * kPointerSize);  // x1 = PCA
index c2e15e0..03dab5b 100644 (file)
@@ -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<LookupMode, 0, 1> {};
 
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
   DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub);
 };
 
index e7d2d4a..690c8c2 100644 (file)
@@ -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
index 7f5e2a3..b15b414 100644 (file)
@@ -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,
index da237a6..fdfec41 100644 (file)
@@ -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 {
index 626e14e..eb858b0 100644 (file)
@@ -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<Flags, 0, 3> {};
 
-  DEFINE_CALL_INTERFACE_DESCRIPTOR(Instanceof);
   DEFINE_PLATFORM_CODE_STUB(Instanceof, PlatformCodeStub);
 };
 
@@ -719,6 +732,7 @@ class ArrayConstructorStub: public PlatformCodeStub {
 
   class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
 
+  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<int, 2, Code::kArgumentsBits> {};
   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<Map> 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<bool, 0, 1> {};
   class ResultSizeBits : public BitField<int, 1, 3> {};
 
+  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<ExtraICState>(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<int, 2 * kBitsPerRegisterNumber + 5, 1> {};  // NOLINT
 
+  DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
   DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub);
 };
 
@@ -2102,6 +2148,7 @@ class StoreElementStub : public PlatformCodeStub {
 
   class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
 
+  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<StubFunctionMode, 0, 1> {};
 
+  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<bool, 0, 1> {};
 
+  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);
 };
 
index e92254d..ef507b5 100644 (file)
@@ -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).
index 7943f26..eabb5a5 100644 (file)
@@ -109,6 +109,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
   class IndexBits: public BitField<int, 6, 3> {};
   class LookupModeBits: public BitField<LookupMode, 9, 1> {};
 
+  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
index f97c64c..3a0d526 100644 (file)
@@ -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
index d9504c7..27952f3 100644 (file)
@@ -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);
index b5eeff4..0db3d9c 100644 (file)
@@ -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);
index fb50985..e49abf2 100644 (file)
@@ -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<Address>(callback->getter());
   ApiFunction fun(getter_address);
index fd77944..815a5d0 100644 (file)
@@ -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<Address>(callback->getter());
   __ mov(getter_address, Immediate(function_address));
 
index 399b96f..c4d6ecf 100644 (file)
@@ -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<Address>(callback->getter());
   __ Move(api_function_address, getter_address, RelocInfo::EXTERNAL_REFERENCE);
 
index eb2d737..62d7105 100644 (file)
@@ -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);
 }
 
index 4475900..b773c91 100644 (file)
@@ -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
index a76c5cd..dfa74e0 100644 (file)
@@ -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.
index 7d174e5..d17fa1b 100644 (file)
@@ -104,6 +104,7 @@ class NameDictionaryLookupStub: public PlatformCodeStub {
   class IndexBits: public BitField<int, 8, 4> {};
   class LookupModeBits: public BitField<LookupMode, 12, 1> {};
 
+  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
index d0e24dd..84fdca4 100644 (file)
@@ -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
index c59d9e0..3f3ee8f 100644 (file)
@@ -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);
index 0ab6c1d..b7b1386 100644 (file)
@@ -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);