}
-void LoadFieldStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { edx };
- descriptor->Initialize(ARRAY_SIZE(registers), registers);
-}
-
-
-void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { edx };
- descriptor->Initialize(ARRAY_SIZE(registers), registers);
-}
-
-
-void StringLengthStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { edx, ecx };
- descriptor->Initialize(ARRAY_SIZE(registers), registers);
-}
-
-
-void KeyedStringLengthStub::InitializeInterfaceDescriptor(
- CodeStubInterfaceDescriptor* descriptor) {
- Register registers[] = { edx, ecx };
- descriptor->Initialize(ARRAY_SIZE(registers), registers);
-}
-
-
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { edx, ecx, eax };
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-x87.cc).
- // ----------- S t a t e -------------
- // -- ecx : name
- // -- edx : receiver
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false);
+ Register receiver = LoadIC::ReceiverRegister();
+ Register name = LoadIC::NameRegister();
+ Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
}
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC load call (from ic-x87.cc).
- // ----------- S t a t e -------------
- // -- ecx : key
- // -- edx : receiver
- // -----------------------------------
- Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false);
+ Register receiver = KeyedLoadIC::ReceiverRegister();
+ Register name = KeyedLoadIC::NameRegister();
+ Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
}
// All extension objects were empty and it is safe to use a global
// load IC call.
- __ mov(edx, GlobalObjectOperand());
- __ mov(ecx, var->name());
+ __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand());
+ __ mov(LoadIC::NameRegister(), var->name());
ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL
: CONTEXTUAL;
switch (var->location()) {
case Variable::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable");
- // Use inline caching. Variable name is passed in ecx and the global
- // object in eax.
- __ mov(edx, GlobalObjectOperand());
- __ mov(ecx, var->name());
+ __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand());
+ __ mov(LoadIC::NameRegister(), var->name());
CallLoadIC(CONTEXTUAL);
context()->Plug(eax);
break;
// receiver = iter; f = iter.next; arg = received;
__ bind(&l_next);
- __ mov(ecx, isolate()->factory()->next_string()); // "next"
- __ push(ecx);
+ Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
+ Register keyedload_name = KeyedLoadIC::NameRegister();
+ ASSERT(keyedload_receiver.is(edx));
+ ASSERT(keyedload_name.is(ecx));
+
+ __ mov(keyedload_name,
+ isolate()->factory()->next_string()); // "next"
+ __ push(keyedload_name);
__ push(Operand(esp, 2 * kPointerSize)); // iter
__ push(eax); // received
// result = receiver[f](arg);
__ bind(&l_call);
- __ mov(edx, Operand(esp, kPointerSize));
+ __ mov(keyedload_receiver, Operand(esp, kPointerSize));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax);
// if (!result.done) goto l_try;
__ bind(&l_loop);
__ push(eax); // save result
- __ mov(edx, eax); // result
- __ mov(ecx, isolate()->factory()->done_string()); // "done"
+ Register load_receiver = LoadIC::ReceiverRegister();
+ Register load_name = LoadIC::NameRegister();
+ ASSERT(load_receiver.is(edx));
+ ASSERT(load_name.is(ecx));
+ __ mov(load_receiver, eax); // result
+ __ mov(load_name,
+ isolate()->factory()->done_string()); // "done"
CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic);
__ j(zero, &l_try);
// result.value
- __ pop(edx); // result
- __ mov(ecx, isolate()->factory()->value_string()); // "value"
+ __ pop(load_receiver); // result
+ __ mov(load_name,
+ isolate()->factory()->value_string()); // "value"
CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
context()->DropAndPlug(2, eax); // drop iter and g
break;
SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral();
ASSERT(!key->value()->IsSmi());
- __ mov(ecx, Immediate(key->value()));
+ __ mov(LoadIC::NameRegister(), Immediate(key->value()));
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
}
if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj());
- __ mov(edx, result_register());
+ __ mov(LoadIC::ReceiverRegister(), result_register());
EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(eax);
} else {
VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key());
- __ pop(edx); // Object.
- __ mov(ecx, result_register()); // Key.
+ __ pop(KeyedLoadIC::ReceiverRegister()); // Object.
+ __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key.
EmitKeyedPropertyLoad(expr);
context()->Plug(eax);
}
} else {
// Load the function from the receiver.
ASSERT(callee->IsProperty());
- __ mov(edx, Operand(esp, 0));
+ __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver.
// Load the function from the receiver.
ASSERT(callee->IsProperty());
- __ mov(edx, Operand(esp, 0));
+ __ mov(KeyedLoadIC::ReceiverRegister(), Operand(esp, 0));
// Move the key into the right register for the keyed load IC.
- __ mov(ecx, eax);
+ __ mov(KeyedLoadIC::NameRegister(), eax);
EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
__ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
// Load the function from the receiver.
- __ mov(edx, Operand(esp, 0));
- __ mov(ecx, Immediate(expr->name()));
+ __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
+ __ mov(LoadIC::NameRegister(), Immediate(expr->name()));
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
// Push the target function under the receiver.
if (assign_type == NAMED_PROPERTY) {
// Put the object both on the stack and in edx.
VisitForAccumulatorValue(prop->obj());
+ ASSERT(!eax.is(LoadIC::ReceiverRegister()));
__ push(eax);
- __ mov(edx, eax);
+ __ mov(LoadIC::ReceiverRegister(), eax);
EmitNamedPropertyLoad(prop);
} else {
VisitForStackValue(prop->obj());
VisitForStackValue(prop->key());
- __ mov(edx, Operand(esp, kPointerSize)); // Object.
- __ mov(ecx, Operand(esp, 0)); // Key.
+ __ mov(KeyedLoadIC::ReceiverRegister(),
+ Operand(esp, kPointerSize)); // Object.
+ __ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key.
EmitKeyedPropertyLoad(prop);
}
}
if (proxy != NULL && proxy->var()->IsUnallocated()) {
Comment cmnt(masm_, "[ Global variable");
- __ mov(edx, GlobalObjectOperand());
- __ mov(ecx, Immediate(proxy->name()));
+ __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand());
+ __ mov(LoadIC::NameRegister(), Immediate(proxy->name()));
// Use a regular load, not a contextual load, to avoid a reference
// error.
CallLoadIC(NOT_CONTEXTUAL);
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
+ ASSERT(edx.is(ReceiverRegister()));
+ ASSERT(ecx.is(NameRegister()));
Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary;
}
+// A register that isn't one of the parameters to the load ic.
+static const Register LoadIC_TempRegister() { return ebx; }
+
+
+// A register that isn't one of the parameters to the load ic.
+static const Register KeyedLoadIC_TempRegister() {
+ return LoadIC_TempRegister();
+}
+
+
void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : key (index)
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
Label miss;
- Register receiver = edx;
- Register index = ecx;
- Register scratch = ebx;
+ Register receiver = ReceiverRegister();
+ Register index = NameRegister();
+ Register scratch = KeyedLoadIC_TempRegister();
Register result = eax;
+ ASSERT(!result.is(scratch));
StringCharAtGenerator char_at_generator(receiver,
index,
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
+ // Return address is on the stack.
Label slow;
+ Register receiver = ReceiverRegister();
+ Register key = NameRegister();
+ Register scratch = eax;
+ ASSERT(!scratch.is(receiver) && !scratch.is(key));
+
// Check that the receiver isn't a smi.
- __ JumpIfSmi(edx, &slow);
+ __ JumpIfSmi(receiver, &slow);
// Check that the key is an array index, that is Uint32.
- __ test(ecx, Immediate(kSmiTagMask | kSmiSignMask));
+ __ test(key, Immediate(kSmiTagMask | kSmiSignMask));
__ j(not_zero, &slow);
// Get the map of the receiver.
- __ mov(eax, FieldOperand(edx, HeapObject::kMapOffset));
+ __ mov(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
// Check that it has indexed interceptor and access checks
// are not enabled for this object.
- __ movzx_b(eax, FieldOperand(eax, Map::kBitFieldOffset));
- __ and_(eax, Immediate(kSlowCaseBitFieldMask));
- __ cmp(eax, Immediate(1 << Map::kHasIndexedInterceptor));
+ __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
+ __ and_(scratch, Immediate(kSlowCaseBitFieldMask));
+ __ cmp(scratch, Immediate(1 << Map::kHasIndexedInterceptor));
__ j(not_zero, &slow);
// Everything is fine, call runtime.
- __ pop(eax);
- __ push(edx); // receiver
- __ push(ecx); // key
- __ push(eax); // return address
+ __ pop(scratch);
+ __ push(receiver); // receiver
+ __ push(key); // key
+ __ push(scratch); // return address
// Perform tail call to the entry.
ExternalReference ref =
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
+ ASSERT(edx.is(ReceiverRegister()));
+ ASSERT(ecx.is(NameRegister()));
Label slow, notin;
Factory* factory = masm->isolate()->factory();
Operand mapped_location =
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
+ ASSERT(edx.is(ReceiverRegister()));
+ ASSERT(ecx.is(NameRegister()));
// Probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
+ ASSERT(edx.is(ReceiverRegister()));
+ ASSERT(ecx.is(NameRegister()));
+
Label miss, slow;
GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss);
void LoadIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : name
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
+ // Return address is on the stack.
__ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
- __ pop(ebx);
- __ push(edx); // receiver
- __ push(ecx); // name
- __ push(ebx); // return address
+ __ pop(LoadIC_TempRegister());
+ __ push(ReceiverRegister()); // receiver
+ __ push(NameRegister()); // name
+ __ push(LoadIC_TempRegister()); // return address
// Perform tail call to the entry.
ExternalReference ref =
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
- __ pop(ebx);
- __ push(edx); // receiver
- __ push(ecx); // name
- __ push(ebx); // return address
+ // Return address is on the stack.
+ __ pop(LoadIC_TempRegister());
+ __ push(ReceiverRegister()); // receiver
+ __ push(NameRegister()); // name
+ __ push(LoadIC_TempRegister()); // return address
// Perform tail call to the entry.
__ TailCallRuntime(Runtime::kGetProperty, 2, 1);
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
+ // Return address is on the stack.
__ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1);
- __ pop(ebx);
- __ push(edx); // receiver
- __ push(ecx); // name
- __ push(ebx); // return address
+ __ pop(KeyedLoadIC_TempRegister());
+ __ push(ReceiverRegister()); // receiver
+ __ push(NameRegister()); // name
+ __ push(KeyedLoadIC_TempRegister()); // return address
// Perform tail call to the entry.
ExternalReference ref =
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
- // ----------- S t a t e -------------
- // -- ecx : key
- // -- edx : receiver
- // -- esp[0] : return address
- // -----------------------------------
-
- __ pop(ebx);
- __ push(edx); // receiver
- __ push(ecx); // name
- __ push(ebx); // return address
+ // Return address is on the stack.
+ __ pop(KeyedLoadIC_TempRegister());
+ __ push(ReceiverRegister()); // receiver
+ __ push(NameRegister()); // name
+ __ push(KeyedLoadIC_TempRegister()); // return address
// Perform tail call to the entry.
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
- ASSERT(ToRegister(instr->global_object()).is(edx));
+ ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->result()).is(eax));
- __ mov(ecx, instr->name());
+ __ mov(LoadIC::NameRegister(), instr->name());
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
CallCode(ic, RelocInfo::CODE_TARGET, instr);
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
- ASSERT(ToRegister(instr->object()).is(edx));
+ ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->result()).is(eax));
- __ mov(ecx, instr->name());
+ __ mov(LoadIC::NameRegister(), instr->name());
Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
CallCode(ic, RelocInfo::CODE_TARGET, instr);
}
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
- ASSERT(ToRegister(instr->object()).is(edx));
- ASSERT(ToRegister(instr->key()).is(ecx));
+ ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister()));
+ ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister()));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr);
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi);
- LOperand* global_object = UseFixed(instr->global_object(), edx);
+ LOperand* global_object = UseFixed(instr->global_object(),
+ LoadIC::ReceiverRegister());
LLoadGlobalGeneric* result =
new(zone()) LLoadGlobalGeneric(context, global_object);
return MarkAsCall(DefineFixed(result, eax), instr);
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi);
- LOperand* object = UseFixed(instr->object(), edx);
+ LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object);
return MarkAsCall(DefineFixed(result, eax), instr);
}
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi);
- LOperand* object = UseFixed(instr->object(), edx);
- LOperand* key = UseFixed(instr->key(), ecx);
+ LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister());
+ LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister());
LLoadKeyedGeneric* result =
new(zone()) LLoadKeyedGeneric(context, object, key);
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
+ ASSERT(edx.is(KeyedLoadIC::ReceiverRegister()));
+ ASSERT(ecx.is(KeyedLoadIC::NameRegister()));
Label slow, miss;
// This stub is meant to be tail-jumped to, the receiver must already