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