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

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: Only verify representation while transitioning 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
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 // Unless we are in the most general state, check whether the map is still a
782 // valid transition.
783 if (transition->CanTransitionBeInvalidated()) {
784 __ mov(scratch1, transition);
danno 2013/04/24 15:23:00 Perhaps create a macro-assembler function for this
Toon Verwaest 2013/04/25 14:49:10 Done.
785 __ mov(scratch1, FieldOperand(scratch1, Map::kBitField3Offset));
786 __ and_(scratch1, Immediate(Smi::FromInt(Map::InvalidTransition::kMask)));
787 __ j(not_zero, miss_label);
788 }
789
790 if (FLAG_track_fields && representation.IsSmi()) {
791 __ JumpIfNotSmi(value_reg, miss_label);
792 } else if (FLAG_track_double_fields && representation.IsDouble()) {
793 Label do_store;
794 __ JumpIfSmi(value_reg, &do_store);
795 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
796 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
797 __ bind(&do_store);
798 }
799
775 // Check that we are allowed to write this. 800 // Check that we are allowed to write this.
776 if (object->GetPrototype()->IsJSObject()) { 801 if (object->GetPrototype()->IsJSObject()) {
777 JSObject* holder; 802 JSObject* holder;
778 // holder == object indicates that no property was found. 803 // holder == object indicates that no property was found.
779 if (lookup->holder() != *object) { 804 if (lookup->holder() != *object) {
780 holder = lookup->holder(); 805 holder = lookup->holder();
781 } else { 806 } else {
782 // Find the top object. 807 // Find the top object.
783 holder = *object; 808 holder = *object;
784 do { 809 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 874 // 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. 875 // object and the number of in-object properties is not going to change.
851 index -= object->map()->inobject_properties(); 876 index -= object->map()->inobject_properties();
852 877
853 // TODO(verwaest): Share this code as a code stub. 878 // TODO(verwaest): Share this code as a code stub.
854 if (index < 0) { 879 if (index < 0) {
855 // Set the property straight into the object. 880 // Set the property straight into the object.
856 int offset = object->map()->instance_size() + (index * kPointerSize); 881 int offset = object->map()->instance_size() + (index * kPointerSize);
857 __ mov(FieldOperand(receiver_reg, offset), value_reg); 882 __ mov(FieldOperand(receiver_reg, offset), value_reg);
858 883
859 // Update the write barrier for the array address. 884 if (!FLAG_track_fields || !representation.IsSmi()) {
860 // Pass the value being stored in the now unused name_reg. 885 // Update the write barrier for the array address.
861 __ mov(name_reg, value_reg); 886 // Pass the value being stored in the now unused name_reg.
862 __ RecordWriteField(receiver_reg, 887 __ mov(name_reg, value_reg);
863 offset, 888 __ RecordWriteField(receiver_reg,
864 name_reg, 889 offset,
865 scratch1, 890 name_reg,
866 kDontSaveFPRegs); 891 scratch1,
892 kDontSaveFPRegs);
893 }
867 } else { 894 } else {
868 // Write to the properties array. 895 // Write to the properties array.
869 int offset = index * kPointerSize + FixedArray::kHeaderSize; 896 int offset = index * kPointerSize + FixedArray::kHeaderSize;
870 // Get the properties array (optimistically). 897 // Get the properties array (optimistically).
871 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 898 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
872 __ mov(FieldOperand(scratch1, offset), eax); 899 __ mov(FieldOperand(scratch1, offset), eax);
873 900
874 // Update the write barrier for the array address. 901 if (!FLAG_track_fields || !representation.IsSmi()) {
875 // Pass the value being stored in the now unused name_reg. 902 // Update the write barrier for the array address.
876 __ mov(name_reg, value_reg); 903 // Pass the value being stored in the now unused name_reg.
877 __ RecordWriteField(scratch1, 904 __ mov(name_reg, value_reg);
878 offset, 905 __ RecordWriteField(scratch1,
879 name_reg, 906 offset,
880 receiver_reg, 907 name_reg,
881 kDontSaveFPRegs); 908 receiver_reg,
909 kDontSaveFPRegs);
910 }
882 } 911 }
883 912
884 // Return the value (register eax). 913 // Return the value (register eax).
885 ASSERT(value_reg.is(eax)); 914 ASSERT(value_reg.is(eax));
886 __ ret(0); 915 __ ret(0);
887 } 916 }
888 917
889 918
890 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 919 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
891 // but may be destroyed if store is successful. 920 // but may be destroyed if store is successful.
(...skipping 19 matching lines...) Expand all
911 // checks. 940 // checks.
912 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 941 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
913 942
914 int index = lookup->GetFieldIndex().field_index(); 943 int index = lookup->GetFieldIndex().field_index();
915 944
916 // Adjust for the number of properties stored in the object. Even in the 945 // 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 946 // 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. 947 // object and the number of in-object properties is not going to change.
919 index -= object->map()->inobject_properties(); 948 index -= object->map()->inobject_properties();
920 949
950 Representation representation = lookup->GetPropertyDetails().representation();
951 ASSERT(!representation.IsNone());
952 if (FLAG_track_fields && representation.IsSmi()) {
953 __ JumpIfNotSmi(value_reg, miss_label);
954 } else if (FLAG_track_double_fields && representation.IsDouble()) {
955 Label do_store;
956 __ JumpIfSmi(value_reg, &do_store);
957 __ CheckMap(value_reg, masm->isolate()->factory()->heap_number_map(),
958 miss_label, DONT_DO_SMI_CHECK, REQUIRE_EXACT_MAP);
959 __ bind(&do_store);
960 }
961
921 // TODO(verwaest): Share this code as a code stub. 962 // TODO(verwaest): Share this code as a code stub.
922 if (index < 0) { 963 if (index < 0) {
923 // Set the property straight into the object. 964 // Set the property straight into the object.
924 int offset = object->map()->instance_size() + (index * kPointerSize); 965 int offset = object->map()->instance_size() + (index * kPointerSize);
925 __ mov(FieldOperand(receiver_reg, offset), value_reg); 966 __ mov(FieldOperand(receiver_reg, offset), value_reg);
926 967
927 // Update the write barrier for the array address. 968 if (!FLAG_track_fields || !representation.IsSmi()) {
928 // Pass the value being stored in the now unused name_reg. 969 // Update the write barrier for the array address.
929 __ mov(name_reg, value_reg); 970 // Pass the value being stored in the now unused name_reg.
930 __ RecordWriteField(receiver_reg, 971 __ mov(name_reg, value_reg);
931 offset, 972 __ RecordWriteField(receiver_reg,
932 name_reg, 973 offset,
933 scratch1, 974 name_reg,
934 kDontSaveFPRegs); 975 scratch1,
976 kDontSaveFPRegs);
977 }
935 } else { 978 } else {
936 // Write to the properties array. 979 // Write to the properties array.
937 int offset = index * kPointerSize + FixedArray::kHeaderSize; 980 int offset = index * kPointerSize + FixedArray::kHeaderSize;
938 // Get the properties array (optimistically). 981 // Get the properties array (optimistically).
939 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 982 __ mov(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
940 __ mov(FieldOperand(scratch1, offset), eax); 983 __ mov(FieldOperand(scratch1, offset), eax);
941 984
942 // Update the write barrier for the array address. 985 if (!FLAG_track_fields || !representation.IsSmi()) {
943 // Pass the value being stored in the now unused name_reg. 986 // Update the write barrier for the array address.
944 __ mov(name_reg, value_reg); 987 // Pass the value being stored in the now unused name_reg.
945 __ RecordWriteField(scratch1, 988 __ mov(name_reg, value_reg);
946 offset, 989 __ RecordWriteField(scratch1,
947 name_reg, 990 offset,
948 receiver_reg, 991 name_reg,
949 kDontSaveFPRegs); 992 receiver_reg,
993 kDontSaveFPRegs);
994 }
950 } 995 }
951 996
952 // Return the value (register eax). 997 // Return the value (register eax).
953 ASSERT(value_reg.is(eax)); 998 ASSERT(value_reg.is(eax));
954 __ ret(0); 999 __ ret(0);
955 } 1000 }
956 1001
957 1002
958 // Calls GenerateCheckPropertyCell for each global object in the prototype chain 1003 // Calls GenerateCheckPropertyCell for each global object in the prototype chain
959 // from object to (but not including) holder. 1004 // from object to (but not including) holder.
(...skipping 2009 matching lines...) Expand 10 before | Expand all | Expand 10 after
2969 Label miss; 3014 Label miss;
2970 3015
2971 if (check == PROPERTY) { 3016 if (check == PROPERTY) {
2972 GenerateNameCheck(name, this->name(), &miss); 3017 GenerateNameCheck(name, this->name(), &miss);
2973 } 3018 }
2974 3019
2975 __ JumpIfSmi(receiver(), &miss); 3020 __ JumpIfSmi(receiver(), &miss);
2976 Register map_reg = scratch1(); 3021 Register map_reg = scratch1();
2977 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 3022 __ mov(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
2978 int receiver_count = receiver_maps->length(); 3023 int receiver_count = receiver_maps->length();
3024 int number_of_handled_maps = 0;
2979 for (int current = 0; current < receiver_count; ++current) { 3025 for (int current = 0; current < receiver_count; ++current) {
2980 __ cmp(map_reg, receiver_maps->at(current)); 3026 Handle<Map> map = receiver_maps->at(current);
2981 __ j(equal, handlers->at(current)); 3027 if (!map->is_invalid_transition()) {
3028 number_of_handled_maps++;
3029 __ cmp(map_reg, map);
3030 __ j(equal, handlers->at(current));
3031 }
2982 } 3032 }
3033 ASSERT(number_of_handled_maps != 0);
2983 3034
2984 __ bind(&miss); 3035 __ bind(&miss);
2985 TailCallBuiltin(masm(), MissBuiltin(kind())); 3036 TailCallBuiltin(masm(), MissBuiltin(kind()));
2986 3037
2987 // Return the generated code. 3038 // Return the generated code.
2988 InlineCacheState state = 3039 InlineCacheState state =
2989 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; 3040 number_of_handled_maps > 1 ? POLYMORPHIC : MONOMORPHIC;
2990 return GetICCode(kind(), type, name, state); 3041 return GetICCode(kind(), type, name, state);
2991 } 3042 }
2992 3043
2993 3044
2994 // Specialized stub for constructing objects from functions which only have only 3045 // Specialized stub for constructing objects from functions which only have only
2995 // simple assignments of the form this.x = ...; in their body. 3046 // simple assignments of the form this.x = ...; in their body.
2996 Handle<Code> ConstructStubCompiler::CompileConstructStub( 3047 Handle<Code> ConstructStubCompiler::CompileConstructStub(
2997 Handle<JSFunction> function) { 3048 Handle<JSFunction> function) {
2998 // ----------- S t a t e ------------- 3049 // ----------- S t a t e -------------
2999 // -- eax : argc 3050 // -- eax : argc
(...skipping 690 matching lines...) Expand 10 before | Expand all | Expand 10 after
3690 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); 3741 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3691 } 3742 }
3692 } 3743 }
3693 3744
3694 3745
3695 #undef __ 3746 #undef __
3696 3747
3697 } } // namespace v8::internal 3748 } } // namespace v8::internal
3698 3749
3699 #endif // V8_TARGET_ARCH_IA32 3750 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698