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

Side by Side Diff: src/ic.cc

Issue 26968004: Turn Load/StoreGlobal into a handler. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 2 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/objects.cc » ('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 748 matching lines...) Expand 10 before | Expand all | Expand 10 after
759 target()->arguments_count(), kind_, extra_ic_state()); 759 target()->arguments_count(), kind_, extra_ic_state());
760 } 760 }
761 761
762 762
763 void CallICBase::UpdateCaches(LookupResult* lookup, 763 void CallICBase::UpdateCaches(LookupResult* lookup,
764 Handle<Object> object, 764 Handle<Object> object,
765 Handle<String> name) { 765 Handle<String> name) {
766 // Bail out if we didn't find a result. 766 // Bail out if we didn't find a result.
767 if (!lookup->IsProperty() || !lookup->IsCacheable()) return; 767 if (!lookup->IsProperty() || !lookup->IsCacheable()) return;
768 768
769 // Compute the number of arguments. 769 if (state() == UNINITIALIZED) {
770 Handle<Code> code; 770 set_target(*pre_monomorphic_stub());
771 code = state() == UNINITIALIZED 771 TRACE_IC("CallIC", name);
772 ? pre_monomorphic_stub() 772 return;
773 : ComputeMonomorphicStub(lookup, object, name); 773 }
774 774
775 Handle<Code> code = ComputeMonomorphicStub(lookup, object, name);
775 // If there's no appropriate stub we simply avoid updating the caches. 776 // If there's no appropriate stub we simply avoid updating the caches.
776 // TODO(verwaest): Install a slow fallback in this case to avoid not learning, 777 // TODO(verwaest): Install a slow fallback in this case to avoid not learning,
777 // and deopting Crankshaft code. 778 // and deopting Crankshaft code.
778 if (code.is_null()) return; 779 if (code.is_null()) return;
779 780
780 Handle<JSObject> cache_object = object->IsJSObject() 781 Handle<JSObject> cache_object = object->IsJSObject()
781 ? Handle<JSObject>::cast(object) 782 ? Handle<JSObject>::cast(object)
782 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())), 783 : Handle<JSObject>(JSObject::cast(object->GetPrototype(isolate())),
783 isolate()); 784 isolate());
784 785
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
945 } 946 }
946 receiver_maps->Add(new_receiver_map); 947 receiver_maps->Add(new_receiver_map);
947 return true; 948 return true;
948 } 949 }
949 950
950 951
951 bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver, 952 bool IC::UpdatePolymorphicIC(Handle<HeapObject> receiver,
952 Handle<String> name, 953 Handle<String> name,
953 Handle<Code> code) { 954 Handle<Code> code) {
954 if (!code->is_handler()) return false; 955 if (!code->is_handler()) return false;
955
956 MapHandleList receiver_maps; 956 MapHandleList receiver_maps;
957 CodeHandleList handlers; 957 CodeHandleList handlers;
958 958
959 int number_of_valid_maps; 959 int number_of_valid_maps;
960 int handler_to_overwrite = -1; 960 int handler_to_overwrite = -1;
961 Handle<Map> new_receiver_map(receiver->map()); 961 Handle<Map> new_receiver_map(receiver->map());
962 { 962 {
963 DisallowHeapAllocation no_gc; 963 DisallowHeapAllocation no_gc;
964 target()->FindAllMaps(&receiver_maps); 964 target()->FindAllMaps(&receiver_maps);
965 int number_of_maps = receiver_maps.length(); 965 int number_of_maps = receiver_maps.length();
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
1124 // well. For now just fail to update the cache. 1124 // well. For now just fail to update the cache.
1125 if (!object->IsHeapObject()) return; 1125 if (!object->IsHeapObject()) return;
1126 1126
1127 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object); 1127 Handle<HeapObject> receiver = Handle<HeapObject>::cast(object);
1128 1128
1129 Handle<Code> code; 1129 Handle<Code> code;
1130 if (state() == UNINITIALIZED) { 1130 if (state() == UNINITIALIZED) {
1131 // This is the first time we execute this inline cache. 1131 // This is the first time we execute this inline cache.
1132 // Set the target to the pre monomorphic stub to delay 1132 // Set the target to the pre monomorphic stub to delay
1133 // setting the monomorphic state. 1133 // setting the monomorphic state.
1134 code = pre_monomorphic_stub(); 1134 set_target(*pre_monomorphic_stub());
1135 TRACE_IC("LoadIC", name);
1136 return;
1135 } else if (!lookup->IsCacheable()) { 1137 } else if (!lookup->IsCacheable()) {
1136 // Bail out if the result is not cacheable. 1138 // Bail out if the result is not cacheable.
1137 code = slow_stub(); 1139 code = slow_stub();
1138 } else if (object->IsString() && 1140 } else if (object->IsString() &&
1139 name->Equals(isolate()->heap()->length_string())) { 1141 name->Equals(isolate()->heap()->length_string())) {
1140 int length_index = String::kLengthOffset / kPointerSize; 1142 int length_index = String::kLengthOffset / kPointerSize;
1141 code = SimpleFieldLoad(length_index); 1143 code = SimpleFieldLoad(length_index);
1142 } else if (!object->IsJSObject()) { 1144 } else if (!object->IsJSObject()) {
1143 // TODO(jkummerow): It would be nice to support non-JSObjects in 1145 // TODO(jkummerow): It would be nice to support non-JSObjects in
1144 // ComputeLoadHandler, then we wouldn't need to go generic here. 1146 // ComputeLoadHandler, then we wouldn't need to go generic here.
(...skipping 21 matching lines...) Expand all
1166 1168
1167 Handle<Code> IC::ComputeHandler(LookupResult* lookup, 1169 Handle<Code> IC::ComputeHandler(LookupResult* lookup,
1168 Handle<JSObject> receiver, 1170 Handle<JSObject> receiver,
1169 Handle<String> name, 1171 Handle<String> name,
1170 Handle<Object> value) { 1172 Handle<Object> value) {
1171 Handle<Code> code = isolate()->stub_cache()->FindHandler( 1173 Handle<Code> code = isolate()->stub_cache()->FindHandler(
1172 name, receiver, kind()); 1174 name, receiver, kind());
1173 if (!code.is_null()) return code; 1175 if (!code.is_null()) return code;
1174 1176
1175 code = CompileHandler(lookup, receiver, name, value); 1177 code = CompileHandler(lookup, receiver, name, value);
1178 ASSERT(code->is_handler());
1176 1179
1177 if (code->is_handler() && code->type() != Code::NORMAL) { 1180 if (code->type() != Code::NORMAL) {
1178 HeapObject::UpdateMapCodeCache(receiver, name, code); 1181 HeapObject::UpdateMapCodeCache(receiver, name, code);
1179 } 1182 }
1180 1183
1181 return code; 1184 return code;
1182 } 1185 }
1183 1186
1184 1187
1185 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup, 1188 Handle<Code> LoadIC::CompileHandler(LookupResult* lookup,
1186 Handle<JSObject> receiver, 1189 Handle<JSObject> receiver,
1187 Handle<String> name, 1190 Handle<String> name,
(...skipping 18 matching lines...) Expand all
1206 // be embedded into code. 1209 // be embedded into code.
1207 if (constant->IsConsString()) break; 1210 if (constant->IsConsString()) break;
1208 return compiler.CompileLoadConstant(receiver, holder, name, constant); 1211 return compiler.CompileLoadConstant(receiver, holder, name, constant);
1209 } 1212 }
1210 case NORMAL: 1213 case NORMAL:
1211 if (kind() != Code::LOAD_IC) break; 1214 if (kind() != Code::LOAD_IC) break;
1212 if (holder->IsGlobalObject()) { 1215 if (holder->IsGlobalObject()) {
1213 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder); 1216 Handle<GlobalObject> global = Handle<GlobalObject>::cast(holder);
1214 Handle<PropertyCell> cell( 1217 Handle<PropertyCell> cell(
1215 global->GetPropertyCell(lookup), isolate()); 1218 global->GetPropertyCell(lookup), isolate());
1216 // TODO(verwaest): Turn into a handler. 1219 Handle<Code> code = compiler.CompileLoadGlobal(
1217 return isolate()->stub_cache()->ComputeLoadGlobal( 1220 receiver, global, cell, name, lookup->IsDontDelete());
1218 name, receiver, global, cell, lookup->IsDontDelete()); 1221 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1222 HeapObject::UpdateMapCodeCache(receiver, name, code);
1223 return code;
1219 } 1224 }
1220 // There is only one shared stub for loading normalized 1225 // There is only one shared stub for loading normalized
1221 // properties. It does not traverse the prototype chain, so the 1226 // properties. It does not traverse the prototype chain, so the
1222 // property must be found in the receiver for the stub to be 1227 // property must be found in the receiver for the stub to be
1223 // applicable. 1228 // applicable.
1224 if (!holder.is_identical_to(receiver)) break; 1229 if (!holder.is_identical_to(receiver)) break;
1225 return isolate()->builtins()->LoadIC_Normal(); 1230 return isolate()->builtins()->LoadIC_Normal();
1226 case CALLBACKS: { 1231 case CALLBACKS: {
1227 // Use simple field loads for some well-known callback properties. 1232 // Use simple field loads for some well-known callback properties.
1228 int object_offset; 1233 int object_offset;
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
1617 return compiler.CompileStoreTransition( 1622 return compiler.CompileStoreTransition(
1618 receiver, lookup, transition, name); 1623 receiver, lookup, transition, name);
1619 } 1624 }
1620 case NORMAL: 1625 case NORMAL:
1621 if (kind() == Code::KEYED_STORE_IC) break; 1626 if (kind() == Code::KEYED_STORE_IC) break;
1622 if (receiver->IsGlobalObject()) { 1627 if (receiver->IsGlobalObject()) {
1623 // The stub generated for the global object picks the value directly 1628 // The stub generated for the global object picks the value directly
1624 // from the property cell. So the property must be directly on the 1629 // from the property cell. So the property must be directly on the
1625 // global object. 1630 // global object.
1626 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver); 1631 Handle<GlobalObject> global = Handle<GlobalObject>::cast(receiver);
1627 Handle<PropertyCell> cell( 1632 Handle<PropertyCell> cell(global->GetPropertyCell(lookup), isolate());
1628 global->GetPropertyCell(lookup), isolate()); 1633 Handle<Type> union_type(PropertyCell::UpdateType(cell, value),
1629 // TODO(verwaest): Turn into a handler. 1634 isolate());
1630 return isolate()->stub_cache()->ComputeStoreGlobal( 1635 StoreGlobalStub stub(strict_mode(), union_type->IsConstant());
1631 name, global, cell, value, strict_mode()); 1636
1637 Handle<Code> code = stub.GetCodeCopyFromTemplate(
1638 isolate(), receiver->map(), *cell);
1639 // TODO(verwaest): Move caching of these NORMAL stubs outside as well.
1640 HeapObject::UpdateMapCodeCache(receiver, name, code);
1641 return code;
1632 } 1642 }
1633 ASSERT(holder.is_identical_to(receiver)); 1643 ASSERT(holder.is_identical_to(receiver));
1634 return strict_mode() == kStrictMode 1644 return strict_mode() == kStrictMode
1635 ? isolate()->builtins()->StoreIC_Normal_Strict() 1645 ? isolate()->builtins()->StoreIC_Normal_Strict()
1636 : isolate()->builtins()->StoreIC_Normal(); 1646 : isolate()->builtins()->StoreIC_Normal();
1637 case CALLBACKS: { 1647 case CALLBACKS: {
1638 if (kind() == Code::KEYED_STORE_IC) break; 1648 if (kind() == Code::KEYED_STORE_IC) break;
1639 Handle<Object> callback(lookup->GetCallbackObject(), isolate()); 1649 Handle<Object> callback(lookup->GetCallbackObject(), isolate());
1640 if (callback->IsExecutableAccessorInfo()) { 1650 if (callback->IsExecutableAccessorInfo()) {
1641 Handle<ExecutableAccessorInfo> info = 1651 Handle<ExecutableAccessorInfo> info =
(...skipping 1071 matching lines...) Expand 10 before | Expand all | Expand 10 after
2713 #undef ADDR 2723 #undef ADDR
2714 }; 2724 };
2715 2725
2716 2726
2717 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2727 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2718 return IC_utilities[id]; 2728 return IC_utilities[id];
2719 } 2729 }
2720 2730
2721 2731
2722 } } // namespace v8::internal 2732 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ia32/stub-cache-ia32.cc ('k') | src/objects.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698