On 9/11/17 7:41 AM, Henri Sivonen wrote:
Frame construction runs recursive algorithms along the depth of the
DOM tree.
It's not just frame construction. Recursive algorithms are all over the
place in layout and DOM code.
Frame construction may be a long pole here in terms of crashes due to a
combination of several things:
1) Largish stack frames (not least because it stores a bunch of state in
RAII things).
2) Frame construction itself having a depth check in ProcessChildren
that prevents the frame tree from getting too deep (though it really
only limits the depth the frame constructor itself is willing to go to).
3) Layout having a separate IsFrameTreeTooDeep check that makes it stop
reflowing descendants at some point.
There are three areas where changes could be made:
1) We could re-calibrate the depth limit.
2) The HTML parser could try harder to make the DOM rewrites keep
text nodes visible.
3) The frame constructor could switch from a full-features recursive
algorithm to an iterative text node-only traversal near the depth
limit.
Option #3 won't really help with the third check I list above. Maybe
we'll construct frames for all the content, but we still won't lay it
out, hence it won't be visible.
I'd expect text node recovery (flattening out elements and just
considering text nodes) in the frame constructor to be a more robust
solution than trying to address the problem in the HTML parser. What's
the feasibility of such a frame constructor change?
Just doing that for initial construction is probably not too terrible.
Making it behave correctly (read: not crash exploitably) in the face of
dynamic mutations is pretty hard, because it would violate various
layout and frame constructor invariants. It might be more tractable
than it used to be because maybe we can pretend like things are
display:contents or something, but that means still doing stuff for all
the ancestors of the textnodes, and in a non-recursive way. It might be
doable, though.
My findings from testing with a very high limit so far are as follows:
What testcases were used? The actual stack depth needed for frame
construction and layout is highly styling-dependent, because it affects
what codepaths are taken. For example, I would expect something like this:
<!DOCTYPE html>
<div><div>....
To need less stack than something like this:
<!DOCTYPE html>
<style>div { display: table-cell }</style>
<div><div>....
* Windows 64-bit: between 740 and 750.
* 32-bit Firefox on 64-bit Windows 10: between 500 and 510.
* 32-bit Firefox on 64-bit Windows 7: between 510 and 520.
Were those measurements done with PGO builds? We need to make sure we
do that, because PGO builds have quite different (and larger) stack
frame sizes.
As for other browsers:
I didn't find a depth limit for Chrome. (Tried up to 16000.)
Which version of Chrome? Per comments in
https://bugzilla.mozilla.org/show_bug.cgi?id=485941 at least in their
XML parser they do have a depth limit of about 5000, but that was
apparently removed and then readded recently. Of course they may have
different behavior for XML and HTML.
OK if I change the limit on a per-OS basis according to these numbers?
I'd really like to see testcases with: 1) Lots of nested inlines instead
of lots of nested blocks and 2) my display:table-cell stress test to see
what the numbers look like then.
-Boris
_______________________________________________
dev-platform mailing list
dev-platform@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-platform