| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 842 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 MaybeObject* LoadIC::Load(State state, | 853 MaybeObject* LoadIC::Load(State state, |
| 854 Handle<Object> object, | 854 Handle<Object> object, |
| 855 Handle<String> name) { | 855 Handle<String> name) { |
| 856 // If the object is undefined or null it's illegal to try to get any | 856 // If the object is undefined or null it's illegal to try to get any |
| 857 // of its properties; throw a TypeError in that case. | 857 // of its properties; throw a TypeError in that case. |
| 858 if (object->IsUndefined() || object->IsNull()) { | 858 if (object->IsUndefined() || object->IsNull()) { |
| 859 return TypeError("non_object_property_load", object, name); | 859 return TypeError("non_object_property_load", object, name); |
| 860 } | 860 } |
| 861 | 861 |
| 862 if (FLAG_use_ic) { | 862 if (FLAG_use_ic) { |
| 863 Code* non_monomorphic_stub = | |
| 864 (state == UNINITIALIZED) ? pre_monomorphic_stub() : megamorphic_stub(); | |
| 865 | |
| 866 // Use specialized code for getting the length of strings and | 863 // Use specialized code for getting the length of strings and |
| 867 // string wrapper objects. The length property of string wrapper | 864 // string wrapper objects. The length property of string wrapper |
| 868 // objects is read-only and therefore always returns the length of | 865 // objects is read-only and therefore always returns the length of |
| 869 // the underlying string value. See ECMA-262 15.5.5.1. | 866 // the underlying string value. See ECMA-262 15.5.5.1. |
| 870 if ((object->IsString() || object->IsStringWrapper()) && | 867 if ((object->IsString() || object->IsStringWrapper()) && |
| 871 name->Equals(isolate()->heap()->length_symbol())) { | 868 name->Equals(isolate()->heap()->length_symbol())) { |
| 872 HandleScope scope(isolate()); | 869 AssertNoAllocation no_allocation; |
| 873 #ifdef DEBUG | 870 Code* stub = NULL; |
| 874 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); | 871 if (state == UNINITIALIZED) { |
| 875 #endif | 872 stub = pre_monomorphic_stub(); |
| 876 if (state == PREMONOMORPHIC) { | 873 } else if (state == PREMONOMORPHIC) { |
| 877 if (object->IsString()) { | 874 if (object->IsString()) { |
| 878 set_target(isolate()->builtins()->builtin( | 875 stub = isolate()->builtins()->builtin( |
| 879 Builtins::kLoadIC_StringLength)); | 876 Builtins::kLoadIC_StringLength); |
| 880 } else { | 877 } else { |
| 881 set_target(isolate()->builtins()->builtin( | 878 stub = isolate()->builtins()->builtin( |
| 882 Builtins::kLoadIC_StringWrapperLength)); | 879 Builtins::kLoadIC_StringWrapperLength); |
| 883 } | 880 } |
| 884 } else if (state == MONOMORPHIC && object->IsStringWrapper()) { | 881 } else if (state == MONOMORPHIC && object->IsStringWrapper()) { |
| 885 set_target(isolate()->builtins()->builtin( | 882 stub = isolate()->builtins()->builtin( |
| 886 Builtins::kLoadIC_StringWrapperLength)); | 883 Builtins::kLoadIC_StringWrapperLength); |
| 887 } else { | 884 } else if (state != MEGAMORPHIC) { |
| 888 set_target(non_monomorphic_stub); | 885 stub = megamorphic_stub(); |
| 886 } |
| 887 if (stub != NULL) { |
| 888 set_target(stub); |
| 889 #ifdef DEBUG |
| 890 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); |
| 891 #endif |
| 889 } | 892 } |
| 890 // Get the string if we have a string wrapper object. | 893 // Get the string if we have a string wrapper object. |
| 891 if (object->IsJSValue()) { | 894 if (object->IsJSValue()) { |
| 892 object = Handle<Object>(Handle<JSValue>::cast(object)->value(), | 895 return Smi::FromInt( |
| 893 isolate()); | 896 String::cast(Handle<JSValue>::cast(object)->value())->length()); |
| 894 } | 897 } |
| 895 return Smi::FromInt(String::cast(*object)->length()); | 898 return Smi::FromInt(String::cast(*object)->length()); |
| 896 } | 899 } |
| 897 | 900 |
| 898 // Use specialized code for getting the length of arrays. | 901 // Use specialized code for getting the length of arrays. |
| 899 if (object->IsJSArray() && | 902 if (object->IsJSArray() && |
| 900 name->Equals(isolate()->heap()->length_symbol())) { | 903 name->Equals(isolate()->heap()->length_symbol())) { |
| 904 AssertNoAllocation no_allocation; |
| 905 Code* stub = NULL; |
| 906 if (state == UNINITIALIZED) { |
| 907 stub = pre_monomorphic_stub(); |
| 908 } else if (state == PREMONOMORPHIC) { |
| 909 stub = isolate()->builtins()->builtin( |
| 910 Builtins::kLoadIC_ArrayLength); |
| 911 } else if (state != MEGAMORPHIC) { |
| 912 stub = megamorphic_stub(); |
| 913 } |
| 914 if (stub != NULL) { |
| 915 set_target(stub); |
| 901 #ifdef DEBUG | 916 #ifdef DEBUG |
| 902 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); | 917 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n"); |
| 903 #endif | 918 #endif |
| 904 if (state == PREMONOMORPHIC) { | |
| 905 set_target(isolate()->builtins()->builtin( | |
| 906 Builtins::kLoadIC_ArrayLength)); | |
| 907 } else { | |
| 908 set_target(non_monomorphic_stub); | |
| 909 } | 919 } |
| 910 return JSArray::cast(*object)->length(); | 920 return JSArray::cast(*object)->length(); |
| 911 } | 921 } |
| 912 | 922 |
| 913 // Use specialized code for getting prototype of functions. | 923 // Use specialized code for getting prototype of functions. |
| 914 if (object->IsJSFunction() && | 924 if (object->IsJSFunction() && |
| 915 name->Equals(isolate()->heap()->prototype_symbol()) && | 925 name->Equals(isolate()->heap()->prototype_symbol()) && |
| 916 JSFunction::cast(*object)->should_have_prototype()) { | 926 JSFunction::cast(*object)->should_have_prototype()) { |
| 927 { AssertNoAllocation no_allocation; |
| 928 Code* stub = NULL; |
| 929 if (state == UNINITIALIZED) { |
| 930 stub = pre_monomorphic_stub(); |
| 931 } else if (state == PREMONOMORPHIC) { |
| 932 stub = isolate()->builtins()->builtin( |
| 933 Builtins::kLoadIC_FunctionPrototype); |
| 934 } else if (state != MEGAMORPHIC) { |
| 935 stub = megamorphic_stub(); |
| 936 } |
| 937 if (stub != NULL) { |
| 938 set_target(stub); |
| 917 #ifdef DEBUG | 939 #ifdef DEBUG |
| 918 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); | 940 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); |
| 919 #endif | 941 #endif |
| 920 if (state == PREMONOMORPHIC) { | 942 } |
| 921 set_target(isolate()->builtins()->builtin( | |
| 922 Builtins::kLoadIC_FunctionPrototype)); | |
| 923 } else { | |
| 924 set_target(non_monomorphic_stub); | |
| 925 } | 943 } |
| 926 return Accessors::FunctionGetPrototype(*object, 0); | 944 return Accessors::FunctionGetPrototype(*object, 0); |
| 927 } | 945 } |
| 928 } | 946 } |
| 929 | 947 |
| 930 // Check if the name is trivially convertible to an index and get | 948 // Check if the name is trivially convertible to an index and get |
| 931 // the element if so. | 949 // the element if so. |
| 932 uint32_t index; | 950 uint32_t index; |
| 933 if (name->AsArrayIndex(&index)) return object->GetElement(index); | 951 if (name->AsArrayIndex(&index)) return object->GetElement(index); |
| 934 | 952 |
| (...skipping 1608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2543 #undef ADDR | 2561 #undef ADDR |
| 2544 }; | 2562 }; |
| 2545 | 2563 |
| 2546 | 2564 |
| 2547 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2565 Address IC::AddressFromUtilityId(IC::UtilityId id) { |
| 2548 return IC_utilities[id]; | 2566 return IC_utilities[id]; |
| 2549 } | 2567 } |
| 2550 | 2568 |
| 2551 | 2569 |
| 2552 } } // namespace v8::internal | 2570 } } // namespace v8::internal |
| OLD | NEW |