OLD | NEW |
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 850 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
861 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); | 861 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); |
862 #endif | 862 #endif |
863 } | 863 } |
864 // Get the string if we have a string wrapper object. | 864 // Get the string if we have a string wrapper object. |
865 Handle<Object> string = object->IsJSValue() | 865 Handle<Object> string = object->IsJSValue() |
866 ? Handle<Object>(Handle<JSValue>::cast(object)->value()) | 866 ? Handle<Object>(Handle<JSValue>::cast(object)->value()) |
867 : object; | 867 : object; |
868 *result = Smi::FromInt(String::cast(*string)->length()); | 868 *result = Smi::FromInt(String::cast(*string)->length()); |
869 return true; | 869 return true; |
870 } | 870 } |
| 871 |
| 872 // Use specialized code for getting the length of arrays. |
| 873 if (object->IsJSArray() && name->Equals(isolate()->heap()->length_symbol())) { |
| 874 Handle<Code> stub; |
| 875 if (state == UNINITIALIZED) { |
| 876 stub = pre_monomorphic_stub(); |
| 877 } else if (state == PREMONOMORPHIC) { |
| 878 ArrayLengthStub array_length_stub(kind()); |
| 879 stub = array_length_stub.GetCode(); |
| 880 } else if (state != MEGAMORPHIC) { |
| 881 ASSERT(state != GENERIC); |
| 882 stub = megamorphic_stub(); |
| 883 } |
| 884 if (!stub.is_null()) { |
| 885 set_target(*stub); |
| 886 #ifdef DEBUG |
| 887 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); |
| 888 #endif |
| 889 } |
| 890 *result = JSArray::cast(*object)->length(); |
| 891 return true; |
| 892 } |
| 893 |
871 return false; | 894 return false; |
872 } | 895 } |
873 | 896 |
874 | 897 |
875 MaybeObject* LoadIC::Load(State state, | 898 MaybeObject* LoadIC::Load(State state, |
876 Handle<Object> object, | 899 Handle<Object> object, |
877 Handle<String> name) { | 900 Handle<String> name) { |
878 // If the object is undefined or null it's illegal to try to get any | 901 // If the object is undefined or null it's illegal to try to get any |
879 // of its properties; throw a TypeError in that case. | 902 // of its properties; throw a TypeError in that case. |
880 if (object->IsUndefined() || object->IsNull()) { | 903 if (object->IsUndefined() || object->IsNull()) { |
881 return TypeError("non_object_property_load", object, name); | 904 return TypeError("non_object_property_load", object, name); |
882 } | 905 } |
883 | 906 |
884 if (FLAG_use_ic) { | 907 if (FLAG_use_ic) { |
885 MaybeObject* result; | 908 MaybeObject* result; |
886 if (HandleLoad(state, object, name, &result)) { | 909 if (HandleLoad(state, object, name, &result)) { |
887 return result; | 910 return result; |
888 } | 911 } |
889 | 912 |
890 // Use specialized code for getting the length of arrays. | |
891 if (object->IsJSArray() && | |
892 name->Equals(isolate()->heap()->length_symbol())) { | |
893 Handle<Code> stub; | |
894 if (state == UNINITIALIZED) { | |
895 stub = pre_monomorphic_stub(); | |
896 } else if (state == PREMONOMORPHIC) { | |
897 stub = isolate()->builtins()->LoadIC_ArrayLength(); | |
898 } else if (state != MEGAMORPHIC) { | |
899 ASSERT(state != GENERIC); | |
900 stub = megamorphic_stub(); | |
901 } | |
902 if (!stub.is_null()) { | |
903 set_target(*stub); | |
904 #ifdef DEBUG | |
905 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); | |
906 #endif | |
907 } | |
908 return JSArray::cast(*object)->length(); | |
909 } | |
910 | |
911 // Use specialized code for getting prototype of functions. | 913 // Use specialized code for getting prototype of functions. |
912 if (object->IsJSFunction() && | 914 if (object->IsJSFunction() && |
913 name->Equals(isolate()->heap()->prototype_symbol()) && | 915 name->Equals(isolate()->heap()->prototype_symbol()) && |
914 Handle<JSFunction>::cast(object)->should_have_prototype()) { | 916 Handle<JSFunction>::cast(object)->should_have_prototype()) { |
915 Handle<Code> stub; | 917 Handle<Code> stub; |
916 if (state == UNINITIALIZED) { | 918 if (state == UNINITIALIZED) { |
917 stub = pre_monomorphic_stub(); | 919 stub = pre_monomorphic_stub(); |
918 } else if (state == PREMONOMORPHIC) { | 920 } else if (state == PREMONOMORPHIC) { |
919 stub = isolate()->builtins()->LoadIC_FunctionPrototype(); | 921 stub = isolate()->builtins()->LoadIC_FunctionPrototype(); |
920 } else if (state != MEGAMORPHIC) { | 922 } else if (state != MEGAMORPHIC) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1168 return TypeError("non_object_property_load", object, name); | 1170 return TypeError("non_object_property_load", object, name); |
1169 } | 1171 } |
1170 | 1172 |
1171 if (FLAG_use_ic) { | 1173 if (FLAG_use_ic) { |
1172 MaybeObject* result; | 1174 MaybeObject* result; |
1173 if (HandleLoad(state, object, name, &result)) { | 1175 if (HandleLoad(state, object, name, &result)) { |
1174 return result; | 1176 return result; |
1175 } | 1177 } |
1176 | 1178 |
1177 // TODO(1073): don't ignore the current stub state. | 1179 // TODO(1073): don't ignore the current stub state. |
1178 // Use specialized code for getting the length of arrays. | |
1179 if (object->IsJSArray() && | |
1180 name->Equals(isolate()->heap()->length_symbol())) { | |
1181 Handle<JSArray> array = Handle<JSArray>::cast(object); | |
1182 Handle<Code> code = | |
1183 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array); | |
1184 ASSERT(!code.is_null()); | |
1185 set_target(*code); | |
1186 TRACE_IC("KeyedLoadIC", name, state, target()); | |
1187 return array->length(); | |
1188 } | |
1189 | |
1190 // Use specialized code for getting prototype of functions. | 1180 // Use specialized code for getting prototype of functions. |
1191 if (object->IsJSFunction() && | 1181 if (object->IsJSFunction() && |
1192 name->Equals(isolate()->heap()->prototype_symbol()) && | 1182 name->Equals(isolate()->heap()->prototype_symbol()) && |
1193 Handle<JSFunction>::cast(object)->should_have_prototype()) { | 1183 Handle<JSFunction>::cast(object)->should_have_prototype()) { |
1194 Handle<JSFunction> function = Handle<JSFunction>::cast(object); | 1184 Handle<JSFunction> function = Handle<JSFunction>::cast(object); |
1195 Handle<Code> code = | 1185 Handle<Code> code = |
1196 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype( | 1186 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype( |
1197 name, function); | 1187 name, function); |
1198 ASSERT(!code.is_null()); | 1188 ASSERT(!code.is_null()); |
1199 set_target(*code); | 1189 set_target(*code); |
(...skipping 1682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2882 #undef ADDR | 2872 #undef ADDR |
2883 }; | 2873 }; |
2884 | 2874 |
2885 | 2875 |
2886 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2876 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
2887 return IC_utilities[id]; | 2877 return IC_utilities[id]; |
2888 } | 2878 } |
2889 | 2879 |
2890 | 2880 |
2891 } } // namespace v8::internal | 2881 } } // namespace v8::internal |
OLD | NEW |