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