}
-void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { r0, r3, r1, r2 };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r1, r0 };
Register receiver = ReceiverRegister();
Register key = NameRegister();
Register value = ValueRegister();
- ASSERT(receiver.is(r2));
- ASSERT(key.is(r1));
+ ASSERT(receiver.is(r1));
+ ASSERT(key.is(r2));
ASSERT(value.is(r0));
Label slow, notin;
const Register StoreIC::ValueRegister() { return r0; }
-const Register KeyedStoreIC::ReceiverRegister() { return r2; }
-const Register KeyedStoreIC::NameRegister() { return r1; }
-const Register KeyedStoreIC::ValueRegister() { return r0; }
+const Register KeyedStoreIC::ReceiverRegister() {
+ return StoreIC::ReceiverRegister();
+}
+
+
+const Register KeyedStoreIC::NameRegister() {
+ return StoreIC::NameRegister();
+}
+
+
+const Register KeyedStoreIC::ValueRegister() {
+ return StoreIC::ValueRegister();
+}
+
+
+const Register KeyedStoreIC::MapRegister() {
+ return r3;
+}
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
Register value = ValueRegister();
Register key = NameRegister();
Register receiver = ReceiverRegister();
- ASSERT(receiver.is(r2));
- ASSERT(key.is(r1));
+ ASSERT(receiver.is(r1));
+ ASSERT(key.is(r2));
ASSERT(value.is(r0));
Register receiver_map = r3;
Register elements_map = r6;
Register* KeyedStoreStubCompiler::registers() {
- // receiver, name, scratch1, scratch2, scratch3.
+ // receiver, name, scratch1/map, scratch2, scratch3.
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
- static Register registers[] = { receiver, name, r3, r4, r5 };
+ Register map = KeyedStoreIC::MapRegister();
+ static Register registers[] = { receiver, name, map, r4, r5 };
return registers;
}
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
+ // Polymorphic keyed stores may use the map register
Register map_reg = scratch1();
+ ASSERT(kind() != Code::KEYED_STORE_IC ||
+ map_reg.is(KeyedStoreIC::MapRegister()));
int receiver_count = types->length();
int number_of_handled_maps = 0;
}
-void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- // x0: value
- // x3: target map
- // x1: key
- // x2: receiver
- Register registers[] = { x0, x3, x1, x2 };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: left operand
Register value = ValueRegister();
Register key = NameRegister();
Register receiver = ReceiverRegister();
- ASSERT(receiver.is(x2));
- ASSERT(key.is(x1));
+ ASSERT(receiver.is(x1));
+ ASSERT(key.is(x2));
ASSERT(value.is(x0));
Register map = x3;
const Register StoreIC::ValueRegister() { return x0; }
-const Register KeyedStoreIC::ReceiverRegister() { return x2; }
-const Register KeyedStoreIC::NameRegister() { return x1; }
-const Register KeyedStoreIC::ValueRegister() { return x0; }
+const Register KeyedStoreIC::ReceiverRegister() {
+ return StoreIC::ReceiverRegister();
+}
+
+
+const Register KeyedStoreIC::NameRegister() {
+ return StoreIC::NameRegister();
+}
+
+
+const Register KeyedStoreIC::ValueRegister() {
+ return StoreIC::ValueRegister();
+}
+
+
+const Register KeyedStoreIC::MapRegister() {
+ return x3;
+}
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
Register value = ValueRegister();
Register key = NameRegister();
Register receiver = ReceiverRegister();
- ASSERT(receiver.is(x2));
- ASSERT(key.is(x1));
+ ASSERT(receiver.is(x1));
+ ASSERT(key.is(x2));
ASSERT(value.is(x0));
Register receiver_map = x3;
Register* KeyedStoreStubCompiler::registers() {
- // receiver, name, scratch1, scratch2, scratch3.
+ // receiver, name, scratch1/map, scratch2, scratch3.
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
- static Register registers[] = { receiver, name, x3, x4, x5 };
+ Register map = KeyedStoreIC::MapRegister();
+ static Register registers[] = { receiver, name, map, x4, x5 };
return registers;
}
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
+ // Polymorphic keyed stores may use the map register
Register map_reg = scratch1();
+ ASSERT(kind() != Code::KEYED_STORE_IC ||
+ map_reg.is(KeyedStoreIC::MapRegister()));
__ Ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = types->length();
int number_of_handled_maps = 0;
template<>
HValue* CodeStubGraphBuilder<ElementsTransitionAndStoreStub>::BuildCodeStub() {
- HValue* value = GetParameter(0);
- HValue* map = GetParameter(1);
- HValue* key = GetParameter(2);
- HValue* object = GetParameter(3);
+ HValue* value = GetParameter(ElementsTransitionAndStoreStub::kValueIndex);
+ HValue* map = GetParameter(ElementsTransitionAndStoreStub::kMapIndex);
+ HValue* key = GetParameter(ElementsTransitionAndStoreStub::kKeyIndex);
+ HValue* object = GetParameter(ElementsTransitionAndStoreStub::kObjectIndex);
if (FLAG_trace_elements_transitions) {
// Tracing elements transitions is the job of the runtime.
}
+void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
+ CodeStubInterfaceDescriptor* descriptor) {
+ Register registers[] = { ValueRegister(),
+ MapRegister(),
+ KeyRegister(),
+ ObjectRegister() };
+ descriptor->Initialize(ARRAY_SIZE(registers), registers,
+ FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
+}
+
+
void StoreGlobalStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { StoreIC::ReceiverRegister(),
virtual void InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) V8_OVERRIDE;
+ enum RegisterInfo {
+ kValueIndex,
+ kMapIndex,
+ kKeyIndex,
+ kObjectIndex,
+ kRegisterArgumentCount
+ };
+
+ static const Register ValueRegister() {
+ return KeyedStoreIC::ValueRegister();
+ }
+ static const Register MapRegister() { return KeyedStoreIC::MapRegister(); }
+ static const Register KeyRegister() { return KeyedStoreIC::NameRegister(); }
+ static const Register ObjectRegister() {
+ return KeyedStoreIC::ReceiverRegister();
+ }
+
private:
class FromBits: public BitField<ElementsKind, 0, 8> {};
class ToBits: public BitField<ElementsKind, 8, 8> {};
}
-void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { eax, ebx, ecx, edx };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { edx, eax };
}
+const Register KeyedStoreIC::MapRegister() {
+ return ebx;
+}
+
+
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// Return address is on the stack.
LoadIC_PushArgs(masm);
Register* KeyedStoreStubCompiler::registers() {
- // receiver, name, scratch1, scratch2, scratch3.
+ // receiver, name, scratch1/map, scratch2, scratch3.
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
- static Register registers[] = { receiver, name, ebx, edi, no_reg };
+ Register map = KeyedStoreIC::MapRegister();
+ static Register registers[] = { receiver, name, map, edi, no_reg };
return registers;
}
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
+ // Polymorphic keyed stores may use the map register
Register map_reg = scratch1();
+ ASSERT(kind() != Code::KEYED_STORE_IC ||
+ map_reg.is(KeyedStoreIC::MapRegister()));
__ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = types->length();
int number_of_handled_maps = 0;
static const Register NameRegister();
static const Register ValueRegister();
+ // The map register isn't part of the normal call specification, but
+ // ElementsTransitionAndStoreStub, used in polymorphic keyed store
+ // stub implementations requires it to be initialized.
+ static const Register MapRegister();
+
KeyedStoreIC(FrameDepth depth, Isolate* isolate)
: StoreIC(depth, isolate) {
ASSERT(target()->is_keyed_store_stub());
}
-void ElementsTransitionAndStoreStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { rax, rbx, rcx, rdx };
- descriptor->Initialize(ARRAY_SIZE(registers), registers,
- FUNCTION_ADDR(ElementsTransitionAndStoreIC_Miss));
-}
-
-
void BinaryOpICStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rdx, rax };
}
+const Register KeyedStoreIC::MapRegister() {
+ return rbx;
+}
+
+
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// The return address is on the stack.
Register* KeyedStoreStubCompiler::registers() {
- // receiver, name, scratch1, scratch2, scratch3.
+ // receiver, name, scratch1/map, scratch2, scratch3.
Register receiver = KeyedStoreIC::ReceiverRegister();
Register name = KeyedStoreIC::NameRegister();
- static Register registers[] = { receiver, name, rbx, rdi, r8 };
+ Register map = KeyedStoreIC::MapRegister();
+ static Register registers[] = { receiver, name, map, rdi, r8 };
return registers;
}
Label* smi_target = IncludesNumberType(types) ? &number_case : &miss;
__ JumpIfSmi(receiver(), smi_target);
+ // Polymorphic keyed stores may use the map register
Register map_reg = scratch1();
+ ASSERT(kind() != Code::KEYED_STORE_IC ||
+ map_reg.is(KeyedStoreIC::MapRegister()));
__ movp(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
int receiver_count = types->length();
int number_of_handled_maps = 0;