| 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 |