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