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 |