Ignore:
Timestamp:
Aug 16, 2019, 2:33:28 PM (6 years ago)
Author:
Justin Michaud
Message:

Fix InBounds speculation of typed array PutByVal and add extra step to integer range optimization to search for equality relationships on the RHS value
https://bugs.webkit.org/show_bug.cgi?id=200782

Reviewed by Saam Barati.

JSTests:

  • microbenchmarks/int8-out-of-bounds.js: Added.

(foo):

  • microbenchmarks/memcpy-typed-loop.js: Added.

(doTest):
(let.arr1.new.Int32Array.1000.let.arr2.new.Int32Array.1000):
(arr2):

  • stress/int8-repeat-in-then-out-of-bounds.js: Added.

(foo):

Source/JavaScriptCore:

Speculate that putByVals on typed arrays are in bounds initially, and add an extra rule to integer range optimization to
remove CheckInBounds when we are looping over two arrays. We do this by fixing a bug in the llint slow paths that marked
typed array accesses as out of bounds, and we also add an extra step to integer range optimization to search for equality
relationships on the RHS value.

Microbenchmarks give a 40% improvement on the memcpy loop test, and neutral on the out-of-bounds typed array test.

  • dfg/DFGIntegerRangeOptimizationPhase.cpp:
  • dfg/DFGOperations.cpp:

(JSC::DFG::putByVal):

  • jit/JITOperations.cpp:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::LLINT_SLOW_PATH_DECL):

  • runtime/JSGenericTypedArrayView.h:
  • runtime/JSObject.h:

(JSC::JSObject::putByIndexInline):
(JSC::JSObject::canGetIndexQuickly const):
(JSC::JSObject::getIndexQuickly const):
(JSC::JSObject::tryGetIndexQuickly const):
(JSC::JSObject::canSetIndexQuickly):
(JSC::JSObject::setIndexQuickly):

  • runtime/JSObjectInlines.h:

(JSC::JSObject::canGetIndexQuicklyForTypedArray const):
(JSC::JSObject::canSetIndexQuicklyForTypedArray const):
(JSC::JSObject::getIndexQuicklyForTypedArray const):
(JSC::JSObject::setIndexQuicklyForTypedArray):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/dfg/DFGIntegerRangeOptimizationPhase.cpp

    r247724 r248798  
    275275        RELEASE_ASSERT(left != m_right);
    276276        m_left = left;
     277    }
     278    void setRight(NodeFlowProjection right)
     279    {
     280        RELEASE_ASSERT(right != m_left);
     281        m_right = right;
    277282    }
    278283    bool addToOffset(int offset)
     
    13271332                        }
    13281333                    }
     1334
     1335                    if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
     1336                        dataLogLn("CheckInBounds ", node, " has: ", nonNegative, " ", lessThanLength);
    13291337                   
    13301338                    if (nonNegative && lessThanLength) {
     
    16441652            if (timeToLive && otherRelationship.kind() == Relationship::Equal) {
    16451653                if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
    1646                     dataLog("      Considering: ", otherRelationship, "\n");
     1654                    dataLog("      Considering (lhs): ", otherRelationship, "\n");
    16471655               
    16481656                // We have:
     
    16651673                    }
    16661674                }
     1675            }
     1676        }
     1677
     1678        if (timeToLive && relationship.kind() != Relationship::Equal) {
     1679            for (Relationship& possibleEquality : relationshipMap.get(relationship.right())) {
     1680                if (possibleEquality.kind() != Relationship::Equal
     1681                    || possibleEquality.offset() == std::numeric_limits<int>::min()
     1682                    || possibleEquality.right() == relationship.left())
     1683                    continue;
     1684                if (DFGIntegerRangeOptimizationPhaseInternal::verbose)
     1685                    dataLog("      Considering (rhs): ", possibleEquality, "\n");
     1686
     1687                // We have:
     1688                //     @a op @b + C
     1689                //     @b == @c + D
     1690                //
     1691                // This implies:
     1692                //     @a op @c + (C + D)
     1693                //
     1694                // Where: @a == relationship.left(), @b == relationship.right()
     1695
     1696                Relationship newRelationship = relationship;
     1697                newRelationship.setRight(possibleEquality.right());
     1698                if (newRelationship.addToOffset(possibleEquality.offset()))
     1699                    toAdd.append(newRelationship);
    16671700            }
    16681701        }
Note: See TracChangeset for help on using the changeset viewer.