| OLD | NEW | 
|---|
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "v8.h" | 5 #include "v8.h" | 
| 6 | 6 | 
| 7 #include "accessors.h" | 7 #include "accessors.h" | 
| 8 #include "api.h" | 8 #include "api.h" | 
| 9 #include "arguments.h" | 9 #include "arguments.h" | 
| 10 #include "codegen.h" | 10 #include "codegen.h" | 
| (...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1457   // and so the stubs can't be harvested for the object needed for a map check. | 1457   // and so the stubs can't be harvested for the object needed for a map check. | 
| 1458   if (target()->type() != Code::NORMAL) { | 1458   if (target()->type() != Code::NORMAL) { | 
| 1459     TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); | 1459     TRACE_GENERIC_IC(isolate(), "KeyedIC", "non-NORMAL target type"); | 
| 1460     return generic_stub(); | 1460     return generic_stub(); | 
| 1461   } | 1461   } | 
| 1462 | 1462 | 
| 1463   Handle<Map> receiver_map(receiver->map(), isolate()); | 1463   Handle<Map> receiver_map(receiver->map(), isolate()); | 
| 1464   MapHandleList target_receiver_maps; | 1464   MapHandleList target_receiver_maps; | 
| 1465   TargetMaps(&target_receiver_maps); | 1465   TargetMaps(&target_receiver_maps); | 
| 1466   if (target_receiver_maps.length() == 0) { | 1466   if (target_receiver_maps.length() == 0) { | 
| 1467     Handle<Map> monomorphic_map = ComputeTransitionedMap(receiver, store_mode); | 1467     Handle<Map> monomorphic_map = | 
|  | 1468         ComputeTransitionedMap(receiver_map, store_mode); | 
| 1468     store_mode = GetNonTransitioningStoreMode(store_mode); | 1469     store_mode = GetNonTransitioningStoreMode(store_mode); | 
| 1469     return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1470     return isolate()->stub_cache()->ComputeKeyedStoreElement( | 
| 1470         monomorphic_map, strict_mode(), store_mode); | 1471         monomorphic_map, strict_mode(), store_mode); | 
| 1471   } | 1472   } | 
| 1472 | 1473 | 
| 1473   // There are several special cases where an IC that is MONOMORPHIC can still | 1474   // There are several special cases where an IC that is MONOMORPHIC can still | 
| 1474   // transition to a different GetNonTransitioningStoreMode IC that handles a | 1475   // transition to a different GetNonTransitioningStoreMode IC that handles a | 
| 1475   // superset of the original IC. Handle those here if the receiver map hasn't | 1476   // superset of the original IC. Handle those here if the receiver map hasn't | 
| 1476   // changed or it has transitioned to a more general kind. | 1477   // changed or it has transitioned to a more general kind. | 
| 1477   KeyedAccessStoreMode old_store_mode = | 1478   KeyedAccessStoreMode old_store_mode = | 
| 1478       KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); | 1479       KeyedStoreIC::GetKeyedAccessStoreMode(target()->extra_ic_state()); | 
| 1479   Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | 1480   Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | 
| 1480   if (state() == MONOMORPHIC) { | 1481   if (state() == MONOMORPHIC) { | 
| 1481     Handle<Map> transitioned_receiver_map = receiver_map; | 1482     Handle<Map> transitioned_receiver_map = receiver_map; | 
| 1482     if (IsTransitionStoreMode(store_mode)) { | 1483     if (IsTransitionStoreMode(store_mode)) { | 
| 1483       transitioned_receiver_map = ComputeTransitionedMap(receiver, store_mode); | 1484       transitioned_receiver_map = | 
|  | 1485           ComputeTransitionedMap(receiver_map, store_mode); | 
| 1484     } | 1486     } | 
| 1485     if ((receiver_map.is_identical_to(previous_receiver_map) && | 1487     if ((receiver_map.is_identical_to(previous_receiver_map) && | 
| 1486          IsTransitionStoreMode(store_mode)) || | 1488          IsTransitionStoreMode(store_mode)) || | 
| 1487         IsTransitionOfMonomorphicTarget(*previous_receiver_map, | 1489         IsTransitionOfMonomorphicTarget(*previous_receiver_map, | 
| 1488                                         *transitioned_receiver_map)) { | 1490                                         *transitioned_receiver_map)) { | 
| 1489       // If the "old" and "new" maps are in the same elements map family, or | 1491       // If the "old" and "new" maps are in the same elements map family, or | 
| 1490       // if they at least come from the same origin for a transitioning store, | 1492       // if they at least come from the same origin for a transitioning store, | 
| 1491       // stay MONOMORPHIC and use the map for the most generic ElementsKind. | 1493       // stay MONOMORPHIC and use the map for the most generic ElementsKind. | 
| 1492       store_mode = GetNonTransitioningStoreMode(store_mode); | 1494       store_mode = GetNonTransitioningStoreMode(store_mode); | 
| 1493       return isolate()->stub_cache()->ComputeKeyedStoreElement( | 1495       return isolate()->stub_cache()->ComputeKeyedStoreElement( | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 1505     } | 1507     } | 
| 1506   } | 1508   } | 
| 1507 | 1509 | 
| 1508   ASSERT(state() != GENERIC); | 1510   ASSERT(state() != GENERIC); | 
| 1509 | 1511 | 
| 1510   bool map_added = | 1512   bool map_added = | 
| 1511       AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1513       AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 
| 1512 | 1514 | 
| 1513   if (IsTransitionStoreMode(store_mode)) { | 1515   if (IsTransitionStoreMode(store_mode)) { | 
| 1514     Handle<Map> transitioned_receiver_map = | 1516     Handle<Map> transitioned_receiver_map = | 
| 1515         ComputeTransitionedMap(receiver, store_mode); | 1517         ComputeTransitionedMap(receiver_map, store_mode); | 
| 1516     map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, | 1518     map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, | 
| 1517                                             transitioned_receiver_map); | 1519                                             transitioned_receiver_map); | 
| 1518   } | 1520   } | 
| 1519 | 1521 | 
| 1520   if (!map_added) { | 1522   if (!map_added) { | 
| 1521     // If the miss wasn't due to an unseen map, a polymorphic stub | 1523     // If the miss wasn't due to an unseen map, a polymorphic stub | 
| 1522     // won't help, use the generic stub. | 1524     // won't help, use the generic stub. | 
| 1523     TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); | 1525     TRACE_GENERIC_IC(isolate(), "KeyedIC", "same map added twice"); | 
| 1524     return generic_stub(); | 1526     return generic_stub(); | 
| 1525   } | 1527   } | 
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1561       return generic_stub(); | 1563       return generic_stub(); | 
| 1562     } | 1564     } | 
| 1563   } | 1565   } | 
| 1564 | 1566 | 
| 1565   return isolate()->stub_cache()->ComputeStoreElementPolymorphic( | 1567   return isolate()->stub_cache()->ComputeStoreElementPolymorphic( | 
| 1566       &target_receiver_maps, store_mode, strict_mode()); | 1568       &target_receiver_maps, store_mode, strict_mode()); | 
| 1567 } | 1569 } | 
| 1568 | 1570 | 
| 1569 | 1571 | 
| 1570 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( | 1572 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( | 
| 1571     Handle<JSObject> receiver, | 1573     Handle<Map> map, | 
| 1572     KeyedAccessStoreMode store_mode) { | 1574     KeyedAccessStoreMode store_mode) { | 
| 1573   switch (store_mode) { | 1575   switch (store_mode) { | 
| 1574     case STORE_TRANSITION_SMI_TO_OBJECT: | 1576     case STORE_TRANSITION_SMI_TO_OBJECT: | 
| 1575     case STORE_TRANSITION_DOUBLE_TO_OBJECT: | 1577     case STORE_TRANSITION_DOUBLE_TO_OBJECT: | 
| 1576     case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: | 1578     case STORE_AND_GROW_TRANSITION_SMI_TO_OBJECT: | 
| 1577     case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: | 1579     case STORE_AND_GROW_TRANSITION_DOUBLE_TO_OBJECT: | 
| 1578       return JSObject::GetElementsTransitionMap(receiver, FAST_ELEMENTS); | 1580       return Map::TransitionElementsTo(map, FAST_ELEMENTS); | 
| 1579     case STORE_TRANSITION_SMI_TO_DOUBLE: | 1581     case STORE_TRANSITION_SMI_TO_DOUBLE: | 
| 1580     case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE: | 1582     case STORE_AND_GROW_TRANSITION_SMI_TO_DOUBLE: | 
| 1581       return JSObject::GetElementsTransitionMap(receiver, FAST_DOUBLE_ELEMENTS); | 1583       return Map::TransitionElementsTo(map, FAST_DOUBLE_ELEMENTS); | 
| 1582     case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT: | 1584     case STORE_TRANSITION_HOLEY_SMI_TO_OBJECT: | 
| 1583     case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: | 1585     case STORE_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: | 
| 1584     case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT: | 1586     case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_OBJECT: | 
| 1585     case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: | 1587     case STORE_AND_GROW_TRANSITION_HOLEY_DOUBLE_TO_OBJECT: | 
| 1586       return JSObject::GetElementsTransitionMap(receiver, | 1588       return Map::TransitionElementsTo(map, FAST_HOLEY_ELEMENTS); | 
| 1587                                                 FAST_HOLEY_ELEMENTS); |  | 
| 1588     case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: | 1589     case STORE_TRANSITION_HOLEY_SMI_TO_DOUBLE: | 
| 1589     case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: | 1590     case STORE_AND_GROW_TRANSITION_HOLEY_SMI_TO_DOUBLE: | 
| 1590       return JSObject::GetElementsTransitionMap(receiver, | 1591       return Map::TransitionElementsTo(map, FAST_HOLEY_DOUBLE_ELEMENTS); | 
| 1591                                                 FAST_HOLEY_DOUBLE_ELEMENTS); |  | 
| 1592     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: | 1592     case STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS: | 
| 1593       ASSERT(receiver->map()->has_external_array_elements()); | 1593       ASSERT(map->has_external_array_elements()); | 
| 1594       // Fall through | 1594       // Fall through | 
| 1595     case STORE_NO_TRANSITION_HANDLE_COW: | 1595     case STORE_NO_TRANSITION_HANDLE_COW: | 
| 1596     case STANDARD_STORE: | 1596     case STANDARD_STORE: | 
| 1597     case STORE_AND_GROW_NO_TRANSITION: | 1597     case STORE_AND_GROW_NO_TRANSITION: | 
| 1598       return Handle<Map>(receiver->map(), isolate()); | 1598       return map; | 
| 1599   } | 1599   } | 
| 1600   return Handle<Map>::null(); | 1600   UNREACHABLE(); | 
|  | 1601   return MaybeHandle<Map>().ToHandleChecked(); | 
| 1601 } | 1602 } | 
| 1602 | 1603 | 
| 1603 | 1604 | 
| 1604 bool IsOutOfBoundsAccess(Handle<JSObject> receiver, | 1605 bool IsOutOfBoundsAccess(Handle<JSObject> receiver, | 
| 1605                          int index) { | 1606                          int index) { | 
| 1606   if (receiver->IsJSArray()) { | 1607   if (receiver->IsJSArray()) { | 
| 1607     return JSArray::cast(*receiver)->length()->IsSmi() && | 1608     return JSArray::cast(*receiver)->length()->IsSmi() && | 
| 1608         index >= Smi::cast(JSArray::cast(*receiver)->length())->value(); | 1609         index >= Smi::cast(JSArray::cast(*receiver)->length())->value(); | 
| 1609   } | 1610   } | 
| 1610   return index >= receiver->elements()->length(); | 1611   return index >= receiver->elements()->length(); | 
| (...skipping 1296 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2907 #undef ADDR | 2908 #undef ADDR | 
| 2908 }; | 2909 }; | 
| 2909 | 2910 | 
| 2910 | 2911 | 
| 2911 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 2912 Address IC::AddressFromUtilityId(IC::UtilityId id) { | 
| 2912   return IC_utilities[id]; | 2913   return IC_utilities[id]; | 
| 2913 } | 2914 } | 
| 2914 | 2915 | 
| 2915 | 2916 | 
| 2916 } }  // namespace v8::internal | 2917 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|