OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
673 private: | 673 private: |
674 Register value_; | 674 Register value_; |
675 Register key_; | 675 Register key_; |
676 Register receiver_; | 676 Register receiver_; |
677 Label patch_site_; | 677 Label patch_site_; |
678 }; | 678 }; |
679 | 679 |
680 | 680 |
681 void DeferredReferenceSetKeyedValue::Generate() { | 681 void DeferredReferenceSetKeyedValue::Generate() { |
682 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1); | 682 __ IncrementCounter(&Counters::keyed_store_inline_miss, 1); |
683 // Push receiver and key arguments on the stack. | 683 // Move value, receiver, and key to registers rax, rdx, and rcx, as |
684 __ push(receiver_); | 684 // the IC stub expects. |
685 __ push(key_); | 685 // Move value to rax, using xchg if the receiver or key is in rax. |
686 // Move value argument to eax as expected by the IC stub. | 686 if (!value_.is(rax)) { |
687 if (!value_.is(rax)) __ movq(rax, value_); | 687 if (!receiver_.is(rax) && !key_.is(rax)) { |
| 688 __ movq(rax, value_); |
| 689 } else { |
| 690 __ xchg(rax, value_); |
| 691 // Update receiver_ and key_ if they are affected by the swap. |
| 692 if (receiver_.is(rax)) { |
| 693 receiver_ = value_; |
| 694 } else if (receiver_.is(value_)) { |
| 695 receiver_ = rax; |
| 696 } |
| 697 if (key_.is(rax)) { |
| 698 key_ = value_; |
| 699 } else if (key_.is(value_)) { |
| 700 key_ = rax; |
| 701 } |
| 702 } |
| 703 } |
| 704 // Value is now in rax. Its original location is remembered in value_, |
| 705 // and the value is restored to value_ before returning. |
| 706 // The variables receiver_ and key_ are not preserved. |
| 707 // Move receiver and key to rdx and rcx, swapping if necessary. |
| 708 if (receiver_.is(rdx)) { |
| 709 if (!key_.is(rcx)) { |
| 710 __ movq(rcx, key_); |
| 711 } // Else everything is already in the right place. |
| 712 } else if (receiver_.is(rcx)) { |
| 713 if (key_.is(rdx)) { |
| 714 __ xchg(rcx, rdx); |
| 715 } else if (key_.is(rcx)) { |
| 716 __ movq(rdx, receiver_); |
| 717 } else { |
| 718 __ movq(rdx, receiver_); |
| 719 __ movq(rcx, key_); |
| 720 } |
| 721 } else if (key_.is(rcx)) { |
| 722 __ movq(rdx, receiver_); |
| 723 } else { |
| 724 __ movq(rcx, key_); |
| 725 __ movq(rdx, receiver_); |
| 726 } |
| 727 |
688 // Call the IC stub. | 728 // Call the IC stub. |
689 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); | 729 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Initialize)); |
690 __ Call(ic, RelocInfo::CODE_TARGET); | 730 __ Call(ic, RelocInfo::CODE_TARGET); |
691 // The delta from the start of the map-compare instructions (initial movq) | 731 // The delta from the start of the map-compare instructions (initial movq) |
692 // to the test instruction. We use masm_-> directly here instead of the | 732 // to the test instruction. We use masm_-> directly here instead of the |
693 // __ macro because the macro sometimes uses macro expansion to turn | 733 // __ macro because the macro sometimes uses macro expansion to turn |
694 // into something that can't return a value. This is encountered | 734 // into something that can't return a value. This is encountered |
695 // when doing generated code coverage tests. | 735 // when doing generated code coverage tests. |
696 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); | 736 int delta_to_patch_site = masm_->SizeOfCodeGeneratedSince(patch_site()); |
697 // Here we use masm_-> instead of the __ macro because this is the | 737 // Here we use masm_-> instead of the __ macro because this is the |
698 // instruction that gets patched and coverage code gets in the way. | 738 // instruction that gets patched and coverage code gets in the way. |
699 masm_->testl(rax, Immediate(-delta_to_patch_site)); | 739 masm_->testl(rax, Immediate(-delta_to_patch_site)); |
700 // Restore value (returned from store IC), key and receiver | 740 // Restore value (returned from store IC). |
701 // registers. | |
702 if (!value_.is(rax)) __ movq(value_, rax); | 741 if (!value_.is(rax)) __ movq(value_, rax); |
703 __ pop(key_); | |
704 __ pop(receiver_); | |
705 } | 742 } |
706 | 743 |
707 | 744 |
708 void CodeGenerator::CallApplyLazy(Expression* applicand, | 745 void CodeGenerator::CallApplyLazy(Expression* applicand, |
709 Expression* receiver, | 746 Expression* receiver, |
710 VariableProxy* arguments, | 747 VariableProxy* arguments, |
711 int position) { | 748 int position) { |
712 // An optimized implementation of expressions of the form | 749 // An optimized implementation of expressions of the form |
713 // x.apply(y, arguments). | 750 // x.apply(y, arguments). |
714 // If the arguments object of the scope has not been allocated, | 751 // If the arguments object of the scope has not been allocated, |
(...skipping 6811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7526 masm->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); | 7563 masm->SmiToIndex(kScratchRegister, key.reg(), kPointerSizeLog2); |
7527 __ movq(Operand(tmp.reg(), | 7564 __ movq(Operand(tmp.reg(), |
7528 index.reg, | 7565 index.reg, |
7529 index.scale, | 7566 index.scale, |
7530 FixedArray::kHeaderSize - kHeapObjectTag), | 7567 FixedArray::kHeaderSize - kHeapObjectTag), |
7531 value.reg()); | 7568 value.reg()); |
7532 __ IncrementCounter(&Counters::keyed_store_inline, 1); | 7569 __ IncrementCounter(&Counters::keyed_store_inline, 1); |
7533 | 7570 |
7534 deferred->BindExit(); | 7571 deferred->BindExit(); |
7535 | 7572 |
7536 cgen_->frame()->Push(&receiver); | |
7537 cgen_->frame()->Push(&key); | |
7538 cgen_->frame()->Push(&value); | 7573 cgen_->frame()->Push(&value); |
7539 } else { | 7574 } else { |
7540 Result answer = cgen_->frame()->CallKeyedStoreIC(); | 7575 Result answer = cgen_->frame()->CallKeyedStoreIC(); |
7541 // Make sure that we do not have a test instruction after the | 7576 // Make sure that we do not have a test instruction after the |
7542 // call. A test instruction after the call is used to | 7577 // call. A test instruction after the call is used to |
7543 // indicate that we have generated an inline version of the | 7578 // indicate that we have generated an inline version of the |
7544 // keyed store. | 7579 // keyed store. |
7545 masm->nop(); | 7580 masm->nop(); |
7546 cgen_->frame()->Push(&answer); | 7581 cgen_->frame()->Push(&answer); |
7547 } | 7582 } |
7548 cgen_->UnloadReference(this); | 7583 set_unloaded(); |
7549 break; | 7584 break; |
7550 } | 7585 } |
7551 | 7586 |
7552 default: | 7587 default: |
7553 UNREACHABLE(); | 7588 UNREACHABLE(); |
7554 } | 7589 } |
7555 } | 7590 } |
7556 | 7591 |
7557 | 7592 |
7558 void FastNewClosureStub::Generate(MacroAssembler* masm) { | 7593 void FastNewClosureStub::Generate(MacroAssembler* masm) { |
(...skipping 4035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11594 } | 11629 } |
11595 | 11630 |
11596 #endif | 11631 #endif |
11597 | 11632 |
11598 | 11633 |
11599 #undef __ | 11634 #undef __ |
11600 | 11635 |
11601 } } // namespace v8::internal | 11636 } } // namespace v8::internal |
11602 | 11637 |
11603 #endif // V8_TARGET_ARCH_X64 | 11638 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |