OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 831 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 } else if (state == MONOMORPHIC) { | 842 } else if (state == MONOMORPHIC) { |
843 set_target(megamorphic_stub()); | 843 set_target(megamorphic_stub()); |
844 } | 844 } |
845 | 845 |
846 #ifdef DEBUG | 846 #ifdef DEBUG |
847 TraceIC("KeyedLoadIC", name, state, target()); | 847 TraceIC("KeyedLoadIC", name, state, target()); |
848 #endif | 848 #endif |
849 } | 849 } |
850 | 850 |
851 | 851 |
| 852 static bool StoreICableLookup(LookupResult* lookup) { |
| 853 // Bail out if we didn't find a result. |
| 854 if (!lookup->IsValid() || !lookup->IsCacheable()) return false; |
| 855 |
| 856 // If the property is read-only, we leave the IC in its current |
| 857 // state. |
| 858 if (lookup->IsReadOnly()) return false; |
| 859 |
| 860 if (!lookup->IsLoaded()) return false; |
| 861 |
| 862 return true; |
| 863 } |
| 864 |
| 865 |
852 Object* StoreIC::Store(State state, | 866 Object* StoreIC::Store(State state, |
853 Handle<Object> object, | 867 Handle<Object> object, |
854 Handle<String> name, | 868 Handle<String> name, |
855 Handle<Object> value) { | 869 Handle<Object> value) { |
856 // If the object is undefined or null it's illegal to try to set any | 870 // If the object is undefined or null it's illegal to try to set any |
857 // properties on it; throw a TypeError in that case. | 871 // properties on it; throw a TypeError in that case. |
858 if (object->IsUndefined() || object->IsNull()) { | 872 if (object->IsUndefined() || object->IsNull()) { |
859 return TypeError("non_object_property_store", object, name); | 873 return TypeError("non_object_property_store", object, name); |
860 } | 874 } |
861 | 875 |
862 // Ignore stores where the receiver is not a JSObject. | 876 // Ignore stores where the receiver is not a JSObject. |
863 if (!object->IsJSObject()) return *value; | 877 if (!object->IsJSObject()) return *value; |
864 Handle<JSObject> receiver = Handle<JSObject>::cast(object); | 878 Handle<JSObject> receiver = Handle<JSObject>::cast(object); |
865 | 879 |
866 // Check if the given name is an array index. | 880 // Check if the given name is an array index. |
867 uint32_t index; | 881 uint32_t index; |
868 if (name->AsArrayIndex(&index)) { | 882 if (name->AsArrayIndex(&index)) { |
869 HandleScope scope; | 883 HandleScope scope; |
870 Handle<Object> result = SetElement(receiver, index, value); | 884 Handle<Object> result = SetElement(receiver, index, value); |
871 if (result.is_null()) return Failure::Exception(); | 885 if (result.is_null()) return Failure::Exception(); |
872 return *value; | 886 return *value; |
873 } | 887 } |
874 | 888 |
875 // Lookup the property locally in the receiver. | 889 // Lookup the property locally in the receiver. |
876 LookupResult lookup; | 890 if (FLAG_use_ic && !receiver->IsJSGlobalProxy()) { |
877 receiver->LocalLookup(*name, &lookup); | 891 LookupResult lookup; |
878 | 892 receiver->LocalLookup(*name, &lookup); |
879 // Update inline cache and stub cache. | 893 if (StoreICableLookup(&lookup)) { |
880 if (FLAG_use_ic && lookup.IsLoaded()) { | 894 UpdateCaches(&lookup, state, receiver, name, value); |
881 UpdateCaches(&lookup, state, receiver, name, value); | 895 } |
882 } | 896 } |
883 | 897 |
884 // Set the property. | 898 // Set the property. |
885 return receiver->SetProperty(*name, *value, NONE); | 899 return receiver->SetProperty(*name, *value, NONE); |
886 } | 900 } |
887 | 901 |
888 | 902 |
889 void StoreIC::UpdateCaches(LookupResult* lookup, | 903 void StoreIC::UpdateCaches(LookupResult* lookup, |
890 State state, | 904 State state, |
891 Handle<JSObject> receiver, | 905 Handle<JSObject> receiver, |
892 Handle<String> name, | 906 Handle<String> name, |
893 Handle<Object> value) { | 907 Handle<Object> value) { |
894 ASSERT(lookup->IsLoaded()); | 908 ASSERT(lookup->IsLoaded()); |
895 // Skip JSGlobalProxy. | 909 // Skip JSGlobalProxy. |
896 if (receiver->IsJSGlobalProxy()) return; | 910 ASSERT(!receiver->IsJSGlobalProxy()); |
897 | 911 |
898 // Bail out if we didn't find a result. | 912 ASSERT(StoreICableLookup(lookup)); |
899 if (!lookup->IsValid() || !lookup->IsCacheable()) return; | |
900 | |
901 // If the property is read-only, we leave the IC in its current | |
902 // state. | |
903 if (lookup->IsReadOnly()) return; | |
904 | 913 |
905 // If the property has a non-field type allowing map transitions | 914 // If the property has a non-field type allowing map transitions |
906 // where there is extra room in the object, we leave the IC in its | 915 // where there is extra room in the object, we leave the IC in its |
907 // current state. | 916 // current state. |
908 PropertyType type = lookup->type(); | 917 PropertyType type = lookup->type(); |
909 | 918 |
910 // Compute the code stub for this store; used for rewriting to | 919 // Compute the code stub for this store; used for rewriting to |
911 // monomorphic state and making sure that the code stub is in the | 920 // monomorphic state and making sure that the code stub is in the |
912 // stub cache. | 921 // stub cache. |
913 Object* code = NULL; | 922 Object* code = NULL; |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1257 #undef ADDR | 1266 #undef ADDR |
1258 }; | 1267 }; |
1259 | 1268 |
1260 | 1269 |
1261 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 1270 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
1262 return IC_utilities[id]; | 1271 return IC_utilities[id]; |
1263 } | 1272 } |
1264 | 1273 |
1265 | 1274 |
1266 } } // namespace v8::internal | 1275 } } // namespace v8::internal |
OLD | NEW |