Pass key in register for keyed load IC

The calling convention for keyed load IC is changed to have the key passed both in a register (r0) and on the stack.

Next steps will be first to remove the key from the stack and then pass the receiver in a register (r1).
Review URL: http://codereview.chromium.org/1937003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4584 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
sgjesse@chromium.org 2010-05-05 06:40:14 +00:00
parent 4501cea97b
commit a355e45e22
6 changed files with 65 additions and 52 deletions

View File

@ -5391,7 +5391,8 @@ void DeferredReferenceGetKeyedValue::Generate() {
// The rest of the instructions in the deferred code must be together. // The rest of the instructions in the deferred code must be together.
{ Assembler::BlockConstPoolScope block_const_pool(masm_); { Assembler::BlockConstPoolScope block_const_pool(masm_);
// Call keyed load IC. It has all arguments on the stack. // Call keyed load IC. It has all arguments on the stack and the key in r0.
__ ldr(r0, MemOperand(sp, 0));
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the // The call must be followed by a nop instruction to indicate that the
@ -5514,7 +5515,6 @@ void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
void CodeGenerator::EmitKeyedLoad() { void CodeGenerator::EmitKeyedLoad() {
if (loop_nesting() == 0) { if (loop_nesting() == 0) {
VirtualFrame::SpilledScope spilled(frame_);
Comment cmnt(masm_, "[ Load from keyed property"); Comment cmnt(masm_, "[ Load from keyed property");
frame_->CallKeyedLoadIC(); frame_->CallKeyedLoadIC();
} else { } else {

View File

@ -161,9 +161,10 @@ void Debug::GenerateStoreICDebugBreak(MacroAssembler* masm) {
void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
Generate_DebugBreakCallHelper(masm, 0); Generate_DebugBreakCallHelper(masm, r0.bit());
} }

View File

@ -728,7 +728,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
ASSERT_NOT_NULL(object_slot); ASSERT_NOT_NULL(object_slot);
// Load the object. // Load the object.
Move(r2, object_slot); Move(r1, object_slot);
// Assert that the key is a smi. // Assert that the key is a smi.
Literal* key_literal = property->key()->AsLiteral(); Literal* key_literal = property->key()->AsLiteral();
@ -736,12 +736,12 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
ASSERT(key_literal->handle()->IsSmi()); ASSERT(key_literal->handle()->IsSmi());
// Load the key. // Load the key.
__ mov(r1, Operand(key_literal->handle())); __ mov(r0, Operand(key_literal->handle()));
// Push both as arguments to ic. // Push both as arguments to ic.
__ Push(r2, r1); __ Push(r1, r0);
// Do a keyed property load. // Call keyed load IC. It has all arguments on the stack and the key in r0.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
@ -1005,6 +1005,8 @@ void FullCodeGenerator::EmitNamedPropertyLoad(Property* prop) {
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) {
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
// Call keyed load IC. It has all arguments on the stack and the key in r0.
__ ldr(r0, MemOperand(sp, 0));
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
} }
@ -1247,6 +1249,9 @@ void FullCodeGenerator::VisitCall(Call* expr) {
VisitForValue(prop->key(), kStack); VisitForValue(prop->key(), kStack);
// Record source code position for IC call. // Record source code position for IC call.
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
// Call keyed load IC. It has all arguments on the stack and the key in
// r0.
__ ldr(r0, MemOperand(sp, 0));
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET); __ Call(ic, RelocInfo::CODE_TARGET);
// Load receiver object into r1. // Load receiver object into r1.

View File

@ -682,12 +682,13 @@ Object* KeyedLoadIC_Miss(Arguments args);
void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) { void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
__ ldm(ia, sp, r2.bit() | r3.bit()); __ ldr(r1, MemOperand(sp, kPointerSize));
__ Push(r3, r2); __ Push(r1, r0);
ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss)); ExternalReference ref = ExternalReference(IC_Utility(kKeyedLoadIC_Miss));
__ TailCallExternalReference(ref, 2, 1); __ TailCallExternalReference(ref, 2, 1);
@ -697,12 +698,13 @@ void KeyedLoadIC::GenerateMiss(MacroAssembler* masm) {
void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) { void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
__ ldm(ia, sp, r2.bit() | r3.bit()); __ ldr(r1, MemOperand(sp, kPointerSize));
__ Push(r3, r2); __ Push(r1, r0);
__ TailCallRuntime(Runtime::kGetProperty, 2, 1); __ TailCallRuntime(Runtime::kGetProperty, 2, 1);
} }
@ -711,13 +713,14 @@ void KeyedLoadIC::GenerateRuntimeGetProperty(MacroAssembler* masm) {
void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label slow, fast, check_pixel_array, check_number_dictionary; Label slow, fast, check_pixel_array, check_number_dictionary;
// Get the key and receiver object from the stack. // Get the object from the stack.
__ ldm(ia, sp, r0.bit() | r1.bit()); __ ldr(r1, MemOperand(sp, kPointerSize));
// Check that the object isn't a smi. // Check that the object isn't a smi.
__ BranchOnSmi(r1, &slow); __ BranchOnSmi(r1, &slow);
@ -790,6 +793,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
// Slow case: Push extra copies of the arguments (2). // Slow case: Push extra copies of the arguments (2).
__ bind(&slow); __ bind(&slow);
__ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1); __ IncrementCounter(&Counters::keyed_load_generic_slow, 1, r0, r1);
__ ldr(r0, MemOperand(sp, 0));
GenerateRuntimeGetProperty(masm); GenerateRuntimeGetProperty(masm);
} }
@ -797,6 +801,7 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
void KeyedLoadIC::GenerateString(MacroAssembler* masm) { void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
@ -806,8 +811,8 @@ void KeyedLoadIC::GenerateString(MacroAssembler* masm) {
Label slow_char_code; Label slow_char_code;
Label got_char_code; Label got_char_code;
// Get the key and receiver object from the stack. // Get the object from the stack.
__ ldm(ia, sp, r0.bit() | r1.bit()); __ ldr(r1, MemOperand(sp, kPointerSize));
Register object = r1; Register object = r1;
Register index = r0; Register index = r0;
@ -907,13 +912,14 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
ExternalArrayType array_type) { ExternalArrayType array_type) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label slow, failed_allocation; Label slow, failed_allocation;
// Get the key and receiver object from the stack. // Get the object from the stack.
__ ldm(ia, sp, r0.bit() | r1.bit()); __ ldr(r1, MemOperand(sp, kPointerSize));
// r0: key // r0: key
// r1: receiver object // r1: receiver object
@ -1143,6 +1149,7 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
// Slow case: Load name and receiver from stack and jump to runtime. // Slow case: Load name and receiver from stack and jump to runtime.
__ bind(&slow); __ bind(&slow);
__ IncrementCounter(&Counters::keyed_load_external_array_slow, 1, r0, r1); __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1, r0, r1);
__ ldr(r0, MemOperand(sp, 0));
GenerateRuntimeGetProperty(masm); GenerateRuntimeGetProperty(masm);
} }
@ -1150,13 +1157,14 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) { void KeyedLoadIC::GenerateIndexedInterceptor(MacroAssembler* masm) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label slow; Label slow;
// Get the key and receiver object from the stack. // Get the object from the stack.
__ ldm(ia, sp, r0.bit() | r1.bit()); __ ldr(r1, MemOperand(sp, kPointerSize));
// Check that the receiver isn't a smi. // Check that the receiver isn't a smi.
__ BranchOnSmi(r1, &slow); __ BranchOnSmi(r1, &slow);

View File

@ -1824,18 +1824,18 @@ Object* KeyedLoadStubCompiler::CompileLoadField(String* name,
int index) { int index) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ ldr(r2, MemOperand(sp, 0)); // Check the key is the cached one.
__ ldr(r0, MemOperand(sp, kPointerSize)); __ cmp(r0, Operand(Handle<String>(name)));
__ cmp(r2, Operand(Handle<String>(name)));
__ b(ne, &miss); __ b(ne, &miss);
GenerateLoadField(receiver, holder, r0, r3, r1, index, name, &miss); __ ldr(r1, MemOperand(sp, kPointerSize)); // Receiver.
GenerateLoadField(receiver, holder, r1, r2, r3, index, name, &miss);
__ bind(&miss); __ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@ -1849,19 +1849,19 @@ Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name,
AccessorInfo* callback) { AccessorInfo* callback) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ ldr(r2, MemOperand(sp, 0)); // Check the key is the cached one.
__ ldr(r0, MemOperand(sp, kPointerSize)); __ cmp(r0, Operand(Handle<String>(name)));
__ cmp(r2, Operand(Handle<String>(name)));
__ b(ne, &miss); __ b(ne, &miss);
Failure* failure = Failure::InternalError(); Failure* failure = Failure::InternalError();
bool success = GenerateLoadCallback(receiver, holder, r0, r2, r3, r1, __ ldr(r1, MemOperand(sp, kPointerSize)); // Receiver.
bool success = GenerateLoadCallback(receiver, holder, r1, r0, r2, r3,
callback, name, &miss, &failure); callback, name, &miss, &failure);
if (!success) return failure; if (!success) return failure;
@ -1878,19 +1878,18 @@ Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
Object* value) { Object* value) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
// Check the key is the cached one // Check the key is the cached one.
__ ldr(r2, MemOperand(sp, 0)); __ cmp(r0, Operand(Handle<String>(name)));
__ ldr(r0, MemOperand(sp, kPointerSize));
__ cmp(r2, Operand(Handle<String>(name)));
__ b(ne, &miss); __ b(ne, &miss);
GenerateLoadConstant(receiver, holder, r0, r3, r1, value, name, &miss); __ ldr(r1, MemOperand(sp, kPointerSize)); // Receiver.
GenerateLoadConstant(receiver, holder, r1, r2, r3, value, name, &miss);
__ bind(&miss); __ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@ -1904,27 +1903,26 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
String* name) { String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
// Check the key is the cached one // Check the key is the cached one.
__ ldr(r2, MemOperand(sp, 0)); __ cmp(r0, Operand(Handle<String>(name)));
__ ldr(r0, MemOperand(sp, kPointerSize));
__ cmp(r2, Operand(Handle<String>(name)));
__ b(ne, &miss); __ b(ne, &miss);
LookupResult lookup; LookupResult lookup;
LookupPostInterceptor(holder, name, &lookup); LookupPostInterceptor(holder, name, &lookup);
__ ldr(r1, MemOperand(sp, kPointerSize)); // Receiver.
GenerateLoadInterceptor(receiver, GenerateLoadInterceptor(receiver,
holder, holder,
&lookup, &lookup,
r1,
r0, r0,
r2, r2,
r3, r3,
r1,
name, name,
&miss); &miss);
__ bind(&miss); __ bind(&miss);
@ -1937,19 +1935,18 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
// Check the key is the cached one // Check the key is the cached one.
__ ldr(r2, MemOperand(sp, 0)); __ cmp(r0, Operand(Handle<String>(name)));
__ ldr(r0, MemOperand(sp, kPointerSize));
__ cmp(r2, Operand(Handle<String>(name)));
__ b(ne, &miss); __ b(ne, &miss);
GenerateLoadArrayLength(masm(), r0, r3, &miss); __ ldr(r1, MemOperand(sp, kPointerSize)); // Receiver.
GenerateLoadArrayLength(masm(), r1, r2, &miss);
__ bind(&miss); __ bind(&miss);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
@ -1960,19 +1957,19 @@ Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ IncrementCounter(&Counters::keyed_load_string_length, 1, r1, r3); __ IncrementCounter(&Counters::keyed_load_string_length, 1, r1, r3);
__ ldr(r2, MemOperand(sp)); // Check the key is the cached one.
__ ldr(r0, MemOperand(sp, kPointerSize)); // receiver __ cmp(r0, Operand(Handle<String>(name)));
__ cmp(r2, Operand(Handle<String>(name)));
__ b(ne, &miss); __ b(ne, &miss);
GenerateLoadStringLength(masm(), r0, r1, r3, &miss); __ ldr(r1, MemOperand(sp, kPointerSize)); // Receiver.
GenerateLoadStringLength(masm(), r1, r2, r3, &miss);
__ bind(&miss); __ bind(&miss);
__ DecrementCounter(&Counters::keyed_load_string_length, 1, r1, r3); __ DecrementCounter(&Counters::keyed_load_string_length, 1, r1, r3);
@ -1986,6 +1983,7 @@ Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- lr : return address // -- lr : return address
// -- r0 : key
// -- sp[0] : key // -- sp[0] : key
// -- sp[4] : receiver // -- sp[4] : receiver
// ----------------------------------- // -----------------------------------

View File

@ -321,6 +321,7 @@ void VirtualFrame::CallStoreIC(Handle<String> name, bool is_contextual) {
void VirtualFrame::CallKeyedLoadIC() { void VirtualFrame::CallKeyedLoadIC() {
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
SpillAllButCopyTOSToR0();
CallCodeObject(ic, RelocInfo::CODE_TARGET, 0); CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
} }