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/ic-x64.cc

Issue 8054043: Porting r9456 to x64 (Optimize KeyedStoreGeneric for Smi arrays). (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: minor change. 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/ia32/ic-ia32.cc ('k') | src/x64/macro-assembler-x64.h » ('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 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
599 599
600 600
601 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, 601 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm,
602 StrictModeFlag strict_mode) { 602 StrictModeFlag strict_mode) {
603 // ----------- S t a t e ------------- 603 // ----------- S t a t e -------------
604 // -- rax : value 604 // -- rax : value
605 // -- rcx : key 605 // -- rcx : key
606 // -- rdx : receiver 606 // -- rdx : receiver
607 // -- rsp[0] : return address 607 // -- rsp[0] : return address
608 // ----------------------------------- 608 // -----------------------------------
609 Label slow, slow_with_tagged_index, fast, array, extra; 609 Label slow, slow_with_tagged_index, fast, array, extra, check_extra_double;
610 Label fast_object_with_map_check, fast_object_without_map_check;
611 Label fast_double_with_map_check, fast_double_without_map_check;
610 612
611 // Check that the object isn't a smi. 613 // Check that the object isn't a smi.
612 __ JumpIfSmi(rdx, &slow_with_tagged_index); 614 __ JumpIfSmi(rdx, &slow_with_tagged_index);
613 // Get the map from the receiver. 615 // Get the map from the receiver.
614 __ movq(rbx, FieldOperand(rdx, HeapObject::kMapOffset)); 616 __ movq(r9, FieldOperand(rdx, HeapObject::kMapOffset));
615 // Check that the receiver does not require access checks. We need 617 // Check that the receiver does not require access checks. We need
616 // to do this because this generic stub does not perform map checks. 618 // to do this because this generic stub does not perform map checks.
617 __ testb(FieldOperand(rbx, Map::kBitFieldOffset), 619 __ testb(FieldOperand(r9, Map::kBitFieldOffset),
618 Immediate(1 << Map::kIsAccessCheckNeeded)); 620 Immediate(1 << Map::kIsAccessCheckNeeded));
619 __ j(not_zero, &slow_with_tagged_index); 621 __ j(not_zero, &slow_with_tagged_index);
620 // Check that the key is a smi. 622 // Check that the key is a smi.
621 __ JumpIfNotSmi(rcx, &slow_with_tagged_index); 623 __ JumpIfNotSmi(rcx, &slow_with_tagged_index);
622 __ SmiToInteger32(rcx, rcx); 624 __ SmiToInteger32(rcx, rcx);
623 625
624 __ CmpInstanceType(rbx, JS_ARRAY_TYPE); 626 __ CmpInstanceType(r9, JS_ARRAY_TYPE);
625 __ j(equal, &array); 627 __ j(equal, &array);
626 // Check that the object is some kind of JSObject. 628 // Check that the object is some kind of JSObject.
627 __ CmpInstanceType(rbx, FIRST_JS_RECEIVER_TYPE); 629 __ CmpInstanceType(r9, FIRST_JS_RECEIVER_TYPE);
628 __ j(below, &slow); 630 __ j(below, &slow);
629 __ CmpInstanceType(rbx, JS_PROXY_TYPE); 631 __ CmpInstanceType(r9, JS_PROXY_TYPE);
630 __ j(equal, &slow); 632 __ j(equal, &slow);
631 __ CmpInstanceType(rbx, JS_FUNCTION_PROXY_TYPE); 633 __ CmpInstanceType(r9, JS_FUNCTION_PROXY_TYPE);
632 __ j(equal, &slow); 634 __ j(equal, &slow);
633 635
634 // Object case: Check key against length in the elements array. 636 // Object case: Check key against length in the elements array.
635 // rax: value 637 // rax: value
636 // rdx: JSObject 638 // rdx: JSObject
637 // rcx: index 639 // rcx: index
638 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 640 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
639 // Check that the object is in fast mode and writable. 641 // Check array bounds.
640 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
641 Heap::kFixedArrayMapRootIndex);
642 __ j(not_equal, &slow);
643 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 642 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
644 // rax: value 643 // rax: value
645 // rbx: FixedArray 644 // rbx: FixedArray
646 // rcx: index 645 // rcx: index
647 __ j(above, &fast); 646 __ j(above, &fast_object_with_map_check);
648 647
649 // Slow case: call runtime. 648 // Slow case: call runtime.
650 __ bind(&slow); 649 __ bind(&slow);
651 __ Integer32ToSmi(rcx, rcx); 650 __ Integer32ToSmi(rcx, rcx);
652 __ bind(&slow_with_tagged_index); 651 __ bind(&slow_with_tagged_index);
653 GenerateRuntimeSetProperty(masm, strict_mode); 652 GenerateRuntimeSetProperty(masm, strict_mode);
654 // Never returns to here. 653 // Never returns to here.
655 654
656 // Extra capacity case: Check if there is extra capacity to 655 // Extra capacity case: Check if there is extra capacity to
657 // perform the store and update the length. Used for adding one 656 // perform the store and update the length. Used for adding one
658 // element to the array by writing to array[array.length]. 657 // element to the array by writing to array[array.length].
659 __ bind(&extra); 658 __ bind(&extra);
660 // rax: value 659 // rax: value
661 // rdx: receiver (a JSArray) 660 // rdx: receiver (a JSArray)
662 // rbx: receiver's elements array (a FixedArray) 661 // rbx: receiver's elements array (a FixedArray)
663 // rcx: index 662 // rcx: index
664 // flags: smicompare (rdx.length(), rbx) 663 // flags: smicompare (rdx.length(), rbx)
665 __ j(not_equal, &slow); // do not leave holes in the array 664 __ j(not_equal, &slow); // do not leave holes in the array
666 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx); 665 __ SmiCompareInteger32(FieldOperand(rbx, FixedArray::kLengthOffset), rcx);
667 __ j(below_equal, &slow); 666 __ j(below_equal, &slow);
668 // Increment index to get new length. 667 // Increment index to get new length.
668 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
669 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
670 __ j(not_equal, &check_extra_double);
669 __ leal(rdi, Operand(rcx, 1)); 671 __ leal(rdi, Operand(rcx, 1));
670 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi); 672 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
671 __ jmp(&fast); 673 __ jmp(&fast_object_without_map_check);
674
675 __ bind(&check_extra_double);
676 // rdi: elements array's map
677 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
678 __ j(not_equal, &slow);
679 __ leal(rdi, Operand(rcx, 1));
680 __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rdi);
681 __ jmp(&fast_double_without_map_check);
672 682
673 // Array case: Get the length and the elements array from the JS 683 // Array case: Get the length and the elements array from the JS
674 // array. Check that the array is in fast mode (and writable); if it 684 // array. Check that the array is in fast mode (and writable); if it
675 // is the length is always a smi. 685 // is the length is always a smi.
676 __ bind(&array); 686 __ bind(&array);
677 // rax: value 687 // rax: value
678 // rdx: receiver (a JSArray) 688 // rdx: receiver (a JSArray)
679 // rcx: index 689 // rcx: index
680 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset)); 690 __ movq(rbx, FieldOperand(rdx, JSObject::kElementsOffset));
681 __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset),
682 Heap::kFixedArrayMapRootIndex);
683 __ j(not_equal, &slow);
684 691
685 // Check the key against the length in the array, compute the 692 // Check the key against the length in the array, compute the
686 // address to store into and fall through to fast case. 693 // address to store into and fall through to fast case.
687 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx); 694 __ SmiCompareInteger32(FieldOperand(rdx, JSArray::kLengthOffset), rcx);
688 __ j(below_equal, &extra); 695 __ j(below_equal, &extra);
689 696
690 // Fast case: Do the store. 697 // Fast case: Do the store.
691 __ bind(&fast); 698 __ bind(&fast_object_with_map_check);
692 // rax: value 699 // rax: value
693 // rbx: receiver's elements array (a FixedArray) 700 // rbx: receiver's elements array (a FixedArray)
694 // rcx: index 701 // rcx: index
695 702 // rdx: receiver (a JSArray)
703 __ movq(rdi, FieldOperand(rbx, HeapObject::kMapOffset));
704 __ CompareRoot(rdi, Heap::kFixedArrayMapRootIndex);
705 __ j(not_equal, &fast_double_with_map_check);
706 __ bind(&fast_object_without_map_check);
707 // Smi stores don't require further checks.
696 Label non_smi_value; 708 Label non_smi_value;
697 __ JumpIfNotSmi(rax, &non_smi_value); 709 __ JumpIfNotSmi(rax, &non_smi_value);
698 // It's irrelevant whether array is smi-only or not when writing a smi. 710 // It's irrelevant whether array is smi-only or not when writing a smi.
699 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize), 711 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
700 rax); 712 rax);
701 __ ret(0); 713 __ ret(0);
702 714
703 __ bind(&non_smi_value); 715 __ bind(&non_smi_value);
704 if (FLAG_smi_only_arrays) { 716 if (FLAG_smi_only_arrays) {
705 // Writing a non-smi, check whether array allows non-smi elements. 717 // Writing a non-smi, check whether array allows non-smi elements.
706 __ movq(rdi, FieldOperand(rdx, HeapObject::kMapOffset)); 718 // r9: receiver's map
707 __ CheckFastObjectElements(rdi, &slow, Label::kNear); 719 __ CheckFastObjectElements(r9, &slow, Label::kNear);
708 } 720 }
709 __ movq(FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize),
710 rax);
711 __ movq(rdx, rax);
712 __ lea(rcx, 721 __ lea(rcx,
713 FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize)); 722 FieldOperand(rbx, rcx, times_pointer_size, FixedArray::kHeaderSize));
723 __ movq(Operand(rcx, 0), rax);
724 __ movq(rdx, rax);
714 __ RecordWrite( 725 __ RecordWrite(
715 rbx, rcx, rdx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK); 726 rbx, rcx, rdx, kDontSaveFPRegs, EMIT_REMEMBERED_SET, OMIT_SMI_CHECK);
716 __ ret(0); 727 __ ret(0);
728
729 __ bind(&fast_double_with_map_check);
730 // Check for fast double array case. If this fails, call through to the
731 // runtime.
732 // rdi: elements array's map
733 __ CompareRoot(rdi, Heap::kFixedDoubleArrayMapRootIndex);
734 __ j(not_equal, &slow);
735 __ bind(&fast_double_without_map_check);
736 // If the value is a number, store it as a double in the FastDoubleElements
737 // array.
738 __ StoreNumberToDoubleElements(rax, rbx, rcx, xmm0, &slow);
739 __ ret(0);
717 } 740 }
718 741
719 742
720 // The generated code does not accept smi keys. 743 // The generated code does not accept smi keys.
721 // The generated code falls through if both probes miss. 744 // The generated code falls through if both probes miss.
722 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm, 745 static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
723 int argc, 746 int argc,
724 Code::Kind kind, 747 Code::Kind kind,
725 Code::ExtraICState extra_ic_state) { 748 Code::ExtraICState extra_ic_state) {
726 // ----------- S t a t e ------------- 749 // ----------- S t a t e -------------
(...skipping 953 matching lines...) Expand 10 before | Expand all | Expand 10 after
1680 Condition cc = *jmp_address == Assembler::kJncShortOpcode 1703 Condition cc = *jmp_address == Assembler::kJncShortOpcode
1681 ? not_zero 1704 ? not_zero
1682 : zero; 1705 : zero;
1683 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); 1706 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
1684 } 1707 }
1685 1708
1686 1709
1687 } } // namespace v8::internal 1710 } } // namespace v8::internal
1688 1711
1689 #endif // V8_TARGET_ARCH_X64 1712 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/ia32/ic-ia32.cc ('k') | src/x64/macro-assembler-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698