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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/ic-inl.h" | 10 #include "src/ic-inl.h" |
(...skipping 600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 Register receiver_reg, | 611 Register receiver_reg, |
612 Register name_reg, | 612 Register name_reg, |
613 Register value_reg, | 613 Register value_reg, |
614 Register scratch1, | 614 Register scratch1, |
615 Register scratch2, | 615 Register scratch2, |
616 Label* miss_label) { | 616 Label* miss_label) { |
617 // Stub never generated for non-global objects that require access | 617 // Stub never generated for non-global objects that require access |
618 // checks. | 618 // checks. |
619 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 619 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
620 | 620 |
621 FieldIndex index = lookup->GetFieldIndex(); | 621 int index = lookup->GetFieldIndex().field_index(); |
| 622 |
| 623 // Adjust for the number of properties stored in the object. Even in the |
| 624 // face of a transition we can use the old map here because the size of the |
| 625 // object and the number of in-object properties is not going to change. |
| 626 index -= object->map()->inobject_properties(); |
622 | 627 |
623 Representation representation = lookup->representation(); | 628 Representation representation = lookup->representation(); |
624 ASSERT(!representation.IsNone()); | 629 ASSERT(!representation.IsNone()); |
625 if (representation.IsSmi()) { | 630 if (representation.IsSmi()) { |
626 __ JumpIfNotSmi(value_reg, miss_label); | 631 __ JumpIfNotSmi(value_reg, miss_label); |
627 } else if (representation.IsHeapObject()) { | 632 } else if (representation.IsHeapObject()) { |
628 __ JumpIfSmi(value_reg, miss_label); | 633 __ JumpIfSmi(value_reg, miss_label); |
629 HeapType* field_type = lookup->GetFieldType(); | 634 HeapType* field_type = lookup->GetFieldType(); |
630 HeapType::Iterator<Map> it = field_type->Classes(); | 635 HeapType::Iterator<Map> it = field_type->Classes(); |
631 if (!it.Done()) { | 636 if (!it.Done()) { |
632 Label do_store; | 637 Label do_store; |
633 while (true) { | 638 while (true) { |
634 __ CompareMap(value_reg, it.Current()); | 639 __ CompareMap(value_reg, it.Current()); |
635 it.Advance(); | 640 it.Advance(); |
636 if (it.Done()) { | 641 if (it.Done()) { |
637 __ j(not_equal, miss_label); | 642 __ j(not_equal, miss_label); |
638 break; | 643 break; |
639 } | 644 } |
640 __ j(equal, &do_store, Label::kNear); | 645 __ j(equal, &do_store, Label::kNear); |
641 } | 646 } |
642 __ bind(&do_store); | 647 __ bind(&do_store); |
643 } | 648 } |
644 } else if (representation.IsDouble()) { | 649 } else if (representation.IsDouble()) { |
645 // Load the double storage. | 650 // Load the double storage. |
646 if (index.is_inobject()) { | 651 if (index < 0) { |
647 __ movp(scratch1, FieldOperand(receiver_reg, index.offset())); | 652 int offset = object->map()->instance_size() + (index * kPointerSize); |
| 653 __ movp(scratch1, FieldOperand(receiver_reg, offset)); |
648 } else { | 654 } else { |
649 __ movp(scratch1, | 655 __ movp(scratch1, |
650 FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 656 FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
651 __ movp(scratch1, FieldOperand(scratch1, index.offset())); | 657 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
| 658 __ movp(scratch1, FieldOperand(scratch1, offset)); |
652 } | 659 } |
653 | 660 |
654 // Store the value into the storage. | 661 // Store the value into the storage. |
655 Label do_store, heap_number; | 662 Label do_store, heap_number; |
656 __ JumpIfNotSmi(value_reg, &heap_number); | 663 __ JumpIfNotSmi(value_reg, &heap_number); |
657 __ SmiToInteger32(scratch2, value_reg); | 664 __ SmiToInteger32(scratch2, value_reg); |
658 __ Cvtlsi2sd(xmm0, scratch2); | 665 __ Cvtlsi2sd(xmm0, scratch2); |
659 __ jmp(&do_store); | 666 __ jmp(&do_store); |
660 | 667 |
661 __ bind(&heap_number); | 668 __ bind(&heap_number); |
662 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), | 669 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(), |
663 miss_label, DONT_DO_SMI_CHECK); | 670 miss_label, DONT_DO_SMI_CHECK); |
664 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); | 671 __ movsd(xmm0, FieldOperand(value_reg, HeapNumber::kValueOffset)); |
665 __ bind(&do_store); | 672 __ bind(&do_store); |
666 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); | 673 __ movsd(FieldOperand(scratch1, HeapNumber::kValueOffset), xmm0); |
667 // Return the value (register rax). | 674 // Return the value (register rax). |
668 ASSERT(value_reg.is(rax)); | 675 ASSERT(value_reg.is(rax)); |
669 __ ret(0); | 676 __ ret(0); |
670 return; | 677 return; |
671 } | 678 } |
672 | 679 |
673 // TODO(verwaest): Share this code as a code stub. | 680 // TODO(verwaest): Share this code as a code stub. |
674 SmiCheck smi_check = representation.IsTagged() | 681 SmiCheck smi_check = representation.IsTagged() |
675 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; | 682 ? INLINE_SMI_CHECK : OMIT_SMI_CHECK; |
676 if (index.is_inobject()) { | 683 if (index < 0) { |
677 // Set the property straight into the object. | 684 // Set the property straight into the object. |
678 __ movp(FieldOperand(receiver_reg, index.offset()), value_reg); | 685 int offset = object->map()->instance_size() + (index * kPointerSize); |
| 686 __ movp(FieldOperand(receiver_reg, offset), value_reg); |
679 | 687 |
680 if (!representation.IsSmi()) { | 688 if (!representation.IsSmi()) { |
681 // Update the write barrier for the array address. | 689 // Update the write barrier for the array address. |
682 // Pass the value being stored in the now unused name_reg. | 690 // Pass the value being stored in the now unused name_reg. |
683 __ movp(name_reg, value_reg); | 691 __ movp(name_reg, value_reg); |
684 __ RecordWriteField( | 692 __ RecordWriteField( |
685 receiver_reg, index.offset(), name_reg, scratch1, kDontSaveFPRegs, | 693 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs, |
686 EMIT_REMEMBERED_SET, smi_check); | 694 EMIT_REMEMBERED_SET, smi_check); |
687 } | 695 } |
688 } else { | 696 } else { |
689 // Write to the properties array. | 697 // Write to the properties array. |
| 698 int offset = index * kPointerSize + FixedArray::kHeaderSize; |
690 // Get the properties array (optimistically). | 699 // Get the properties array (optimistically). |
691 __ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 700 __ movp(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
692 __ movp(FieldOperand(scratch1, index.offset()), value_reg); | 701 __ movp(FieldOperand(scratch1, offset), value_reg); |
693 | 702 |
694 if (!representation.IsSmi()) { | 703 if (!representation.IsSmi()) { |
695 // Update the write barrier for the array address. | 704 // Update the write barrier for the array address. |
696 // Pass the value being stored in the now unused name_reg. | 705 // Pass the value being stored in the now unused name_reg. |
697 __ movp(name_reg, value_reg); | 706 __ movp(name_reg, value_reg); |
698 __ RecordWriteField( | 707 __ RecordWriteField( |
699 scratch1, index.offset(), name_reg, receiver_reg, kDontSaveFPRegs, | 708 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs, |
700 EMIT_REMEMBERED_SET, smi_check); | 709 EMIT_REMEMBERED_SET, smi_check); |
701 } | 710 } |
702 } | 711 } |
703 | 712 |
704 // Return the value (register rax). | 713 // Return the value (register rax). |
705 ASSERT(value_reg.is(rax)); | 714 ASSERT(value_reg.is(rax)); |
706 __ ret(0); | 715 __ ret(0); |
707 } | 716 } |
708 | 717 |
709 | 718 |
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
897 __ j(not_equal, &miss); | 906 __ j(not_equal, &miss); |
898 } | 907 } |
899 | 908 |
900 HandlerFrontendFooter(name, &miss); | 909 HandlerFrontendFooter(name, &miss); |
901 return reg; | 910 return reg; |
902 } | 911 } |
903 | 912 |
904 | 913 |
905 void LoadStubCompiler::GenerateLoadField(Register reg, | 914 void LoadStubCompiler::GenerateLoadField(Register reg, |
906 Handle<JSObject> holder, | 915 Handle<JSObject> holder, |
907 FieldIndex field, | 916 PropertyIndex field, |
908 Representation representation) { | 917 Representation representation) { |
909 if (!reg.is(receiver())) __ movp(receiver(), reg); | 918 if (!reg.is(receiver())) __ movp(receiver(), reg); |
910 if (kind() == Code::LOAD_IC) { | 919 if (kind() == Code::LOAD_IC) { |
911 LoadFieldStub stub(isolate(), field); | 920 LoadFieldStub stub(isolate(), |
| 921 field.is_inobject(holder), |
| 922 field.translate(holder), |
| 923 representation); |
912 GenerateTailCall(masm(), stub.GetCode()); | 924 GenerateTailCall(masm(), stub.GetCode()); |
913 } else { | 925 } else { |
914 KeyedLoadFieldStub stub(isolate(), field); | 926 KeyedLoadFieldStub stub(isolate(), |
| 927 field.is_inobject(holder), |
| 928 field.translate(holder), |
| 929 representation); |
915 GenerateTailCall(masm(), stub.GetCode()); | 930 GenerateTailCall(masm(), stub.GetCode()); |
916 } | 931 } |
917 } | 932 } |
918 | 933 |
919 | 934 |
920 void LoadStubCompiler::GenerateLoadCallback( | 935 void LoadStubCompiler::GenerateLoadCallback( |
921 Register reg, | 936 Register reg, |
922 Handle<ExecutableAccessorInfo> callback) { | 937 Handle<ExecutableAccessorInfo> callback) { |
923 // Insert additional parameters into the stack frame above return address. | 938 // Insert additional parameters into the stack frame above return address. |
924 ASSERT(!scratch4().is(reg)); | 939 ASSERT(!scratch4().is(reg)); |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1427 // ----------------------------------- | 1442 // ----------------------------------- |
1428 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1443 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
1429 } | 1444 } |
1430 | 1445 |
1431 | 1446 |
1432 #undef __ | 1447 #undef __ |
1433 | 1448 |
1434 } } // namespace v8::internal | 1449 } } // namespace v8::internal |
1435 | 1450 |
1436 #endif // V8_TARGET_ARCH_X64 | 1451 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |