| 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 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1556  |  1556  | 
|  1557   // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS |  1557   // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS | 
|  1558   // via megamorphic stubs, since they don't have a map in their relocation info |  1558   // via megamorphic stubs, since they don't have a map in their relocation info | 
|  1559   // and so the stubs can't be harvested for the object needed for a map check. |  1559   // and so the stubs can't be harvested for the object needed for a map check. | 
|  1560   if (target()->type() != NORMAL) { |  1560   if (target()->type() != NORMAL) { | 
|  1561     TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); |  1561     TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); | 
|  1562     return generic_stub; |  1562     return generic_stub; | 
|  1563   } |  1563   } | 
|  1564  |  1564  | 
|  1565   bool monomorphic = false; |  1565   bool monomorphic = false; | 
 |  1566   bool is_transition_stub = IsTransitionStubKind(stub_kind); | 
 |  1567   Handle<Map> receiver_map(receiver->map()); | 
 |  1568   Handle<Map> monomorphic_map = receiver_map; | 
|  1566   MapHandleList target_receiver_maps; |  1569   MapHandleList target_receiver_maps; | 
|  1567   if (ic_state != UNINITIALIZED && ic_state != PREMONOMORPHIC) { |  1570   if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { | 
 |  1571     // Optimistically assume that ICs that haven't reached the MONOMORPHIC state | 
 |  1572     // yet will do so and stay there. | 
 |  1573     monomorphic = true; | 
 |  1574   } else { | 
|  1568     GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); |  1575     GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); | 
|  1569   } |  1576     if (ic_state == MONOMORPHIC && is_transition_stub) { | 
|  1570   if (!IsTransitionStubKind(stub_kind)) { |  1577       // The first time a receiver is seen that is a transitioned version of the | 
|  1571     if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { |  1578       // previous monomorphic receiver type, assume the new ElementsKind is the | 
|  1572       monomorphic = true; |  1579       // monomorphic type. This benefits global arrays that only transition | 
|  1573     } else { |  1580       // once, and all call sites accessing them are faster if they remain | 
|  1574       if (ic_state == MONOMORPHIC) { |  1581       // monomorphic. If this optimistic assumption is not true, the IC will | 
|  1575         // The first time a receiver is seen that is a transitioned version of |  1582       // miss again and it will become polymorphic and support both the | 
|  1576         // the previous monomorphic receiver type, assume the new ElementsKind |  1583       // untransitioned and transitioned maps. | 
|  1577         // is the monomorphic type. This benefits global arrays that only |  1584       monomorphic = IsMoreGeneralElementsKindTransition( | 
|  1578         // transition once, and all call sites accessing them are faster if they |  1585           target_receiver_maps.at(0)->elements_kind(), | 
|  1579         // remain monomorphic. If this optimistic assumption is not true, the IC |  1586           receiver->GetElementsKind()); | 
|  1580         // will miss again and it will become polymorphic and support both the |  | 
|  1581         // untransitioned and transitioned maps. |  | 
|  1582         monomorphic = IsMoreGeneralElementsKindTransition( |  | 
|  1583             target_receiver_maps.at(0)->elements_kind(), |  | 
|  1584             receiver->GetElementsKind()); |  | 
|  1585       } |  | 
|  1586     } |  1587     } | 
|  1587   } |  1588   } | 
|  1588  |  1589  | 
|  1589   if (monomorphic) { |  1590   if (monomorphic) { | 
 |  1591     if (is_transition_stub) { | 
 |  1592       monomorphic_map = ComputeTransitionedMap(receiver, stub_kind); | 
 |  1593       ASSERT(*monomorphic_map != *receiver_map); | 
 |  1594       stub_kind = GetNoTransitionStubKind(stub_kind); | 
 |  1595     } | 
|  1590     return ComputeMonomorphicStub( |  1596     return ComputeMonomorphicStub( | 
|  1591         receiver, stub_kind, strict_mode, generic_stub); |  1597         monomorphic_map, stub_kind, strict_mode, generic_stub); | 
|  1592   } |  1598   } | 
|  1593   ASSERT(target() != *generic_stub); |  1599   ASSERT(target() != *generic_stub); | 
|  1594  |  1600  | 
|  1595   // Determine the list of receiver maps that this call site has seen, |  1601   // Determine the list of receiver maps that this call site has seen, | 
|  1596   // adding the map that was just encountered. |  1602   // adding the map that was just encountered. | 
|  1597   Handle<Map> receiver_map(receiver->map()); |  | 
|  1598   bool map_added = |  1603   bool map_added = | 
|  1599       AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |  1604       AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 
|  1600   if (IsTransitionStubKind(stub_kind)) { |  1605   if (IsTransitionStubKind(stub_kind)) { | 
|  1601     Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); |  1606     Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); | 
|  1602     map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); |  1607     map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); | 
|  1603   } |  1608   } | 
|  1604   if (!map_added) { |  1609   if (!map_added) { | 
|  1605     // If the miss wasn't due to an unseen map, a polymorphic stub |  1610     // If the miss wasn't due to an unseen map, a polymorphic stub | 
|  1606     // won't help, use the generic stub. |  1611     // won't help, use the generic stub. | 
|  1607     TRACE_GENERIC_IC("KeyedIC", "same map added twice"); |  1612     TRACE_GENERIC_IC("KeyedIC", "same map added twice"); | 
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1648            receiver_map->has_fast_double_elements() || |  1653            receiver_map->has_fast_double_elements() || | 
|  1649            receiver_map->has_external_array_elements()); |  1654            receiver_map->has_external_array_elements()); | 
|  1650     bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; |  1655     bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; | 
|  1651     return GetElementStubWithoutMapCheck(is_js_array, |  1656     return GetElementStubWithoutMapCheck(is_js_array, | 
|  1652                                          receiver_map->elements_kind(), |  1657                                          receiver_map->elements_kind(), | 
|  1653                                          grow_mode); |  1658                                          grow_mode); | 
|  1654   } |  1659   } | 
|  1655 } |  1660 } | 
|  1656  |  1661  | 
|  1657  |  1662  | 
|  1658 Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver, |  1663 Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<Map> receiver_map, | 
|  1659                                              StubKind stub_kind, |  1664                                              StubKind stub_kind, | 
|  1660                                              StrictModeFlag strict_mode, |  1665                                              StrictModeFlag strict_mode, | 
|  1661                                              Handle<Code> generic_stub) { |  1666                                              Handle<Code> generic_stub) { | 
|  1662   if (receiver->HasFastSmiOrObjectElements() || |  1667   ElementsKind elements_kind = receiver_map->elements_kind(); | 
|  1663       receiver->HasExternalArrayElements() || |  1668   if (IsFastElementsKind(elements_kind) || | 
|  1664       receiver->HasFastDoubleElements() || |  1669       IsExternalArrayElementsKind(elements_kind) || | 
|  1665       receiver->HasDictionaryElements()) { |  1670       IsDictionaryElementsKind(elements_kind)) { | 
|  1666     return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement( |  1671     return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement( | 
|  1667         receiver, stub_kind, strict_mode); |  1672         receiver_map, stub_kind, strict_mode); | 
|  1668   } else { |  1673   } else { | 
|  1669     return generic_stub; |  1674     return generic_stub; | 
|  1670   } |  1675   } | 
|  1671 } |  1676 } | 
|  1672  |  1677  | 
|  1673  |  1678  | 
|  1674 Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver, |  1679 Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver, | 
|  1675                                             StubKind stub_kind) { |  1680                                             StubKind stub_kind) { | 
|  1676   switch (stub_kind) { |  1681   switch (stub_kind) { | 
|  1677     case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT: |  1682     case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT: | 
| (...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2639 #undef ADDR |  2644 #undef ADDR | 
|  2640 }; |  2645 }; | 
|  2641  |  2646  | 
|  2642  |  2647  | 
|  2643 Address IC::AddressFromUtilityId(IC::UtilityId id) { |  2648 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 
|  2644   return IC_utilities[id]; |  2649   return IC_utilities[id]; | 
|  2645 } |  2650 } | 
|  2646  |  2651  | 
|  2647  |  2652  | 
|  2648 } }  // namespace v8::internal |  2653 } }  // namespace v8::internal | 
| OLD | NEW |