Or store the metadata immediately before the code, as GHC does for thunk entry 
code.

keegan

----- Original Message -----
From: "Niko Matsakis" <nmatsa...@mozilla.com>
To: "Patrick Walton" <pcwal...@mozilla.com>
Cc: dev-servo@lists.mozilla.org
Sent: Monday, March 31, 2014 3:10:39 AM
Subject: Re: [dev-servo] Crazy idea: CSS selector JITting at parse time

Interesting thought. You could also use an embedding involving either
coded no-ops at the start of each instruction and/or an unconditional
jump over some meta-data. This would reduce coupling at the cost of
somewhat more memory. Naturally you'd want to measure the effect on
performance too, though I suspect it'd be minimal.


Niko

On Sat, Mar 29, 2014 at 05:23:02PM -0700, Patrick Walton wrote:
> Hi everyone,
> 
> I've been discussing this idea with a few people in person over the
> past week, and nobody told me it was completely insane. ;) So I
> thought I'd send this idea around.
> 
> By now many people have heard of WebKit's CSS JIT. It's a
> surprisingly small amount of code. One of the issues that they cite
> in their blog post [1] is compilation time: the compilation has to be
> very fast in order to avoid nullifying the gains. With that in mind,
> I had an idea: what if the "AST" that the CSS parser generated was
> actually machine code?
> 
> The AST for the CSS grammar is extremely small: 176 lines of Rust for
> the whole thing [2], and the selector grammar is just a fraction of
> that. This is because selectors describe a very simple language, even
> with all the extensions that have been added over the years. So one
> could write a simple template-emitting compiler that takes CSS
> selectors and writes a small template of machine code. (This is in
> fact the approach that WebKit uses.) For example, I could imagine
> that the JIT code for the selector ".foo #a" might look like
> (assuming that "#a" has already been matched in the ID hash):
> 
>       ; assume that node is in ebx
>     l1: mov ebx,[ebx+offsetof(parentNode)]
>         test ebx,ebx
>       jz nomatch
>         mov edx,[ebx+offsetof(class)]
>         xor ecx,ecx
>     l2: cmp [edx+ecx*4],"foo"
>         je match
>         inc ecx
>         cmp ecx,[ebx+offsetof(classcount)]
>         jne l2
>         jmp l1
> 
> This is just 29 bytes of code when assembled. This is likely larger
> than the equivalent `nsRuleNode`, but `nsRuleNode` instances are not
> a large amount of the heap in my cursory glances at `about:memory`.
> 
> The major question is: If you don't have an AST, then how do you
> implement the CSSOM and style debugging? Here's the trick: Since CSS
> selectors are so simple compared to, say, the output of a JS JIT, it
> should be possible to *disassemble* the code by simply
> pattern-matching. Since the compiler is nothing more than a very
> simple template processor (and it has to be, for speed reasons) it
> should be possible to reverse the output and go from JIT code back to
> the CSS selectors. This would be done by performing some very simple
> analysis (not full disassembly) on the machine code. For instance, on
> the above selector, it might do:
> 
>         ; start with `#a` from the rule hash
> 
>     l1: mov ebx,[ebx+offsetof(parentNode)]
>         test ebx,ebx
>       jz nomatch
>       ; found a test for parentNode, so we must be a descendant or
>         ; child selector (depending on whether we see a backwards jump)
> 
>         mov edx,[ebx+offsetof(class)]
>         xor ecx,ecx
>     l2: cmp [edx+ecx*4],"foo"
>         je match
>         inc ecx
>         cmp ecx,[ebx+offsetof(classcount)]
>         jne l2
>         ; found a test for the "foo" class
> 
>         jmp l1
>         ; found a backwards jump, so we know we're a descendant selector
>         ; result: `.foo #a`
> 
> So you wouldn't need a full disassembler, just a simple pattern matcher.
> 
> Note that one doesn't have to JIT everything: for more complex tests
> such as "attribute contains substring", we can just call out to
> functions implemented in Rust in the JIT code. The disassembler can
> just pattern match on those function addresses and arguments. This
> also increases the maintainability of this approach in the presence
> of new stuff that the CSS working groups add to the spec: we can
> implement all new features as functions at first, and only JIT them
> if they become widely used.
> 
> Thoughts?
> 
> Patrick
> 
> [1]: https://www.webkit.org/blog/3271/webkit-css-selector-jit-compiler/
> 
> [2]: https://github.com/mozilla-servo/rust-cssparser/blob/master/ast.rs
> _______________________________________________
> dev-servo mailing list
> dev-servo@lists.mozilla.org
> https://lists.mozilla.org/listinfo/dev-servo
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo
_______________________________________________
dev-servo mailing list
dev-servo@lists.mozilla.org
https://lists.mozilla.org/listinfo/dev-servo

Reply via email to