Use IC register definitions in platform files.

R=jkummerow@chromium.org

Review URL: https://codereview.chromium.org/356713003

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@22035 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
mvstanton@chromium.org 2014-06-26 10:00:36 +00:00
parent e26102ac24
commit 4273c7c070
29 changed files with 465 additions and 526 deletions

View File

@ -87,34 +87,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
} }
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r0, r2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r1, r0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r2, r1, r0 }; Register registers[] = { r2, r1, r0 };

View File

@ -176,15 +176,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc). // Calling convention for IC load (from ic-arm.cc).
// ----------- S t a t e ------------- Register receiver = LoadIC::ReceiverRegister();
// -- r2 : name Register name = LoadIC::NameRegister();
// -- lr : return address Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
// -- r0 : receiver
// -- [sp] : receiver
// -----------------------------------
// Registers r0 and r2 contain objects that need to be pushed on the
// expression stack of the fake JS frame.
Generate_DebugBreakCallHelper(masm, r0.bit() | r2.bit(), 0);
} }
@ -203,11 +197,10 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// ---------- S t a t e -------------- // Calling convention for keyed IC load (from ic-arm.cc).
// -- lr : return address Register receiver = KeyedLoadIC::ReceiverRegister();
// -- r0 : key Register name = KeyedLoadIC::NameRegister();
// -- r1 : receiver Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit(), 0);
} }

View File

@ -1389,8 +1389,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ bind(&fast); __ bind(&fast);
} }
__ ldr(r0, GlobalObjectOperand()); __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand());
__ mov(r2, Operand(var->name())); __ mov(LoadIC::NameRegister(), Operand(var->name()));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL ? NOT_CONTEXTUAL
: CONTEXTUAL; : CONTEXTUAL;
@ -1472,10 +1472,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
switch (var->location()) { switch (var->location()) {
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable"); Comment cmnt(masm_, "[ Global variable");
// Use inline caching. Variable name is passed in r2 and the global __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand());
// object (receiver) in r0. __ mov(LoadIC::NameRegister(), Operand(var->name()));
__ ldr(r0, GlobalObjectOperand());
__ mov(r2, Operand(var->name()));
CallLoadIC(CONTEXTUAL); CallLoadIC(CONTEXTUAL);
context()->Plug(r0); context()->Plug(r0);
break; break;
@ -2053,14 +2051,19 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// receiver = iter; f = 'next'; arg = received; // receiver = iter; f = 'next'; arg = received;
__ bind(&l_next); __ bind(&l_next);
Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
Register keyedload_name = KeyedLoadIC::NameRegister();
ASSERT(keyedload_receiver.is(r1));
ASSERT(keyedload_name.is(r0));
__ LoadRoot(r2, Heap::knext_stringRootIndex); // "next" __ LoadRoot(r2, Heap::knext_stringRootIndex); // "next"
__ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter __ ldr(r3, MemOperand(sp, 1 * kPointerSize)); // iter
__ Push(r2, r3, r0); // "next", iter, received __ Push(r2, r3, r0); // "next", iter, received
// result = receiver[f](arg); // result = receiver[f](arg);
__ bind(&l_call); __ bind(&l_call);
__ ldr(r1, MemOperand(sp, kPointerSize)); __ ldr(keyedload_receiver, MemOperand(sp, kPointerSize));
__ ldr(r0, MemOperand(sp, 2 * kPointerSize)); __ ldr(keyedload_name, MemOperand(sp, 2 * kPointerSize));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None()); CallIC(ic, TypeFeedbackId::None());
__ mov(r1, r0); __ mov(r1, r0);
@ -2073,19 +2076,24 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// if (!result.done) goto l_try; // if (!result.done) goto l_try;
__ bind(&l_loop); __ bind(&l_loop);
__ push(r0); // save result Register load_receiver = LoadIC::ReceiverRegister();
__ LoadRoot(r2, Heap::kdone_stringRootIndex); // "done" Register load_name = LoadIC::NameRegister();
CallLoadIC(NOT_CONTEXTUAL); // result.done in r0 ASSERT(load_receiver.is(r0));
ASSERT(load_name.is(r2));
__ push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
CallLoadIC(NOT_CONTEXTUAL); // r0=result.done
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic); CallIC(bool_ic);
__ cmp(r0, Operand(0)); __ cmp(r0, Operand(0));
__ b(eq, &l_try); __ b(eq, &l_try);
// result.value // result.value
__ pop(r0); // result __ pop(load_receiver); // result
__ LoadRoot(r2, Heap::kvalue_stringRootIndex); // "value" __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
CallLoadIC(NOT_CONTEXTUAL); // result.value in r0 CallLoadIC(NOT_CONTEXTUAL); // r0=result.value
context()->DropAndPlug(2, r0); // drop iter and g context()->DropAndPlug(2, r0); // drop iter and g
break; break;
} }
} }
@ -2258,15 +2266,15 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral(); Literal* key = prop->key()->AsLiteral();
__ mov(r2, Operand(key->value())); __ mov(LoadIC::NameRegister(), Operand(key->value()));
// Call load IC. It has arguments receiver and property name r0 and r2. // Call load IC. It has register arguments receiver and property.
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
} }
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
// Call keyed load IC. It has arguments key and receiver in r0 and r1. // Call keyed load IC. It has register arguments receiver and key.
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, prop->PropertyFeedbackId()); CallIC(ic, prop->PropertyFeedbackId());
} }
@ -2555,13 +2563,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj()); VisitForAccumulatorValue(expr->obj());
ASSERT(r0.is(LoadIC::ReceiverRegister()));
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG); PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(r0); context()->Plug(r0);
} else { } else {
VisitForStackValue(expr->obj()); VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key()); VisitForAccumulatorValue(expr->key());
__ pop(r1); ASSERT(r0.is(KeyedLoadIC::NameRegister()));
__ pop(KeyedLoadIC::ReceiverRegister());
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
context()->Plug(r0); context()->Plug(r0);
} }
@ -2598,7 +2608,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else { } else {
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ ldr(r0, MemOperand(sp, 0)); __ ldr(LoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitNamedPropertyLoad(callee->AsProperty()); EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver. // Push the target function under the receiver.
@ -2616,12 +2626,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
Expression* key) { Expression* key) {
// Load the key. // Load the key.
VisitForAccumulatorValue(key); VisitForAccumulatorValue(key);
ASSERT(r0.is(KeyedLoadIC::NameRegister()));
Expression* callee = expr->expression(); Expression* callee = expr->expression();
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ ldr(r1, MemOperand(sp, 0)); __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0));
EmitKeyedPropertyLoad(callee->AsProperty()); EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
@ -4039,7 +4050,8 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ push(r0); __ push(r0);
// Load the function from the receiver. // Load the function from the receiver.
__ mov(r2, Operand(expr->name())); ASSERT(r0.is(LoadIC::ReceiverRegister()));
__ mov(LoadIC::NameRegister(), Operand(expr->name()));
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
// Push the target function under the receiver. // Push the target function under the receiver.
@ -4218,13 +4230,15 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == NAMED_PROPERTY) { if (assign_type == NAMED_PROPERTY) {
// Put the object both on the stack and in the accumulator. // Put the object both on the stack and in the accumulator.
VisitForAccumulatorValue(prop->obj()); VisitForAccumulatorValue(prop->obj());
__ push(r0); ASSERT(r0.is(LoadIC::ReceiverRegister()));
__ push(LoadIC::ReceiverRegister());
EmitNamedPropertyLoad(prop); EmitNamedPropertyLoad(prop);
} else { } else {
VisitForStackValue(prop->obj()); VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key()); VisitForAccumulatorValue(prop->key());
__ ldr(r1, MemOperand(sp, 0)); ASSERT(r0.is(KeyedLoadIC::NameRegister()));
__ push(r0); __ ldr(KeyedLoadIC::ReceiverRegister(), MemOperand(sp, 0));
__ push(KeyedLoadIC::NameRegister());
EmitKeyedPropertyLoad(prop); EmitKeyedPropertyLoad(prop);
} }
} }
@ -4371,8 +4385,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
VariableProxy* proxy = expr->AsVariableProxy(); VariableProxy* proxy = expr->AsVariableProxy();
if (proxy != NULL && proxy->var()->IsUnallocated()) { if (proxy != NULL && proxy->var()->IsUnallocated()) {
Comment cmnt(masm_, "[ Global variable"); Comment cmnt(masm_, "[ Global variable");
__ ldr(r0, GlobalObjectOperand()); __ ldr(LoadIC::ReceiverRegister(), GlobalObjectOperand());
__ mov(r2, Operand(proxy->name())); __ mov(LoadIC::NameRegister(), Operand(proxy->name()));
// Use a regular load, not a contextual load, to avoid a reference // Use a regular load, not a contextual load, to avoid a reference
// error. // error.
CallLoadIC(NOT_CONTEXTUAL); CallLoadIC(NOT_CONTEXTUAL);

View File

@ -316,6 +316,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// -- lr : return address // -- lr : return address
// -- r0 : receiver // -- r0 : receiver
// ----------------------------------- // -----------------------------------
ASSERT(r0.is(ReceiverRegister()));
ASSERT(r2.is(NameRegister()));
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
@ -333,6 +335,9 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// -- lr : return address // -- lr : return address
// -- r0 : receiver // -- r0 : receiver
// ----------------------------------- // -----------------------------------
ASSERT(r0.is(ReceiverRegister()));
ASSERT(r2.is(NameRegister()));
Label miss, slow; Label miss, slow;
GenerateNameDictionaryReceiverCheck(masm, r0, r1, r3, r4, &miss); GenerateNameDictionaryReceiverCheck(masm, r0, r1, r3, r4, &miss);
@ -351,18 +356,18 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
} }
// A register that isn't one of the parameters to the load ic.
static const Register LoadIC_TempRegister() { return r3; }
void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e ------------- // The return address is on the stack.
// -- r2 : name
// -- lr : return address
// -- r0 : receiver
// -----------------------------------
Isolate* isolate = masm->isolate(); Isolate* isolate = masm->isolate();
__ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4); __ IncrementCounter(isolate->counters()->load_miss(), 1, r3, r4);
__ mov(r3, r0); __ mov(LoadIC_TempRegister(), ReceiverRegister());
__ Push(r3, r2); __ Push(LoadIC_TempRegister(), NameRegister());
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -372,14 +377,10 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e -------------- // The return address is on the stack.
// -- r2 : name
// -- lr : return address
// -- r0 : receiver
// -----------------------------------
__ mov(r3, r0); __ mov(LoadIC_TempRegister(), ReceiverRegister());
__ Push(r3, r2); __ Push(LoadIC_TempRegister(), NameRegister());
__ TailCallRuntime(Runtime::kGetProperty, 2, 1); __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
} }
@ -476,6 +477,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
// -- r0 : key // -- r0 : key
// -- r1 : receiver // -- r1 : receiver
// ----------------------------------- // -----------------------------------
ASSERT(r1.is(ReceiverRegister()));
ASSERT(r0.is(NameRegister()));
Label slow, notin; Label slow, notin;
MemOperand mapped_location = MemOperand mapped_location =
GenerateMappedArgumentsLookup(masm, r1, r0, r2, r3, r4, &notin, &slow); GenerateMappedArgumentsLookup(masm, r1, r0, r2, r3, r4, &notin, &slow);
@ -526,16 +529,12 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// ---------- S t a t e -------------- // The return address is on the stack.
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
Isolate* isolate = masm->isolate(); Isolate* isolate = masm->isolate();
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, r3, r4);
__ Push(r1, r0); __ Push(ReceiverRegister(), NameRegister());
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -553,13 +552,9 @@ const Register KeyedLoadIC::NameRegister() { return r0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e -------------- // The return address is on the stack.
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
__ Push(r1, r0); __ Push(ReceiverRegister(), NameRegister());
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
} }
@ -574,8 +569,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
Label slow, check_name, index_smi, index_name, property_array_property; Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary; Label probe_dictionary, check_number_dictionary;
Register key = r0; Register key = NameRegister();
Register receiver = r1; Register receiver = ReceiverRegister();
ASSERT(key.is(r0));
ASSERT(receiver.is(r1));
Isolate* isolate = masm->isolate(); Isolate* isolate = masm->isolate();
@ -737,17 +734,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// ---------- S t a t e -------------- // Return address is on the stack.
// -- lr : return address
// -- r0 : key (index)
// -- r1 : receiver
// -----------------------------------
Label miss; Label miss;
Register receiver = r1; Register receiver = ReceiverRegister();
Register index = r0; Register index = NameRegister();
Register scratch = r3; Register scratch = r3;
Register result = r0; Register result = r0;
ASSERT(!scratch.is(receiver) && !scratch.is(index));
StringCharAtGenerator char_at_generator(receiver, StringCharAtGenerator char_at_generator(receiver,
index, index,
@ -769,32 +763,35 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// ---------- S t a t e -------------- // Return address is on the stack.
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
Label slow; Label slow;
Register receiver = ReceiverRegister();
Register key = NameRegister();
Register scratch1 = r2;
Register scratch2 = r3;
ASSERT(!scratch1.is(receiver) && !scratch1.is(key));
ASSERT(!scratch2.is(receiver) && !scratch2.is(key));
// Check that the receiver isn't a smi. // Check that the receiver isn't a smi.
__ JumpIfSmi(r1, &slow); __ JumpIfSmi(receiver, &slow);
// Check that the key is an array index, that is Uint32. // Check that the key is an array index, that is Uint32.
__ NonNegativeSmiTst(r0); __ NonNegativeSmiTst(key);
__ b(ne, &slow); __ b(ne, &slow);
// Get the map of the receiver. // Get the map of the receiver.
__ ldr(r2, FieldMemOperand(r1, HeapObject::kMapOffset)); __ ldr(scratch1, FieldMemOperand(receiver, HeapObject::kMapOffset));
// Check that it has indexed interceptor and access checks // Check that it has indexed interceptor and access checks
// are not enabled for this object. // are not enabled for this object.
__ ldrb(r3, FieldMemOperand(r2, Map::kBitFieldOffset)); __ ldrb(scratch2, FieldMemOperand(scratch1, Map::kBitFieldOffset));
__ and_(r3, r3, Operand(kSlowCaseBitFieldMask)); __ and_(scratch2, scratch2, Operand(kSlowCaseBitFieldMask));
__ cmp(r3, Operand(1 << Map::kHasIndexedInterceptor)); __ cmp(scratch2, Operand(1 << Map::kHasIndexedInterceptor));
__ b(ne, &slow); __ b(ne, &slow);
// Everything is fine, call runtime. // Everything is fine, call runtime.
__ Push(r1, r0); // Receiver, key. __ Push(receiver, key); // Receiver, key.
// Perform tail call to the entry. // Perform tail call to the entry.
__ TailCallExternalReference( __ TailCallExternalReference(

View File

@ -2216,7 +2216,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp); LOperand* context = UseFixed(instr->context(), cp);
LOperand* global_object = UseFixed(instr->global_object(), r0); LOperand* global_object = UseFixed(instr->global_object(),
LoadIC::ReceiverRegister());
LLoadGlobalGeneric* result = LLoadGlobalGeneric* result =
new(zone()) LLoadGlobalGeneric(context, global_object); new(zone()) LLoadGlobalGeneric(context, global_object);
return MarkAsCall(DefineFixed(result, r0), instr); return MarkAsCall(DefineFixed(result, r0), instr);
@ -2270,7 +2271,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp); LOperand* context = UseFixed(instr->context(), cp);
LOperand* object = UseFixed(instr->object(), r0); LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
LInstruction* result = LInstruction* result =
DefineFixed(new(zone()) LLoadNamedGeneric(context, object), r0); DefineFixed(new(zone()) LLoadNamedGeneric(context, object), r0);
return MarkAsCall(result, instr); return MarkAsCall(result, instr);
@ -2330,8 +2331,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp); LOperand* context = UseFixed(instr->context(), cp);
LOperand* object = UseFixed(instr->object(), r1); LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister());
LOperand* key = UseFixed(instr->key(), r0); LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister());
LInstruction* result = LInstruction* result =
DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), r0); DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), r0);

View File

@ -2969,10 +2969,10 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp)); ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->global_object()).is(r0)); ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->result()).is(r0)); ASSERT(ToRegister(instr->result()).is(r0));
__ mov(r2, Operand(instr->name())); __ mov(LoadIC::NameRegister(), Operand(instr->name()));
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
@ -3088,11 +3088,11 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp)); ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).is(r0)); ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->result()).is(r0)); ASSERT(ToRegister(instr->result()).is(r0));
// Name is always in r2. // Name is always in r2.
__ mov(r2, Operand(instr->name())); __ mov(LoadIC::NameRegister(), Operand(instr->name()));
Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);
} }
@ -3394,8 +3394,8 @@ MemOperand LCodeGen::PrepareKeyedOperand(Register key,
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp)); ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).is(r1)); ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->key()).is(r0)); ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister()));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS); CallCode(ic, RelocInfo::CODE_TARGET, instr, NEVER_INLINE_TARGET_ADDRESS);

View File

@ -1479,6 +1479,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
// -- r0 : key // -- r0 : key
// -- r1 : receiver // -- r1 : receiver
// ----------------------------------- // -----------------------------------
ASSERT(r1.is(KeyedLoadIC::ReceiverRegister()));
ASSERT(r0.is(KeyedLoadIC::NameRegister()));
Label slow, miss; Label slow, miss;
Register key = r0; Register key = r0;

View File

@ -102,36 +102,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
} }
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x0: receiver
Register registers[] = { x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
// x1: receiver
Register registers[] = { x1 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { x0, x2 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { x1, x0 };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
// x2: receiver // x2: receiver

View File

@ -235,15 +235,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc). // Calling convention for IC load (from ic-arm.cc).
// ----------- S t a t e ------------- Register receiver = LoadIC::ReceiverRegister();
// -- x2 : name Register name = LoadIC::NameRegister();
// -- lr : return address Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10);
// -- x0 : receiver
// -- [sp] : receiver
// -----------------------------------
// Registers x0 and x2 contain objects that need to be pushed on the
// expression stack of the fake JS frame.
Generate_DebugBreakCallHelper(masm, x0.Bit() | x2.Bit(), 0, x10);
} }
@ -262,11 +256,10 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// ---------- S t a t e -------------- // Calling convention for keyed IC load (from ic-arm.cc).
// -- lr : return address Register receiver = KeyedLoadIC::ReceiverRegister();
// -- x0 : key Register name = KeyedLoadIC::NameRegister();
// -- x1 : receiver Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10);
Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit(), 0, x10);
} }

View File

@ -1393,8 +1393,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
__ Bind(&fast); __ Bind(&fast);
} }
__ Ldr(x0, GlobalObjectMemOperand()); __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand());
__ Mov(x2, Operand(var->name())); __ Mov(LoadIC::NameRegister(), Operand(var->name()));
ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ? NOT_CONTEXTUAL
: CONTEXTUAL; : CONTEXTUAL;
CallLoadIC(mode); CallLoadIC(mode);
@ -1472,10 +1472,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
switch (var->location()) { switch (var->location()) {
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
Comment cmnt(masm_, "Global variable"); Comment cmnt(masm_, "Global variable");
// Use inline caching. Variable name is passed in x2 and the global __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand());
// object (receiver) in x0. __ Mov(LoadIC::NameRegister(), Operand(var->name()));
__ Ldr(x0, GlobalObjectMemOperand());
__ Mov(x2, Operand(var->name()));
CallLoadIC(CONTEXTUAL); CallLoadIC(CONTEXTUAL);
context()->Plug(x0); context()->Plug(x0);
break; break;
@ -1949,7 +1947,7 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral(); Literal* key = prop->key()->AsLiteral();
__ Mov(x2, Operand(key->value())); __ Mov(LoadIC::NameRegister(), Operand(key->value()));
// Call load IC. It has arguments receiver and property name x0 and x2. // Call load IC. It has arguments receiver and property name x0 and x2.
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
} }
@ -2262,13 +2260,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj()); VisitForAccumulatorValue(expr->obj());
ASSERT(x0.is(LoadIC::ReceiverRegister()));
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG); PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(x0); context()->Plug(x0);
} else { } else {
VisitForStackValue(expr->obj()); VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key()); VisitForAccumulatorValue(expr->key());
__ Pop(x1); ASSERT(x0.is(KeyedLoadIC::NameRegister()));
__ Pop(KeyedLoadIC::ReceiverRegister());
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
context()->Plug(x0); context()->Plug(x0);
} }
@ -2304,7 +2304,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else { } else {
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ Peek(x0, 0); __ Peek(LoadIC::ReceiverRegister(), 0);
EmitNamedPropertyLoad(callee->AsProperty()); EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver. // Push the target function under the receiver.
@ -2321,12 +2321,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
Expression* key) { Expression* key) {
// Load the key. // Load the key.
VisitForAccumulatorValue(key); VisitForAccumulatorValue(key);
ASSERT(x0.is(KeyedLoadIC::NameRegister()));
Expression* callee = expr->expression(); Expression* callee = expr->expression();
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ Peek(x1, 0); __ Peek(KeyedLoadIC::ReceiverRegister(), 0);
EmitKeyedPropertyLoad(callee->AsProperty()); EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
@ -3746,12 +3747,13 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
// Push the builtins object as the receiver. // Push the builtins object as the receiver.
__ Ldr(x10, GlobalObjectMemOperand()); __ Ldr(x10, GlobalObjectMemOperand());
__ Ldr(x0, FieldMemOperand(x10, GlobalObject::kBuiltinsOffset)); __ Ldr(LoadIC::ReceiverRegister(),
__ Push(x0); FieldMemOperand(x10, GlobalObject::kBuiltinsOffset));
__ Push(LoadIC::ReceiverRegister());
// Load the function from the receiver. // Load the function from the receiver.
Handle<String> name = expr->name(); Handle<String> name = expr->name();
__ Mov(x2, Operand(name)); __ Mov(LoadIC::NameRegister(), Operand(name));
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
// Push the target function under the receiver. // Push the target function under the receiver.
@ -3927,14 +3929,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == NAMED_PROPERTY) { if (assign_type == NAMED_PROPERTY) {
// Put the object both on the stack and in the accumulator. // Put the object both on the stack and in the accumulator.
VisitForAccumulatorValue(prop->obj()); VisitForAccumulatorValue(prop->obj());
__ Push(x0); ASSERT(x0.is(LoadIC::ReceiverRegister()));
__ Push(LoadIC::ReceiverRegister());
EmitNamedPropertyLoad(prop); EmitNamedPropertyLoad(prop);
} else { } else {
// KEYED_PROPERTY // KEYED_PROPERTY
VisitForStackValue(prop->obj()); VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key()); VisitForAccumulatorValue(prop->key());
__ Peek(x1, 0); ASSERT(x0.is(KeyedLoadIC::NameRegister()));
__ Push(x0); __ Peek(KeyedLoadIC::ReceiverRegister(), 0);
__ Push(KeyedLoadIC::NameRegister());
EmitKeyedPropertyLoad(prop); EmitKeyedPropertyLoad(prop);
} }
} }
@ -4084,8 +4088,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
VariableProxy* proxy = expr->AsVariableProxy(); VariableProxy* proxy = expr->AsVariableProxy();
if (proxy != NULL && proxy->var()->IsUnallocated()) { if (proxy != NULL && proxy->var()->IsUnallocated()) {
Comment cmnt(masm_, "Global variable"); Comment cmnt(masm_, "Global variable");
__ Ldr(x0, GlobalObjectMemOperand()); __ Ldr(LoadIC::ReceiverRegister(), GlobalObjectMemOperand());
__ Mov(x2, Operand(proxy->name())); __ Mov(LoadIC::NameRegister(), Operand(proxy->name()));
// Use a regular load, not a contextual load, to avoid a reference // Use a regular load, not a contextual load, to avoid a reference
// error. // error.
CallLoadIC(NOT_CONTEXTUAL); CallLoadIC(NOT_CONTEXTUAL);
@ -4433,14 +4437,19 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// receiver = iter; f = 'next'; arg = received; // receiver = iter; f = 'next'; arg = received;
__ Bind(&l_next); __ Bind(&l_next);
Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
Register keyedload_name = KeyedLoadIC::NameRegister();
ASSERT(keyedload_receiver.is(x1));
ASSERT(keyedload_name.is(x0));
__ LoadRoot(x2, Heap::knext_stringRootIndex); // "next" __ LoadRoot(x2, Heap::knext_stringRootIndex); // "next"
__ Peek(x3, 1 * kPointerSize); // iter __ Peek(x3, 1 * kPointerSize); // iter
__ Push(x2, x3, x0); // "next", iter, received __ Push(x2, x3, x0); // "next", iter, received
// result = receiver[f](arg); // result = receiver[f](arg);
__ Bind(&l_call); __ Bind(&l_call);
__ Peek(x1, 1 * kPointerSize); __ Peek(keyedload_receiver, 1 * kPointerSize);
__ Peek(x0, 2 * kPointerSize); __ Peek(keyedload_name, 2 * kPointerSize);
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None()); CallIC(ic, TypeFeedbackId::None());
__ Mov(x1, x0); __ Mov(x1, x0);
@ -4453,19 +4462,23 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// if (!result.done) goto l_try; // if (!result.done) goto l_try;
__ Bind(&l_loop); __ Bind(&l_loop);
__ Push(x0); // save result Register load_receiver = LoadIC::ReceiverRegister();
__ LoadRoot(x2, Heap::kdone_stringRootIndex); // "done" Register load_name = LoadIC::NameRegister();
CallLoadIC(NOT_CONTEXTUAL); // result.done in x0 ASSERT(load_receiver.is(x0));
ASSERT(load_name.is(x2));
__ Push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
CallLoadIC(NOT_CONTEXTUAL); // x0=result.done
// The ToBooleanStub argument (result.done) is in x0. // The ToBooleanStub argument (result.done) is in x0.
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic); CallIC(bool_ic);
__ Cbz(x0, &l_try); __ Cbz(x0, &l_try);
// result.value // result.value
__ Pop(x0); // result __ Pop(load_receiver); // result
__ LoadRoot(x2, Heap::kvalue_stringRootIndex); // "value" __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
CallLoadIC(NOT_CONTEXTUAL); // result.value in x0 CallLoadIC(NOT_CONTEXTUAL); // x0=result.value
context()->DropAndPlug(2, x0); // drop iter and g context()->DropAndPlug(2, x0); // drop iter and g
break; break;
} }
} }

View File

@ -412,6 +412,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// -- lr : return address // -- lr : return address
// -- x0 : receiver // -- x0 : receiver
// ----------------------------------- // -----------------------------------
ASSERT(x0.is(ReceiverRegister()));
ASSERT(x2.is(NameRegister()));
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
@ -429,6 +431,8 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// -- lr : return address // -- lr : return address
// -- x0 : receiver // -- x0 : receiver
// ----------------------------------- // -----------------------------------
ASSERT(x0.is(ReceiverRegister()));
ASSERT(x2.is(NameRegister()));
Label miss, slow; Label miss, slow;
GenerateNameDictionaryReceiverCheck(masm, x0, x1, x3, x4, &miss); GenerateNameDictionaryReceiverCheck(masm, x0, x1, x3, x4, &miss);
@ -448,18 +452,14 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e ------------- // The return address is on the stack.
// -- x2 : name
// -- lr : return address
// -- x0 : receiver
// -----------------------------------
Isolate* isolate = masm->isolate(); Isolate* isolate = masm->isolate();
ASM_LOCATION("LoadIC::GenerateMiss"); ASM_LOCATION("LoadIC::GenerateMiss");
__ IncrementCounter(isolate->counters()->load_miss(), 1, x3, x4); __ IncrementCounter(isolate->counters()->load_miss(), 1, x3, x4);
// Perform tail call to the entry. // Perform tail call to the entry.
__ Push(x0, x2); __ Push(ReceiverRegister(), NameRegister());
ExternalReference ref = ExternalReference ref =
ExternalReference(IC_Utility(kLoadIC_Miss), isolate); ExternalReference(IC_Utility(kLoadIC_Miss), isolate);
__ TailCallExternalReference(ref, 2, 1); __ TailCallExternalReference(ref, 2, 1);
@ -467,13 +467,8 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e -------------- // The return address is on the stack.
// -- x2 : name __ Push(ReceiverRegister(), NameRegister());
// -- lr : return address
// -- x0 : receiver
// -----------------------------------
__ Push(x0, x2);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1); __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
} }
@ -485,8 +480,11 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
// -- x1 : receiver // -- x1 : receiver
// ----------------------------------- // -----------------------------------
Register result = x0; Register result = x0;
Register key = x0; Register receiver = ReceiverRegister();
Register receiver = x1; Register key = NameRegister();
ASSERT(receiver.is(x1));
ASSERT(key.is(x0));
Label miss, unmapped; Label miss, unmapped;
Register map_scratch = x2; Register map_scratch = x2;
@ -518,7 +516,6 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
// -- x1 : key // -- x1 : key
// -- x2 : receiver // -- x2 : receiver
// ----------------------------------- // -----------------------------------
Label slow, notin; Label slow, notin;
Register value = x0; Register value = x0;
@ -563,16 +560,12 @@ void KeyedStoreIC::GenerateSloppyArguments(MacroAssembler* masm) {
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// ---------- S t a t e -------------- // The return address is on the stack.
// -- lr : return address
// -- x0 : key
// -- x1 : receiver
// -----------------------------------
Isolate* isolate = masm->isolate(); Isolate* isolate = masm->isolate();
__ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11); __ IncrementCounter(isolate->counters()->keyed_load_miss(), 1, x10, x11);
__ Push(x1, x0); __ Push(ReceiverRegister(), NameRegister());
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -590,15 +583,8 @@ const Register KeyedLoadIC::NameRegister() { return x0; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e -------------- // The return address is on the stack.
// -- lr : return address __ Push(ReceiverRegister(), NameRegister());
// -- x0 : key
// -- x1 : receiver
// -----------------------------------
Register key = x0;
Register receiver = x1;
__ Push(receiver, key);
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);
} }
@ -774,8 +760,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
Label slow, check_name, index_smi, index_name; Label slow, check_name, index_smi, index_name;
Register key = x0; Register key = NameRegister();
Register receiver = x1; Register receiver = ReceiverRegister();
ASSERT(key.is(x0));
ASSERT(receiver.is(x1));
__ JumpIfNotSmi(key, &check_name); __ JumpIfNotSmi(key, &check_name);
__ Bind(&index_smi); __ Bind(&index_smi);
@ -802,17 +790,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// ---------- S t a t e -------------- // Return address is on the stack.
// -- lr : return address
// -- x0 : key (index)
// -- x1 : receiver
// -----------------------------------
Label miss; Label miss;
Register index = x0; Register receiver = ReceiverRegister();
Register receiver = x1; Register index = NameRegister();
Register result = x0; Register result = x0;
Register scratch = x3; Register scratch = x3;
ASSERT(!scratch.is(receiver) && !scratch.is(index));
StringCharAtGenerator char_at_generator(receiver, StringCharAtGenerator char_at_generator(receiver,
index, index,
@ -834,14 +819,15 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// ---------- S t a t e -------------- // Return address is on the stack.
// -- lr : return address
// -- x0 : key
// -- x1 : receiver
// -----------------------------------
Label slow; Label slow;
Register key = x0;
Register receiver = x1; Register receiver = ReceiverRegister();
Register key = NameRegister();
Register scratch1 = x2;
Register scratch2 = x3;
ASSERT(!scratch1.is(receiver) && !scratch1.is(key));
ASSERT(!scratch2.is(receiver) && !scratch2.is(key));
// Check that the receiver isn't a smi. // Check that the receiver isn't a smi.
__ JumpIfSmi(receiver, &slow); __ JumpIfSmi(receiver, &slow);
@ -850,16 +836,16 @@ void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
__ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow); __ TestAndBranchIfAnySet(key, kSmiTagMask | kSmiSignMask, &slow);
// Get the map of the receiver. // Get the map of the receiver.
Register map = x2; Register map = scratch1;
__ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset)); __ Ldr(map, FieldMemOperand(receiver, HeapObject::kMapOffset));
// Check that it has indexed interceptor and access checks // Check that it has indexed interceptor and access checks
// are not enabled for this object. // are not enabled for this object.
__ Ldrb(x3, FieldMemOperand(map, Map::kBitFieldOffset)); __ Ldrb(scratch2, FieldMemOperand(map, Map::kBitFieldOffset));
ASSERT(kSlowCaseBitFieldMask == ASSERT(kSlowCaseBitFieldMask ==
((1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor))); ((1 << Map::kIsAccessCheckNeeded) | (1 << Map::kHasIndexedInterceptor)));
__ Tbnz(x3, Map::kIsAccessCheckNeeded, &slow); __ Tbnz(scratch2, Map::kIsAccessCheckNeeded, &slow);
__ Tbz(x3, Map::kHasIndexedInterceptor, &slow); __ Tbz(scratch2, Map::kHasIndexedInterceptor, &slow);
// Everything is fine, call runtime. // Everything is fine, call runtime.
__ Push(receiver, key); __ Push(receiver, key);

View File

@ -1658,7 +1658,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp); LOperand* context = UseFixed(instr->context(), cp);
LOperand* global_object = UseFixed(instr->global_object(), x0); LOperand* global_object = UseFixed(instr->global_object(),
LoadIC::ReceiverRegister());
LLoadGlobalGeneric* result = LLoadGlobalGeneric* result =
new(zone()) LLoadGlobalGeneric(context, global_object); new(zone()) LLoadGlobalGeneric(context, global_object);
return MarkAsCall(DefineFixed(result, x0), instr); return MarkAsCall(DefineFixed(result, x0), instr);
@ -1714,8 +1715,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp); LOperand* context = UseFixed(instr->context(), cp);
LOperand* object = UseFixed(instr->object(), x1); LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister());
LOperand* key = UseFixed(instr->key(), x0); LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister());
LInstruction* result = LInstruction* result =
DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), x0); DefineFixed(new(zone()) LLoadKeyedGeneric(context, object, key), x0);
@ -1731,7 +1732,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), cp); LOperand* context = UseFixed(instr->context(), cp);
LOperand* object = UseFixed(instr->object(), x0); LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
LInstruction* result = LInstruction* result =
DefineFixed(new(zone()) LLoadNamedGeneric(context, object), x0); DefineFixed(new(zone()) LLoadNamedGeneric(context, object), x0);
return MarkAsCall(result, instr); return MarkAsCall(result, instr);

View File

@ -3399,9 +3399,9 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp)); ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->global_object()).Is(x0)); ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->result()).Is(x0)); ASSERT(ToRegister(instr->result()).Is(x0));
__ Mov(x2, Operand(instr->name())); __ Mov(LoadIC::NameRegister(), Operand(instr->name()));
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
@ -3653,8 +3653,8 @@ void LCodeGen::DoLoadKeyedFixed(LLoadKeyedFixed* instr) {
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp)); ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->object()).Is(x1)); ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->key()).Is(x0)); ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister()));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
@ -3704,9 +3704,10 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(cp)); ASSERT(ToRegister(instr->context()).is(cp));
// LoadIC expects x2 to hold the name, and x0 to hold the receiver. // LoadIC expects name and receiver in registers.
ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->object()).is(x0)); ASSERT(ToRegister(instr->object()).is(x0));
__ Mov(x2, Operand(instr->name())); __ Mov(LoadIC::NameRegister(), Operand(instr->name()));
Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);

View File

@ -1454,6 +1454,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
// -- x0 : key // -- x0 : key
// -- x1 : receiver // -- x1 : receiver
// ----------------------------------- // -----------------------------------
ASSERT(x1.is(KeyedLoadIC::ReceiverRegister()));
ASSERT(x0.is(KeyedLoadIC::NameRegister()));
Label slow, miss; Label slow, miss;
Register result = x0; Register result = x0;

View File

@ -614,6 +614,36 @@ void KeyedLoadGenericElementStub::InitializeInterfaceDescriptor(
} }
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { LoadIC::ReceiverRegister() };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { KeyedLoadIC::ReceiverRegister() };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { LoadIC::ReceiverRegister(),
LoadIC::NameRegister() };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { KeyedLoadIC::ReceiverRegister(),
KeyedLoadIC::NameRegister() };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadDictionaryElementPlatformStub::Generate( void KeyedLoadDictionaryElementPlatformStub::Generate(
MacroAssembler* masm) { MacroAssembler* masm) {
KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);

View File

@ -93,34 +93,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
} }
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( void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { edx, ecx, eax }; Register registers[] = { edx, ecx, eax };

View File

@ -180,11 +180,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-ia32.cc). // Register state for IC load call (from ic-ia32.cc).
// ----------- S t a t e ------------- Register receiver = LoadIC::ReceiverRegister();
// -- ecx : name Register name = LoadIC::NameRegister();
// -- edx : receiver Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
// -----------------------------------
Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false);
} }
@ -202,11 +200,9 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC load call (from ic-ia32.cc). // Register state for keyed IC load call (from ic-ia32.cc).
// ----------- S t a t e ------------- Register receiver = KeyedLoadIC::ReceiverRegister();
// -- ecx : key Register name = KeyedLoadIC::NameRegister();
// -- edx : receiver Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
// -----------------------------------
Generate_DebugBreakCallHelper(masm, ecx.bit() | edx.bit(), 0, false);
} }

View File

@ -1337,8 +1337,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
// All extension objects were empty and it is safe to use a global // All extension objects were empty and it is safe to use a global
// load IC call. // load IC call.
__ mov(edx, GlobalObjectOperand()); __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand());
__ mov(ecx, var->name()); __ mov(LoadIC::NameRegister(), var->name());
ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL ? NOT_CONTEXTUAL
: CONTEXTUAL; : CONTEXTUAL;
@ -1418,10 +1418,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
switch (var->location()) { switch (var->location()) {
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable"); Comment cmnt(masm_, "[ Global variable");
// Use inline caching. Variable name is passed in ecx and the global __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand());
// object in eax. __ mov(LoadIC::NameRegister(), var->name());
__ mov(edx, GlobalObjectOperand());
__ mov(ecx, var->name());
CallLoadIC(CONTEXTUAL); CallLoadIC(CONTEXTUAL);
context()->Plug(eax); context()->Plug(eax);
break; break;
@ -2011,14 +2009,20 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// receiver = iter; f = iter.next; arg = received; // receiver = iter; f = iter.next; arg = received;
__ bind(&l_next); __ bind(&l_next);
__ mov(ecx, isolate()->factory()->next_string()); // "next" Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
__ push(ecx); 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(Operand(esp, 2 * kPointerSize)); // iter
__ push(eax); // received __ push(eax); // received
// result = receiver[f](arg); // result = receiver[f](arg);
__ bind(&l_call); __ bind(&l_call);
__ mov(edx, Operand(esp, kPointerSize)); __ mov(keyedload_receiver, Operand(esp, kPointerSize));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None()); CallIC(ic, TypeFeedbackId::None());
__ mov(edi, eax); __ mov(edi, eax);
@ -2032,8 +2036,13 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// if (!result.done) goto l_try; // if (!result.done) goto l_try;
__ bind(&l_loop); __ bind(&l_loop);
__ push(eax); // save result __ push(eax); // save result
__ mov(edx, eax); // result Register load_receiver = LoadIC::ReceiverRegister();
__ mov(ecx, isolate()->factory()->done_string()); // "done" 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 CallLoadIC(NOT_CONTEXTUAL); // result.done in eax
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic); CallIC(bool_ic);
@ -2041,8 +2050,9 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
__ j(zero, &l_try); __ j(zero, &l_try);
// result.value // result.value
__ pop(edx); // result __ pop(load_receiver); // result
__ mov(ecx, isolate()->factory()->value_string()); // "value" __ mov(load_name,
isolate()->factory()->value_string()); // "value"
CallLoadIC(NOT_CONTEXTUAL); // result.value in eax CallLoadIC(NOT_CONTEXTUAL); // result.value in eax
context()->DropAndPlug(2, eax); // drop iter and g context()->DropAndPlug(2, eax); // drop iter and g
break; break;
@ -2202,7 +2212,7 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral(); Literal* key = prop->key()->AsLiteral();
ASSERT(!key->value()->IsSmi()); ASSERT(!key->value()->IsSmi());
__ mov(ecx, Immediate(key->value())); __ mov(LoadIC::NameRegister(), Immediate(key->value()));
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
} }
@ -2500,15 +2510,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj()); VisitForAccumulatorValue(expr->obj());
__ mov(edx, result_register()); __ mov(LoadIC::ReceiverRegister(), result_register());
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG); PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(eax); context()->Plug(eax);
} else { } else {
VisitForStackValue(expr->obj()); VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key()); VisitForAccumulatorValue(expr->key());
__ pop(edx); // Object. __ pop(KeyedLoadIC::ReceiverRegister()); // Object.
__ mov(ecx, result_register()); // Key. __ mov(KeyedLoadIC::NameRegister(), result_register()); // Key.
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
context()->Plug(eax); context()->Plug(eax);
} }
@ -2541,7 +2551,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else { } else {
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ mov(edx, Operand(esp, 0)); __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
EmitNamedPropertyLoad(callee->AsProperty()); EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver. // Push the target function under the receiver.
@ -2563,9 +2573,9 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); 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. // Move the key into the right register for the keyed load IC.
__ mov(ecx, eax); __ mov(KeyedLoadIC::NameRegister(), eax);
EmitKeyedPropertyLoad(callee->AsProperty()); EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
@ -4023,8 +4033,8 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset)); __ push(FieldOperand(eax, GlobalObject::kBuiltinsOffset));
// Load the function from the receiver. // Load the function from the receiver.
__ mov(edx, Operand(esp, 0)); __ mov(LoadIC::ReceiverRegister(), Operand(esp, 0));
__ mov(ecx, Immediate(expr->name())); __ mov(LoadIC::NameRegister(), Immediate(expr->name()));
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
// Push the target function under the receiver. // Push the target function under the receiver.
@ -4207,14 +4217,16 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
if (assign_type == NAMED_PROPERTY) { if (assign_type == NAMED_PROPERTY) {
// Put the object both on the stack and in edx. // Put the object both on the stack and in edx.
VisitForAccumulatorValue(prop->obj()); VisitForAccumulatorValue(prop->obj());
ASSERT(!eax.is(LoadIC::ReceiverRegister()));
__ push(eax); __ push(eax);
__ mov(edx, eax); __ mov(LoadIC::ReceiverRegister(), eax);
EmitNamedPropertyLoad(prop); EmitNamedPropertyLoad(prop);
} else { } else {
VisitForStackValue(prop->obj()); VisitForStackValue(prop->obj());
VisitForStackValue(prop->key()); VisitForStackValue(prop->key());
__ mov(edx, Operand(esp, kPointerSize)); // Object. __ mov(KeyedLoadIC::ReceiverRegister(),
__ mov(ecx, Operand(esp, 0)); // Key. Operand(esp, kPointerSize)); // Object.
__ mov(KeyedLoadIC::NameRegister(), Operand(esp, 0)); // Key.
EmitKeyedPropertyLoad(prop); EmitKeyedPropertyLoad(prop);
} }
} }
@ -4371,8 +4383,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
if (proxy != NULL && proxy->var()->IsUnallocated()) { if (proxy != NULL && proxy->var()->IsUnallocated()) {
Comment cmnt(masm_, "[ Global variable"); Comment cmnt(masm_, "[ Global variable");
__ mov(edx, GlobalObjectOperand()); __ mov(LoadIC::ReceiverRegister(), GlobalObjectOperand());
__ mov(ecx, Immediate(proxy->name())); __ mov(LoadIC::NameRegister(), Immediate(proxy->name()));
// Use a regular load, not a contextual load, to avoid a reference // Use a regular load, not a contextual load, to avoid a reference
// error. // error.
CallLoadIC(NOT_CONTEXTUAL); CallLoadIC(NOT_CONTEXTUAL);

View File

@ -388,6 +388,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// -- edx : receiver // -- edx : receiver
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(edx.is(ReceiverRegister()));
ASSERT(ecx.is(NameRegister()));
Label slow, check_name, index_smi, index_name, property_array_property; Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary; Label probe_dictionary, check_number_dictionary;
@ -560,18 +562,25 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
} }
// 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) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- ecx : key (index)
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label miss; Label miss;
Register receiver = edx; Register receiver = ReceiverRegister();
Register index = ecx; Register index = NameRegister();
Register scratch = ebx; Register scratch = KeyedLoadIC_TempRegister();
Register result = eax; Register result = eax;
ASSERT(!result.is(scratch));
StringCharAtGenerator char_at_generator(receiver, StringCharAtGenerator char_at_generator(receiver,
index, index,
@ -593,35 +602,36 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- ecx : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
Label slow; 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. // 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. // 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); __ j(not_zero, &slow);
// Get the map of the receiver. // 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 // Check that it has indexed interceptor and access checks
// are not enabled for this object. // are not enabled for this object.
__ movzx_b(eax, FieldOperand(eax, Map::kBitFieldOffset)); __ movzx_b(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
__ and_(eax, Immediate(kSlowCaseBitFieldMask)); __ and_(scratch, Immediate(kSlowCaseBitFieldMask));
__ cmp(eax, Immediate(1 << Map::kHasIndexedInterceptor)); __ cmp(scratch, Immediate(1 << Map::kHasIndexedInterceptor));
__ j(not_zero, &slow); __ j(not_zero, &slow);
// Everything is fine, call runtime. // Everything is fine, call runtime.
__ pop(eax); __ pop(scratch);
__ push(edx); // receiver __ push(receiver); // receiver
__ push(ecx); // key __ push(key); // key
__ push(eax); // return address __ push(scratch); // return address
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -640,6 +650,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
// -- edx : receiver // -- edx : receiver
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(edx.is(ReceiverRegister()));
ASSERT(ecx.is(NameRegister()));
Label slow, notin; Label slow, notin;
Factory* factory = masm->isolate()->factory(); Factory* factory = masm->isolate()->factory();
Operand mapped_location = Operand mapped_location =
@ -930,6 +942,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// -- edx : receiver // -- edx : receiver
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(edx.is(ReceiverRegister()));
ASSERT(ecx.is(NameRegister()));
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
@ -947,6 +961,9 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// -- edx : receiver // -- edx : receiver
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(edx.is(ReceiverRegister()));
ASSERT(ecx.is(NameRegister()));
Label miss, slow; Label miss, slow;
GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss); GenerateNameDictionaryReceiverCheck(masm, edx, eax, ebx, &miss);
@ -967,18 +984,13 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- ecx : name
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
__ IncrementCounter(masm->isolate()->counters()->load_miss(), 1); __ IncrementCounter(masm->isolate()->counters()->load_miss(), 1);
__ pop(ebx); __ pop(LoadIC_TempRegister());
__ push(edx); // receiver __ push(ReceiverRegister()); // receiver
__ push(ecx); // name __ push(NameRegister()); // name
__ push(ebx); // return address __ push(LoadIC_TempRegister()); // return address
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -988,16 +1000,11 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- ecx : key __ pop(LoadIC_TempRegister());
// -- edx : receiver __ push(ReceiverRegister()); // receiver
// -- esp[0] : return address __ push(NameRegister()); // name
// ----------------------------------- __ push(LoadIC_TempRegister()); // return address
__ pop(ebx);
__ push(edx); // receiver
__ push(ecx); // name
__ push(ebx); // return address
// Perform tail call to the entry. // Perform tail call to the entry.
__ TailCallRuntime(Runtime::kGetProperty, 2, 1); __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
@ -1005,18 +1012,13 @@ void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- ecx : key
// -- edx : receiver
// -- esp[0] : return address
// -----------------------------------
__ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1); __ IncrementCounter(masm->isolate()->counters()->keyed_load_miss(), 1);
__ pop(ebx); __ pop(KeyedLoadIC_TempRegister());
__ push(edx); // receiver __ push(ReceiverRegister()); // receiver
__ push(ecx); // name __ push(NameRegister()); // name
__ push(ebx); // return address __ push(KeyedLoadIC_TempRegister()); // return address
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -1039,16 +1041,11 @@ const Register KeyedLoadIC::NameRegister() { return LoadIC::NameRegister(); }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- ecx : key __ pop(KeyedLoadIC_TempRegister());
// -- edx : receiver __ push(ReceiverRegister()); // receiver
// -- esp[0] : return address __ push(NameRegister()); // name
// ----------------------------------- __ push(KeyedLoadIC_TempRegister()); // return address
__ pop(ebx);
__ push(edx); // receiver
__ push(ecx); // name
__ push(ebx); // return address
// Perform tail call to the entry. // Perform tail call to the entry.
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);

View File

@ -2832,10 +2832,10 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi)); 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)); ASSERT(ToRegister(instr->result()).is(eax));
__ mov(ecx, instr->name()); __ mov(LoadIC::NameRegister(), instr->name());
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
@ -2966,10 +2966,10 @@ void LCodeGen::EmitPushTaggedOperand(LOperand* operand) {
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi)); 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)); ASSERT(ToRegister(instr->result()).is(eax));
__ mov(ecx, instr->name()); __ mov(LoadIC::NameRegister(), instr->name());
Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
} }
@ -3207,8 +3207,8 @@ Operand LCodeGen::BuildFastArrayOperand(
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(esi)); ASSERT(ToRegister(instr->context()).is(esi));
ASSERT(ToRegister(instr->object()).is(edx)); ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->key()).is(ecx)); ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister()));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);

View File

@ -2090,7 +2090,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi); 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 = LLoadGlobalGeneric* result =
new(zone()) LLoadGlobalGeneric(context, global_object); new(zone()) LLoadGlobalGeneric(context, global_object);
return MarkAsCall(DefineFixed(result, eax), instr); return MarkAsCall(DefineFixed(result, eax), instr);
@ -2145,7 +2146,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi); 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); LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object);
return MarkAsCall(DefineFixed(result, eax), instr); return MarkAsCall(DefineFixed(result, eax), instr);
} }
@ -2203,8 +2204,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), esi); LOperand* context = UseFixed(instr->context(), esi);
LOperand* object = UseFixed(instr->object(), edx); LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister());
LOperand* key = UseFixed(instr->key(), ecx); LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister());
LLoadKeyedGeneric* result = LLoadKeyedGeneric* result =
new(zone()) LLoadKeyedGeneric(context, object, key); new(zone()) LLoadKeyedGeneric(context, object, key);

View File

@ -1454,6 +1454,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
// -- edx : receiver // -- edx : receiver
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(edx.is(KeyedLoadIC::ReceiverRegister()));
ASSERT(ecx.is(KeyedLoadIC::NameRegister()));
Label slow, miss; Label slow, miss;
// This stub is meant to be tail-jumped to, the receiver must already // This stub is meant to be tail-jumped to, the receiver must already

View File

@ -89,34 +89,6 @@ void RegExpConstructResultStub::InitializeInterfaceDescriptor(
} }
void LoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedLoadFieldStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rdx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void StringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rax, rcx };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStringLengthStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rdx, rax };
descriptor->Initialize(ARRAY_SIZE(registers), registers);
}
void KeyedStoreFastElementStub::InitializeInterfaceDescriptor( void KeyedStoreFastElementStub::InitializeInterfaceDescriptor(
CodeStubInterfaceDescriptor* descriptor) { CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rdx, rcx, rax }; Register registers[] = { rdx, rcx, rax };

View File

@ -162,11 +162,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Register state for IC load call (from ic-x64.cc). // Register state for IC load call (from ic-x64.cc).
// ----------- S t a t e ------------- Register receiver = LoadIC::ReceiverRegister();
// -- rax : receiver Register name = LoadIC::NameRegister();
// -- rcx : name Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
// -----------------------------------
Generate_DebugBreakCallHelper(masm, rax.bit() | rcx.bit(), 0, false);
} }
@ -184,11 +182,9 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC load call (from ic-x64.cc). // Register state for keyed IC load call (from ic-x64.cc).
// ----------- S t a t e ------------- Register receiver = KeyedLoadIC::ReceiverRegister();
// -- rax : key Register name = KeyedLoadIC::NameRegister();
// -- rdx : receiver Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0, false);
// -----------------------------------
Generate_DebugBreakCallHelper(masm, rax.bit() | rdx.bit(), 0, false);
} }

View File

@ -1372,8 +1372,8 @@ void FullCodeGenerator::EmitLoadGlobalCheckExtensions(Variable* var,
// All extension objects were empty and it is safe to use a global // All extension objects were empty and it is safe to use a global
// load IC call. // load IC call.
__ movp(rax, GlobalObjectOperand()); __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand());
__ Move(rcx, var->name()); __ Move(LoadIC::NameRegister(), var->name());
ContextualMode mode = (typeof_state == INSIDE_TYPEOF) ContextualMode mode = (typeof_state == INSIDE_TYPEOF)
? NOT_CONTEXTUAL ? NOT_CONTEXTUAL
: CONTEXTUAL; : CONTEXTUAL;
@ -1452,10 +1452,8 @@ void FullCodeGenerator::EmitVariableLoad(VariableProxy* proxy) {
switch (var->location()) { switch (var->location()) {
case Variable::UNALLOCATED: { case Variable::UNALLOCATED: {
Comment cmnt(masm_, "[ Global variable"); Comment cmnt(masm_, "[ Global variable");
// Use inline caching. Variable name is passed in rcx and the global __ Move(LoadIC::NameRegister(), var->name());
// object on the stack. __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand());
__ Move(rcx, var->name());
__ movp(rax, GlobalObjectOperand());
CallLoadIC(CONTEXTUAL); CallLoadIC(CONTEXTUAL);
context()->Plug(rax); context()->Plug(rax);
break; break;
@ -2044,6 +2042,11 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// receiver = iter; f = 'next'; arg = received; // receiver = iter; f = 'next'; arg = received;
__ bind(&l_next); __ bind(&l_next);
Register keyedload_receiver = KeyedLoadIC::ReceiverRegister();
Register keyedload_name = KeyedLoadIC::NameRegister();
ASSERT(keyedload_receiver.is(rdx));
ASSERT(keyedload_name.is(rax));
__ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next" __ LoadRoot(rcx, Heap::knext_stringRootIndex); // "next"
__ Push(rcx); __ Push(rcx);
__ Push(Operand(rsp, 2 * kPointerSize)); // iter __ Push(Operand(rsp, 2 * kPointerSize)); // iter
@ -2051,8 +2054,8 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// result = receiver[f](arg); // result = receiver[f](arg);
__ bind(&l_call); __ bind(&l_call);
__ movp(rdx, Operand(rsp, kPointerSize)); __ movp(keyedload_receiver, Operand(rsp, kPointerSize));
__ movp(rax, Operand(rsp, 2 * kPointerSize)); __ movp(keyedload_name, Operand(rsp, 2 * kPointerSize));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallIC(ic, TypeFeedbackId::None()); CallIC(ic, TypeFeedbackId::None());
__ movp(rdi, rax); __ movp(rdi, rax);
@ -2065,17 +2068,22 @@ void FullCodeGenerator::VisitYield(Yield* expr) {
// if (!result.done) goto l_try; // if (!result.done) goto l_try;
__ bind(&l_loop); __ bind(&l_loop);
__ Push(rax); // save result Register load_receiver = LoadIC::ReceiverRegister();
__ LoadRoot(rcx, Heap::kdone_stringRootIndex); // "done" Register load_name = LoadIC::NameRegister();
CallLoadIC(NOT_CONTEXTUAL); // result.done in rax ASSERT(load_receiver.is(rax));
ASSERT(load_name.is(rcx));
__ Push(load_receiver); // save result
__ LoadRoot(load_name, Heap::kdone_stringRootIndex); // "done"
CallLoadIC(NOT_CONTEXTUAL); // rax=result.done
Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate()); Handle<Code> bool_ic = ToBooleanStub::GetUninitialized(isolate());
CallIC(bool_ic); CallIC(bool_ic);
__ testp(result_register(), result_register()); __ testp(result_register(), result_register());
__ j(zero, &l_try); __ j(zero, &l_try);
// result.value // result.value
__ Pop(rax); // result __ Pop(load_receiver); // result
__ LoadRoot(rcx, Heap::kvalue_stringRootIndex); // "value" __ LoadRoot(load_name, Heap::kvalue_stringRootIndex); // "value"
CallLoadIC(NOT_CONTEXTUAL); // result.value in rax CallLoadIC(NOT_CONTEXTUAL); // result.value in rax
context()->DropAndPlug(2, rax); // drop iter and g context()->DropAndPlug(2, rax); // drop iter and g
break; break;
@ -2236,7 +2244,7 @@ void FullCodeGenerator::EmitCreateIteratorResult(bool done) {
void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Literal* key = prop->key()->AsLiteral(); Literal* key = prop->key()->AsLiteral();
__ Move(rcx, key->value()); __ Move(LoadIC::NameRegister(), key->value());
CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, prop->PropertyFeedbackId());
} }
@ -2495,13 +2503,15 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
if (key->IsPropertyName()) { if (key->IsPropertyName()) {
VisitForAccumulatorValue(expr->obj()); VisitForAccumulatorValue(expr->obj());
ASSERT(rax.is(LoadIC::ReceiverRegister()));
EmitNamedPropertyLoad(expr); EmitNamedPropertyLoad(expr);
PrepareForBailoutForId(expr->LoadId(), TOS_REG); PrepareForBailoutForId(expr->LoadId(), TOS_REG);
context()->Plug(rax); context()->Plug(rax);
} else { } else {
VisitForStackValue(expr->obj()); VisitForStackValue(expr->obj());
VisitForAccumulatorValue(expr->key()); VisitForAccumulatorValue(expr->key());
__ Pop(rdx); ASSERT(rax.is(KeyedLoadIC::NameRegister()));
__ Pop(KeyedLoadIC::ReceiverRegister());
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
context()->Plug(rax); context()->Plug(rax);
} }
@ -2534,7 +2544,7 @@ void FullCodeGenerator::EmitCallWithLoadIC(Call* expr) {
} else { } else {
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ movp(rax, Operand(rsp, 0)); __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0));
EmitNamedPropertyLoad(callee->AsProperty()); EmitNamedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
// Push the target function under the receiver. // Push the target function under the receiver.
@ -2551,12 +2561,13 @@ void FullCodeGenerator::EmitKeyedCallWithLoadIC(Call* expr,
Expression* key) { Expression* key) {
// Load the key. // Load the key.
VisitForAccumulatorValue(key); VisitForAccumulatorValue(key);
ASSERT(rax.is(KeyedLoadIC::NameRegister()));
Expression* callee = expr->expression(); Expression* callee = expr->expression();
// Load the function from the receiver. // Load the function from the receiver.
ASSERT(callee->IsProperty()); ASSERT(callee->IsProperty());
__ movp(rdx, Operand(rsp, 0)); __ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0));
EmitKeyedPropertyLoad(callee->AsProperty()); EmitKeyedPropertyLoad(callee->AsProperty());
PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG); PrepareForBailoutForId(callee->AsProperty()->LoadId(), TOS_REG);
@ -4034,8 +4045,8 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset)); __ Push(FieldOperand(rax, GlobalObject::kBuiltinsOffset));
// Load the function from the receiver. // Load the function from the receiver.
__ movp(rax, Operand(rsp, 0)); __ movp(LoadIC::ReceiverRegister(), Operand(rsp, 0));
__ Move(rcx, expr->name()); __ Move(LoadIC::NameRegister(), expr->name());
CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId()); CallLoadIC(NOT_CONTEXTUAL, expr->CallRuntimeFeedbackId());
// Push the target function under the receiver. // Push the target function under the receiver.
@ -4214,13 +4225,17 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
} }
if (assign_type == NAMED_PROPERTY) { if (assign_type == NAMED_PROPERTY) {
VisitForAccumulatorValue(prop->obj()); VisitForAccumulatorValue(prop->obj());
ASSERT(rax.is(LoadIC::ReceiverRegister()));
__ Push(rax); // Copy of receiver, needed for later store. __ Push(rax); // Copy of receiver, needed for later store.
EmitNamedPropertyLoad(prop); EmitNamedPropertyLoad(prop);
} else { } else {
VisitForStackValue(prop->obj()); VisitForStackValue(prop->obj());
VisitForAccumulatorValue(prop->key()); VisitForAccumulatorValue(prop->key());
__ movp(rdx, Operand(rsp, 0)); // Leave receiver on stack ASSERT(rax.is(KeyedLoadIC::NameRegister()));
__ Push(rax); // Copy of key, needed for later store. // Leave receiver on stack
__ movp(KeyedLoadIC::ReceiverRegister(), Operand(rsp, 0));
// Copy of key, needed for later store.
__ Push(KeyedLoadIC::NameRegister());
EmitKeyedPropertyLoad(prop); EmitKeyedPropertyLoad(prop);
} }
} }
@ -4373,8 +4388,8 @@ void FullCodeGenerator::VisitForTypeofValue(Expression* expr) {
if (proxy != NULL && proxy->var()->IsUnallocated()) { if (proxy != NULL && proxy->var()->IsUnallocated()) {
Comment cmnt(masm_, "[ Global variable"); Comment cmnt(masm_, "[ Global variable");
__ Move(rcx, proxy->name()); __ Move(LoadIC::NameRegister(), proxy->name());
__ movp(rax, GlobalObjectOperand()); __ movp(LoadIC::ReceiverRegister(), GlobalObjectOperand());
// Use a regular load, not a contextual load, to avoid a reference // Use a regular load, not a contextual load, to avoid a reference
// error. // error.
CallLoadIC(NOT_CONTEXTUAL); CallLoadIC(NOT_CONTEXTUAL);

View File

@ -332,6 +332,8 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// -- rdx : receiver // -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(rdx.is(ReceiverRegister()));
ASSERT(rax.is(NameRegister()));
Label slow, check_name, index_smi, index_name, property_array_property; Label slow, check_name, index_smi, index_name, property_array_property;
Label probe_dictionary, check_number_dictionary; Label probe_dictionary, check_number_dictionary;
@ -490,17 +492,14 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
Label miss; Label miss;
Register receiver = rdx; Register receiver = ReceiverRegister();
Register index = rax; Register index = NameRegister();
Register scratch = rcx; Register scratch = rcx;
Register result = rax; Register result = rax;
ASSERT(!scratch.is(receiver) && !scratch.is(index));
StringCharAtGenerator char_at_generator(receiver, StringCharAtGenerator char_at_generator(receiver,
index, index,
@ -522,35 +521,36 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// ----------- S t a t e ------------- // Return address is on the stack.
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
Label slow; Label slow;
Register receiver = ReceiverRegister();
Register key = NameRegister();
Register scratch = rcx;
ASSERT(!scratch.is(receiver) && !scratch.is(key));
// Check that the receiver isn't a smi. // Check that the receiver isn't a smi.
__ JumpIfSmi(rdx, &slow); __ JumpIfSmi(receiver, &slow);
// Check that the key is an array index, that is Uint32. // Check that the key is an array index, that is Uint32.
STATIC_ASSERT(kSmiValueSize <= 32); STATIC_ASSERT(kSmiValueSize <= 32);
__ JumpUnlessNonNegativeSmi(rax, &slow); __ JumpUnlessNonNegativeSmi(key, &slow);
// Get the map of the receiver. // Get the map of the receiver.
__ movp(rcx, FieldOperand(rdx, HeapObject::kMapOffset)); __ movp(scratch, FieldOperand(receiver, HeapObject::kMapOffset));
// Check that it has indexed interceptor and access checks // Check that it has indexed interceptor and access checks
// are not enabled for this object. // are not enabled for this object.
__ movb(rcx, FieldOperand(rcx, Map::kBitFieldOffset)); __ movb(scratch, FieldOperand(scratch, Map::kBitFieldOffset));
__ andb(rcx, Immediate(kSlowCaseBitFieldMask)); __ andb(scratch, Immediate(kSlowCaseBitFieldMask));
__ cmpb(rcx, Immediate(1 << Map::kHasIndexedInterceptor)); __ cmpb(scratch, Immediate(1 << Map::kHasIndexedInterceptor));
__ j(not_zero, &slow); __ j(not_zero, &slow);
// Everything is fine, call runtime. // Everything is fine, call runtime.
__ PopReturnAddressTo(rcx); __ PopReturnAddressTo(scratch);
__ Push(rdx); // receiver __ Push(receiver); // receiver
__ Push(rax); // key __ Push(key); // key
__ PushReturnAddressFrom(rcx); __ PushReturnAddressFrom(scratch);
// Perform tail call to the entry. // Perform tail call to the entry.
__ TailCallExternalReference( __ TailCallExternalReference(
@ -892,6 +892,8 @@ void KeyedLoadIC::GenerateSloppyArguments(MacroAssembler* masm) {
// -- rdx : receiver // -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(rdx.is(ReceiverRegister()));
ASSERT(rax.is(NameRegister()));
Label slow, notin; Label slow, notin;
Operand mapped_location = Operand mapped_location =
GenerateMappedArgumentsLookup( GenerateMappedArgumentsLookup(
@ -956,6 +958,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// -- rcx : name // -- rcx : name
// -- rsp[0] : return address // -- rsp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(rax.is(ReceiverRegister()));
ASSERT(rcx.is(NameRegister()));
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC); Code::Flags flags = Code::ComputeHandlerFlags(Code::LOAD_IC);
@ -972,6 +976,8 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
// -- rcx : name // -- rcx : name
// -- rsp[0] : return address // -- rsp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(rax.is(ReceiverRegister()));
ASSERT(rcx.is(NameRegister()));
Label miss, slow; Label miss, slow;
GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss); GenerateNameDictionaryReceiverCheck(masm, rax, rdx, rbx, &miss);
@ -991,20 +997,25 @@ void LoadIC::GenerateNormal(MacroAssembler* masm) {
} }
// A register that isn't one of the parameters to the load ic.
static const Register LoadIC_TempRegister() { return rbx; }
static const Register KeyedLoadIC_TempRegister() {
return rbx;
}
void LoadIC::GenerateMiss(MacroAssembler* masm) { void LoadIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e ------------- // The return address is on the stack.
// -- rax : receiver
// -- rcx : name
// -- rsp[0] : return address
// -----------------------------------
Counters* counters = masm->isolate()->counters(); Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->load_miss(), 1); __ IncrementCounter(counters->load_miss(), 1);
__ PopReturnAddressTo(rbx); __ PopReturnAddressTo(LoadIC_TempRegister());
__ Push(rax); // receiver __ Push(ReceiverRegister()); // receiver
__ Push(rcx); // name __ Push(NameRegister()); // name
__ PushReturnAddressFrom(rbx); __ PushReturnAddressFrom(LoadIC_TempRegister());
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -1014,16 +1025,12 @@ void LoadIC::GenerateMiss(MacroAssembler* masm) {
void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ----------- S t a t e ------------- // The return address is on the stack.
// -- rax : receiver
// -- rcx : name
// -- rsp[0] : return address
// -----------------------------------
__ PopReturnAddressTo(rbx); __ PopReturnAddressTo(LoadIC_TempRegister());
__ Push(rax); // receiver __ Push(ReceiverRegister()); // receiver
__ Push(rcx); // name __ Push(NameRegister()); // name
__ PushReturnAddressFrom(rbx); __ PushReturnAddressFrom(LoadIC_TempRegister());
// Perform tail call to the entry. // Perform tail call to the entry.
__ TailCallRuntime(Runtime::kGetProperty, 2, 1); __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
@ -1031,19 +1038,14 @@ void LoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// ----------- S t a t e ------------- // The return address is on the stack.
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
Counters* counters = masm->isolate()->counters(); Counters* counters = masm->isolate()->counters();
__ IncrementCounter(counters->keyed_load_miss(), 1); __ IncrementCounter(counters->keyed_load_miss(), 1);
__ PopReturnAddressTo(rbx); __ PopReturnAddressTo(KeyedLoadIC_TempRegister());
__ Push(rdx); // receiver __ Push(ReceiverRegister()); // receiver
__ Push(rax); // name __ Push(NameRegister()); // name
__ PushReturnAddressFrom(rbx); __ PushReturnAddressFrom(KeyedLoadIC_TempRegister());
// Perform tail call to the entry. // Perform tail call to the entry.
ExternalReference ref = ExternalReference ref =
@ -1060,16 +1062,12 @@ const Register KeyedLoadIC::NameRegister() { return rax; }
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ----------- S t a t e ------------- // The return address is on the stack.
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address
// -----------------------------------
__ PopReturnAddressTo(rbx); __ PopReturnAddressTo(KeyedLoadIC_TempRegister());
__ Push(rdx); // receiver __ Push(ReceiverRegister()); // receiver
__ Push(rax); // name __ Push(NameRegister()); // name
__ PushReturnAddressFrom(rbx); __ PushReturnAddressFrom(KeyedLoadIC_TempRegister());
// Perform tail call to the entry. // Perform tail call to the entry.
__ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1); __ TailCallRuntime(Runtime::kKeyedGetProperty, 2, 1);

View File

@ -2849,10 +2849,10 @@ void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) {
void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(rsi)); ASSERT(ToRegister(instr->context()).is(rsi));
ASSERT(ToRegister(instr->global_object()).is(rax)); ASSERT(ToRegister(instr->global_object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->result()).is(rax)); ASSERT(ToRegister(instr->result()).is(rax));
__ Move(rcx, instr->name()); __ Move(LoadIC::NameRegister(), instr->name());
ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL; ContextualMode mode = instr->for_typeof() ? NOT_CONTEXTUAL : CONTEXTUAL;
Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode); Handle<Code> ic = LoadIC::initialize_stub(isolate(), mode);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
@ -2989,10 +2989,10 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) { void LCodeGen::DoLoadNamedGeneric(LLoadNamedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(rsi)); ASSERT(ToRegister(instr->context()).is(rsi));
ASSERT(ToRegister(instr->object()).is(rax)); ASSERT(ToRegister(instr->object()).is(LoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->result()).is(rax)); ASSERT(ToRegister(instr->result()).is(rax));
__ Move(rcx, instr->name()); __ Move(LoadIC::NameRegister(), instr->name());
Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL); Handle<Code> ic = LoadIC::initialize_stub(isolate(), NOT_CONTEXTUAL);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
} }
@ -3286,8 +3286,8 @@ Operand LCodeGen::BuildFastArrayOperand(
void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) {
ASSERT(ToRegister(instr->context()).is(rsi)); ASSERT(ToRegister(instr->context()).is(rsi));
ASSERT(ToRegister(instr->object()).is(rdx)); ASSERT(ToRegister(instr->object()).is(KeyedLoadIC::ReceiverRegister()));
ASSERT(ToRegister(instr->key()).is(rax)); ASSERT(ToRegister(instr->key()).is(KeyedLoadIC::NameRegister()));
Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Initialize();
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);

View File

@ -2040,7 +2040,8 @@ LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) { LInstruction* LChunkBuilder::DoLoadGlobalGeneric(HLoadGlobalGeneric* instr) {
LOperand* context = UseFixed(instr->context(), rsi); LOperand* context = UseFixed(instr->context(), rsi);
LOperand* global_object = UseFixed(instr->global_object(), rax); LOperand* global_object = UseFixed(instr->global_object(),
LoadIC::ReceiverRegister());
LLoadGlobalGeneric* result = LLoadGlobalGeneric* result =
new(zone()) LLoadGlobalGeneric(context, global_object); new(zone()) LLoadGlobalGeneric(context, global_object);
return MarkAsCall(DefineFixed(result, rax), instr); return MarkAsCall(DefineFixed(result, rax), instr);
@ -2107,7 +2108,7 @@ LInstruction* LChunkBuilder::DoLoadNamedField(HLoadNamedField* instr) {
LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadNamedGeneric(HLoadNamedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), rsi); LOperand* context = UseFixed(instr->context(), rsi);
LOperand* object = UseFixed(instr->object(), rax); LOperand* object = UseFixed(instr->object(), LoadIC::ReceiverRegister());
LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object); LLoadNamedGeneric* result = new(zone()) LLoadNamedGeneric(context, object);
return MarkAsCall(DefineFixed(result, rax), instr); return MarkAsCall(DefineFixed(result, rax), instr);
} }
@ -2193,8 +2194,8 @@ LInstruction* LChunkBuilder::DoLoadKeyed(HLoadKeyed* instr) {
LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) { LInstruction* LChunkBuilder::DoLoadKeyedGeneric(HLoadKeyedGeneric* instr) {
LOperand* context = UseFixed(instr->context(), rsi); LOperand* context = UseFixed(instr->context(), rsi);
LOperand* object = UseFixed(instr->object(), rdx); LOperand* object = UseFixed(instr->object(), KeyedLoadIC::ReceiverRegister());
LOperand* key = UseFixed(instr->key(), rax); LOperand* key = UseFixed(instr->key(), KeyedLoadIC::NameRegister());
LLoadKeyedGeneric* result = LLoadKeyedGeneric* result =
new(zone()) LLoadKeyedGeneric(context, object, key); new(zone()) LLoadKeyedGeneric(context, object, key);

View File

@ -1398,6 +1398,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
// -- rdx : receiver // -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// ----------------------------------- // -----------------------------------
ASSERT(rdx.is(KeyedLoadIC::ReceiverRegister()));
ASSERT(rax.is(KeyedLoadIC::NameRegister()));
Label slow, miss; Label slow, miss;
// This stub is meant to be tail-jumped to, the receiver must already // This stub is meant to be tail-jumped to, the receiver must already