| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "src/codegen.h" | 9 #include "src/codegen.h" |
| 10 #include "src/ic/ic.h" | 10 #include "src/ic/ic.h" |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 667 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, | 667 __ LoadTransitionedArrayMapConditional(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS, |
| 668 ebx, edi, slow); | 668 ebx, edi, slow); |
| 669 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); | 669 mode = AllocationSite::GetMode(FAST_DOUBLE_ELEMENTS, FAST_ELEMENTS); |
| 670 ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key, | 670 ElementsTransitionGenerator::GenerateDoubleToObject(masm, receiver, key, |
| 671 value, ebx, mode, slow); | 671 value, ebx, mode, slow); |
| 672 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); | 672 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); |
| 673 __ jmp(&finish_object_store); | 673 __ jmp(&finish_object_store); |
| 674 } | 674 } |
| 675 | 675 |
| 676 | 676 |
| 677 void KeyedStoreIC::GenerateGeneric(MacroAssembler* masm, | 677 void KeyedStoreIC::GenerateGeneric( |
| 678 StrictMode strict_mode) { | 678 MacroAssembler* masm, StrictMode strict_mode, |
| 679 KeyedStoreStubCacheRequirement handler_requirement) { |
| 679 // Return address is on the stack. | 680 // Return address is on the stack. |
| 680 Label slow, fast_object, fast_object_grow; | 681 Label slow, fast_object, fast_object_grow; |
| 681 Label fast_double, fast_double_grow; | 682 Label fast_double, fast_double_grow; |
| 682 Label array, extra, check_if_double_array; | 683 Label array, extra, check_if_double_array, maybe_name_key, miss; |
| 683 Register receiver = StoreDescriptor::ReceiverRegister(); | 684 Register receiver = StoreDescriptor::ReceiverRegister(); |
| 684 Register key = StoreDescriptor::NameRegister(); | 685 Register key = StoreDescriptor::NameRegister(); |
| 685 DCHECK(receiver.is(edx)); | 686 DCHECK(receiver.is(edx)); |
| 686 DCHECK(key.is(ecx)); | 687 DCHECK(key.is(ecx)); |
| 687 | 688 |
| 688 // Check that the object isn't a smi. | 689 // Check that the object isn't a smi. |
| 689 __ JumpIfSmi(receiver, &slow); | 690 __ JumpIfSmi(receiver, &slow); |
| 690 // Get the map from the receiver. | 691 // Get the map from the receiver. |
| 691 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); | 692 __ mov(edi, FieldOperand(receiver, HeapObject::kMapOffset)); |
| 692 // Check that the receiver does not require access checks and is not observed. | 693 // Check that the receiver does not require access checks and is not observed. |
| 693 // The generic stub does not perform map checks or handle observed objects. | 694 // The generic stub does not perform map checks or handle observed objects. |
| 694 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), | 695 __ test_b(FieldOperand(edi, Map::kBitFieldOffset), |
| 695 1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved); | 696 1 << Map::kIsAccessCheckNeeded | 1 << Map::kIsObserved); |
| 696 __ j(not_zero, &slow); | 697 __ j(not_zero, &slow); |
| 697 // Check that the key is a smi. | 698 // Check that the key is a smi. |
| 698 __ JumpIfNotSmi(key, &slow); | 699 __ JumpIfNotSmi(key, &maybe_name_key); |
| 699 __ CmpInstanceType(edi, JS_ARRAY_TYPE); | 700 __ CmpInstanceType(edi, JS_ARRAY_TYPE); |
| 700 __ j(equal, &array); | 701 __ j(equal, &array); |
| 701 // Check that the object is some kind of JSObject. | 702 // Check that the object is some kind of JSObject. |
| 702 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); | 703 __ CmpInstanceType(edi, FIRST_JS_OBJECT_TYPE); |
| 703 __ j(below, &slow); | 704 __ j(below, &slow); |
| 704 | 705 |
| 705 // Object case: Check key against length in the elements array. | 706 // Object case: Check key against length in the elements array. |
| 706 // Key is a smi. | 707 // Key is a smi. |
| 707 // edi: receiver map | 708 // edi: receiver map |
| 708 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); | 709 __ mov(ebx, FieldOperand(receiver, JSObject::kElementsOffset)); |
| 709 // Check array bounds. Both the key and the length of FixedArray are smis. | 710 // Check array bounds. Both the key and the length of FixedArray are smis. |
| 710 __ cmp(key, FieldOperand(ebx, FixedArray::kLengthOffset)); | 711 __ cmp(key, FieldOperand(ebx, FixedArray::kLengthOffset)); |
| 711 __ j(below, &fast_object); | 712 __ j(below, &fast_object); |
| 712 | 713 |
| 713 // Slow case: call runtime. | 714 // Slow case: call runtime. |
| 714 __ bind(&slow); | 715 __ bind(&slow); |
| 715 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); | 716 PropertyICCompiler::GenerateRuntimeSetProperty(masm, strict_mode); |
| 717 // Never returns to here. |
| 718 |
| 719 __ bind(&maybe_name_key); |
| 720 __ mov(ebx, FieldOperand(key, HeapObject::kMapOffset)); |
| 721 __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset)); |
| 722 __ JumpIfNotUniqueNameInstanceType(ebx, &slow); |
| 723 Code::Flags flags = Code::RemoveTypeAndHolderFromFlags( |
| 724 Code::ComputeHandlerFlags(Code::STORE_IC)); |
| 725 masm->isolate()->stub_cache()->GenerateProbe(masm, flags, false, receiver, |
| 726 key, ebx, no_reg); |
| 727 // Cache miss. |
| 728 if (handler_requirement == kCallRuntimeOnMissingHandler) { |
| 729 __ jmp(&slow); |
| 730 } else { |
| 731 DCHECK(handler_requirement == kMissOnMissingHandler); |
| 732 __ jmp(&miss); |
| 733 } |
| 716 | 734 |
| 717 // Extra capacity case: Check if there is extra capacity to | 735 // Extra capacity case: Check if there is extra capacity to |
| 718 // perform the store and update the length. Used for adding one | 736 // perform the store and update the length. Used for adding one |
| 719 // element to the array by writing to array[array.length]. | 737 // element to the array by writing to array[array.length]. |
| 720 __ bind(&extra); | 738 __ bind(&extra); |
| 721 // receiver is a JSArray. | 739 // receiver is a JSArray. |
| 722 // key is a smi. | 740 // key is a smi. |
| 723 // ebx: receiver->elements, a FixedArray | 741 // ebx: receiver->elements, a FixedArray |
| 724 // edi: receiver map | 742 // edi: receiver map |
| 725 // flags: compare (key, receiver.length()) | 743 // flags: compare (key, receiver.length()) |
| (...skipping 22 matching lines...) Expand all Loading... |
| 748 | 766 |
| 749 // Check the key against the length in the array and fall through to the | 767 // Check the key against the length in the array and fall through to the |
| 750 // common store code. | 768 // common store code. |
| 751 __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset)); // Compare smis. | 769 __ cmp(key, FieldOperand(receiver, JSArray::kLengthOffset)); // Compare smis. |
| 752 __ j(above_equal, &extra); | 770 __ j(above_equal, &extra); |
| 753 | 771 |
| 754 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, | 772 KeyedStoreGenerateGenericHelper(masm, &fast_object, &fast_double, &slow, |
| 755 kCheckMap, kDontIncrementLength); | 773 kCheckMap, kDontIncrementLength); |
| 756 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, | 774 KeyedStoreGenerateGenericHelper(masm, &fast_object_grow, &fast_double_grow, |
| 757 &slow, kDontCheckMap, kIncrementLength); | 775 &slow, kDontCheckMap, kIncrementLength); |
| 776 |
| 777 if (handler_requirement == kMissOnMissingHandler) { |
| 778 __ bind(&miss); |
| 779 GenerateMiss(masm); |
| 780 } |
| 758 } | 781 } |
| 759 | 782 |
| 760 | 783 |
| 761 void LoadIC::GenerateNormal(MacroAssembler* masm) { | 784 void LoadIC::GenerateNormal(MacroAssembler* masm) { |
| 762 Register dictionary = eax; | 785 Register dictionary = eax; |
| 763 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); | 786 DCHECK(!dictionary.is(LoadDescriptor::ReceiverRegister())); |
| 764 DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); | 787 DCHECK(!dictionary.is(LoadDescriptor::NameRegister())); |
| 765 | 788 |
| 766 Label slow; | 789 Label slow; |
| 767 | 790 |
| (...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 Condition cc = | 1000 Condition cc = |
| 978 (check == ENABLE_INLINED_SMI_CHECK) | 1001 (check == ENABLE_INLINED_SMI_CHECK) |
| 979 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) | 1002 ? (*jmp_address == Assembler::kJncShortOpcode ? not_zero : zero) |
| 980 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); | 1003 : (*jmp_address == Assembler::kJnzShortOpcode ? not_carry : carry); |
| 981 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); | 1004 *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc); |
| 982 } | 1005 } |
| 983 } | 1006 } |
| 984 } // namespace v8::internal | 1007 } // namespace v8::internal |
| 985 | 1008 |
| 986 #endif // V8_TARGET_ARCH_X87 | 1009 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |