| 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 |