Chromium Code Reviews| 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 |