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

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

Issue 14146005: Track representations of fields (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add test for tracking fields 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/ia32/macro-assembler-ia32.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 754 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 __ CheckMap(receiver_reg, Handle<Map>(object->map()), 767 __ CheckMap(receiver_reg, Handle<Map>(object->map()),
768 miss_label, DO_SMI_CHECK, REQUIRE_EXACT_MAP); 768 miss_label, DO_SMI_CHECK, REQUIRE_EXACT_MAP);
769 769
770 // Perform global security token check if needed. 770 // Perform global security token check if needed.
771 if (object->IsJSGlobalProxy()) { 771 if (object->IsJSGlobalProxy()) {
772 __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label); 772 __ CheckAccessGlobalProxy(receiver_reg, scratch1, scratch2, miss_label);
773 } 773 }
774 774
775 int descriptor = transition->LastAdded();
776 DescriptorArray* descriptors = transition->instance_descriptors();
777 PropertyDetails details = descriptors->GetDetails(descriptor);
778 Representation representation = details.representation();
779 ASSERT(!representation.IsNone());
780
781 // Ensure no transitions to deprecated maps are followed.
782 __ CheckMapDeprecated(transition, scratch1, miss_label);
783
784 if (FLAG_track_fields && representation.IsSmi()) {
785 __ JumpIfNotSmi(value_reg, miss_label);
786 } else if (FLAG_track_double_fields && representation.IsDouble()) {
787 Label do_store;
788 __ JumpIfSmi(value_reg, &do_store);
789 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
790 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
791 __ bind(&do_store);
792 }
793
775 // Check that we are allowed to write this. 794 // Check that we are allowed to write this.
776 if (object->GetPrototype()->IsJSObject()) { 795 if (object->GetPrototype()->IsJSObject()) {
777 JSObject* holder; 796 JSObject* holder;
778 // holder == object indicates that no property was found. 797 // holder == object indicates that no property was found.
779 if (lookup->holder() != *object) { 798 if (lookup->holder() != *object) {
780 holder = lookup->holder(); 799 holder = lookup->holder();
781 } else { 800 } else {
782 // Find the top object. 801 // Find the top object.
783 holder = *object; 802 holder = *object;
784 do { 803 do {
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 // face of a transition we can use the old map here because the size of the 868 // face of a transition we can use the old map here because the size of the
850 // object and the number of in-object properties is not going to change. 869 // object and the number of in-object properties is not going to change.
851 index -= object->map()->inobject_properties(); 870 index -= object->map()->inobject_properties();
852 871
853 // TODO(verwaest): Share this code as a code stub. 872 // TODO(verwaest): Share this code as a code stub.
854 if (index < 0) { 873 if (index < 0) {
855 // Set the property straight into the object. 874 // Set the property straight into the object.
856 int offset = object->map()->instance_size() + (index * kPointerSize); 875 int offset = object->map()->instance_size() + (index * kPointerSize);
857 __ mov(FieldOperand(receiver_reg, offset), value_reg); 876 __ mov(FieldOperand(receiver_reg, offset), value_reg);
858 877
859 // Update the write barrier for the array address. 878 if (!FLAG_track_fields || !representation.IsSmi()) {
860 // Pass the value being stored in the now unused name_reg. 879 // Update the write barrier for the array address.
861 __ mov(name_reg, value_reg); 880 // Pass the value being stored in the now unused name_reg.
862 __ RecordWriteField(receiver_reg, 881 __ mov(name_reg, value_reg);
863 offset, 882 __ RecordWriteField(receiver_reg,
864 name_reg, 883 offset,
865 scratch1, 884 name_reg,
866 kDontSaveFPRegs); 885 scratch1,
886 kDontSaveFPRegs);
887 }
867 } else { 888 } else {
868 // Write to the properties array. 889 // Write to the properties array.
869 int offset = index * kPointerSize + FixedArray::kHeaderSize; 890 int offset = index * kPointerSize + FixedArray::kHeaderSize;
870 // Get the properties array (optimistically). 891 // Get the properties array (optimistically).
871 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 892 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
872 __ mov(FieldOperand(scratch1, offset), eax); 893 __ mov(FieldOperand(scratch1, offset), eax);
873 894
874 // Update the write barrier for the array address. 895 if (!FLAG_track_fields || !representation.IsSmi()) {
875 // Pass the value being stored in the now unused name_reg. 896 // Update the write barrier for the array address.
876 __ mov(name_reg, value_reg); 897 // Pass the value being stored in the now unused name_reg.
877 __ RecordWriteField(scratch1, 898 __ mov(name_reg, value_reg);
878 offset, 899 __ RecordWriteField(scratch1,
879 name_reg, 900 offset,
880 receiver_reg, 901 name_reg,
881 kDontSaveFPRegs); 902 receiver_reg,
903 kDontSaveFPRegs);
904 }
882 } 905 }
883 906
884 // Return the value (register eax). 907 // Return the value (register eax).
885 ASSERT(value_reg.is(eax)); 908 ASSERT(value_reg.is(eax));
886 __ ret(0); 909 __ ret(0);
887 } 910 }
888 911
889 912
890 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 913 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
891 // but may be destroyed if store is successful. 914 // but may be destroyed if store is successful.
(...skipping 19 matching lines...) Expand all
911 // checks. 934 // checks.
912 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 935 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
913 936
914 int index = lookup->GetFieldIndex().field_index(); 937 int index = lookup->GetFieldIndex().field_index();
915 938
916 // Adjust for the number of properties stored in the object. Even in the 939 // 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 940 // 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. 941 // object and the number of in-object properties is not going to change.
919 index -= object->map()->inobject_properties(); 942 index -= object->map()->inobject_properties();
920 943
944 Representation representation = lookup->representation();
945 ASSERT(!representation.IsNone());
946 if (FLAG_track_fields && representation.IsSmi()) {
947 __ JumpIfNotSmi(value_reg, miss_label);
948 } else if (FLAG_track_double_fields && representation.IsDouble()) {
949 Label do_store;
950 __ JumpIfSmi(value_reg, &do_store);
951 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
952 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
953 __ bind(&do_store);
954 }
955
921 // TODO(verwaest): Share this code as a code stub. 956 // TODO(verwaest): Share this code as a code stub.
922 if (index < 0) { 957 if (index < 0) {
923 // Set the property straight into the object. 958 // Set the property straight into the object.
924 int offset = object->map()->instance_size() + (index * kPointerSize); 959 int offset = object->map()->instance_size() + (index * kPointerSize);
925 __ mov(FieldOperand(receiver_reg, offset), value_reg); 960 __ mov(FieldOperand(receiver_reg, offset), value_reg);
926 961
927 // Update the write barrier for the array address. 962 if (!FLAG_track_fields || !representation.IsSmi()) {
928 // Pass the value being stored in the now unused name_reg. 963 // Update the write barrier for the array address.
929 __ mov(name_reg, value_reg); 964 // Pass the value being stored in the now unused name_reg.
930 __ RecordWriteField(receiver_reg, 965 __ mov(name_reg, value_reg);
931 offset, 966 __ RecordWriteField(receiver_reg,
932 name_reg, 967 offset,
933 scratch1, 968 name_reg,
934 kDontSaveFPRegs); 969 scratch1,
970 kDontSaveFPRegs);
971 }
935 } else { 972 } else {
936 // Write to the properties array. 973 // Write to the properties array.
937 int offset = index * kPointerSize + FixedArray::kHeaderSize; 974 int offset = index * kPointerSize + FixedArray::kHeaderSize;
938 // Get the properties array (optimistically). 975 // Get the properties array (optimistically).
939 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 976 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
940 __ mov(FieldOperand(scratch1, offset), eax); 977 __ mov(FieldOperand(scratch1, offset), eax);
941 978
942 // Update the write barrier for the array address. 979 if (!FLAG_track_fields || !representation.IsSmi()) {
943 // Pass the value being stored in the now unused name_reg. 980 // Update the write barrier for the array address.
944 __ mov(name_reg, value_reg); 981 // Pass the value being stored in the now unused name_reg.
945 __ RecordWriteField(scratch1, 982 __ mov(name_reg, value_reg);
946 offset, 983 __ RecordWriteField(scratch1,
947 name_reg, 984 offset,
948 receiver_reg, 985 name_reg,
949 kDontSaveFPRegs); 986 receiver_reg,
987 kDontSaveFPRegs);
988 }
950 } 989 }
951 990
952 // Return the value (register eax). 991 // Return the value (register eax).
953 ASSERT(value_reg.is(eax)); 992 ASSERT(value_reg.is(eax));
954 __ ret(0); 993 __ ret(0);
955 } 994 }
956 995
957 996
958 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 997 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
959 // from object to (but not including) holder. 998 // from object to (but not including) holder.
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
2969 Label miss; 3008 Label miss;
2970 3009
2971 if (check == PROPERTY) { 3010 if (check == PROPERTY) {
2972 GenerateNameCheck(name, this->name(), &miss); 3011 GenerateNameCheck(name, this->name(), &miss);
2973 } 3012 }
2974 3013
2975 __ JumpIfSmi(receiver(), &miss); 3014 __ JumpIfSmi(receiver(), &miss);
2976 Register map_reg = scratch1(); 3015 Register map_reg = scratch1();
2977 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 3016 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
2978 int receiver_count = receiver_maps->length(); 3017 int receiver_count = receiver_maps->length();
3018 int number_of_handled_maps = 0;
2979 for (int current = 0; current < receiver_count; ++current) { 3019 for (int current = 0; current < receiver_count; ++current) {
2980 __ cmp(map_reg, receiver_maps->at(current)); 3020 Handle<Map> map = receiver_maps->at(current);
2981 __ j(equal, handlers->at(current)); 3021 if (!map->is_deprecated()) {
3022 number_of_handled_maps++;
3023 __ cmp(map_reg, map);
3024 __ j(equal, handlers->at(current));
3025 }
2982 } 3026 }
3027 ASSERT(number_of_handled_maps != 0);
2983 3028
2984 __ bind(&miss); 3029 __ bind(&miss);
2985 TailCallBuiltin(masm(), MissBuiltin(kind())); 3030 TailCallBuiltin(masm(), MissBuiltin(kind()));
2986 3031
2987 // Return the generated code. 3032 // Return the generated code.
2988 InlineCacheState state = 3033 InlineCacheState state =
2989 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; 3034 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
2990 return GetICCode(kind(), type, name, state); 3035 return GetICCode(kind(), type, name, state);
2991 } 3036 }
2992 3037
2993 3038
2994 // Specialized stub for constructing objects from functions which only have only 3039 // Specialized stub for constructing objects from functions which only have only
2995 // simple assignments of the form this.x = ...; in their body. 3040 // simple assignments of the form this.x = ...; in their body.
2996 Handle<Code> ConstructStubCompiler::CompileConstructStub( 3041 Handle<Code> ConstructStubCompiler::CompileConstructStub(
2997 Handle<JSFunction> function) { 3042 Handle<JSFunction> function) {
2998 // ----------- S t a t e ------------- 3043 // ----------- S t a t e -------------
2999 // -- eax : argc 3044 // -- eax : argc
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
3690 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3735 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3691 } 3736 }
3692 } 3737 }
3693 3738
3694 3739
3695 #undef __ 3740 #undef __
3696 3741
3697 } } // namespace v8::internal 3742 } } // namespace v8::internal
3698 3743
3699 #endif // V8_TARGET_ARCH_IA32 3744 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | src/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698