News for hackers. Stuff that matters.
Re:Inside a fast CSS engine by sanxiyn on Tuesday August 22, 2017 @01:33PM (#15074621)
Ah yes, parallelism (locking etc) part is entirely handled in generic Rust library (Rayon in this case), and not specific to Stylo at all. Here is where Stylo meets Rayon, https://github.com/servo/servo/blob/master/components/style/...

  //! Implements parallel traversal over the DOM tree.
  //!
  //! This traversal is based on Rayon, and therefore its safety is largely
  //! verified by the type system.

  /// A parallel top-down DOM traversal.
  ///
  /// This algorithm traverses the DOM in a breadth-first, top-down manner. The
  /// goals are:
  /// * Never process a child before its parent (since child style depends on
  ///   parent style). If this were to happen, the styling algorithm would panic.
  /// * Prioritize discovering nodes as quickly as possible to maximize
  ///   opportunities for parallelism.  But this needs to be weighed against
  ///   styling cousins on a single thread to improve sharing.
  /// * Style all the children of a given node (i.e. all sibling nodes) on
  ///   a single thread (with an upper bound to handle nodes with an
  ///   abnormally large number of children). This is important because we use
  ///   a thread-local cache to share styles between siblings.
Re:Inside a fast CSS engine by peoplewindow on Tuesday August 22, 2017 @02:23PM (#15075096)
It looks like Rayon is the same thing as Java's ForkJoinPool and parallel streams but with the neat trick (really, Rust's neat trick) that it can statically check that the code is safe to parallelise through the borrow checker.
Re:Inside a fast CSS engine by sanxiyn on Tuesday August 22, 2017 @02:36PM (#15075195)
Yes, that's a good summary.
Re:Inside a fast CSS engine by taeric on Tuesday August 22, 2017 @02:47PM (#15075299)
I'm curious how well this plays with some of the fancier selectors. Adjacent sibling, in particular.

I'm also curious if this pretty much prohibits ever having a parent selector. I guess you could do a first pass through the styles to remove any DAG nature from them?

Re:Inside a fast CSS engine by sanxiyn on Tuesday August 22, 2017 @03:15PM (#15075497)
DOM element has parent and sibling pointer, so there is nothing particularly difficult about adjacent sibling, later sibling, or even parent selector as far as selector matching goes. Avoiding restyling becomes more tricky, but nothing serious. "Parent before child" is for CSS inheritance, not for selector matching.

For not-very-difficult details, read https://github.com/servo/servo/blob/master/components/select... searching for NotMatchedAndRestartFromClosestLaterSibling and HAS_SLOW_SELECTOR_LATER_SIBLINGS.

Re:Inside a fast CSS engine by taeric on Tuesday August 22, 2017 @04:02PM (#15075875)
As soon as there are parent selectors, the pointers don't help. Specifically, if I restyle a parent, all children of parent need to be adjusted, right?

Siblings... I'm assuming there is nothing hard there. Positions, maybe?

Re:Inside a fast CSS engine by sanxiyn on Tuesday August 22, 2017 @04:19PM (#15076013)
I still don't see what problem parent selectors cause. Restyling parent happens anyway without parent selectors (say, by JavaScript), so it is handled. In https://github.com/servo/servo/blob/master/components/style/..., MustCascadeChildren is returned when you... must.
Re:Inside a fast CSS engine by taeric on Tuesday August 22, 2017 @05:57PM (#15076720)
I was basically restating the restriction for the parallel scan. It goes from parent down so that during the scan you don't do something that causes the scan to have to restart.

I was also shooting from the hip for things I'm interested in, here. I'm not sure it matters. But, if on scanning, you pick relevant rules to apply based on the path to a node, then I could see some trickiness on having to consider both the top down and the bottom up paths to a node.

Siblings.., I don't think has this problem. Not sure why I thought it might.

And javascript is ultimately a different topic. So I wasn't worried about that here.

Re:Inside a fast CSS engine by taeric on Wednesday August 23, 2017 @01:40AM (#15078801)
Coming back to this before I finally sleep.

I missed your point about selector matching and style application. I think that is ultimately where my hip shot missed on this. (I have never had to reserve the right to be wrong. Just to assume it. :)

I still feel there is some danger there, but I think that is just clinging to an initial shot. I am curious why rust's help was needed to get this, now. A basic thread pool seems like it would have been somewhat easy to wire up in any language.

Re:Inside a fast CSS engine by bholley on Wednesday August 23, 2017 @04:34PM (#15084820)
Yeah, the key reason Rust is necessary here is that there is an insane amount of complexity in the heart of modern web engines. Injecting concurrency into the intersection of DOM and Layout is only realistic with some kind of static guarantees against data races, and Rust is the only tool I'm aware of to do that.

One neat thing is that we use rust-bindgen to walk C++ data structures, which extends Rust's concurrency guarantees into C++. We also have an FFI layer for invoking C++ code, and we have some careful static analysis of that callgraph from the entry points to be sure we're not mutating anything.

Re:Inside a fast CSS engine by sanxiyn on Wednesday August 23, 2017 @05:49AM (#15079998)
Right, you don't need Rust to do this. In fact, Qualcomm did this with C++ and TBB in 2013, see http://dl.acm.org/citation.cfm?id=2442543. Rust does give you peace of mind that parallel styling won't be endless source of bugs, or worse, vulnerabilities.