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