Index: src/x64/full-codegen-x64.cc |
=================================================================== |
--- src/x64/full-codegen-x64.cc (revision 5467) |
+++ src/x64/full-codegen-x64.cc (working copy) |
@@ -625,10 +625,7 @@ |
__ pop(rdx); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- // Absence of a test rax instruction following the call |
- // indicates that none of the load was inlined. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
} |
} |
} |
@@ -941,8 +938,7 @@ |
RelocInfo::Mode mode = (typeof_state == INSIDE_TYPEOF) |
? RelocInfo::CODE_TARGET |
: RelocInfo::CODE_TARGET_CONTEXT; |
- __ call(ic, mode); |
- __ nop(); // Signal no inlined code. |
+ EmitCallIC(ic, mode); |
} |
@@ -1019,7 +1015,7 @@ |
slow)); |
__ Move(rax, key_literal->handle()); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
__ jmp(done); |
} |
} |
@@ -1043,11 +1039,7 @@ |
__ Move(rcx, var->name()); |
__ movq(rax, CodeGenerator::GlobalObject()); |
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
- __ Call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
- // A test rax instruction following the call is used by the IC to |
- // indicate that the inobject property case was inlined. Ensure there |
- // is no test rax instruction here. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
Apply(context, rax); |
} else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
@@ -1110,10 +1102,7 @@ |
// Do a keyed property load. |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- // Notice: We must not have a "test rax, ..." instruction after the |
- // call. It is treated specially by the LoadIC code. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
Apply(context, rax); |
} |
} |
@@ -1212,8 +1201,7 @@ |
__ Move(rcx, key->handle()); |
__ movq(rdx, Operand(rsp, 0)); |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
break; |
} |
// Fall through. |
@@ -1425,16 +1413,14 @@ |
Literal* key = prop->key()->AsLiteral(); |
__ Move(rcx, key->handle()); |
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
- __ Call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
} |
void FullCodeGenerator::EmitKeyedPropertyLoad(Property* prop) { |
SetSourcePosition(prop->position()); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
- __ Call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
} |
@@ -1553,8 +1539,7 @@ |
__ pop(rax); // Restore value. |
__ Move(rcx, prop->key()->AsLiteral()->handle()); |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); // Signal no inlined code. |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
break; |
} |
case KEYED_PROPERTY: { |
@@ -1565,8 +1550,7 @@ |
__ pop(rdx); |
__ pop(rax); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); // Signal no inlined code. |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
break; |
} |
} |
@@ -1589,8 +1573,7 @@ |
__ Move(rcx, var->name()); |
__ movq(rdx, CodeGenerator::GlobalObject()); |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
- __ Call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
} else if (var->mode() != Variable::CONST || op == Token::INIT_CONST) { |
// Perform the assignment for non-const variables and for initialization |
@@ -1674,8 +1657,7 @@ |
__ pop(rdx); |
} |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
- __ Call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
// If the assignment ends an initialization block, revert to fast case. |
if (expr->ends_initialization_block()) { |
@@ -1713,10 +1695,7 @@ |
// Record source code position before IC call. |
SetSourcePosition(expr->position()); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
- __ Call(ic, RelocInfo::CODE_TARGET); |
- // This nop signals to the IC that there is no inlined code at the call |
- // site for it to patch. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
// If the assignment ends an initialization block, revert to fast case. |
if (expr->ends_initialization_block()) { |
@@ -1765,7 +1744,7 @@ |
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, |
in_loop); |
- __ Call(ic, mode); |
+ EmitCallIC(ic, mode); |
// Restore context register. |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
Apply(context_, rax); |
@@ -1789,7 +1768,7 @@ |
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
Handle<Code> ic = CodeGenerator::ComputeKeyedCallInitialize(arg_count, |
in_loop); |
- __ Call(ic, mode); |
+ EmitCallIC(ic, mode); |
// Restore context register. |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
Apply(context_, rax); |
@@ -1924,11 +1903,7 @@ |
// Record source code position for IC call. |
SetSourcePosition(prop->position()); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- // By emitting a nop we make sure that we do not have a "test rax,..." |
- // instruction after the call as it is treated specially |
- // by the LoadIC code. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
// Pop receiver. |
__ pop(rbx); |
// Push result (function). |
@@ -2841,7 +2816,7 @@ |
__ Move(rcx, expr->name()); |
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; |
Handle<Code> ic = CodeGenerator::ComputeCallInitialize(arg_count, in_loop); |
- __ call(ic, RelocInfo::CODE_TARGET); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
// Restore context register. |
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset)); |
} else { |
@@ -3139,10 +3114,7 @@ |
__ Move(rcx, prop->key()->AsLiteral()->handle()); |
__ pop(rdx); |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- // This nop signals to the IC that there is no inlined code at the call |
- // site for it to patch. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
if (expr->is_postfix()) { |
if (context_ != Expression::kEffect) { |
ApplyTOS(context_); |
@@ -3156,10 +3128,7 @@ |
__ pop(rcx); |
__ pop(rdx); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- // This nop signals to the IC that there is no inlined code at the call |
- // site for it to patch. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
if (expr->is_postfix()) { |
if (context_ != Expression::kEffect) { |
ApplyTOS(context_); |
@@ -3182,8 +3151,7 @@ |
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
// Use a regular load, not a contextual load, to avoid a reference |
// error. |
- __ Call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); // Signal no inlined code. |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
if (where == kStack) __ push(rax); |
} else if (proxy != NULL && |
proxy->var()->slot() != NULL && |
@@ -3431,12 +3399,38 @@ |
} |
-Register FullCodeGenerator::result_register() { return rax; } |
+Register FullCodeGenerator::result_register() { |
+ return rax; |
+} |
-Register FullCodeGenerator::context_register() { return rsi; } |
+Register FullCodeGenerator::context_register() { |
+ return rsi; |
+} |
+void FullCodeGenerator::EmitCallIC(Handle<Code> ic, RelocInfo::Mode mode) { |
+ ASSERT(mode == RelocInfo::CODE_TARGET || |
+ mode == RelocInfo::CODE_TARGET_CONTEXT); |
+ __ call(ic, mode); |
+ |
+ // If we're calling a (keyed) load or store stub, we have to mark |
+ // the call as containing no inlined code so we will not attempt to |
+ // patch it. |
+ switch (ic->kind()) { |
+ case Code::LOAD_IC: |
+ case Code::KEYED_LOAD_IC: |
+ case Code::STORE_IC: |
+ case Code::KEYED_STORE_IC: |
+ __ nop(); // Signals no inlined code. |
+ break; |
+ default: |
+ // Do nothing. |
+ break; |
+ } |
+} |
+ |
+ |
void FullCodeGenerator::StoreToFrameField(int frame_offset, Register value) { |
ASSERT(IsAligned(frame_offset, kPointerSize)); |
__ movq(Operand(rbp, frame_offset), value); |