OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 693 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
704 __ mov(unmapped_location, eax); | 704 __ mov(unmapped_location, eax); |
705 __ lea(edi, unmapped_location); | 705 __ lea(edi, unmapped_location); |
706 __ mov(edx, eax); | 706 __ mov(edx, eax); |
707 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); | 707 __ RecordWrite(ebx, edi, edx, kDontSaveFPRegs); |
708 __ Ret(); | 708 __ Ret(); |
709 __ bind(&slow); | 709 __ bind(&slow); |
710 GenerateMiss(masm, MISS); | 710 GenerateMiss(masm, MISS); |
711 } | 711 } |
712 | 712 |
713 | 713 |
714 static void HasElementCallbacksInPrototypeChain( | |
danno
2013/10/23 12:22:11
This (and similar code in other implementations) b
mvstanton
2013/10/30 10:42:42
Done.
| |
715 MacroAssembler* masm, | |
716 Label* found) { | |
717 Factory* factory = masm->isolate()->factory(); | |
718 Label loop, not_found; | |
719 | |
720 // ebx contained elements pointer. | |
721 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); | |
722 | |
723 // Loop based on the map going up the prototype chain. | |
724 __ bind(&loop); | |
725 __ test(FieldOperand(ebx, Map::kBitField4Offset), | |
726 Immediate(Smi::FromInt(Map::HasElementCallbacks::kMask))); | |
727 __ j(not_zero, found); | |
728 | |
729 // Next map | |
730 __ mov(ebx, FieldOperand(ebx, Map::kPrototypeOffset)); | |
731 __ cmp(ebx, Immediate(factory->null_value())); | |
732 __ j(equal, ¬_found); | |
733 __ mov(ebx, FieldOperand(ebx, HeapObject::kMapOffset)); | |
734 __ jmp(&loop); | |
735 | |
736 // Restore ebx | |
737 __ bind(¬_found); | |
738 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | |
739 } | |
740 | |
741 | |
714 static void KeyedStoreGenerateGenericHelper( | 742 static void KeyedStoreGenerateGenericHelper( |
danno
2013/10/23 12:22:11
I wish *so* badly that we generaed this in Hydroge
mvstanton
2013/10/30 10:42:42
I've added this to the TODO list.
| |
715 MacroAssembler* masm, | 743 MacroAssembler* masm, |
716 Label* fast_object, | 744 Label* fast_object, |
717 Label* fast_double, | 745 Label* fast_double, |
718 Label* slow, | 746 Label* slow, |
719 KeyedStoreCheckMap check_map, | 747 KeyedStoreCheckMap check_map, |
720 KeyedStoreIncrementLength increment_length) { | 748 KeyedStoreIncrementLength increment_length) { |
721 Label transition_smi_elements; | 749 Label transition_smi_elements; |
722 Label finish_object_store, non_double_value, transition_double_elements; | 750 Label finish_object_store, non_double_value, transition_double_elements; |
723 Label fast_double_without_map_check; | 751 Label fast_double_without_map_check; |
724 // eax: value | 752 // eax: value |
725 // ecx: key (a smi) | 753 // ecx: key (a smi) |
726 // edx: receiver | 754 // edx: receiver |
727 // ebx: FixedArray receiver->elements | 755 // ebx: FixedArray receiver->elements |
728 // edi: receiver map | 756 // edi: receiver map |
729 // Fast case: Do the store, could either Object or double. | 757 // Fast case: Do the store, could either Object or double. |
730 __ bind(fast_object); | 758 __ bind(fast_object); |
731 if (check_map == kCheckMap) { | 759 if (check_map == kCheckMap) { |
732 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); | 760 __ mov(edi, FieldOperand(ebx, HeapObject::kMapOffset)); |
733 __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); | 761 __ cmp(edi, masm->isolate()->factory()->fixed_array_map()); |
734 __ j(not_equal, fast_double); | 762 __ j(not_equal, fast_double); |
735 } | 763 } |
764 | |
765 // HOLECHECK: guards "A[i] = V" | |
766 // We have to go to the runtime if the current value is undefined because | |
767 // there may be a callback on the element | |
768 Label holecheck_passed1; | |
769 __ cmp(CodeGenerator::FixedArrayElementOperand(ebx, ecx), | |
770 masm->isolate()->factory()->the_hole_value()); | |
771 __ j(not_equal, &holecheck_passed1); | |
772 HasElementCallbacksInPrototypeChain(masm, slow); | |
773 | |
774 __ bind(&holecheck_passed1); | |
775 | |
736 // Smi stores don't require further checks. | 776 // Smi stores don't require further checks. |
737 Label non_smi_value; | 777 Label non_smi_value; |
738 __ JumpIfNotSmi(eax, &non_smi_value); | 778 __ JumpIfNotSmi(eax, &non_smi_value); |
779 | |
danno
2013/10/23 12:22:11
nit: please remove the extraneous whitespace chang
mvstanton
2013/10/30 10:42:42
Done.
| |
739 if (increment_length == kIncrementLength) { | 780 if (increment_length == kIncrementLength) { |
740 // Add 1 to receiver->length. | 781 // Add 1 to receiver->length. |
741 __ add(FieldOperand(edx, JSArray::kLengthOffset), | 782 __ add(FieldOperand(edx, JSArray::kLengthOffset), |
742 Immediate(Smi::FromInt(1))); | 783 Immediate(Smi::FromInt(1))); |
743 } | 784 } |
744 // It's irrelevant whether array is smi-only or not when writing a smi. | 785 // It's irrelevant whether array is smi-only or not when writing a smi. |
745 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax); | 786 __ mov(CodeGenerator::FixedArrayElementOperand(ebx, ecx), eax); |
746 __ ret(0); | 787 __ ret(0); |
747 | 788 |
748 __ bind(&non_smi_value); | 789 __ bind(&non_smi_value); |
(...skipping 17 matching lines...) Expand all Loading... | |
766 | 807 |
767 __ bind(fast_double); | 808 __ bind(fast_double); |
768 if (check_map == kCheckMap) { | 809 if (check_map == kCheckMap) { |
769 // Check for fast double array case. If this fails, call through to the | 810 // Check for fast double array case. If this fails, call through to the |
770 // runtime. | 811 // runtime. |
771 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); | 812 __ cmp(edi, masm->isolate()->factory()->fixed_double_array_map()); |
772 __ j(not_equal, slow); | 813 __ j(not_equal, slow); |
773 // If the value is a number, store it as a double in the FastDoubleElements | 814 // If the value is a number, store it as a double in the FastDoubleElements |
774 // array. | 815 // array. |
775 } | 816 } |
817 | |
818 // HOLECHECK: guards "A[i] double hole?" | |
819 // We have to see if the double version of the hole is present. If so | |
820 // go to the runtime. | |
821 uint32_t offset = FixedDoubleArray::kHeaderSize + sizeof(kHoleNanLower32); | |
822 __ cmp(FieldOperand(ebx, ecx, times_4, offset), Immediate(kHoleNanUpper32)); | |
823 __ j(not_equal, &fast_double_without_map_check); | |
824 HasElementCallbacksInPrototypeChain(masm, slow); | |
825 | |
776 __ bind(&fast_double_without_map_check); | 826 __ bind(&fast_double_without_map_check); |
777 __ StoreNumberToDoubleElements(eax, ebx, ecx, edi, xmm0, | 827 __ StoreNumberToDoubleElements(eax, ebx, ecx, edi, xmm0, |
778 &transition_double_elements, false); | 828 &transition_double_elements, false); |
779 if (increment_length == kIncrementLength) { | 829 if (increment_length == kIncrementLength) { |
780 // Add 1 to receiver->length. | 830 // Add 1 to receiver->length. |
781 __ add(FieldOperand(edx, JSArray::kLengthOffset), | 831 __ add(FieldOperand(edx, JSArray::kLengthOffset), |
782 Immediate(Smi::FromInt(1))); | 832 Immediate(Smi::FromInt(1))); |
783 } | 833 } |
784 __ ret(0); | 834 __ ret(0); |
785 | 835 |
786 __ bind(&transition_smi_elements); | 836 __ bind(&transition_smi_elements); |
787 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); | 837 __ mov(ebx, FieldOperand(edx, HeapObject::kMapOffset)); |
788 | 838 |
789 // Transition the array appropriately depending on the value type. | 839 // Transition the array appropriately depending on the value type. |
790 __ CheckMap(eax, | 840 __ CheckMap(eax, |
791 masm->isolate()->factory()->heap_number_map(), | 841 masm->isolate()->factory()->heap_number_map(), |
792 &non_double_value, | 842 &non_double_value, |
793 DONT_DO_SMI_CHECK); | 843 DONT_DO_SMI_CHECK); |
794 | 844 |
795 // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS | 845 // Value is a double. Transition FAST_SMI_ELEMENTS -> FAST_DOUBLE_ELEMENTS |
796 // and complete the store. | 846 // and complete the store. |
847 | |
danno
2013/10/23 12:22:11
nit: please remove the extraneous whitespace chang
mvstanton
2013/10/30 10:42:42
Done.
| |
797 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, | 848 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, |
798 FAST_DOUBLE_ELEMENTS, | 849 FAST_DOUBLE_ELEMENTS, |
799 ebx, | 850 ebx, |
800 edi, | 851 edi, |
801 slow); | 852 slow); |
802 AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, | 853 AllocationSiteMode mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, |
803 FAST_DOUBLE_ELEMENTS); | 854 FAST_DOUBLE_ELEMENTS); |
804 ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow); | 855 ElementsTransitionGenerator::GenerateSmiToDouble(masm, mode, slow); |
805 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | 856 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
806 __ jmp(&fast_double_without_map_check); | 857 __ jmp(&fast_double_without_map_check); |
807 | 858 |
808 __ bind(&non_double_value); | 859 __ bind(&non_double_value); |
860 | |
danno
2013/10/23 12:22:11
nit: please remove the extraneous whitespace chang
mvstanton
2013/10/30 10:42:42
Done.
| |
809 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS | 861 // Value is not a double, FAST_SMI_ELEMENTS -> FAST_ELEMENTS |
810 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, | 862 __ LoadTransitionedArrayMapConditional(FAST_SMI_ELEMENTS, |
811 FAST_ELEMENTS, | 863 FAST_ELEMENTS, |
812 ebx, | 864 ebx, |
813 edi, | 865 edi, |
814 slow); | 866 slow); |
815 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); | 867 mode = AllocationSite::GetMode(FAST_SMI_ELEMENTS, FAST_ELEMENTS); |
816 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode, | 868 ElementsTransitionGenerator::GenerateMapChangeElementsTransition(masm, mode, |
817 slow); | 869 slow); |
818 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); | 870 __ mov(ebx, FieldOperand(edx, JSObject::kElementsOffset)); |
(...skipping 839 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1658 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) | 1710 Condition cc = (check == ENABLE_INLINED_SMI_CHECK) |
1659 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1711 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
1660 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1712 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
1661 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1713 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
1662 } | 1714 } |
1663 | 1715 |
1664 | 1716 |
1665 } } // namespace v8::internal | 1717 } } // namespace v8::internal |
1666 | 1718 |
1667 #endif // V8_TARGET_ARCH_IA32 | 1719 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |