| 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 |