Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 8166017: Track elements_kind transitions in KeyedStoreICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: fix nits Created 9 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/stub-cache.cc ('k') | test/mjsunit/element-kind.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 2589 matching lines...) Expand 10 before | Expand all | Expand 10 after
2600 DO_SMI_CHECK); 2600 DO_SMI_CHECK);
2601 2601
2602 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2602 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2603 __ jmp(ic, RelocInfo::CODE_TARGET); 2603 __ jmp(ic, RelocInfo::CODE_TARGET);
2604 2604
2605 // Return the generated code. 2605 // Return the generated code.
2606 return GetCode(NORMAL, NULL); 2606 return GetCode(NORMAL, NULL);
2607 } 2607 }
2608 2608
2609 2609
2610 MaybeObject* KeyedStoreStubCompiler::CompileStoreElementWithTransition(
2611 Map* transitioned_map,
2612 Map* untransitioned_map_1,
2613 Map* untransitioned_map_2) {
2614 // ----------- S t a t e -------------
2615 // -- rax : value
2616 // -- rcx : key
2617 // -- rdx : receiver
2618 // -- rsp[0] : return address
2619 // -----------------------------------
2620
2621 // The order of map occurrences in the generated code below is important.
2622 // Both IC code and Crankshaft rely on |transitioned_map| being the first
2623 // map in the stub.
2624
2625 Code* notransition_stub;
2626 ElementsKind elements_kind = transitioned_map->elements_kind();
2627 bool is_js_array = transitioned_map->instance_type() == JS_ARRAY_TYPE;
2628 MaybeObject* maybe_stub =
2629 KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
2630 if (!maybe_stub->To(&notransition_stub)) return maybe_stub;
2631
2632 Label just_store, miss;
2633 __ JumpIfSmi(rdx, &miss, Label::kNear);
2634 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
2635 // rbx: receiver->map().
2636 __ Cmp(rbx, Handle<Map>(transitioned_map));
2637 __ j(equal, &just_store);
2638 ASSERT_NE(untransitioned_map_1, NULL);
2639 __ Cmp(rbx, Handle<Map>(untransitioned_map_1));
2640 Code* generic_stub = (strict_mode_ == kStrictMode)
2641 ? isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic_Strict)
2642 : isolate()->builtins()->builtin(Builtins::kKeyedStoreIC_Generic);
2643 __ j(equal, Handle<Code>(generic_stub), RelocInfo::CODE_TARGET);
2644 if (untransitioned_map_2 != NULL) {
2645 __ Cmp(rbx, Handle<Map>(untransitioned_map_2));
2646 __ j(equal, Handle<Code>(generic_stub), RelocInfo::CODE_TARGET);
2647 }
2648 __ bind(&miss);
2649 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2650 __ jmp(ic, RelocInfo::CODE_TARGET);
2651
2652 __ bind(&just_store);
2653 __ jmp(Handle<Code>(notransition_stub), RelocInfo::CODE_TARGET);
2654
2655 // Return the generated code.
2656 return GetCode(NORMAL, NULL, MEGAMORPHIC);
2657 }
2658
2659
2610 MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic( 2660 MaybeObject* KeyedStoreStubCompiler::CompileStoreMegamorphic(
2611 MapList* receiver_maps, 2661 MapList* receiver_maps,
2612 CodeList* handler_ics) { 2662 CodeList* handler_ics) {
2613 // ----------- S t a t e ------------- 2663 // ----------- S t a t e -------------
2614 // -- rax : value 2664 // -- rax : value
2615 // -- rcx : key 2665 // -- rcx : key
2616 // -- rdx : receiver 2666 // -- rdx : receiver
2617 // -- rsp[0] : return address 2667 // -- rsp[0] : return address
2618 // ----------------------------------- 2668 // -----------------------------------
2619 Label miss; 2669 Label miss;
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
3691 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3741 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3692 MacroAssembler* masm, 3742 MacroAssembler* masm,
3693 bool is_js_array, 3743 bool is_js_array,
3694 ElementsKind elements_kind) { 3744 ElementsKind elements_kind) {
3695 // ----------- S t a t e ------------- 3745 // ----------- S t a t e -------------
3696 // -- rax : value 3746 // -- rax : value
3697 // -- rcx : key 3747 // -- rcx : key
3698 // -- rdx : receiver 3748 // -- rdx : receiver
3699 // -- rsp[0] : return address 3749 // -- rsp[0] : return address
3700 // ----------------------------------- 3750 // -----------------------------------
3701 Label miss_force_generic; 3751 Label miss_force_generic, transition_elements_kind;
3702 3752
3703 // This stub is meant to be tail-jumped to, the receiver must already 3753 // This stub is meant to be tail-jumped to, the receiver must already
3704 // have been verified by the caller to not be a smi. 3754 // have been verified by the caller to not be a smi.
3705 3755
3706 // Check that the key is a smi. 3756 // Check that the key is a smi.
3707 __ JumpIfNotSmi(rcx, &miss_force_generic); 3757 __ JumpIfNotSmi(rcx, &miss_force_generic);
3708 3758
3709 // Get the elements array and make sure it is a fast element array, not 'cow'. 3759 // Get the elements array and make sure it is a fast element array, not 'cow'.
3710 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); 3760 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset));
3711 __ CompareRoot(FieldOperand(rdi, HeapObject::kMapOffset), 3761 __ CompareRoot(FieldOperand(rdi, HeapObject::kMapOffset),
3712 Heap::kFixedArrayMapRootIndex); 3762 Heap::kFixedArrayMapRootIndex);
3713 __ j(not_equal, &miss_force_generic); 3763 __ j(not_equal, &miss_force_generic);
3714 3764
3715 // Check that the key is within bounds. 3765 // Check that the key is within bounds.
3716 if (is_js_array) { 3766 if (is_js_array) {
3717 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); 3767 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset));
3718 __ j(above_equal, &miss_force_generic); 3768 __ j(above_equal, &miss_force_generic);
3719 } else { 3769 } else {
3720 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 3770 __ SmiCompare(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
3721 __ j(above_equal, &miss_force_generic); 3771 __ j(above_equal, &miss_force_generic);
3722 } 3772 }
3723 3773
3724 // Do the store and update the write barrier.
3725 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) { 3774 if (elements_kind == FAST_SMI_ONLY_ELEMENTS) {
3726 __ JumpIfNotSmi(rax, &miss_force_generic); 3775 __ JumpIfNotSmi(rax, &transition_elements_kind);
3727 __ SmiToInteger32(rcx, rcx); 3776 __ SmiToInteger32(rcx, rcx);
3728 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize), 3777 __ movq(FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize),
3729 rax); 3778 rax);
3730 } else { 3779 } else {
3780 // Do the store and update the write barrier.
3731 ASSERT(elements_kind == FAST_ELEMENTS); 3781 ASSERT(elements_kind == FAST_ELEMENTS);
3732 __ SmiToInteger32(rcx, rcx); 3782 __ SmiToInteger32(rcx, rcx);
3733 __ lea(rcx, 3783 __ lea(rcx,
3734 FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize)); 3784 FieldOperand(rdi, rcx, times_pointer_size, FixedArray::kHeaderSize));
3735 __ movq(Operand(rcx, 0), rax); 3785 __ movq(Operand(rcx, 0), rax);
3736 // Make sure to preserve the value in register rax. 3786 // Make sure to preserve the value in register rax.
3737 __ movq(rdx, rax); 3787 __ movq(rdx, rax);
3738 __ RecordWrite(rdi, rcx, rdx, kDontSaveFPRegs); 3788 __ RecordWrite(rdi, rcx, rdx, kDontSaveFPRegs);
3739 } 3789 }
3740 3790
3741 // Done. 3791 // Done.
3742 __ ret(0); 3792 __ ret(0);
3743 3793
3744 // Handle store cache miss. 3794 // Handle store cache miss.
3745 __ bind(&miss_force_generic); 3795 __ bind(&miss_force_generic);
3746 Handle<Code> ic_force_generic = 3796 Handle<Code> ic_force_generic =
3747 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3797 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3748 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3798 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3799
3800 __ bind(&transition_elements_kind);
3801 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
3802 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3749 } 3803 }
3750 3804
3751 3805
3752 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( 3806 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3753 MacroAssembler* masm, 3807 MacroAssembler* masm,
3754 bool is_js_array) { 3808 bool is_js_array) {
3755 // ----------- S t a t e ------------- 3809 // ----------- S t a t e -------------
3756 // -- rax : value 3810 // -- rax : value
3757 // -- rcx : key 3811 // -- rcx : key
3758 // -- rdx : receiver 3812 // -- rdx : receiver
3759 // -- rsp[0] : return address 3813 // -- rsp[0] : return address
3760 // ----------------------------------- 3814 // -----------------------------------
3761 Label miss_force_generic; 3815 Label miss_force_generic, transition_elements_kind;
3762 3816
3763 // This stub is meant to be tail-jumped to, the receiver must already 3817 // This stub is meant to be tail-jumped to, the receiver must already
3764 // have been verified by the caller to not be a smi. 3818 // have been verified by the caller to not be a smi.
3765 3819
3766 // Check that the key is a smi. 3820 // Check that the key is a smi.
3767 __ JumpIfNotSmi(rcx, &miss_force_generic); 3821 __ JumpIfNotSmi(rcx, &miss_force_generic);
3768 3822
3769 // Get the elements array. 3823 // Get the elements array.
3770 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset)); 3824 __ movq(rdi, FieldOperand(rdx, JSObject::kElementsOffset));
3771 __ AssertFastElements(rdi); 3825 __ AssertFastElements(rdi);
3772 3826
3773 // Check that the key is within bounds. 3827 // Check that the key is within bounds.
3774 if (is_js_array) { 3828 if (is_js_array) {
3775 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); 3829 __ SmiCompare(rcx, FieldOperand(rdx, JSArray::kLengthOffset));
3776 } else { 3830 } else {
3777 __ SmiCompare(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); 3831 __ SmiCompare(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset));
3778 } 3832 }
3779 __ j(above_equal, &miss_force_generic); 3833 __ j(above_equal, &miss_force_generic);
3780 3834
3781 // Handle smi values specially 3835 // Handle smi values specially
3782 __ SmiToInteger32(rcx, rcx); 3836 __ SmiToInteger32(rcx, rcx);
3783 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0, &miss_force_generic); 3837 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0,
3838 &transition_elements_kind);
3784 __ ret(0); 3839 __ ret(0);
3785 3840
3786 // Handle store cache miss, replacing the ic with the generic stub. 3841 // Handle store cache miss, replacing the ic with the generic stub.
3787 __ bind(&miss_force_generic); 3842 __ bind(&miss_force_generic);
3788 Handle<Code> ic_force_generic = 3843 Handle<Code> ic_force_generic =
3789 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric(); 3844 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3790 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET); 3845 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3846
3847 __ bind(&transition_elements_kind);
3848 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss();
3849 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3791 } 3850 }
3792 3851
3793 3852
3794 #undef __ 3853 #undef __
3795 3854
3796 } } // namespace v8::internal 3855 } } // namespace v8::internal
3797 3856
3798 #endif // V8_TARGET_ARCH_X64 3857 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/stub-cache.cc ('k') | test/mjsunit/element-kind.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698