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/ic-inl.h" | 9 #include "src/ic-inl.h" |
10 #include "src/codegen.h" | 10 #include "src/codegen.h" |
(...skipping 643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 Register receiver_reg, | 654 Register receiver_reg, |
655 Register name_reg, | 655 Register name_reg, |
656 Register value_reg, | 656 Register value_reg, |
657 Register scratch1, | 657 Register scratch1, |
658 Register scratch2, | 658 Register scratch2, |
659 Label* miss_label) { | 659 Label* miss_label) { |
660 // Stub never generated for non-global objects that require access | 660 // Stub never generated for non-global objects that require access |
661 // checks. | 661 // checks. |
662 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 662 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
663 | 663 |
664 int index = lookup->GetFieldIndex().field_index(); | 664 FieldIndex index = lookup->GetFieldIndex(); |
665 | |
666 // Adjust for the number of properties stored in the object. Even in the | |
667 // face of a transition we can use the old map here because the size of the | |
668 // object and the number of in-object properties is not going to change. | |
669 index -= object->map()->inobject_properties(); | |
670 | 665 |
671 Representation representation = lookup->representation(); | 666 Representation representation = lookup->representation(); |
672 ASSERT(!representation.IsNone()); | 667 ASSERT(!representation.IsNone()); |
673 if (representation.IsSmi()) { | 668 if (representation.IsSmi()) { |
674 __ JumpIfNotSmi(value_reg, miss_label); | 669 __ JumpIfNotSmi(value_reg, miss_label); |
675 } else if (representation.IsHeapObject()) { | 670 } else if (representation.IsHeapObject()) { |
676 __ JumpIfSmi(value_reg, miss_label); | 671 __ JumpIfSmi(value_reg, miss_label); |
677 HeapType* field_type = lookup->GetFieldType(); | 672 HeapType* field_type = lookup->GetFieldType(); |
678 HeapType::Iterator<Map> it = field_type->Classes(); | 673 HeapType::Iterator<Map> it = field_type->Classes(); |
679 if (!it.Done()) { | 674 if (!it.Done()) { |
680 Label do_store; | 675 Label do_store; |
681 while (true) { | 676 while (true) { |
682 __ CompareMap(value_reg, it.Current()); | 677 __ CompareMap(value_reg, it.Current()); |
683 it.Advance(); | 678 it.Advance(); |
684 if (it.Done()) { | 679 if (it.Done()) { |
685 __ j(not_equal, miss_label); | 680 __ j(not_equal, miss_label); |
686 break; | 681 break; |
687 } | 682 } |
688 __ j(equal, &do_store, Label::kNear); | 683 __ j(equal, &do_store, Label::kNear); |
689 } | 684 } |
690 __ bind(&do_store); | 685 __ bind(&do_store); |
691 } | 686 } |
692 } else if (representation.IsDouble()) { | 687 } else if (representation.IsDouble()) { |
693 // Load the double storage. | 688 // Load the double storage. |
694 if (index < 0) { | 689 if (index.is_inobject()) { |
695 int offset = object->map()->instance_size() + (index * kPointerSize); | 690 __ mov(scratch1, FieldOperand(receiver_reg, index.offset())); |
696 __ mov(scratch1, FieldOperand(receiver_reg, offset)); | |
697 } else { | 691 } else { |
698 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 692 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
699 int offset = index * kPointerSize + FixedArray::kHeaderSize; | 693 __ mov(scratch1, FieldOperand(scratch1, index.offset())); |
700 __ mov(scratch1, FieldOperand(scratch1, offset)); | |
701 } | 694 } |
702 | 695 |
703 // Store the value into the storage. | 696 // Store the value into the storage. |
704 Label do_store, heap_number; | 697 Label do_store, heap_number; |
705 __ JumpIfNotSmi(value_reg, &heap_number); | 698 __ JumpIfNotSmi(value_reg, &heap_number); |
706 __ SmiUntag(value_reg); | 699 __ SmiUntag(value_reg); |
707 __ Cvtsi2sd(xmm0, value_reg); | 700 __ Cvtsi2sd(xmm0, value_reg); |
708 __ SmiTag(value_reg); | 701 __ SmiTag(value_reg); |
709 __ jmp(&do_store); | 702 __ jmp(&do_store); |
710 __ bind(&heap_number); | 703 __ bind(&heap_number); |
711 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), | 704 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
712 miss_label, DONT_DO_SMI_CHECK); | 705 miss_label, DONT_DO_SMI_CHECK); |
713 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 706 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); |
714 __ bind(&do_store); | 707 __ bind(&do_store); |
715 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); | 708 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); |
716 // Return the value (register eax). | 709 // Return the value (register eax). |
717 ASSERT(value_reg.is(eax)); | 710 ASSERT(value_reg.is(eax)); |
718 __ ret(0); | 711 __ ret(0); |
719 return; | 712 return; |
720 } | 713 } |
721 | 714 |
722 ASSERT(!representation.IsDouble()); | 715 ASSERT(!representation.IsDouble()); |
723 // TODO(verwaest): Share this code as a code stub. | 716 // TODO(verwaest): Share this code as a code stub. |
724 SmiCheck smi_check = representation.IsTagged() | 717 SmiCheck smi_check = representation.IsTagged() |
725 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; | 718 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; |
726 if (index < 0) { | 719 if (index.is_inobject()) { |
727 // Set the property straight into the object. | 720 // Set the property straight into the object. |
728 int offset = object->map()->instance_size() + (index * kPointerSize); | 721 __ mov(FieldOperand(receiver_reg, index.offset()), value_reg); |
729 __ mov(FieldOperand(receiver_reg, offset), value_reg); | |
730 | 722 |
731 if (!representation.IsSmi()) { | 723 if (!representation.IsSmi()) { |
732 // Update the write barrier for the array address. | 724 // Update the write barrier for the array address. |
733 // Pass the value being stored in the now unused name_reg. | 725 // Pass the value being stored in the now unused name_reg. |
734 __ mov(name_reg, value_reg); | 726 __ mov(name_reg, value_reg); |
735 __ RecordWriteField(receiver_reg, | 727 __ RecordWriteField(receiver_reg, |
736 offset, | 728 index.offset(), |
737 name_reg, | 729 name_reg, |
738 scratch1, | 730 scratch1, |
739 kDontSaveFPRegs, | 731 kDontSaveFPRegs, |
740 EMIT_REMEMBERED_SET, | 732 EMIT_REMEMBERED_SET, |
741 smi_check); | 733 smi_check); |
742 } | 734 } |
743 } else { | 735 } else { |
744 // Write to the properties array. | 736 // Write to the properties array. |
745 int offset = index * kPointerSize + FixedArray::kHeaderSize; | |
746 // Get the properties array (optimistically). | 737 // Get the properties array (optimistically). |
747 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 738 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
748 __ mov(FieldOperand(scratch1, offset), value_reg); | 739 __ mov(FieldOperand(scratch1, index.offset()), value_reg); |
749 | 740 |
750 if (!representation.IsSmi()) { | 741 if (!representation.IsSmi()) { |
751 // Update the write barrier for the array address. | 742 // Update the write barrier for the array address. |
752 // Pass the value being stored in the now unused name_reg. | 743 // Pass the value being stored in the now unused name_reg. |
753 __ mov(name_reg, value_reg); | 744 __ mov(name_reg, value_reg); |
754 __ RecordWriteField(scratch1, | 745 __ RecordWriteField(scratch1, |
755 offset, | 746 index.offset(), |
756 name_reg, | 747 name_reg, |
757 receiver_reg, | 748 receiver_reg, |
758 kDontSaveFPRegs, | 749 kDontSaveFPRegs, |
759 EMIT_REMEMBERED_SET, | 750 EMIT_REMEMBERED_SET, |
760 smi_check); | 751 smi_check); |
761 } | 752 } |
762 } | 753 } |
763 | 754 |
764 // Return the value (register eax). | 755 // Return the value (register eax). |
765 ASSERT(value_reg.is(eax)); | 756 ASSERT(value_reg.is(eax)); |
(...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
965 __ j(not_equal, &miss); | 956 __ j(not_equal, &miss); |
966 } | 957 } |
967 | 958 |
968 HandlerFrontendFooter(name, &miss); | 959 HandlerFrontendFooter(name, &miss); |
969 return reg; | 960 return reg; |
970 } | 961 } |
971 | 962 |
972 | 963 |
973 void LoadStubCompiler::GenerateLoadField(Register reg, | 964 void LoadStubCompiler::GenerateLoadField(Register reg, |
974 Handle<JSObject> holder, | 965 Handle<JSObject> holder, |
975 PropertyIndex field, | 966 FieldIndex field, |
976 Representation representation) { | 967 Representation representation) { |
977 if (!reg.is(receiver())) __ mov(receiver(), reg); | 968 if (!reg.is(receiver())) __ mov(receiver(), reg); |
978 if (kind() == Code::LOAD_IC) { | 969 if (kind() == Code::LOAD_IC) { |
979 LoadFieldStub stub(isolate(), | 970 LoadFieldStub stub(isolate(), field); |
980 field.is_inobject(holder), | |
981 field.translate(holder), | |
982 representation); | |
983 GenerateTailCall(masm(), stub.GetCode()); | 971 GenerateTailCall(masm(), stub.GetCode()); |
984 } else { | 972 } else { |
985 KeyedLoadFieldStub stub(isolate(), | 973 KeyedLoadFieldStub stub(isolate(), field); |
986 field.is_inobject(holder), | |
987 field.translate(holder), | |
988 representation); | |
989 GenerateTailCall(masm(), stub.GetCode()); | 974 GenerateTailCall(masm(), stub.GetCode()); |
990 } | 975 } |
991 } | 976 } |
992 | 977 |
993 | 978 |
994 void LoadStubCompiler::GenerateLoadCallback( | 979 void LoadStubCompiler::GenerateLoadCallback( |
995 Register reg, | 980 Register reg, |
996 Handle<ExecutableAccessorInfo> callback) { | 981 Handle<ExecutableAccessorInfo> callback) { |
997 // Insert additional parameters into the stack frame above return address. | 982 // Insert additional parameters into the stack frame above return address. |
998 ASSERT(!scratch3().is(reg)); | 983 ASSERT(!scratch3().is(reg)); |
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1500 // ----------------------------------- | 1485 // ----------------------------------- |
1501 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1486 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
1502 } | 1487 } |
1503 | 1488 |
1504 | 1489 |
1505 #undef __ | 1490 #undef __ |
1506 | 1491 |
1507 } } // namespace v8::internal | 1492 } } // namespace v8::internal |
1508 | 1493 |
1509 #endif // V8_TARGET_ARCH_IA32 | 1494 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |