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;
// 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;
// -- 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
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);
};
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
private:
bool NeedsImmovableCode() { return true; }
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub);
};
class LookupModeBits: public BitField<LookupMode, 0, 1> {};
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub);
};
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; }
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) {
}
+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
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,
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));
__ 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());
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;
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.
// -- 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
static void GenerateAheadOfTime(Isolate* isolate);
private:
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(StoreRegistersState, PlatformCodeStub);
};
static void GenerateAheadOfTime(Isolate* isolate);
private:
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(RestoreRegistersState, 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.
private:
bool NeedsImmovableCode() { return true; }
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(DirectCEntry, PlatformCodeStub);
};
class LookupModeBits: public BitField<LookupMode, 0, 1> {};
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(NameDictionaryLookup, PlatformCodeStub);
};
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; }
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; }
}
+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
}
+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};
}
+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
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,
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));
__ 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);
} 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 {
// 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) {}
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:
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_); }
class FlagBits : public BitField<Flags, 0, 3> {};
- DEFINE_CALL_INTERFACE_DESCRIPTOR(Instanceof);
DEFINE_PLATFORM_CODE_STUB(Instanceof, PlatformCodeStub);
};
class ArgumentCountBits : public BitField<ArgumentCountKey, 0, 2> {};
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ArrayConstructor);
DEFINE_PLATFORM_CODE_STUB(ArrayConstructor, PlatformCodeStub);
};
private:
void GenerateCase(MacroAssembler* masm, ElementsKind kind);
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(InternalArrayConstructor);
DEFINE_PLATFORM_CODE_STUB(InternalArrayConstructor, 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_);
private:
virtual void PrintState(OStream& os) const OVERRIDE; // NOLINT
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(CallFunctionWithFeedback);
DEFINE_PLATFORM_CODE_STUB(CallIC, 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);
};
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);
};
public:
explicit CallApiGetterStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ApiGetter);
DEFINE_PLATFORM_CODE_STUB(CallApiGetter, PlatformCodeStub);
};
static void GenerateAheadOfTime(Isolate* isolate,
const BinaryOpIC::State& state);
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOpWithAllocationSite);
DEFINE_PLATFORM_CODE_STUB(BinaryOpICWithAllocationSite, PlatformCodeStub);
};
Handle<Map> known_map_;
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
DEFINE_PLATFORM_CODE_STUB(CompareIC, 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);
};
int handler_offset_;
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(JSEntry, 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_); }
public:
explicit RegExpExecStub(Isolate* isolate) : PlatformCodeStub(isolate) { }
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
DEFINE_PLATFORM_CODE_STUB(RegExpExec, PlatformCodeStub);
};
return LoadIC::State(static_cast<ExtraICState>(minor_key_));
}
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(VectorLoadICTrampoline);
DEFINE_PLATFORM_CODE_STUB(LoadICTrampoline, PlatformCodeStub);
};
class SSE3Bits:
public BitField<int, 2 * kBitsPerRegisterNumber + 5, 1> {}; // NOLINT
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(DoubleToI, PlatformCodeStub);
};
class ElementsKindBits : public BitField<ElementsKind, 0, 8> {};
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(Store);
DEFINE_PLATFORM_CODE_STUB(StoreElement, PlatformCodeStub);
};
explicit StoreArrayLiteralElementStub(Isolate* isolate)
: PlatformCodeStub(isolate) { }
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(StoreArrayLiteralElement);
DEFINE_PLATFORM_CODE_STUB(StoreArrayLiteralElement, PlatformCodeStub);
};
class FunctionModeField : public BitField<StubFunctionMode, 0, 1> {};
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(StubFailureTrampoline, 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);
};
class SaveDoublesBits : public BitField<bool, 0, 1> {};
+ DEFINE_NULL_CALL_INTERFACE_DESCRIPTOR();
DEFINE_PLATFORM_CODE_STUB(StoreBufferOverflow, PlatformCodeStub);
};
public:
explicit SubStringStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
DEFINE_PLATFORM_CODE_STUB(SubString, PlatformCodeStub);
};
public:
explicit StringCompareStub(Isolate* isolate) : PlatformCodeStub(isolate) {}
+ DEFINE_CALL_INTERFACE_DESCRIPTOR(ContextOnly);
DEFINE_PLATFORM_CODE_STUB(StringCompare, PlatformCodeStub);
};
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;
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
// -- ...
// -- 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).
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);
};
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
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; }
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) {
}
+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
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));
__ 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);
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);
__ 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);
__ 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));
__ 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);
}
+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);
}
V(Store) \
V(ElementTransitionAndStore) \
V(Instanceof) \
+ V(VectorLoadICTrampoline) \
V(VectorLoadIC) \
V(FastNewClosure) \
V(FastNewContext) \
V(FastCloneShallowObject) \
V(CreateAllocationSite) \
V(CallFunction) \
+ V(CallFunctionWithFeedback) \
V(CallConstruct) \
V(RegExpConstructResult) \
V(TransitionElementsKind) \
V(Named) \
V(CallHandler) \
V(ArgumentAdaptor) \
- V(ApiFunction)
+ V(ApiGetter) \
+ V(ApiFunction) \
+ V(ArgumentsAccessRead) \
+ V(StoreArrayLiteralElement) \
+ V(MathPowTagged) \
+ V(MathPowInteger) \
+ V(ContextOnly)
class CallInterfaceDescriptorData {
};
-#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();
class StoreDescriptor : public CallInterfaceDescriptor {
public:
- DECLARE_DESCRIPTOR(StoreDescriptor)
+ DECLARE_DESCRIPTOR(StoreDescriptor, CallInterfaceDescriptor)
enum ParameterIndices {
kReceiverIndex,
};
-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();
};
-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
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;
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;
void CallICStub::Generate(MacroAssembler* masm) {
// rdi - function
- // rbx - vector
// rdx - slot id
Isolate* isolate = masm->isolate();
Label extra_checks_or_miss, slow_start;
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.
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);
};
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
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; }
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) {
}
+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
// 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));
__ 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);
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);