| 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);
|
|
|