[Webkit-unassigned] [Bug 142966] Optimize typed array access with a masked index

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Mon Mar 23 08:40:16 PDT 2015


https://bugs.webkit.org/show_bug.cgi?id=142966

--- Comment #4 from Filip Pizlo <fpizlo at apple.com> ---
Comment on attachment 249236
  --> https://bugs.webkit.org/attachment.cgi?id=249236
Optimize away bounds checks when given masked typed array indexes

View in context: https://bugs.webkit.org/attachment.cgi?id=249236&action=review

Looks pretty good so far, but please move the helper to a more appropriate place.  And please don't remove the old flow-sensitive CheckInBounds elimination.

> Source/JavaScriptCore/dfg/DFGAbstractInterpreterInlines.h:2301
> +bool indexInBounds(Node* indexNode, int32_t length);

This declaration should be anywhere but here.  It's wrong to declare a method in X.h and define it in Y.h - at the very least, the header in which it's declared should correspond to the compilation module in which it is defined.  It's also wrong to make declarations in Inlines.h files; those are reserved for definitions of inline functions.  This isn't an inline function, and it's not a definition.

We often put such universal helpers in Graph.  You can continue this pattern.  Just add a method to Graph called indexInBounds().

> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:46
> +// Pattern match an array index expression returning true if it is known to be within
> +// bounds otherwise false. This matches a constant index, or a masked index with an
> +// optional constant offset, and optionally right shifted.
> +bool indexInBounds(Node* indexNode, int32_t length)

See above.  This definition is also in the wrong place.  It's an anti-pattern to define helpers inside the compilation module for a phase.  (We do make this mistake sometimes, but I'd really rather we stop doing it.)

We usually put such helpers in Graph.h/cpp.

> Source/JavaScriptCore/dfg/DFGConstantFoldingPhase.cpp:269
> -                JSValue left = m_state.forNode(node->child1()).value();
> +                // The length is obtained in strength reduction.
>                  JSValue right = m_state.forNode(node->child2()).value();
> -                if (left && right && left.isInt32() && right.isInt32()
> -                    && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())) {
> +                if (!right || !right.isInt32())
> +                    break;
> +                // Array length is known.
> +                int32_t length = right.asInt32();
> +                if (indexInBounds(node->child1().node(), length)) {

It appears that you're relying on the left child being folded to a constant, rather than it being proved constant.  There is a small difference, but it's a difference we prefer to deal with head-on.  The constant folder can theoretically produce flow-sensitive constants.  For example, a node may be constant only along some control flow path.  In that case, this will miss CheckInBounds where the index was such a partial constant.

Can you bring back the old folding rule, that did handle the flow-sensitive case?  I believe it's just a matter of not removing the old "if (left && right && left.isInt32() && right.isInt32() && static_cast<uint32_t>(left.asInt32()) < static_cast<uint32_t>(right.asInt32())..." thing.

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20150323/e90dec4e/attachment-0002.html>


More information about the webkit-unassigned mailing list