Commit ebc21fc9 authored by whesse@chromium.org's avatar whesse@chromium.org

Change keyed load IC interface on x64 to pass arguments in registers.

Review URL: http://codereview.chromium.org/2470001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4787 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c3b4097f
...@@ -8766,6 +8766,9 @@ Result CodeGenerator::EmitKeyedLoad() { ...@@ -8766,6 +8766,9 @@ Result CodeGenerator::EmitKeyedLoad() {
key.ToRegister(); key.ToRegister();
receiver.ToRegister(); receiver.ToRegister();
// If key and receiver are shared registers on the frame, their values will
// be automatically saved and restored when going to deferred code.
// The result is in elements, which is guaranteed non-shared.
DeferredReferenceGetKeyedValue* deferred = DeferredReferenceGetKeyedValue* deferred =
new DeferredReferenceGetKeyedValue(elements.reg(), new DeferredReferenceGetKeyedValue(elements.reg(),
receiver.reg(), receiver.reg(),
......
...@@ -454,11 +454,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) { ...@@ -454,11 +454,10 @@ void KeyedLoadIC::GenerateGeneric(MacroAssembler* masm) {
__ mov(edi, __ mov(edi,
Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets)); Operand::StaticArray(ecx, times_pointer_size, cache_field_offsets));
__ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset)); __ movzx_b(ecx, FieldOperand(ebx, Map::kInObjectPropertiesOffset));
__ cmp(edi, Operand(ecx)); __ sub(edi, Operand(ecx));
__ j(above_equal, &slow); __ j(above_equal, &slow);
// Load in-object property. // Load in-object property.
__ sub(edi, Operand(ecx));
__ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset)); __ movzx_b(ecx, FieldOperand(ebx, Map::kInstanceSizeOffset));
__ add(ecx, Operand(edi)); __ add(ecx, Operand(edi));
__ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0)); __ mov(eax, FieldOperand(edx, ecx, times_pointer_size, 0));
...@@ -690,7 +689,7 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm, ...@@ -690,7 +689,7 @@ void KeyedLoadIC::GenerateExternalArray(MacroAssembler* masm,
__ fincstp(); __ fincstp();
// Fall through to slow case. // Fall through to slow case.
// Slow case: Load key and receiver from stack and jump to runtime. // Slow case: Jump to runtime.
__ bind(&slow); __ bind(&slow);
__ IncrementCounter(&Counters::keyed_load_external_array_slow, 1); __ IncrementCounter(&Counters::keyed_load_external_array_slow, 1);
GenerateRuntimeGetProperty(masm); GenerateRuntimeGetProperty(masm);
......
...@@ -418,9 +418,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { ...@@ -418,9 +418,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ movq(rax, Operand(rbp, kIndexOffset)); __ movq(rax, Operand(rbp, kIndexOffset));
__ jmp(&entry); __ jmp(&entry);
__ bind(&loop); __ bind(&loop);
__ movq(rcx, Operand(rbp, kArgumentsOffset)); // load arguments __ movq(rdx, Operand(rbp, kArgumentsOffset)); // load arguments
__ push(rcx);
__ push(rax);
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
...@@ -430,8 +428,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) { ...@@ -430,8 +428,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
// we have generated an inline version of the keyed load. In this // we have generated an inline version of the keyed load. In this
// case, we know that we are not generating a test instruction next. // case, we know that we are not generating a test instruction next.
// Remove IC arguments from the stack and push the nth argument. // Push the nth argument.
__ addq(rsp, Immediate(2 * kPointerSize));
__ push(rax); __ push(rax);
// Update the index on the stack and in register rax. // Update the index on the stack and in register rax.
......
...@@ -660,9 +660,25 @@ class DeferredReferenceGetKeyedValue: public DeferredCode { ...@@ -660,9 +660,25 @@ class DeferredReferenceGetKeyedValue: public DeferredCode {
void DeferredReferenceGetKeyedValue::Generate() { void DeferredReferenceGetKeyedValue::Generate() {
__ push(receiver_); // First IC argument. if (receiver_.is(rdx)) {
__ push(key_); // Second IC argument. if (!key_.is(rax)) {
__ movq(rax, key_);
} // else do nothing.
} else if (receiver_.is(rax)) {
if (key_.is(rdx)) {
__ xchg(rax, rdx);
} else if (key_.is(rax)) {
__ movq(rdx, receiver_);
} else {
__ movq(rdx, receiver_);
__ movq(rax, key_);
}
} else if (key_.is(rax)) {
__ movq(rdx, receiver_);
} else {
__ movq(rax, key_);
__ movq(rdx, receiver_);
}
// Calculate the delta from the IC call instruction to the map check // Calculate the delta from the IC call instruction to the map check
// movq instruction in the inlined version. This delta is stored in // movq instruction in the inlined version. This delta is stored in
// a test(rax, delta) instruction after the call so that we can find // a test(rax, delta) instruction after the call so that we can find
...@@ -686,8 +702,6 @@ void DeferredReferenceGetKeyedValue::Generate() { ...@@ -686,8 +702,6 @@ void DeferredReferenceGetKeyedValue::Generate() {
__ IncrementCounter(&Counters::keyed_load_inline_miss, 1); __ IncrementCounter(&Counters::keyed_load_inline_miss, 1);
if (!dst_.is(rax)) __ movq(dst_, rax); if (!dst_.is(rax)) __ movq(dst_, rax);
__ pop(key_);
__ pop(receiver_);
} }
...@@ -5852,7 +5866,6 @@ void CodeGenerator::EmitDynamicLoadFromSlotFastCase(Slot* slot, ...@@ -5852,7 +5866,6 @@ void CodeGenerator::EmitDynamicLoadFromSlotFastCase(Slot* slot,
frame_->Push(&arguments); frame_->Push(&arguments);
frame_->Push(key_literal->handle()); frame_->Push(key_literal->handle());
*result = EmitKeyedLoad(); *result = EmitKeyedLoad();
frame_->Drop(2); // Drop key and receiver.
done->Jump(result); done->Jump(result);
} }
} }
...@@ -7447,6 +7460,9 @@ Result CodeGenerator::EmitKeyedLoad() { ...@@ -7447,6 +7460,9 @@ Result CodeGenerator::EmitKeyedLoad() {
key.ToRegister(); key.ToRegister();
receiver.ToRegister(); receiver.ToRegister();
// If key and receiver are shared registers on the frame, their values will
// be automatically saved and restored when going to deferred code.
// The result is returned in elements, which is not shared.
DeferredReferenceGetKeyedValue* deferred = DeferredReferenceGetKeyedValue* deferred =
new DeferredReferenceGetKeyedValue(elements.reg(), new DeferredReferenceGetKeyedValue(elements.reg(),
receiver.reg(), receiver.reg(),
...@@ -7459,9 +7475,9 @@ Result CodeGenerator::EmitKeyedLoad() { ...@@ -7459,9 +7475,9 @@ Result CodeGenerator::EmitKeyedLoad() {
// initialization code. // initialization code.
__ bind(deferred->patch_site()); __ bind(deferred->patch_site());
// Use masm-> here instead of the double underscore macro since extra // Use masm-> here instead of the double underscore macro since extra
// coverage code can interfere with the patching. Do not use // coverage code can interfere with the patching. Do not use a load
// root array to load null_value, since it must be patched with // from the root away to load null_value, since the load must be patched
// the expected receiver map. // with the expected receiver map, which is not in the root array.
masm_->movq(kScratchRegister, Factory::null_value(), masm_->movq(kScratchRegister, Factory::null_value(),
RelocInfo::EMBEDDED_OBJECT); RelocInfo::EMBEDDED_OBJECT);
masm_->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset), masm_->cmpq(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
...@@ -7504,8 +7520,6 @@ Result CodeGenerator::EmitKeyedLoad() { ...@@ -7504,8 +7520,6 @@ Result CodeGenerator::EmitKeyedLoad() {
__ IncrementCounter(&Counters::keyed_load_inline, 1); __ IncrementCounter(&Counters::keyed_load_inline, 1);
deferred->BindExit(); deferred->BindExit();
frame_->Push(&receiver);
frame_->Push(&key);
} else { } else {
Comment cmnt(masm_, "[ Load from keyed Property"); Comment cmnt(masm_, "[ Load from keyed Property");
result = frame_->CallKeyedLoadIC(RelocInfo::CODE_TARGET); result = frame_->CallKeyedLoadIC(RelocInfo::CODE_TARGET);
...@@ -7516,7 +7530,7 @@ Result CodeGenerator::EmitKeyedLoad() { ...@@ -7516,7 +7530,7 @@ Result CodeGenerator::EmitKeyedLoad() {
// the push that follows might be peep-hole optimized away. // the push that follows might be peep-hole optimized away.
__ nop(); __ nop();
} }
ASSERT(frame()->height() == original_height); ASSERT(frame()->height() == original_height - 2);
return result; return result;
} }
...@@ -7560,7 +7574,6 @@ void Reference::GetValue() { ...@@ -7560,7 +7574,6 @@ void Reference::GetValue() {
Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
ASSERT(slot != NULL); ASSERT(slot != NULL);
cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
if (!persist_after_get_) set_unloaded();
break; break;
} }
...@@ -7573,27 +7586,28 @@ void Reference::GetValue() { ...@@ -7573,27 +7586,28 @@ void Reference::GetValue() {
} }
Result result = cgen_->EmitNamedLoad(GetName(), is_global); Result result = cgen_->EmitNamedLoad(GetName(), is_global);
cgen_->frame()->Push(&result); cgen_->frame()->Push(&result);
if (!persist_after_get_) {
set_unloaded();
}
break; break;
} }
case KEYED: { case KEYED: {
// A load of a bare identifier (load from global) cannot be keyed. // A load of a bare identifier (load from global) cannot be keyed.
ASSERT(expression_->AsVariableProxy()->AsVariable() == NULL); ASSERT(expression_->AsVariableProxy()->AsVariable() == NULL);
if (persist_after_get_) {
cgen_->frame()->PushElementAt(1);
cgen_->frame()->PushElementAt(1);
}
Result value = cgen_->EmitKeyedLoad(); Result value = cgen_->EmitKeyedLoad();
cgen_->frame()->Push(&value); cgen_->frame()->Push(&value);
if (!persist_after_get_) {
cgen_->UnloadReference(this);
}
break; break;
} }
default: default:
UNREACHABLE(); UNREACHABLE();
} }
if (!persist_after_get_) {
set_unloaded();
}
} }
......
...@@ -124,9 +124,10 @@ void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) { ...@@ -124,9 +124,10 @@ void Debug::GenerateConstructCallDebugBreak(MacroAssembler* masm) {
void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) { void Debug::GenerateKeyedLoadICDebugBreak(MacroAssembler* masm) {
// Register state for keyed IC load call (from ic-x64.cc). // Register state for keyed IC load call (from ic-x64.cc).
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// No registers used on entry. // -- rax : key
// -- rdx : receiver
// ----------------------------------- // -----------------------------------
Generate_DebugBreakCallHelper(masm, 0, false); Generate_DebugBreakCallHelper(masm, rax.bit() | rdx.bit(), false);
} }
......
...@@ -1176,7 +1176,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var, ...@@ -1176,7 +1176,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
// Load the object. // Load the object.
MemOperand object_loc = EmitSlotSearch(object_slot, rax); MemOperand object_loc = EmitSlotSearch(object_slot, rax);
__ push(object_loc); __ movq(rdx, object_loc);
// 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();
...@@ -1184,7 +1184,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var, ...@@ -1184,7 +1184,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
ASSERT(key_literal->handle()->IsSmi()); ASSERT(key_literal->handle()->IsSmi());
// Load the key. // Load the key.
__ Push(key_literal->handle()); __ Move(rax, key_literal->handle());
// Do a keyed property load. // Do a keyed property load.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
...@@ -1192,8 +1192,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var, ...@@ -1192,8 +1192,7 @@ void FullCodeGenerator::EmitVariableLoad(Variable* var,
// Notice: We must not have a "test rax, ..." instruction after the // Notice: We must not have a "test rax, ..." instruction after the
// call. It is treated specially by the LoadIC code. // call. It is treated specially by the LoadIC code.
__ nop(); __ nop();
// Drop key and object left on the stack by IC, and push the result. Apply(context, rax);
DropAndApply(2, context, rax);
} }
} }
...@@ -1699,10 +1698,10 @@ void FullCodeGenerator::VisitProperty(Property* expr) { ...@@ -1699,10 +1698,10 @@ void FullCodeGenerator::VisitProperty(Property* expr) {
Apply(context_, rax); Apply(context_, rax);
} else { } else {
VisitForValue(expr->obj(), kStack); VisitForValue(expr->obj(), kStack);
VisitForValue(expr->key(), kStack); VisitForValue(expr->key(), kAccumulator);
__ pop(rdx);
EmitKeyedPropertyLoad(expr); EmitKeyedPropertyLoad(expr);
// Drop key and receiver left on the stack by IC. Apply(context_, rax);
DropAndApply(2, context_, rax);
} }
} }
...@@ -1824,7 +1823,8 @@ void FullCodeGenerator::VisitCall(Call* expr) { ...@@ -1824,7 +1823,8 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Call to a keyed property, use keyed load IC followed by function // Call to a keyed property, use keyed load IC followed by function
// call. // call.
VisitForValue(prop->obj(), kStack); VisitForValue(prop->obj(), kStack);
VisitForValue(prop->key(), kStack); VisitForValue(prop->key(), kAccumulator);
__ movq(rdx, Operand(rsp, 0));
// Record source code position for IC call. // Record source code position for IC call.
SetSourcePosition(prop->position()); SetSourcePosition(prop->position());
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
...@@ -1832,8 +1832,6 @@ void FullCodeGenerator::VisitCall(Call* expr) { ...@@ -1832,8 +1832,6 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// By emitting a nop we make sure that we do not have a "test rax,..." // By emitting a nop we make sure that we do not have a "test rax,..."
// instruction after the call it is treated specially by the LoadIC code. // instruction after the call it is treated specially by the LoadIC code.
__ nop(); __ nop();
// Drop key left on the stack by IC.
__ Drop(1);
// Pop receiver. // Pop receiver.
__ pop(rbx); __ pop(rbx);
// Push result (function). // Push result (function).
...@@ -2865,7 +2863,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) { ...@@ -2865,7 +2863,9 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
EmitNamedPropertyLoad(prop); EmitNamedPropertyLoad(prop);
} else { } else {
VisitForValue(prop->obj(), kStack); VisitForValue(prop->obj(), kStack);
VisitForValue(prop->key(), kStack); VisitForValue(prop->key(), kAccumulator);
__ movq(rdx, Operand(rsp, 0)); // Leave receiver on stack
__ push(rax); // Copy of key, needed for later store.
EmitKeyedPropertyLoad(prop); EmitKeyedPropertyLoad(prop);
} }
} }
......
This diff is collapsed.
...@@ -1505,14 +1505,12 @@ Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, ...@@ -1505,14 +1505,12 @@ Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name,
JSObject* holder, JSObject* holder,
AccessorInfo* callback) { AccessorInfo* callback) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// -- rsp[8] : name
// -- rsp[16] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ movq(rax, Operand(rsp, kPointerSize));
__ movq(rcx, Operand(rsp, 2 * kPointerSize));
__ IncrementCounter(&Counters::keyed_load_callback, 1); __ IncrementCounter(&Counters::keyed_load_callback, 1);
// Check that the name has not changed. // Check that the name has not changed.
...@@ -1520,7 +1518,7 @@ Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, ...@@ -1520,7 +1518,7 @@ Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name,
__ j(not_equal, &miss); __ j(not_equal, &miss);
Failure* failure = Failure::InternalError(); Failure* failure = Failure::InternalError();
bool success = GenerateLoadCallback(receiver, holder, rcx, rax, rbx, rdx, bool success = GenerateLoadCallback(receiver, holder, rdx, rax, rbx, rcx,
callback, name, &miss, &failure); callback, name, &miss, &failure);
if (!success) return failure; if (!success) return failure;
...@@ -1535,21 +1533,19 @@ Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name, ...@@ -1535,21 +1533,19 @@ Object* KeyedLoadStubCompiler::CompileLoadCallback(String* name,
Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { Object* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// -- rsp[8] : name
// -- rsp[16] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ movq(rax, Operand(rsp, kPointerSize));
__ movq(rcx, Operand(rsp, 2 * kPointerSize));
__ IncrementCounter(&Counters::keyed_load_array_length, 1); __ IncrementCounter(&Counters::keyed_load_array_length, 1);
// Check that the name has not changed. // Check that the name has not changed.
__ Cmp(rax, Handle<String>(name)); __ Cmp(rax, Handle<String>(name));
__ j(not_equal, &miss); __ j(not_equal, &miss);
GenerateLoadArrayLength(masm(), rcx, rdx, &miss); GenerateLoadArrayLength(masm(), rdx, rcx, &miss);
__ bind(&miss); __ bind(&miss);
__ DecrementCounter(&Counters::keyed_load_array_length, 1); __ DecrementCounter(&Counters::keyed_load_array_length, 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
...@@ -1564,21 +1560,19 @@ Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, ...@@ -1564,21 +1560,19 @@ Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
JSObject* holder, JSObject* holder,
Object* value) { Object* value) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// -- rsp[8] : name
// -- rsp[16] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ movq(rax, Operand(rsp, kPointerSize));
__ movq(rcx, Operand(rsp, 2 * kPointerSize));
__ IncrementCounter(&Counters::keyed_load_constant_function, 1); __ IncrementCounter(&Counters::keyed_load_constant_function, 1);
// Check that the name has not changed. // Check that the name has not changed.
__ Cmp(rax, Handle<String>(name)); __ Cmp(rax, Handle<String>(name));
__ j(not_equal, &miss); __ j(not_equal, &miss);
GenerateLoadConstant(receiver, holder, rcx, rbx, rdx, GenerateLoadConstant(receiver, holder, rdx, rbx, rcx,
value, name, &miss); value, name, &miss);
__ bind(&miss); __ bind(&miss);
__ DecrementCounter(&Counters::keyed_load_constant_function, 1); __ DecrementCounter(&Counters::keyed_load_constant_function, 1);
...@@ -1591,21 +1585,19 @@ Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name, ...@@ -1591,21 +1585,19 @@ Object* KeyedLoadStubCompiler::CompileLoadConstant(String* name,
Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { Object* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// -- rsp[8] : name
// -- rsp[16] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ movq(rax, Operand(rsp, kPointerSize));
__ movq(rcx, Operand(rsp, 2 * kPointerSize));
__ IncrementCounter(&Counters::keyed_load_function_prototype, 1); __ IncrementCounter(&Counters::keyed_load_function_prototype, 1);
// Check that the name has not changed. // Check that the name has not changed.
__ Cmp(rax, Handle<String>(name)); __ Cmp(rax, Handle<String>(name));
__ j(not_equal, &miss); __ j(not_equal, &miss);
GenerateLoadFunctionPrototype(masm(), rcx, rdx, rbx, &miss); GenerateLoadFunctionPrototype(masm(), rdx, rcx, rbx, &miss);
__ bind(&miss); __ bind(&miss);
__ DecrementCounter(&Counters::keyed_load_function_prototype, 1); __ DecrementCounter(&Counters::keyed_load_function_prototype, 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
...@@ -1619,14 +1611,12 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, ...@@ -1619,14 +1611,12 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
JSObject* holder, JSObject* holder,
String* name) { String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rax : key
// -- rdx : receiver
// -- rsp[0] : return address // -- rsp[0] : return address
// -- rsp[8] : name
// -- rsp[16] : receiver
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ movq(rax, Operand(rsp, kPointerSize));
__ movq(rcx, Operand(rsp, 2 * kPointerSize));
__ IncrementCounter(&Counters::keyed_load_interceptor, 1); __ IncrementCounter(&Counters::keyed_load_interceptor, 1);
// Check that the name has not changed. // Check that the name has not changed.
...@@ -1638,9 +1628,9 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, ...@@ -1638,9 +1628,9 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
GenerateLoadInterceptor(receiver, GenerateLoadInterceptor(receiver,
holder, holder,
&lookup, &lookup,
rcx,
rax,
rdx, rdx,
rax,
rcx,
rbx, rbx,
name, name,
&miss); &miss);
...@@ -1655,21 +1645,19 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, ...@@ -1655,21 +1645,19 @@ Object* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { Object* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rsp[0] : return address // -- rax : key
// -- rsp[8] : name // -- rdx : receiver
// -- rsp[16] : receiver // -- rsp[0] : return address
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ movq(rax, Operand(rsp, kPointerSize));
__ movq(rcx, Operand(rsp, 2 * kPointerSize));
__ IncrementCounter(&Counters::keyed_load_string_length, 1); __ IncrementCounter(&Counters::keyed_load_string_length, 1);
// Check that the name has not changed. // Check that the name has not changed.
__ Cmp(rax, Handle<String>(name)); __ Cmp(rax, Handle<String>(name));
__ j(not_equal, &miss); __ j(not_equal, &miss);
GenerateLoadStringLength(masm(), rcx, rdx, rbx, &miss); GenerateLoadStringLength(masm(), rdx, rcx, rbx, &miss);
__ bind(&miss); __ bind(&miss);
__ DecrementCounter(&Counters::keyed_load_string_length, 1); __ DecrementCounter(&Counters::keyed_load_string_length, 1);
GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
...@@ -1847,21 +1835,19 @@ Object* KeyedLoadStubCompiler::CompileLoadField(String* name, ...@@ -1847,21 +1835,19 @@ Object* KeyedLoadStubCompiler::CompileLoadField(String* name,
JSObject* holder, JSObject* holder,
int index) { int index) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- rsp[0] : return address // -- rax : key
// -- rsp[8] : name // -- rdx : receiver
// -- rsp[16] : receiver // -- rsp[0] : return address
// ----------------------------------- // -----------------------------------
Label miss; Label miss;
__ movq(rax, Operand(rsp, kPointerSize));
__ movq(rcx, Operand(rsp, 2 * kPointerSize));
__ IncrementCounter(&Counters::keyed_load_field, 1); __ IncrementCounter(&Counters::keyed_load_field, 1);
// Check that the name has not changed. // Check that the name has not changed.
__ Cmp(rax, Handle<String>(name)); __ Cmp(rax, Handle<String>(name));
__ j(not_equal, &miss); __ j(not_equal, &miss);
GenerateLoadField(receiver, holder, rcx, rbx, rdx, index, name, &miss); GenerateLoadField(receiver, holder, rdx, rbx, rcx, index, name, &miss);
__ bind(&miss); __ bind(&miss);
__ DecrementCounter(&Counters::keyed_load_field, 1); __ DecrementCounter(&Counters::keyed_load_field, 1);
......
...@@ -1077,7 +1077,7 @@ Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) { ...@@ -1077,7 +1077,7 @@ Result VirtualFrame::CallLoadIC(RelocInfo::Mode mode) {
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
Result name = Pop(); Result name = Pop();
Result receiver = Pop(); Result receiver = Pop();
PrepareForCall(0, 0); // One stack arg, not callee-dropped. PrepareForCall(0, 0);
MoveResultsToRegisters(&name, &receiver, rcx, rax); MoveResultsToRegisters(&name, &receiver, rcx, rax);
return RawCallCodeObject(ic, mode); return RawCallCodeObject(ic, mode);
...@@ -1088,7 +1088,10 @@ Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) { ...@@ -1088,7 +1088,10 @@ Result VirtualFrame::CallKeyedLoadIC(RelocInfo::Mode mode) {
// Key and receiver are on top of the frame. The IC expects them on // Key and receiver are on top of the frame. The IC expects them on
// the stack. It does not drop them. // the stack. It does not drop them.
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
PrepareForCall(2, 0); // Two stack args, neither callee-dropped. Result name = Pop();
Result receiver = Pop();
PrepareForCall(0, 0);
MoveResultsToRegisters(&name, &receiver, rax, rdx);
return RawCallCodeObject(ic, mode); return RawCallCodeObject(ic, mode);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment