OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |