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(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { r2, r1, r0 };

View File

@ -176,15 +176,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
// ----------- S t a t e -------------
// -- r2 : name
// -- lr : return address
// -- 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);
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
}
@ -203,11 +197,10 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- lr : return address
// -- r0 : key
// -- r1 : receiver
Generate_DebugBreakCallHelper(masm, r0.bit() | r1.bit(), 0);
// Calling convention for keyed IC load (from ic-arm.cc).
Register receiver = KeyedLoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister();
Generate_DebugBreakCallHelper(masm, receiver.bit() | name.bit(), 0);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1479,6 +1479,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
// -- r0 : key
// -- r1 : receiver
// -----------------------------------
ASSERT(r1.is(KeyedLoadIC::ReceiverRegister()));
ASSERT(r0.is(KeyedLoadIC::NameRegister()));
Label slow, miss;
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(
CodeStubInterfaceDescriptor* descriptor) {
// x2: receiver

View File

@ -235,15 +235,9 @@ void DebugCodegen::GenerateCallICStubDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateLoadICDebugBreak(MacroAssembler* masm) {
// Calling convention for IC load (from ic-arm.cc).
// ----------- S t a t e -------------
// -- x2 : name
// -- lr : return address
// -- 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);
Register receiver = LoadIC::ReceiverRegister();
Register name = LoadIC::NameRegister();
Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10);
}
@ -262,11 +256,10 @@ void DebugCodegen::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void DebugCodegen::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// ---------- S t a t e --------------
// -- lr : return address
// -- x0 : key
// -- x1 : receiver
Generate_DebugBreakCallHelper(masm, x0.Bit() | x1.Bit(), 0, x10);
// Calling convention for keyed IC load (from ic-arm.cc).
Register receiver = KeyedLoadIC::ReceiverRegister();
Register name = KeyedLoadIC::NameRegister();
Generate_DebugBreakCallHelper(masm, receiver.Bit() | name.Bit(), 0, x10);
}

View File

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

View File

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

View File

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

View File

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

View File

@ -1454,6 +1454,8 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
// -- x0 : key
// -- x1 : receiver
// -----------------------------------
ASSERT(x1.is(KeyedLoadIC::ReceiverRegister()));
ASSERT(x0.is(KeyedLoadIC::NameRegister()));
Label slow, miss;
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(
MacroAssembler* 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(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { edx, ecx, eax };

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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(
CodeStubInterfaceDescriptor* descriptor) {
Register registers[] = { rdx, rcx, rax };

View File

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

View File

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

View File

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

View File

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

View File

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