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 |