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 |