| Index: src/x64/codegen-x64.cc
|
| ===================================================================
|
| --- src/x64/codegen-x64.cc (revision 4691)
|
| +++ src/x64/codegen-x64.cc (working copy)
|
| @@ -680,11 +680,51 @@
|
|
|
| void DeferredReferenceSetKeyedValue::Generate() {
|
| __ IncrementCounter(&Counters::keyed_store_inline_miss, 1);
|
| - // Push receiver and key arguments on the stack.
|
| - __ push(receiver_);
|
| - __ push(key_);
|
| - // Move value argument to eax as expected by the IC stub.
|
| - if (!value_.is(rax)) __ movq(rax, value_);
|
| + // Move value, receiver, and key to registers rax, rdx, and rcx, as
|
| + // the IC stub expects.
|
| + // Move value to rax, using xchg if the receiver or key is in rax.
|
| + if (!value_.is(rax)) {
|
| + if (!receiver_.is(rax) && !key_.is(rax)) {
|
| + __ movq(rax, value_);
|
| + } else {
|
| + __ xchg(rax, value_);
|
| + // Update receiver_ and key_ if they are affected by the swap.
|
| + if (receiver_.is(rax)) {
|
| + receiver_ = value_;
|
| + } else if (receiver_.is(value_)) {
|
| + receiver_ = rax;
|
| + }
|
| + if (key_.is(rax)) {
|
| + key_ = value_;
|
| + } else if (key_.is(value_)) {
|
| + key_ = rax;
|
| + }
|
| + }
|
| + }
|
| + // Value is now in rax. Its original location is remembered in value_,
|
| + // and the value is restored to value_ before returning.
|
| + // The variables receiver_ and key_ are not preserved.
|
| + // Move receiver and key to rdx and rcx, swapping if necessary.
|
| + if (receiver_.is(rdx)) {
|
| + if (!key_.is(rcx)) {
|
| + __ movq(rcx, key_);
|
| + } // Else everything is already in the right place.
|
| + } else if (receiver_.is(rcx)) {
|
| + if (key_.is(rdx)) {
|
| + __ xchg(rcx, rdx);
|
| + } else if (key_.is(rcx)) {
|
| + __ movq(rdx, receiver_);
|
| + } else {
|
| + __ movq(rdx, receiver_);
|
| + __ movq(rcx, key_);
|
| + }
|
| + } else if (key_.is(rcx)) {
|
| + __ movq(rdx, receiver_);
|
| + } else {
|
| + __ movq(rcx, key_);
|
| + __ movq(rdx, receiver_);
|
| + }
|
| +
|
| // Call the IC stub.
|
| Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize));
|
| __ Call(ic, RelocInfo::CODE_TARGET);
|
| @@ -697,11 +737,8 @@
|
| // Here we use masm_-> instead of the __ macro because this is the
|
| // instruction that gets patched and coverage code gets in the way.
|
| masm_->testl(rax, Immediate(-delta_to_patch_site));
|
| - // Restore value (returned from store IC), key and receiver
|
| - // registers.
|
| + // Restore value (returned from store IC).
|
| if (!value_.is(rax)) __ movq(value_, rax);
|
| - __ pop(key_);
|
| - __ pop(receiver_);
|
| }
|
|
|
|
|
| @@ -7533,8 +7570,6 @@
|
|
|
| deferred->BindExit();
|
|
|
| - cgen_->frame()->Push(&receiver);
|
| - cgen_->frame()->Push(&key);
|
| cgen_->frame()->Push(&value);
|
| } else {
|
| Result answer = cgen_->frame()->CallKeyedStoreIC();
|
| @@ -7545,7 +7580,7 @@
|
| masm->nop();
|
| cgen_->frame()->Push(&answer);
|
| }
|
| - cgen_->UnloadReference(this);
|
| + set_unloaded();
|
| break;
|
| }
|
|
|
|
|