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

Side by Side Diff: src/ic.cc

Issue 12082023: Do not try to collect the map if the monomorphic IC stub has no map. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add regression test, stay monomorphic when no maps are found in original monomorphic stub. Created 7 years, 10 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 | « no previous file | test/mjsunit/regress/regress-crbug-172345.js » ('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 1121 matching lines...) Expand 10 before | Expand all | Expand 10 after
1132 } 1132 }
1133 } 1133 }
1134 receiver_maps->Add(new_receiver_map); 1134 receiver_maps->Add(new_receiver_map);
1135 return true; 1135 return true;
1136 } 1136 }
1137 1137
1138 1138
1139 static void GetReceiverMapsForStub(Handle<Code> stub, 1139 static void GetReceiverMapsForStub(Handle<Code> stub,
1140 MapHandleList* result) { 1140 MapHandleList* result) {
1141 ASSERT(stub->is_inline_cache_stub()); 1141 ASSERT(stub->is_inline_cache_stub());
1142 if (stub->is_keyed_load_stub() || stub->is_keyed_store_stub()) { 1142 ASSERT(stub->is_keyed_load_stub() || stub->is_keyed_store_stub());
1143 switch (stub->ic_state()) { 1143 switch (stub->ic_state()) {
1144 case MONOMORPHIC: 1144 case MONOMORPHIC: {
1145 result->Add(Handle<Map>(stub->FindFirstMap())); 1145 Map* map = stub->FindFirstMap();
1146 break; 1146 if (map != NULL) {
1147 case POLYMORPHIC: { 1147 result->Add(Handle<Map>(map));
1148 AssertNoAllocation no_allocation;
1149 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1150 for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
1151 RelocInfo* info = it.rinfo();
1152 Handle<Object> object(info->target_object());
1153 ASSERT(object->IsMap());
1154 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
1155 }
1156 break;
1157 } 1148 }
1158 case MEGAMORPHIC: 1149 break;
1159 case GENERIC:
1160 break;
1161 case UNINITIALIZED:
1162 case PREMONOMORPHIC:
1163 case MONOMORPHIC_PROTOTYPE_FAILURE:
1164 case DEBUG_STUB:
1165 UNREACHABLE();
1166 break;
1167 } 1150 }
1151 case POLYMORPHIC: {
1152 AssertNoAllocation no_allocation;
1153 int mask = RelocInfo::ModeMask(RelocInfo::EMBEDDED_OBJECT);
1154 for (RelocIterator it(*stub, mask); !it.done(); it.next()) {
1155 RelocInfo* info = it.rinfo();
1156 Handle<Object> object(info->target_object());
1157 ASSERT(object->IsMap());
1158 AddOneReceiverMapIfMissing(result, Handle<Map>::cast(object));
1159 }
1160 break;
1161 }
1162 case MEGAMORPHIC:
1163 case GENERIC:
1164 break;
1165 case UNINITIALIZED:
1166 case PREMONOMORPHIC:
1167 case MONOMORPHIC_PROTOTYPE_FAILURE:
1168 case DEBUG_STUB:
1169 UNREACHABLE();
1170 break;
1168 } 1171 }
1169 } 1172 }
1170 1173
1171 1174
1172 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) { 1175 Handle<Code> KeyedLoadIC::LoadElementStub(Handle<JSObject> receiver) {
1173 State ic_state = target()->ic_state(); 1176 State ic_state = target()->ic_state();
1174 1177
1175 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1178 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1176 // via megamorphic stubs, since they don't have a map in their relocation info 1179 // via megamorphic stubs, since they don't have a map in their relocation info
1177 // and so the stubs can't be harvested for the object needed for a map check. 1180 // and so the stubs can't be harvested for the object needed for a map check.
1178 if (target()->type() != Code::NORMAL) { 1181 if (target()->type() != Code::NORMAL) {
1179 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); 1182 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
1180 return generic_stub(); 1183 return generic_stub();
1181 } 1184 }
1182 1185
1183 Handle<Map> receiver_map(receiver->map()); 1186 Handle<Map> receiver_map(receiver->map());
1184 MapHandleList target_receiver_maps; 1187 MapHandleList target_receiver_maps;
1185 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1188 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1186 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1189 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1187 // yet will do so and stay there. 1190 // yet will do so and stay there.
1188 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map); 1191 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1189 } 1192 }
1190 1193
1191 if (target() == *string_stub()) { 1194 if (target() == *string_stub()) {
1192 target_receiver_maps.Add(isolate()->factory()->string_map()); 1195 target_receiver_maps.Add(isolate()->factory()->string_map());
1193 } else { 1196 } else {
1194 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); 1197 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
1198 if (target_receiver_maps.length() == 0) {
1199 return isolate()->stub_cache()->ComputeKeyedLoadElement(receiver_map);
1200 }
1195 } 1201 }
1196 1202
1197 // The first time a receiver is seen that is a transitioned version of the 1203 // The first time a receiver is seen that is a transitioned version of the
1198 // previous monomorphic receiver type, assume the new ElementsKind is the 1204 // previous monomorphic receiver type, assume the new ElementsKind is the
1199 // monomorphic type. This benefits global arrays that only transition 1205 // monomorphic type. This benefits global arrays that only transition
1200 // once, and all call sites accessing them are faster if they remain 1206 // once, and all call sites accessing them are faster if they remain
1201 // monomorphic. If this optimistic assumption is not true, the IC will 1207 // monomorphic. If this optimistic assumption is not true, the IC will
1202 // miss again and it will become polymorphic and support both the 1208 // miss again and it will become polymorphic and support both the
1203 // untransitioned and transitioned maps. 1209 // untransitioned and transitioned maps.
1204 if (ic_state == MONOMORPHIC && 1210 if (ic_state == MONOMORPHIC &&
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 MapHandleList target_receiver_maps; 1563 MapHandleList target_receiver_maps;
1558 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1564 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1559 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state 1565 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1560 // yet will do so and stay there. 1566 // yet will do so and stay there.
1561 stub_kind = GetNoTransitionStubKind(stub_kind); 1567 stub_kind = GetNoTransitionStubKind(stub_kind);
1562 return isolate()->stub_cache()->ComputeKeyedStoreElement( 1568 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1563 receiver_map, stub_kind, strict_mode, grow_mode); 1569 receiver_map, stub_kind, strict_mode, grow_mode);
1564 } 1570 }
1565 1571
1566 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); 1572 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
1573 if (target_receiver_maps.length() == 0) {
1574 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1575 // yet will do so and stay there.
1576 stub_kind = GetNoTransitionStubKind(stub_kind);
1577 return isolate()->stub_cache()->ComputeKeyedStoreElement(
1578 receiver_map, stub_kind, strict_mode, grow_mode);
1579 }
1567 // The first time a receiver is seen that is a transitioned version of the 1580 // The first time a receiver is seen that is a transitioned version of the
1568 // previous monomorphic receiver type, assume the new ElementsKind is the 1581 // previous monomorphic receiver type, assume the new ElementsKind is the
1569 // monomorphic type. This benefits global arrays that only transition 1582 // monomorphic type. This benefits global arrays that only transition
1570 // once, and all call sites accessing them are faster if they remain 1583 // once, and all call sites accessing them are faster if they remain
1571 // monomorphic. If this optimistic assumption is not true, the IC will 1584 // monomorphic. If this optimistic assumption is not true, the IC will
1572 // miss again and it will become polymorphic and support both the 1585 // miss again and it will become polymorphic and support both the
1573 // untransitioned and transitioned maps. 1586 // untransitioned and transitioned maps.
1574 if (ic_state == MONOMORPHIC && 1587 if (ic_state == MONOMORPHIC &&
1575 IsTransitionStubKind(stub_kind) && 1588 IsTransitionStubKind(stub_kind) &&
1576 IsMoreGeneralElementsKindTransition( 1589 IsMoreGeneralElementsKindTransition(
(...skipping 973 matching lines...) Expand 10 before | Expand all | Expand 10 after
2550 #undef ADDR 2563 #undef ADDR
2551 }; 2564 };
2552 2565
2553 2566
2554 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2567 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2555 return IC_utilities[id]; 2568 return IC_utilities[id];
2556 } 2569 }
2557 2570
2558 2571
2559 } } // namespace v8::internal 2572 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-crbug-172345.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698