Index: src/ia32/full-codegen-ia32.cc |
=================================================================== |
--- src/ia32/full-codegen-ia32.cc (revision 5467) |
+++ src/ia32/full-codegen-ia32.cc (working copy) |
@@ -631,10 +631,7 @@ |
__ pop(edx); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- // Absence of a test eax instruction following the call |
- // indicates that none of the load was inlined. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
} |
} |
} |
@@ -992,8 +989,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); |
} |
@@ -1070,7 +1066,7 @@ |
slow)); |
__ mov(eax, Immediate(key_literal->handle())); |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
__ jmp(done); |
} |
} |
@@ -1094,12 +1090,7 @@ |
__ mov(eax, CodeGenerator::GlobalObject()); |
__ mov(ecx, var->name()); |
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET_CONTEXT); |
- // By emitting a nop we make sure that we do not have a test eax |
- // instruction after the call it is treated specially by the LoadIC code |
- // Remember that the assembler may choose to do peephole optimization |
- // (eg, push/pop elimination). |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET_CONTEXT); |
Apply(context, eax); |
} else if (slot != NULL && slot->type() == Slot::LOOKUP) { |
@@ -1162,10 +1153,8 @@ |
// 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 eax, ..." instruction after the |
- // call. It is treated specially by the LoadIC code. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
+ |
// Drop key and object left on the stack by IC. |
Apply(context, eax); |
} |
@@ -1263,8 +1252,7 @@ |
__ mov(ecx, Immediate(key->handle())); |
__ mov(edx, Operand(esp, 0)); |
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
break; |
} |
// Fall through. |
@@ -1477,16 +1465,14 @@ |
Literal* key = prop->key()->AsLiteral(); |
__ mov(ecx, Immediate(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); |
} |
@@ -1846,8 +1832,7 @@ |
__ pop(eax); // Restore value. |
__ mov(ecx, 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: { |
@@ -1858,8 +1843,7 @@ |
__ pop(edx); |
__ pop(eax); // Restore value. |
Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
- __ call(ic, RelocInfo::CODE_TARGET); |
- __ nop(); // Signal no inlined code. |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
break; |
} |
} |
@@ -1882,8 +1866,7 @@ |
__ mov(ecx, var->name()); |
__ mov(edx, 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 |
@@ -1967,8 +1950,7 @@ |
__ pop(edx); |
} |
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()) { |
@@ -2006,10 +1988,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()) { |
@@ -2056,7 +2035,7 @@ |
SetSourcePosition(expr->position()); |
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. |
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
Apply(context_, eax); |
@@ -2079,7 +2058,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. |
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
Apply(context_, eax); |
@@ -2203,7 +2182,7 @@ |
} else { |
// Call to a keyed property. |
// For a synthetic property use keyed load IC followed by function call, |
- // for a regular property use keyed CallIC. |
+ // for a regular property use keyed EmitCallIC. |
VisitForValue(prop->obj(), kStack); |
if (prop->is_synthetic()) { |
VisitForValue(prop->key(), kAccumulator); |
@@ -2212,11 +2191,7 @@ |
__ pop(edx); // We do not need to keep the receiver. |
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 eax,..." |
- // instruction after the call as it is treated specially |
- // by the LoadIC code. |
- __ nop(); |
+ EmitCallIC(ic, RelocInfo::CODE_TARGET); |
// Push result (function). |
__ push(eax); |
// Push Global receiver. |
@@ -3144,7 +3119,7 @@ |
__ Set(ecx, Immediate(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. |
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
} else { |
@@ -3450,10 +3425,7 @@ |
__ mov(ecx, prop->key()->AsLiteral()->handle()); |
__ pop(edx); |
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_); |
@@ -3467,10 +3439,7 @@ |
__ pop(ecx); |
__ pop(edx); |
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()) { |
// Result is on the stack |
if (context_ != Expression::kEffect) { |
@@ -3494,8 +3463,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(eax); |
} else if (proxy != NULL && |
proxy->var()->slot() != NULL && |
@@ -3747,12 +3715,38 @@ |
} |
-Register FullCodeGenerator::result_register() { return eax; } |
+Register FullCodeGenerator::result_register() { |
+ return eax; |
+} |
-Register FullCodeGenerator::context_register() { return esi; } |
+Register FullCodeGenerator::context_register() { |
+ return esi; |
+} |
+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_EQ(POINTER_SIZE_ALIGN(frame_offset), frame_offset); |
__ mov(Operand(ebp, frame_offset), value); |