Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/ic.cc

Issue 11941016: Migrate FunctionPrototype (Keyed|Named)LoadIC to CodeStub (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/stub-cache.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 if (result->IsJSFunction()) return *result; 829 if (result->IsJSFunction()) return *result;
830 830
831 return TypeError("property_not_function", object, key); 831 return TypeError("property_not_function", object, key);
832 } 832 }
833 833
834 834
835 bool IC::HandleLoad(State state, 835 bool IC::HandleLoad(State state,
836 Handle<Object> object, 836 Handle<Object> object,
837 Handle<String> name, 837 Handle<String> name,
838 MaybeObject** result) { 838 MaybeObject** result) {
839 // Use specialized code for getting the length of strings and 839 if (FLAG_use_ic) {
840 // string wrapper objects. The length property of string wrapper 840 // Use specialized code for getting the length of strings and
841 // objects is read-only and therefore always returns the length of 841 // string wrapper objects. The length property of string wrapper
842 // the underlying string value. See ECMA-262 15.5.5.1. 842 // objects is read-only and therefore always returns the length of
843 if ((object->IsString() || object->IsStringWrapper()) && 843 // the underlying string value. See ECMA-262 15.5.5.1.
844 name->Equals(isolate()->heap()->length_symbol())) { 844 if ((object->IsString() || object->IsStringWrapper()) &&
845 Handle<Code> stub; 845 name->Equals(isolate()->heap()->length_symbol())) {
846 if (state == UNINITIALIZED) { 846 Handle<Code> stub;
847 stub = pre_monomorphic_stub(); 847 if (state == UNINITIALIZED) {
848 } else if (state == PREMONOMORPHIC) { 848 stub = pre_monomorphic_stub();
849 StringLengthStub string_length_stub(kind(), !object->IsString()); 849 } else if (state == PREMONOMORPHIC) {
850 stub = string_length_stub.GetCode(); 850 StringLengthStub string_length_stub(kind(), !object->IsString());
851 } else if (state == MONOMORPHIC && object->IsStringWrapper()) { 851 stub = string_length_stub.GetCode();
852 StringLengthStub string_length_stub(kind(), true); 852 } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
853 stub = string_length_stub.GetCode(); 853 StringLengthStub string_length_stub(kind(), true);
854 } else if (state != MEGAMORPHIC) { 854 stub = string_length_stub.GetCode();
855 ASSERT(state != GENERIC); 855 } else if (state != MEGAMORPHIC) {
856 stub = megamorphic_stub(); 856 ASSERT(state != GENERIC);
857 stub = megamorphic_stub();
858 }
859 if (!stub.is_null()) {
860 set_target(*stub);
861 #ifdef DEBUG
862 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
863 #endif
864 }
865 // Get the string if we have a string wrapper object.
866 Handle<Object> string = object->IsJSValue()
867 ? Handle<Object>(Handle<JSValue>::cast(object)->value())
868 : object;
869 *result = Smi::FromInt(String::cast(*string)->length());
870 return true;
857 } 871 }
858 if (!stub.is_null()) { 872
859 set_target(*stub); 873 // Use specialized code for getting the length of arrays.
874 if (object->IsJSArray() &&
875 name->Equals(isolate()->heap()->length_symbol())) {
876 Handle<Code> stub;
877 if (state == UNINITIALIZED) {
878 stub = pre_monomorphic_stub();
879 } else if (state == PREMONOMORPHIC) {
880 ArrayLengthStub array_length_stub(kind());
881 stub = array_length_stub.GetCode();
882 } else if (state != MEGAMORPHIC) {
883 ASSERT(state != GENERIC);
884 stub = megamorphic_stub();
885 }
886 if (!stub.is_null()) {
887 set_target(*stub);
860 #ifdef DEBUG 888 #ifdef DEBUG
861 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n"); 889 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /array]\n");
862 #endif 890 #endif
863 } 891 }
864 // Get the string if we have a string wrapper object. 892 *result = JSArray::cast(*object)->length();
865 Handle<Object> string = object->IsJSValue() 893 return true;
866 ? Handle<Object>(Handle<JSValue>::cast(object)->value())
867 : object;
868 *result = Smi::FromInt(String::cast(*string)->length());
869 return true;
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
894 return false;
895 }
896
897
898 MaybeObject* LoadIC::Load(State state,
899 Handle<Object> object,
900 Handle<String> name) {
901 // If the object is undefined or null it's illegal to try to get any
902 // of its properties; throw a TypeError in that case.
903 if (object->IsUndefined() || object->IsNull()) {
904 return TypeError("non_object_property_load", object, name);
905 }
906
907 if (FLAG_use_ic) {
908 MaybeObject* result;
909 if (HandleLoad(state, object, name, &result)) {
910 return result;
911 } 894 }
912 895
913 // Use specialized code for getting prototype of functions. 896 // Use specialized code for getting prototype of functions.
914 if (object->IsJSFunction() && 897 if (object->IsJSFunction() &&
915 name->Equals(isolate()->heap()->prototype_symbol()) && 898 name->Equals(isolate()->heap()->prototype_symbol()) &&
916 Handle<JSFunction>::cast(object)->should_have_prototype()) { 899 Handle<JSFunction>::cast(object)->should_have_prototype()) {
917 Handle<Code> stub; 900 Handle<Code> stub;
918 if (state == UNINITIALIZED) { 901 if (state == UNINITIALIZED) {
919 stub = pre_monomorphic_stub(); 902 stub = pre_monomorphic_stub();
920 } else if (state == PREMONOMORPHIC) { 903 } else if (state == PREMONOMORPHIC) {
921 stub = isolate()->builtins()->LoadIC_FunctionPrototype(); 904 FunctionPrototypeStub function_prototype_stub(kind());
905 stub = function_prototype_stub.GetCode();
922 } else if (state != MEGAMORPHIC) { 906 } else if (state != MEGAMORPHIC) {
923 ASSERT(state != GENERIC); 907 ASSERT(state != GENERIC);
924 stub = megamorphic_stub(); 908 stub = megamorphic_stub();
925 } 909 }
926 if (!stub.is_null()) { 910 if (!stub.is_null()) {
927 set_target(*stub); 911 set_target(*stub);
928 #ifdef DEBUG 912 #ifdef DEBUG
929 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n"); 913 if (FLAG_trace_ic) PrintF("[LoadIC : +#prototype /function]\n");
930 #endif 914 #endif
931 } 915 }
932 return Accessors::FunctionGetPrototype(*object, 0); 916 *result = Accessors::FunctionGetPrototype(*object, 0);
917 return true;
933 } 918 }
934 } 919 }
935 920
921 return false;
922 }
923
924
925 MaybeObject* LoadIC::Load(State state,
926 Handle<Object> object,
927 Handle<String> name) {
928 // If the object is undefined or null it's illegal to try to get any
929 // of its properties; throw a TypeError in that case.
930 if (object->IsUndefined() || object->IsNull()) {
931 return TypeError("non_object_property_load", object, name);
932 }
933
934 MaybeObject* result;
935 if (HandleLoad(state, object, name, &result)) {
936 return result;
937 }
938
936 // Check if the name is trivially convertible to an index and get 939 // Check if the name is trivially convertible to an index and get
937 // the element if so. 940 // the element if so.
938 uint32_t index; 941 uint32_t index;
939 if (name->AsArrayIndex(&index)) return object->GetElement(index); 942 if (name->AsArrayIndex(&index)) return object->GetElement(index);
940 943
941 // Named lookup in the object. 944 // Named lookup in the object.
942 LookupResult lookup(isolate()); 945 LookupResult lookup(isolate());
943 LookupForRead(object, name, &lookup); 946 LookupForRead(object, name, &lookup);
944 947
945 // If we did not find a property, check if we need to throw an exception. 948 // If we did not find a property, check if we need to throw an exception.
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 1166
1164 if (key->IsSymbol()) { 1167 if (key->IsSymbol()) {
1165 Handle<String> name = Handle<String>::cast(key); 1168 Handle<String> name = Handle<String>::cast(key);
1166 1169
1167 // If the object is undefined or null it's illegal to try to get any 1170 // If the object is undefined or null it's illegal to try to get any
1168 // of its properties; throw a TypeError in that case. 1171 // of its properties; throw a TypeError in that case.
1169 if (object->IsUndefined() || object->IsNull()) { 1172 if (object->IsUndefined() || object->IsNull()) {
1170 return TypeError("non_object_property_load", object, name); 1173 return TypeError("non_object_property_load", object, name);
1171 } 1174 }
1172 1175
1173 if (FLAG_use_ic) { 1176 MaybeObject* result;
1174 MaybeObject* result; 1177 if (HandleLoad(state, object, name, &result)) {
1175 if (HandleLoad(state, object, name, &result)) { 1178 return result;
1176 return result;
1177 }
1178
1179 // TODO(1073): don't ignore the current stub state.
1180 // Use specialized code for getting prototype of functions.
1181 if (object->IsJSFunction() &&
1182 name->Equals(isolate()->heap()->prototype_symbol()) &&
1183 Handle<JSFunction>::cast(object)->should_have_prototype()) {
1184 Handle<JSFunction> function = Handle<JSFunction>::cast(object);
1185 Handle<Code> code =
1186 isolate()->stub_cache()->ComputeKeyedLoadFunctionPrototype(
1187 name, function);
1188 ASSERT(!code.is_null());
1189 set_target(*code);
1190 TRACE_IC("KeyedLoadIC", name, state, target());
1191 return Accessors::FunctionGetPrototype(*object, 0);
1192 }
1193 } 1179 }
1194 1180
1195 // Check if the name is trivially convertible to an index and get 1181 // Check if the name is trivially convertible to an index and get
1196 // the element or char if so. 1182 // the element or char if so.
1197 uint32_t index = 0; 1183 uint32_t index = 0;
1198 if (name->AsArrayIndex(&index)) { 1184 if (name->AsArrayIndex(&index)) {
1199 // Rewrite to the generic keyed load stub. 1185 // Rewrite to the generic keyed load stub.
1200 if (FLAG_use_ic) set_target(*generic_stub()); 1186 if (FLAG_use_ic) set_target(*generic_stub());
1201 return Runtime::GetElementOrCharAt(isolate(), object, index); 1187 return Runtime::GetElementOrCharAt(isolate(), object, index);
1202 } 1188 }
(...skipping 1669 matching lines...) Expand 10 before | Expand all | Expand 10 after
2872 #undef ADDR 2858 #undef ADDR
2873 }; 2859 };
2874 2860
2875 2861
2876 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2862 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2877 return IC_utilities[id]; 2863 return IC_utilities[id];
2878 } 2864 }
2879 2865
2880 2866
2881 } } // namespace v8::internal 2867 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/stub-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698