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 "src/ic/ic.h" | 5 #include "src/ic/ic.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/api.h" | 8 #include "src/api.h" |
9 #include "src/api-arguments.h" | 9 #include "src/api-arguments.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 Handle<Code> StoreIC::initialize_stub_in_optimized_code( | 1424 Handle<Code> StoreIC::initialize_stub_in_optimized_code( |
1425 Isolate* isolate, LanguageMode language_mode, State initialization_state) { | 1425 Isolate* isolate, LanguageMode language_mode, State initialization_state) { |
1426 DCHECK(initialization_state == UNINITIALIZED || | 1426 DCHECK(initialization_state == UNINITIALIZED || |
1427 initialization_state == PREMONOMORPHIC || | 1427 initialization_state == PREMONOMORPHIC || |
1428 initialization_state == MEGAMORPHIC); | 1428 initialization_state == MEGAMORPHIC); |
1429 if (initialization_state != MEGAMORPHIC) { | 1429 if (initialization_state != MEGAMORPHIC) { |
1430 VectorStoreICStub stub(isolate, StoreICState(language_mode)); | 1430 VectorStoreICStub stub(isolate, StoreICState(language_mode)); |
1431 return stub.GetCode(); | 1431 return stub.GetCode(); |
1432 } | 1432 } |
1433 | 1433 |
1434 return is_strict(language_mode) | 1434 return PropertyICCompiler::ComputeStore(isolate, initialization_state, |
1435 ? isolate->builtins()->StoreIC_Megamorphic_Strict() | 1435 ComputeExtraICState(language_mode)); |
1436 : isolate->builtins()->StoreIC_Megamorphic(); | |
1437 } | 1436 } |
1438 | 1437 |
1439 Handle<Code> StoreIC::slow_stub() const { | 1438 Handle<Code> StoreIC::slow_stub() const { |
1440 if (kind() == Code::STORE_IC) { | 1439 if (kind() == Code::STORE_IC) { |
1441 return isolate()->builtins()->StoreIC_Slow(); | 1440 return isolate()->builtins()->StoreIC_Slow(); |
1442 } else { | 1441 } else { |
1443 DCHECK(kind() == Code::KEYED_STORE_IC); | 1442 DCHECK(kind() == Code::KEYED_STORE_IC); |
1444 return isolate()->builtins()->KeyedStoreIC_Slow(); | 1443 return isolate()->builtins()->KeyedStoreIC_Slow(); |
1445 } | 1444 } |
1446 } | 1445 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1625 | 1624 |
1626 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, | 1625 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, |
1627 KeyedAccessStoreMode store_mode) { | 1626 KeyedAccessStoreMode store_mode) { |
1628 MapHandleList target_receiver_maps; | 1627 MapHandleList target_receiver_maps; |
1629 TargetMaps(&target_receiver_maps); | 1628 TargetMaps(&target_receiver_maps); |
1630 if (target_receiver_maps.length() == 0) { | 1629 if (target_receiver_maps.length() == 0) { |
1631 Handle<Map> monomorphic_map = | 1630 Handle<Map> monomorphic_map = |
1632 ComputeTransitionedMap(receiver_map, store_mode); | 1631 ComputeTransitionedMap(receiver_map, store_mode); |
1633 store_mode = GetNonTransitioningStoreMode(store_mode); | 1632 store_mode = GetNonTransitioningStoreMode(store_mode); |
1634 Handle<Code> handler = | 1633 Handle<Code> handler = |
1635 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(monomorphic_map, | 1634 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
1636 store_mode); | 1635 monomorphic_map, language_mode(), store_mode); |
1637 return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler); | 1636 return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler); |
1638 } | 1637 } |
1639 | 1638 |
1640 // There are several special cases where an IC that is MONOMORPHIC can still | 1639 // There are several special cases where an IC that is MONOMORPHIC can still |
1641 // transition to a different GetNonTransitioningStoreMode IC that handles a | 1640 // transition to a different GetNonTransitioningStoreMode IC that handles a |
1642 // superset of the original IC. Handle those here if the receiver map hasn't | 1641 // superset of the original IC. Handle those here if the receiver map hasn't |
1643 // changed or it has transitioned to a more general kind. | 1642 // changed or it has transitioned to a more general kind. |
1644 KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode(); | 1643 KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode(); |
1645 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | 1644 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); |
1646 if (state() == MONOMORPHIC) { | 1645 if (state() == MONOMORPHIC) { |
1647 Handle<Map> transitioned_receiver_map = receiver_map; | 1646 Handle<Map> transitioned_receiver_map = receiver_map; |
1648 if (IsTransitionStoreMode(store_mode)) { | 1647 if (IsTransitionStoreMode(store_mode)) { |
1649 transitioned_receiver_map = | 1648 transitioned_receiver_map = |
1650 ComputeTransitionedMap(receiver_map, store_mode); | 1649 ComputeTransitionedMap(receiver_map, store_mode); |
1651 } | 1650 } |
1652 if ((receiver_map.is_identical_to(previous_receiver_map) && | 1651 if ((receiver_map.is_identical_to(previous_receiver_map) && |
1653 IsTransitionStoreMode(store_mode)) || | 1652 IsTransitionStoreMode(store_mode)) || |
1654 IsTransitionOfMonomorphicTarget(*previous_receiver_map, | 1653 IsTransitionOfMonomorphicTarget(*previous_receiver_map, |
1655 *transitioned_receiver_map)) { | 1654 *transitioned_receiver_map)) { |
1656 // If the "old" and "new" maps are in the same elements map family, or | 1655 // If the "old" and "new" maps are in the same elements map family, or |
1657 // if they at least come from the same origin for a transitioning store, | 1656 // if they at least come from the same origin for a transitioning store, |
1658 // stay MONOMORPHIC and use the map for the most generic ElementsKind. | 1657 // stay MONOMORPHIC and use the map for the most generic ElementsKind. |
1659 store_mode = GetNonTransitioningStoreMode(store_mode); | 1658 store_mode = GetNonTransitioningStoreMode(store_mode); |
1660 Handle<Code> handler = | 1659 Handle<Code> handler = |
1661 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 1660 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
1662 transitioned_receiver_map, store_mode); | 1661 transitioned_receiver_map, language_mode(), store_mode); |
1663 ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler); | 1662 ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler); |
1664 return; | 1663 return; |
1665 } | 1664 } |
1666 if (receiver_map.is_identical_to(previous_receiver_map) && | 1665 if (receiver_map.is_identical_to(previous_receiver_map) && |
1667 old_store_mode == STANDARD_STORE && | 1666 old_store_mode == STANDARD_STORE && |
1668 (store_mode == STORE_AND_GROW_NO_TRANSITION || | 1667 (store_mode == STORE_AND_GROW_NO_TRANSITION || |
1669 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 1668 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
1670 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { | 1669 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { |
1671 // A "normal" IC that handles stores can switch to a version that can | 1670 // A "normal" IC that handles stores can switch to a version that can |
1672 // grow at the end of the array, handle OOB accesses or copy COW arrays | 1671 // grow at the end of the array, handle OOB accesses or copy COW arrays |
1673 // and still stay MONOMORPHIC. | 1672 // and still stay MONOMORPHIC. |
1674 Handle<Code> handler = | 1673 Handle<Code> handler = |
1675 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(receiver_map, | 1674 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
1676 store_mode); | 1675 receiver_map, language_mode(), store_mode); |
1677 return ConfigureVectorState(Handle<Name>(), receiver_map, handler); | 1676 return ConfigureVectorState(Handle<Name>(), receiver_map, handler); |
1678 } | 1677 } |
1679 } | 1678 } |
1680 | 1679 |
1681 DCHECK(state() != GENERIC); | 1680 DCHECK(state() != GENERIC); |
1682 | 1681 |
1683 bool map_added = | 1682 bool map_added = |
1684 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1683 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
1685 | 1684 |
1686 if (IsTransitionStoreMode(store_mode)) { | 1685 if (IsTransitionStoreMode(store_mode)) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1727 external_arrays != target_receiver_maps.length()) { | 1726 external_arrays != target_receiver_maps.length()) { |
1728 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | 1727 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
1729 "unsupported combination of external and normal arrays"); | 1728 "unsupported combination of external and normal arrays"); |
1730 return; | 1729 return; |
1731 } | 1730 } |
1732 } | 1731 } |
1733 | 1732 |
1734 MapHandleList transitioned_maps(target_receiver_maps.length()); | 1733 MapHandleList transitioned_maps(target_receiver_maps.length()); |
1735 CodeHandleList handlers(target_receiver_maps.length()); | 1734 CodeHandleList handlers(target_receiver_maps.length()); |
1736 PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( | 1735 PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( |
1737 &target_receiver_maps, &transitioned_maps, &handlers, store_mode); | 1736 &target_receiver_maps, &transitioned_maps, &handlers, store_mode, |
| 1737 language_mode()); |
1738 ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers); | 1738 ConfigureVectorState(&target_receiver_maps, &transitioned_maps, &handlers); |
1739 } | 1739 } |
1740 | 1740 |
1741 | 1741 |
1742 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( | 1742 Handle<Map> KeyedStoreIC::ComputeTransitionedMap( |
1743 Handle<Map> map, KeyedAccessStoreMode store_mode) { | 1743 Handle<Map> map, KeyedAccessStoreMode store_mode) { |
1744 switch (store_mode) { | 1744 switch (store_mode) { |
1745 case STORE_TRANSITION_TO_OBJECT: | 1745 case STORE_TRANSITION_TO_OBJECT: |
1746 case STORE_AND_GROW_TRANSITION_TO_OBJECT: { | 1746 case STORE_AND_GROW_TRANSITION_TO_OBJECT: { |
1747 ElementsKind kind = IsFastHoleyElementsKind(map->elements_kind()) | 1747 ElementsKind kind = IsFastHoleyElementsKind(map->elements_kind()) |
(...skipping 982 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2730 KeyedLoadICNexus nexus(vector, vector_slot); | 2730 KeyedLoadICNexus nexus(vector, vector_slot); |
2731 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); | 2731 KeyedLoadIC ic(IC::EXTRA_CALL_FRAME, isolate, &nexus); |
2732 ic.UpdateState(receiver, key); | 2732 ic.UpdateState(receiver, key); |
2733 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); | 2733 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, ic.Load(receiver, key)); |
2734 } | 2734 } |
2735 | 2735 |
2736 return *result; | 2736 return *result; |
2737 } | 2737 } |
2738 } // namespace internal | 2738 } // namespace internal |
2739 } // namespace v8 | 2739 } // namespace v8 |
OLD | NEW |