Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: src/ic.cc

Issue 10532063: Optimistically assume that elements IC only transition once. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1545 matching lines...) Expand 10 before | Expand all | Expand 10 after
1556 1556
1557 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS 1557 // Don't handle megamorphic property accesses for INTERCEPTORS or CALLBACKS
1558 // via megamorphic stubs, since they don't have a map in their relocation info 1558 // via megamorphic stubs, since they don't have a map in their relocation info
1559 // and so the stubs can't be harvested for the object needed for a map check. 1559 // and so the stubs can't be harvested for the object needed for a map check.
1560 if (target()->type() != NORMAL) { 1560 if (target()->type() != NORMAL) {
1561 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type"); 1561 TRACE_GENERIC_IC("KeyedIC", "non-NORMAL target type");
1562 return generic_stub; 1562 return generic_stub;
1563 } 1563 }
1564 1564
1565 bool monomorphic = false; 1565 bool monomorphic = false;
1566 bool is_transition_stub = IsTransitionStubKind(stub_kind);
1567 Handle<Map> receiver_map(receiver->map());
1568 Handle<Map> monomorphic_map = receiver_map;
1566 MapHandleList target_receiver_maps; 1569 MapHandleList target_receiver_maps;
1567 if (ic_state != UNINITIALIZED && ic_state != PREMONOMORPHIC) { 1570 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) {
1571 // Optimistically assume that ICs that haven't reached the MONOMORPHIC state
1572 // yet will do so and stay there.
1573 monomorphic = true;
1574 } else {
1568 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps); 1575 GetReceiverMapsForStub(Handle<Code>(target()), &target_receiver_maps);
1569 } 1576 if (ic_state == MONOMORPHIC && is_transition_stub) {
1570 if (!IsTransitionStubKind(stub_kind)) { 1577 // The first time a receiver is seen that is a transitioned version of the
1571 if (ic_state == UNINITIALIZED || ic_state == PREMONOMORPHIC) { 1578 // previous monomorphic receiver type, assume the new ElementsKind is the
1572 monomorphic = true; 1579 // monomorphic type. This benefits global arrays that only transition
1573 } else { 1580 // once, and all call sites accessing them are faster if they remain
1574 if (ic_state == MONOMORPHIC) { 1581 // monomorphic. If this optimistic assumption is not true, the IC will
1575 // The first time a receiver is seen that is a transitioned version of 1582 // miss again and it will become polymorphic and support both the
1576 // the previous monomorphic receiver type, assume the new ElementsKind 1583 // untransitioned and transitioned maps.
1577 // is the monomorphic type. This benefits global arrays that only 1584 monomorphic = IsMoreGeneralElementsKindTransition(
1578 // transition once, and all call sites accessing them are faster if they 1585 target_receiver_maps.at(0)->elements_kind(),
1579 // remain monomorphic. If this optimistic assumption is not true, the IC 1586 receiver->GetElementsKind());
1580 // will miss again and it will become polymorphic and support both the
1581 // untransitioned and transitioned maps.
1582 monomorphic = IsMoreGeneralElementsKindTransition(
1583 target_receiver_maps.at(0)->elements_kind(),
1584 receiver->GetElementsKind());
1585 }
1586 } 1587 }
1587 } 1588 }
1588 1589
1589 if (monomorphic) { 1590 if (monomorphic) {
1591 if (is_transition_stub) {
1592 monomorphic_map = ComputeTransitionedMap(receiver, stub_kind);
1593 ASSERT(*monomorphic_map != *receiver_map);
1594 stub_kind = GetNoTransitionStubKind(stub_kind);
1595 }
1590 return ComputeMonomorphicStub( 1596 return ComputeMonomorphicStub(
1591 receiver, stub_kind, strict_mode, generic_stub); 1597 monomorphic_map, stub_kind, strict_mode, generic_stub);
1592 } 1598 }
1593 ASSERT(target() != *generic_stub); 1599 ASSERT(target() != *generic_stub);
1594 1600
1595 // Determine the list of receiver maps that this call site has seen, 1601 // Determine the list of receiver maps that this call site has seen,
1596 // adding the map that was just encountered. 1602 // adding the map that was just encountered.
1597 Handle<Map> receiver_map(receiver->map());
1598 bool map_added = 1603 bool map_added =
1599 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map); 1604 AddOneReceiverMapIfMissing(&target_receiver_maps, receiver_map);
1600 if (IsTransitionStubKind(stub_kind)) { 1605 if (IsTransitionStubKind(stub_kind)) {
1601 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind); 1606 Handle<Map> new_map = ComputeTransitionedMap(receiver, stub_kind);
1602 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map); 1607 map_added |= AddOneReceiverMapIfMissing(&target_receiver_maps, new_map);
1603 } 1608 }
1604 if (!map_added) { 1609 if (!map_added) {
1605 // If the miss wasn't due to an unseen map, a polymorphic stub 1610 // If the miss wasn't due to an unseen map, a polymorphic stub
1606 // won't help, use the generic stub. 1611 // won't help, use the generic stub.
1607 TRACE_GENERIC_IC("KeyedIC", "same map added twice"); 1612 TRACE_GENERIC_IC("KeyedIC", "same map added twice");
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1648 receiver_map->has_fast_double_elements() || 1653 receiver_map->has_fast_double_elements() ||
1649 receiver_map->has_external_array_elements()); 1654 receiver_map->has_external_array_elements());
1650 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 1655 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
1651 return GetElementStubWithoutMapCheck(is_js_array, 1656 return GetElementStubWithoutMapCheck(is_js_array,
1652 receiver_map->elements_kind(), 1657 receiver_map->elements_kind(),
1653 grow_mode); 1658 grow_mode);
1654 } 1659 }
1655 } 1660 }
1656 1661
1657 1662
1658 Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<JSObject> receiver, 1663 Handle<Code> KeyedIC::ComputeMonomorphicStub(Handle<Map> receiver_map,
1659 StubKind stub_kind, 1664 StubKind stub_kind,
1660 StrictModeFlag strict_mode, 1665 StrictModeFlag strict_mode,
1661 Handle<Code> generic_stub) { 1666 Handle<Code> generic_stub) {
1662 if (receiver->HasFastSmiOrObjectElements() || 1667 ElementsKind elements_kind = receiver_map->elements_kind();
1663 receiver->HasExternalArrayElements() || 1668 if (IsFastElementsKind(elements_kind) ||
1664 receiver->HasFastDoubleElements() || 1669 IsExternalArrayElementsKind(elements_kind) ||
1665 receiver->HasDictionaryElements()) { 1670 IsDictionaryElementsKind(elements_kind)) {
1666 return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement( 1671 return isolate()->stub_cache()->ComputeKeyedLoadOrStoreElement(
1667 receiver, stub_kind, strict_mode); 1672 receiver_map, stub_kind, strict_mode);
1668 } else { 1673 } else {
1669 return generic_stub; 1674 return generic_stub;
1670 } 1675 }
1671 } 1676 }
1672 1677
1673 1678
1674 Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver, 1679 Handle<Map> KeyedIC::ComputeTransitionedMap(Handle<JSObject> receiver,
1675 StubKind stub_kind) { 1680 StubKind stub_kind) {
1676 switch (stub_kind) { 1681 switch (stub_kind) {
1677 case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT: 1682 case KeyedIC::STORE_TRANSITION_SMI_TO_OBJECT:
(...skipping 961 matching lines...) Expand 10 before | Expand all | Expand 10 after
2639 #undef ADDR 2644 #undef ADDR
2640 }; 2645 };
2641 2646
2642 2647
2643 Address IC::AddressFromUtilityId(IC::UtilityId id) { 2648 Address IC::AddressFromUtilityId(IC::UtilityId id) {
2644 return IC_utilities[id]; 2649 return IC_utilities[id];
2645 } 2650 }
2646 2651
2647 2652
2648 } } // namespace v8::internal 2653 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/ic.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698