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

Side by Side Diff: src/ic.cc

Issue 11973008: Replace special IC builtins and stubs in the map's cache by codestubs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments 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/ic.h ('k') | src/objects-inl.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 814 matching lines...) Expand 10 before | Expand all | Expand 10 after
825 ReceiverToObjectIfRequired(result, object); 825 ReceiverToObjectIfRequired(result, object);
826 if (result->IsJSFunction()) return *result; 826 if (result->IsJSFunction()) return *result;
827 827
828 result = TryCallAsFunction(result); 828 result = TryCallAsFunction(result);
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,
836 Handle<Object> object,
837 Handle<String> name,
838 MaybeObject** result) {
839 // Use specialized code for getting the length of strings and
840 // string wrapper objects. The length property of string wrapper
841 // objects is read-only and therefore always returns the length of
842 // the underlying string value. See ECMA-262 15.5.5.1.
843 if ((object->IsString() || object->IsStringWrapper()) &&
844 name->Equals(isolate()->heap()->length_symbol())) {
845 Handle<Code> stub;
846 if (state == UNINITIALIZED) {
847 stub = pre_monomorphic_stub();
848 } else if (state == PREMONOMORPHIC) {
849 StringLengthStub string_length_stub(kind(), !object->IsString());
850 stub = string_length_stub.GetCode();
851 } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
852 StringLengthStub string_length_stub(kind(), true);
853 stub = string_length_stub.GetCode();
854 } else if (state != MEGAMORPHIC) {
855 ASSERT(state != GENERIC);
856 stub = megamorphic_stub();
857 }
858 if (!stub.is_null()) {
859 set_target(*stub);
860 #ifdef DEBUG
861 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
862 #endif
863 }
864 // Get the string if we have a string wrapper object.
865 Handle<Object> string = object->IsJSValue()
866 ? Handle<Object>(Handle<JSValue>::cast(object)->value())
867 : object;
868 *result = Smi::FromInt(String::cast(*string)->length());
869 return true;
870 }
871 return false;
872 }
873
874
835 MaybeObject* LoadIC::Load(State state, 875 MaybeObject* LoadIC::Load(State state,
836 Handle<Object> object, 876 Handle<Object> object,
837 Handle<String> name) { 877 Handle<String> name) {
838 // If the object is undefined or null it's illegal to try to get any 878 // If the object is undefined or null it's illegal to try to get any
839 // of its properties; throw a TypeError in that case. 879 // of its properties; throw a TypeError in that case.
840 if (object->IsUndefined() || object->IsNull()) { 880 if (object->IsUndefined() || object->IsNull()) {
841 return TypeError("non_object_property_load", object, name); 881 return TypeError("non_object_property_load", object, name);
842 } 882 }
843 883
844 if (FLAG_use_ic) { 884 if (FLAG_use_ic) {
845 // Use specialized code for getting the length of strings and 885 MaybeObject* result;
846 // string wrapper objects. The length property of string wrapper 886 if (HandleLoad(state, object, name, &result)) {
847 // objects is read-only and therefore always returns the length of 887 return result;
848 // the underlying string value. See ECMA-262 15.5.5.1.
849 if ((object->IsString() || object->IsStringWrapper()) &&
850 name->Equals(isolate()->heap()->length_symbol())) {
851 Handle<Code> stub;
852 if (state == UNINITIALIZED) {
853 stub = pre_monomorphic_stub();
854 } else if (state == PREMONOMORPHIC) {
855 stub = object->IsString()
856 ? isolate()->builtins()->LoadIC_StringLength()
857 : isolate()->builtins()->LoadIC_StringWrapperLength();
858 } else if (state == MONOMORPHIC && object->IsStringWrapper()) {
859 stub = isolate()->builtins()->LoadIC_StringWrapperLength();
860 } else if (state != MEGAMORPHIC) {
861 ASSERT(state != GENERIC);
862 stub = megamorphic_stub();
863 }
864 if (!stub.is_null()) {
865 set_target(*stub);
866 #ifdef DEBUG
867 if (FLAG_trace_ic) PrintF("[LoadIC : +#length /string]\n");
868 #endif
869 }
870 // Get the string if we have a string wrapper object.
871 Handle<Object> string = object->IsJSValue()
872 ? Handle<Object>(Handle<JSValue>::cast(object)->value())
873 : object;
874 return Smi::FromInt(String::cast(*string)->length());
875 } 888 }
876 889
877 // Use specialized code for getting the length of arrays. 890 // Use specialized code for getting the length of arrays.
878 if (object->IsJSArray() && 891 if (object->IsJSArray() &&
879 name->Equals(isolate()->heap()->length_symbol())) { 892 name->Equals(isolate()->heap()->length_symbol())) {
880 Handle<Code> stub; 893 Handle<Code> stub;
881 if (state == UNINITIALIZED) { 894 if (state == UNINITIALIZED) {
882 stub = pre_monomorphic_stub(); 895 stub = pre_monomorphic_stub();
883 } else if (state == PREMONOMORPHIC) { 896 } else if (state == PREMONOMORPHIC) {
884 stub = isolate()->builtins()->LoadIC_ArrayLength(); 897 stub = isolate()->builtins()->LoadIC_ArrayLength();
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 if (key->IsSymbol()) { 1162 if (key->IsSymbol()) {
1150 Handle<String> name = Handle<String>::cast(key); 1163 Handle<String> name = Handle<String>::cast(key);
1151 1164
1152 // If the object is undefined or null it's illegal to try to get any 1165 // If the object is undefined or null it's illegal to try to get any
1153 // of its properties; throw a TypeError in that case. 1166 // of its properties; throw a TypeError in that case.
1154 if (object->IsUndefined() || object->IsNull()) { 1167 if (object->IsUndefined() || object->IsNull()) {
1155 return TypeError("non_object_property_load", object, name); 1168 return TypeError("non_object_property_load", object, name);
1156 } 1169 }
1157 1170
1158 if (FLAG_use_ic) { 1171 if (FLAG_use_ic) {
1159 // TODO(1073): don't ignore the current stub state. 1172 MaybeObject* result;
1160 1173 if (HandleLoad(state, object, name, &result)) {
1161 // Use specialized code for getting the length of strings. 1174 return result;
1162 if (object->IsString() &&
1163 name->Equals(isolate()->heap()->length_symbol())) {
1164 Handle<String> string = Handle<String>::cast(object);
1165 Handle<Code> code =
1166 isolate()->stub_cache()->ComputeKeyedLoadStringLength(name, string);
1167 ASSERT(!code.is_null());
1168 set_target(*code);
1169 TRACE_IC("KeyedLoadIC", name, state, target());
1170 return Smi::FromInt(string->length());
1171 } 1175 }
1172 1176
1177 // TODO(1073): don't ignore the current stub state.
1173 // Use specialized code for getting the length of arrays. 1178 // Use specialized code for getting the length of arrays.
1174 if (object->IsJSArray() && 1179 if (object->IsJSArray() &&
1175 name->Equals(isolate()->heap()->length_symbol())) { 1180 name->Equals(isolate()->heap()->length_symbol())) {
1176 Handle<JSArray> array = Handle<JSArray>::cast(object); 1181 Handle<JSArray> array = Handle<JSArray>::cast(object);
1177 Handle<Code> code = 1182 Handle<Code> code =
1178 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array); 1183 isolate()->stub_cache()->ComputeKeyedLoadArrayLength(name, array);
1179 ASSERT(!code.is_null()); 1184 ASSERT(!code.is_null());
1180 set_target(*code); 1185 set_target(*code);
1181 TRACE_IC("KeyedLoadIC", name, state, target()); 1186 TRACE_IC("KeyedLoadIC", name, state, target());
1182 return array->length(); 1187 return array->length();
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1605 // We are transitioning from monomorphic to megamorphic case. 1610 // We are transitioning from monomorphic to megamorphic case.
1606 // Place the current monomorphic stub and stub compiled for 1611 // Place the current monomorphic stub and stub compiled for
1607 // the receiver into stub cache. 1612 // the receiver into stub cache.
1608 Map* map = target()->FindFirstMap(); 1613 Map* map = target()->FindFirstMap();
1609 if (map != NULL) { 1614 if (map != NULL) {
1610 isolate()->stub_cache()->Set(*name, map, target()); 1615 isolate()->stub_cache()->Set(*name, map, target());
1611 } 1616 }
1612 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 1617 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1613 set_target((strict_mode == kStrictMode) 1618 set_target((strict_mode == kStrictMode)
1614 ? megamorphic_stub_strict() 1619 ? megamorphic_stub_strict()
1615 : megamorphic_stub()); 1620 : *megamorphic_stub());
1616 } 1621 }
1617 break; 1622 break;
1618 case MEGAMORPHIC: 1623 case MEGAMORPHIC:
1619 // Update the stub cache. 1624 // Update the stub cache.
1620 isolate()->stub_cache()->Set(*name, receiver->map(), *code); 1625 isolate()->stub_cache()->Set(*name, receiver->map(), *code);
1621 break; 1626 break;
1622 case DEBUG_STUB: 1627 case DEBUG_STUB:
1623 break; 1628 break;
1624 case POLYMORPHIC: 1629 case POLYMORPHIC:
1625 case GENERIC: 1630 case GENERIC:
(...skipping 1251 matching lines...) Expand 10 before | Expand all | Expand 10 after
2877 #undef ADDR 2882 #undef ADDR
2878 }; 2883 };
2879 2884
2880 2885
2881 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2886 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2882 return IC_utilities[id]; 2887 return IC_utilities[id];
2883 } 2888 }
2884 2889
2885 2890
2886 } } // namespace v8::internal 2891 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698