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 PropertyICCompiler::ComputeStore(isolate, initialization_state, | 1434 return is_strict(language_mode) |
1435 ComputeExtraICState(language_mode)); | 1435 ? isolate->builtins()->StoreIC_Megamorphic_Strict() |
| 1436 : isolate->builtins()->StoreIC_Megamorphic(); |
1436 } | 1437 } |
1437 | 1438 |
1438 Handle<Code> StoreIC::slow_stub() const { | 1439 Handle<Code> StoreIC::slow_stub() const { |
1439 if (kind() == Code::STORE_IC) { | 1440 if (kind() == Code::STORE_IC) { |
1440 return isolate()->builtins()->StoreIC_Slow(); | 1441 return isolate()->builtins()->StoreIC_Slow(); |
1441 } else { | 1442 } else { |
1442 DCHECK(kind() == Code::KEYED_STORE_IC); | 1443 DCHECK(kind() == Code::KEYED_STORE_IC); |
1443 return isolate()->builtins()->KeyedStoreIC_Slow(); | 1444 return isolate()->builtins()->KeyedStoreIC_Slow(); |
1444 } | 1445 } |
1445 } | 1446 } |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1624 | 1625 |
1625 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, | 1626 void KeyedStoreIC::UpdateStoreElement(Handle<Map> receiver_map, |
1626 KeyedAccessStoreMode store_mode) { | 1627 KeyedAccessStoreMode store_mode) { |
1627 MapHandleList target_receiver_maps; | 1628 MapHandleList target_receiver_maps; |
1628 TargetMaps(&target_receiver_maps); | 1629 TargetMaps(&target_receiver_maps); |
1629 if (target_receiver_maps.length() == 0) { | 1630 if (target_receiver_maps.length() == 0) { |
1630 Handle<Map> monomorphic_map = | 1631 Handle<Map> monomorphic_map = |
1631 ComputeTransitionedMap(receiver_map, store_mode); | 1632 ComputeTransitionedMap(receiver_map, store_mode); |
1632 store_mode = GetNonTransitioningStoreMode(store_mode); | 1633 store_mode = GetNonTransitioningStoreMode(store_mode); |
1633 Handle<Code> handler = | 1634 Handle<Code> handler = |
1634 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 1635 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(monomorphic_map, |
1635 monomorphic_map, language_mode(), store_mode); | 1636 store_mode); |
1636 return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler); | 1637 return ConfigureVectorState(Handle<Name>(), monomorphic_map, handler); |
1637 } | 1638 } |
1638 | 1639 |
1639 // There are several special cases where an IC that is MONOMORPHIC can still | 1640 // There are several special cases where an IC that is MONOMORPHIC can still |
1640 // transition to a different GetNonTransitioningStoreMode IC that handles a | 1641 // transition to a different GetNonTransitioningStoreMode IC that handles a |
1641 // superset of the original IC. Handle those here if the receiver map hasn't | 1642 // superset of the original IC. Handle those here if the receiver map hasn't |
1642 // changed or it has transitioned to a more general kind. | 1643 // changed or it has transitioned to a more general kind. |
1643 KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode(); | 1644 KeyedAccessStoreMode old_store_mode = GetKeyedAccessStoreMode(); |
1644 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); | 1645 Handle<Map> previous_receiver_map = target_receiver_maps.at(0); |
1645 if (state() == MONOMORPHIC) { | 1646 if (state() == MONOMORPHIC) { |
1646 Handle<Map> transitioned_receiver_map = receiver_map; | 1647 Handle<Map> transitioned_receiver_map = receiver_map; |
1647 if (IsTransitionStoreMode(store_mode)) { | 1648 if (IsTransitionStoreMode(store_mode)) { |
1648 transitioned_receiver_map = | 1649 transitioned_receiver_map = |
1649 ComputeTransitionedMap(receiver_map, store_mode); | 1650 ComputeTransitionedMap(receiver_map, store_mode); |
1650 } | 1651 } |
1651 if ((receiver_map.is_identical_to(previous_receiver_map) && | 1652 if ((receiver_map.is_identical_to(previous_receiver_map) && |
1652 IsTransitionStoreMode(store_mode)) || | 1653 IsTransitionStoreMode(store_mode)) || |
1653 IsTransitionOfMonomorphicTarget(*previous_receiver_map, | 1654 IsTransitionOfMonomorphicTarget(*previous_receiver_map, |
1654 *transitioned_receiver_map)) { | 1655 *transitioned_receiver_map)) { |
1655 // If the "old" and "new" maps are in the same elements map family, or | 1656 // If the "old" and "new" maps are in the same elements map family, or |
1656 // if they at least come from the same origin for a transitioning store, | 1657 // if they at least come from the same origin for a transitioning store, |
1657 // stay MONOMORPHIC and use the map for the most generic ElementsKind. | 1658 // stay MONOMORPHIC and use the map for the most generic ElementsKind. |
1658 store_mode = GetNonTransitioningStoreMode(store_mode); | 1659 store_mode = GetNonTransitioningStoreMode(store_mode); |
1659 Handle<Code> handler = | 1660 Handle<Code> handler = |
1660 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 1661 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( |
1661 transitioned_receiver_map, language_mode(), store_mode); | 1662 transitioned_receiver_map, store_mode); |
1662 ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler); | 1663 ConfigureVectorState(Handle<Name>(), transitioned_receiver_map, handler); |
1663 return; | 1664 return; |
1664 } | 1665 } |
1665 if (receiver_map.is_identical_to(previous_receiver_map) && | 1666 if (receiver_map.is_identical_to(previous_receiver_map) && |
1666 old_store_mode == STANDARD_STORE && | 1667 old_store_mode == STANDARD_STORE && |
1667 (store_mode == STORE_AND_GROW_NO_TRANSITION || | 1668 (store_mode == STORE_AND_GROW_NO_TRANSITION || |
1668 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || | 1669 store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS || |
1669 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { | 1670 store_mode == STORE_NO_TRANSITION_HANDLE_COW)) { |
1670 // A "normal" IC that handles stores can switch to a version that can | 1671 // A "normal" IC that handles stores can switch to a version that can |
1671 // grow at the end of the array, handle OOB accesses or copy COW arrays | 1672 // grow at the end of the array, handle OOB accesses or copy COW arrays |
1672 // and still stay MONOMORPHIC. | 1673 // and still stay MONOMORPHIC. |
1673 Handle<Code> handler = | 1674 Handle<Code> handler = |
1674 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler( | 1675 PropertyICCompiler::ComputeKeyedStoreMonomorphicHandler(receiver_map, |
1675 receiver_map, language_mode(), store_mode); | 1676 store_mode); |
1676 return ConfigureVectorState(Handle<Name>(), receiver_map, handler); | 1677 return ConfigureVectorState(Handle<Name>(), receiver_map, handler); |
1677 } | 1678 } |
1678 } | 1679 } |
1679 | 1680 |
1680 DCHECK(state() != GENERIC); | 1681 DCHECK(state() != GENERIC); |
1681 | 1682 |
1682 bool map_added = | 1683 bool map_added = |
1683 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); | 1684 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); |
1684 | 1685 |
1685 if (IsTransitionStoreMode(store_mode)) { | 1686 if (IsTransitionStoreMode(store_mode)) { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1726 external_arrays != target_receiver_maps.length()) { | 1727 external_arrays != target_receiver_maps.length()) { |
1727 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", | 1728 TRACE_GENERIC_IC(isolate(), "KeyedStoreIC", |
1728 "unsupported combination of external and normal arrays"); | 1729 "unsupported combination of external and normal arrays"); |
1729 return; | 1730 return; |
1730 } | 1731 } |
1731 } | 1732 } |
1732 | 1733 |
1733 MapHandleList transitioned_maps(target_receiver_maps.length()); | 1734 MapHandleList transitioned_maps(target_receiver_maps.length()); |
1734 CodeHandleList handlers(target_receiver_maps.length()); | 1735 CodeHandleList handlers(target_receiver_maps.length()); |
1735 PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( | 1736 PropertyICCompiler::ComputeKeyedStorePolymorphicHandlers( |
1736 &target_receiver_maps, &transitioned_maps, &handlers, store_mode, | 1737 &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 |