RESOLVED FIXED 115805
DFGArrayMode::fromObserved is too liberal when it sees different Array and NonArray shapes
https://bugs.webkit.org/show_bug.cgi?id=115805
Summary DFGArrayMode::fromObserved is too liberal when it sees different Array and No...
Mark Hahnenberg
Reported 2013-05-08 08:02:55 PDT
It checks the observed ArrayModes to see if we have seen any ArrayWith* first. If so, it assumes it's an Array::Array, even if we've also observed any NonArrayWith* in the ArrayProfile. This leads to the code generated by jumpSlowForUnwantedArrayMode to check the indexing type against (shape | IsArray) instead of just shape, which can cause us to exit a lot in the case that we saw have a NonArray. To fix, we simply need to change the order of the if-statements in fromObserved to check for NonArray ArrayModes first.
Attachments
Patch (5.93 KB, patch)
2013-05-08 08:09 PDT, Mark Hahnenberg
no flags
Patch (6.40 KB, patch)
2013-05-08 19:43 PDT, Mark Hahnenberg
ggaren: review+
Mark Hahnenberg
Comment 1 2013-05-08 08:09:24 PDT
Filip Pizlo
Comment 2 2013-05-08 16:42:53 PDT
Comment on attachment 201076 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=201076&action=review > Source/JavaScriptCore/dfg/DFGArrayMode.cpp:120 > - if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) > - arrayClass = Array::Array; > - else if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage))) > + if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage))) > arrayClass = Array::NonArray; > + else if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) > + arrayClass = Array::Array; > else > arrayClass = Array::PossiblyArray; Actually, I think the bug here is that PossiblyArray wasn't working right. PossiblyArray is supposed to represent "this could be an Array or a NonArray". So it appears that the problem here is that PossiblyArray isn't being compiled to do the right thing (i.e. accept either Array or NonArray).
Mark Hahnenberg
Comment 3 2013-05-08 16:44:16 PDT
(In reply to comment #2) > (From update of attachment 201076 [details]) > View in context: https://bugs.webkit.org/attachment.cgi?id=201076&action=review > > > Source/JavaScriptCore/dfg/DFGArrayMode.cpp:120 > > - if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) > > - arrayClass = Array::Array; > > - else if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage))) > > + if (observed & (asArrayModes(NonArray) | asArrayModes(NonArrayWithInt32) | asArrayModes(NonArrayWithDouble) | asArrayModes(NonArrayWithContiguous) | asArrayModes(NonArrayWithArrayStorage) | asArrayModes(NonArrayWithSlowPutArrayStorage))) > > arrayClass = Array::NonArray; > > + else if (observed & (asArrayModes(ArrayWithUndecided) | asArrayModes(ArrayWithInt32) | asArrayModes(ArrayWithDouble) | asArrayModes(ArrayWithContiguous) | asArrayModes(ArrayWithArrayStorage) | asArrayModes(ArrayWithSlowPutArrayStorage))) > > + arrayClass = Array::Array; > > else > > arrayClass = Array::PossiblyArray; > > Actually, I think the bug here is that PossiblyArray wasn't working right. PossiblyArray is supposed to represent "this could be an Array or a NonArray". So it appears that the problem here is that PossiblyArray isn't being compiled to do the right thing (i.e. accept either Array or NonArray). Gotcha. So we need to check if there's both NonArray and Array stuff first and if so use PossiblyArray, otherwise do what we were doing.
Mark Hahnenberg
Comment 4 2013-05-08 19:43:01 PDT
Geoffrey Garen
Comment 5 2013-05-09 12:18:51 PDT
Comment on attachment 201129 [details] Patch View in context: https://bugs.webkit.org/attachment.cgi?id=201129&action=review r=me > Source/JavaScriptCore/ChangeLog:11 > + instead of just shape, which can cause us to exit a lot in the case that we saw have a NonArray. Typo: Should be "...case that we saw...".
Mark Hahnenberg
Comment 6 2013-05-09 12:37:43 PDT
Note You need to log in before you can comment on or make changes to this bug.