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