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