Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 14063006: Disentangle field from transition stores. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ic.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 733 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 Immediate(the_hole)); 744 Immediate(the_hole));
745 } else { 745 } else {
746 __ cmp(Operand::Cell(cell), Immediate(the_hole)); 746 __ cmp(Operand::Cell(cell), Immediate(the_hole));
747 } 747 }
748 __ j(not_equal, miss); 748 __ j(not_equal, miss);
749 } 749 }
750 750
751 751
752 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 752 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
753 // but may be destroyed if store is successful. 753 // but may be destroyed if store is successful.
754 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 754 void StubCompiler::GenerateStoreTransition(MacroAssembler* masm,
755 Handle<JSObject> object, 755 Handle<JSObject> object,
756 LookupResult* lookup, 756 LookupResult* lookup,
757 Handle<Map> transition, 757 Handle<Map> transition,
758 Handle<Name> name, 758 Handle<Name> name,
759 Register receiver_reg, 759 Register receiver_reg,
760 Register name_reg, 760 Register name_reg,
761 Register value_reg, 761 Register value_reg,
762 Register scratch1, 762 Register scratch1,
763 Register scratch2, 763 Register scratch2,
764 Label* miss_label, 764 Label* miss_label,
765 Label* miss_restore_name) { 765 Label* miss_restore_name) {
766 // Check that the map of the object hasn't changed. 766 // Check that the map of the object hasn't changed.
767 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS
768 : REQUIRE_EXACT_MAP;
769 __ CheckMap(receiver_reg, Handle<Map>(object->map()), 767 __ CheckMap(receiver_reg, Handle<Map>(object->map()),
770 miss_label, DO_SMI_CHECK, mode); 768 miss_label, DO_SMI_CHECK, REQUIRE_EXACT_MAP);
771 769
772 // Perform global security token check if needed. 770 // Perform global security token check if needed.
773 if (object->IsJSGlobalProxy()) { 771 if (object->IsJSGlobalProxy()) {
774 __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label); 772 __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label);
775 } 773 }
776 774
777 // Check that we are allowed to write this. 775 // Check that we are allowed to write this.
778 if (!transition.is_null() && object->GetPrototype()->IsJSObject()) { 776 if (object->GetPrototype()->IsJSObject()) {
779 JSObject* holder; 777 JSObject* holder;
780 // holder == object indicates that no property was found. 778 // holder == object indicates that no property was found.
781 if (lookup->holder() != *object) { 779 if (lookup->holder() != *object) {
782 holder = lookup->holder(); 780 holder = lookup->holder();
783 } else { 781 } else {
784 // Find the top object. 782 // Find the top object.
785 holder = *object; 783 holder = *object;
786 do { 784 do {
787 holder = JSObject::cast(holder->GetPrototype()); 785 holder = JSObject::cast(holder->GetPrototype());
788 } while (holder->GetPrototype()->IsJSObject()); 786 } while (holder->GetPrototype()->IsJSObject());
(...skipping 18 matching lines...) Expand all
807 masm, miss_restore_name, holder_reg, name, scratch1, scratch2); 805 masm, miss_restore_name, holder_reg, name, scratch1, scratch2);
808 } 806 }
809 } 807 }
810 } 808 }
811 809
812 // Stub never generated for non-global objects that require access 810 // Stub never generated for non-global objects that require access
813 // checks. 811 // checks.
814 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 812 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
815 813
816 // Perform map transition for the receiver if necessary. 814 // Perform map transition for the receiver if necessary.
817 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 815 if (object->map()->unused_property_fields() == 0) {
818 // The properties must be extended before we can store the value. 816 // The properties must be extended before we can store the value.
819 // We jump to a runtime call that extends the properties array. 817 // We jump to a runtime call that extends the properties array.
820 __ pop(scratch1); // Return address. 818 __ pop(scratch1); // Return address.
821 __ push(receiver_reg); 819 __ push(receiver_reg);
822 __ push(Immediate(transition)); 820 __ push(Immediate(transition));
823 __ push(eax); 821 __ push(eax);
824 __ push(scratch1); 822 __ push(scratch1);
825 __ TailCallExternalReference( 823 __ TailCallExternalReference(
826 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 824 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
827 masm->isolate()), 825 masm->isolate()),
828 3, 826 3,
829 1); 827 1);
830 return; 828 return;
831 } 829 }
832 830
833 int index; 831 // Update the map of the object.
834 if (!transition.is_null()) { 832 __ mov(scratch1, Immediate(transition));
835 // Update the map of the object. 833 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
836 __ mov(scratch1, Immediate(transition));
837 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), scratch1);
838 834
839 // Update the write barrier for the map field and pass the now unused 835 // Update the write barrier for the map field and pass the now unused
840 // name_reg as scratch register. 836 // name_reg as scratch register.
841 __ RecordWriteField(receiver_reg, 837 __ RecordWriteField(receiver_reg,
842 HeapObject::kMapOffset, 838 HeapObject::kMapOffset,
843 scratch1, 839 scratch1,
844 name_reg, 840 name_reg,
845 kDontSaveFPRegs, 841 kDontSaveFPRegs,
846 OMIT_REMEMBERED_SET, 842 OMIT_REMEMBERED_SET,
847 OMIT_SMI_CHECK); 843 OMIT_SMI_CHECK);
848 index = transition->instance_descriptors()->GetFieldIndex(
849 transition->LastAdded());
850 } else {
851 index = lookup->GetFieldIndex().field_index();
852 }
853 844
845 int index = transition->instance_descriptors()->GetFieldIndex(
846 transition->LastAdded());
854 847
855 // Adjust for the number of properties stored in the object. Even in the 848 // Adjust for the number of properties stored in the object. Even in the
856 // face of a transition we can use the old map here because the size of the 849 // face of a transition we can use the old map here because the size of the
857 // object and the number of in-object properties is not going to change. 850 // object and the number of in-object properties is not going to change.
858 index -= object->map()->inobject_properties(); 851 index -= object->map()->inobject_properties();
859 852
853 // TODO(verwaest): Share this code as a code stub.
860 if (index < 0) { 854 if (index < 0) {
861 // Set the property straight into the object. 855 // Set the property straight into the object.
862 int offset = object->map()->instance_size() + (index * kPointerSize); 856 int offset = object->map()->instance_size() + (index * kPointerSize);
857 __ mov(FieldOperand(receiver_reg, offset), value_reg);
858
859 // Update the write barrier for the array address.
860 // Pass the value being stored in the now unused name_reg.
861 __ mov(name_reg, value_reg);
862 __ RecordWriteField(receiver_reg,
863 offset,
864 name_reg,
865 scratch1,
866 kDontSaveFPRegs);
867 } else {
868 // Write to the properties array.
869 int offset = index * kPointerSize + FixedArray::kHeaderSize;
870 // Get the properties array (optimistically).
871 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
872 __ mov(FieldOperand(scratch1, offset), eax);
873
874 // Update the write barrier for the array address.
875 // Pass the value being stored in the now unused name_reg.
876 __ mov(name_reg, value_reg);
877 __ RecordWriteField(scratch1,
878 offset,
879 name_reg,
880 receiver_reg,
881 kDontSaveFPRegs);
882 }
883
884 // Return the value (register eax).
885 ASSERT(value_reg.is(eax));
886 __ ret(0);
887 }
888
889
890 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
891 // but may be destroyed if store is successful.
892 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
893 Handle<JSObject> object,
894 LookupResult* lookup,
895 Register receiver_reg,
896 Register name_reg,
897 Register value_reg,
898 Register scratch1,
899 Register scratch2,
900 Label* miss_label) {
901 // Check that the map of the object hasn't changed.
902 __ CheckMap(receiver_reg, Handle<Map>(object->map()),
903 miss_label, DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
904
905 // Perform global security token check if needed.
906 if (object->IsJSGlobalProxy()) {
907 __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label);
908 }
909
910 // Stub never generated for non-global objects that require access
911 // checks.
912 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
913
914 int index = lookup->GetFieldIndex().field_index();
915
916 // Adjust for the number of properties stored in the object. Even in the
917 // face of a transition we can use the old map here because the size of the
918 // object and the number of in-object properties is not going to change.
919 index -= object->map()->inobject_properties();
920
921 // TODO(verwaest): Share this code as a code stub.
922 if (index < 0) {
923 // Set the property straight into the object.
924 int offset = object->map()->instance_size() + (index * kPointerSize);
863 __ mov(FieldOperand(receiver_reg, offset), value_reg); 925 __ mov(FieldOperand(receiver_reg, offset), value_reg);
864 926
865 // Update the write barrier for the array address. 927 // Update the write barrier for the array address.
866 // Pass the value being stored in the now unused name_reg. 928 // Pass the value being stored in the now unused name_reg.
867 __ mov(name_reg, value_reg); 929 __ mov(name_reg, value_reg);
868 __ RecordWriteField(receiver_reg, 930 __ RecordWriteField(receiver_reg,
869 offset, 931 offset,
870 name_reg, 932 name_reg,
871 scratch1, 933 scratch1,
872 kDontSaveFPRegs); 934 kDontSaveFPRegs);
(...skipping 2755 matching lines...) Expand 10 before | Expand all | Expand 10 after
3628 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3690 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3629 } 3691 }
3630 } 3692 }
3631 3693
3632 3694
3633 #undef __ 3695 #undef __
3634 3696
3635 } } // namespace v8::internal 3697 } } // namespace v8::internal
3636 3698
3637 #endif // V8_TARGET_ARCH_IA32 3699 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/arm/stub-cache-arm.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698