Is off-the-main-thread MQ evaluation implementable?

81 views
Skip to first unread message

Yoav Weiss

unread,
Jan 4, 2014, 3:26:48 PM1/4/14
to blink-dev
Following Adam Barth's response on the WHATWG list, I'd like to further understand the complexity of implementing off-the-main-thread MQ evaluation.

Similar past concerns have led me to prototype off-the-main-thread MQ evaluation a few months back. As far as I can tell, the only thing preventing such evaluation is the thread-safety of the MediaQueryExp class, and specifically its use of AtomicStrings.
Since I wrote the CL as a prototype, I've simply converted the class's AtomicString variables & members into String. I'm well aware that this is not ideal, and other ways to make it thread safe should be employed, but once this hurdle to thread safety is passed, everything else seemed to work.

I'd like to know if I'm missing any other components that need to be thread-safe in order to evaluate MQs. 

Thanks!
Yoav

Elliott Sprehn

unread,
Jan 4, 2014, 4:26:21 PM1/4/14
to Yoav Weiss, blink-dev
Is this just for the preload scanner? MQs use a fixed dialect, we should just convert it all to enum tokens (and ints) and use a simple parser so there's no strings.

Adam Barth

unread,
Jan 4, 2014, 5:56:39 PM1/4/14
to Yoav Weiss, blink-dev
Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting.  After Oilpan lands, CSSValues will be GarabageCollected, which will let us interact with them off the main thread.

Currently the CSS parsing deals in parser-specific types, which are then converted to the retained types after parsing.  We've been experimenting with rewriting the CSS parser:


One of the benefits of rewriting the parser is that we'd be able to skip the intermediate types and parse directly into the retained types.  We'll also be able to integrate the CSS parser with the HTML parser and speculatively parse inline CSS on the parser thread.

Once we have that working, then we can do things like approximate simple selector matching in order to preload CSS background-images.  At that point, it should be relatively straightforward to evaluate media queries on the parser thread.

On Sat, Jan 4, 2014 at 1:26 PM, Elliott Sprehn <esp...@google.com> wrote:
Is this just for the preload scanner? MQs use a fixed dialect, we should just convert it all to enum tokens (and ints) and use a simple parser so there's no strings.

Here's an example input from the spec that we'd need to be able to handle on the background thread:

(max-width: 30em) 100%, (max-width: 50em) 50%, calc(33% - 100px)

We're going to need a significant fraction of the CSS machine running on the background thread to correctly evaluate that condition.  Limiting the set of queries authors can make is useful because it limits the amount of state we need to replicate to the parser thread.

As I wrote on the WhatWG list, all of the above is doable, it's just a significant amount of work.  It's work that we want to do anyway to make existing content load faster, but it's going to take some time.

Adam

Darin Fisher

unread,
Jan 5, 2014, 12:00:20 AM1/5/14
to Adam Barth, Yoav Weiss, blink-dev
On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 12:26 PM, Yoav Weiss <yo...@yoav.ws> wrote:
Following Adam Barth's response on the WHATWG list, I'd like to further understand the complexity of implementing off-the-main-thread MQ evaluation.

Similar past concerns have led me to prototype off-the-main-thread MQ evaluation a few months back. As far as I can tell, the only thing preventing such evaluation is the thread-safety of the MediaQueryExp class, and specifically its use of AtomicStrings.
Since I wrote the CL as a prototype, I've simply converted the class's AtomicString variables & members into String. I'm well aware that this is not ideal, and other ways to make it thread safe should be employed, but once this hurdle to thread safety is passed, everything else seemed to work.

I'd like to know if I'm missing any other components that need to be thread-safe in order to evaluate MQs.

Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting.  After Oilpan lands, CSSValues will be GarabageCollected, which will let us interact with them off the main thread.

Are you sure about this? I thought one of the design ideas with Oilpan was to enable precise GC to run from the message loop, where we could assume that it is not necessary to conservatively scan call stacks. It seems that this would require special treatment if any objects are to be shared across threads.

-Darin

Adam Barth

unread,
Jan 5, 2014, 1:48:16 AM1/5/14
to Darin Fisher, Yoav Weiss, blink-dev
On Sat, Jan 4, 2014 at 9:00 PM, Darin Fisher <da...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 12:26 PM, Yoav Weiss <yo...@yoav.ws> wrote:
Following Adam Barth's response on the WHATWG list, I'd like to further understand the complexity of implementing off-the-main-thread MQ evaluation.

Similar past concerns have led me to prototype off-the-main-thread MQ evaluation a few months back. As far as I can tell, the only thing preventing such evaluation is the thread-safety of the MediaQueryExp class, and specifically its use of AtomicStrings.
Since I wrote the CL as a prototype, I've simply converted the class's AtomicString variables & members into String. I'm well aware that this is not ideal, and other ways to make it thread safe should be employed, but once this hurdle to thread safety is passed, everything else seemed to work.

I'd like to know if I'm missing any other components that need to be thread-safe in order to evaluate MQs.

Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting.  After Oilpan lands, CSSValues will be GarabageCollected, which will let us interact with them off the main thread.

Are you sure about this? I thought one of the design ideas with Oilpan was to enable precise GC to run from the message loop, where we could assume that it is not necessary to conservatively scan call stacks. It seems that this would require special treatment if any objects are to be shared across threads.

We can check with some Oilpan experts, but my understanding is that every thread that touches GarbageCollected objects will need to register with the heap.  The mark phase blocks until all the registered threads have reached safe points (e.g., the top of the event loop).  Finalization and sweeping proceeds in parallel on each thread.  There's some added complication for worker threads that can have long-running JavaScript that involves the ability to interrupt JavaScript execution.

It's possible we won't want to register the parser thread with the heap, but my guess is that we'll want to be able to handle GarbageCollected objects on the parser thread so that we can malloc up Nodes and potentially do some tree building in the background.

Adam

Darin Fisher

unread,
Jan 5, 2014, 2:55:38 AM1/5/14
to Adam Barth, Yoav Weiss, blink-dev
On Sat, Jan 4, 2014 at 10:48 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 9:00 PM, Darin Fisher <da...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 12:26 PM, Yoav Weiss <yo...@yoav.ws> wrote:
Following Adam Barth's response on the WHATWG list, I'd like to further understand the complexity of implementing off-the-main-thread MQ evaluation.

Similar past concerns have led me to prototype off-the-main-thread MQ evaluation a few months back. As far as I can tell, the only thing preventing such evaluation is the thread-safety of the MediaQueryExp class, and specifically its use of AtomicStrings.
Since I wrote the CL as a prototype, I've simply converted the class's AtomicString variables & members into String. I'm well aware that this is not ideal, and other ways to make it thread safe should be employed, but once this hurdle to thread safety is passed, everything else seemed to work.

I'd like to know if I'm missing any other components that need to be thread-safe in order to evaluate MQs.

Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting.  After Oilpan lands, CSSValues will be GarabageCollected, which will let us interact with them off the main thread.

Are you sure about this? I thought one of the design ideas with Oilpan was to enable precise GC to run from the message loop, where we could assume that it is not necessary to conservatively scan call stacks. It seems that this would require special treatment if any objects are to be shared across threads.

We can check with some Oilpan experts, but my understanding is that every thread that touches GarbageCollected objects will need to register with the heap.  The mark phase blocks until all the registered threads have reached safe points (e.g., the top of the event loop).  Finalization and sweeping proceeds in parallel on each thread.  There's some added complication for worker threads that can have long-running JavaScript that involves the ability to interrupt JavaScript execution.

Oh, I didn't realize the proposal was to have threads join at their message loops. That sounds rather non-ideal in the general case, but for the main isolate, I wonder how many threads will really need to be part of it. (I assume each isolate has its own heap.)


 

It's possible we won't want to register the parser thread with the heap, but my guess is that we'll want to be able to handle GarbageCollected objects on the parser thread so that we can malloc up Nodes and potentially do some tree building in the background.

If we do this kind of thing, we'll need to be very mindful of the potential jank it introduces when we block the message loops in order to synchronize threads. Hmm...

-Darin

Adam Barth

unread,
Jan 5, 2014, 3:27:56 AM1/5/14
to Darin Fisher, Yoav Weiss, blink-dev, Mads Sig Ager
[+ager]

On Sat, Jan 4, 2014 at 11:55 PM, Darin Fisher <da...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 10:48 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 9:00 PM, Darin Fisher <da...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 12:26 PM, Yoav Weiss <yo...@yoav.ws> wrote:
Following Adam Barth's response on the WHATWG list, I'd like to further understand the complexity of implementing off-the-main-thread MQ evaluation.

Similar past concerns have led me to prototype off-the-main-thread MQ evaluation a few months back. As far as I can tell, the only thing preventing such evaluation is the thread-safety of the MediaQueryExp class, and specifically its use of AtomicStrings.
Since I wrote the CL as a prototype, I've simply converted the class's AtomicString variables & members into String. I'm well aware that this is not ideal, and other ways to make it thread safe should be employed, but once this hurdle to thread safety is passed, everything else seemed to work.

I'd like to know if I'm missing any other components that need to be thread-safe in order to evaluate MQs.

Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting.  After Oilpan lands, CSSValues will be GarabageCollected, which will let us interact with them off the main thread.

Are you sure about this? I thought one of the design ideas with Oilpan was to enable precise GC to run from the message loop, where we could assume that it is not necessary to conservatively scan call stacks. It seems that this would require special treatment if any objects are to be shared across threads.

We can check with some Oilpan experts, but my understanding is that every thread that touches GarbageCollected objects will need to register with the heap.  The mark phase blocks until all the registered threads have reached safe points (e.g., the top of the event loop).  Finalization and sweeping proceeds in parallel on each thread.  There's some added complication for worker threads that can have long-running JavaScript that involves the ability to interrupt JavaScript execution.

Oh, I didn't realize the proposal was to have threads join at their message loops. That sounds rather non-ideal in the general case, but for the main isolate, I wonder how many threads will really need to be part of it. (I assume each isolate has its own heap.)

Each isolate has its own heap, but multiple threads can refer to the same C++ object, like an ExecutionContext or a transferred ArrayBuffer.  It's possible we could be careful about how we referenced these objects from multiple threads and trace each thread's heap separately.  We discussed this idea a bit in one of the Oilpan sync meetings, but there was some reason folks didn't think this was a good approach.

It's possible we won't want to register the parser thread with the heap, but my guess is that we'll want to be able to handle GarbageCollected objects on the parser thread so that we can malloc up Nodes and potentially do some tree building in the background.

If we do this kind of thing, we'll need to be very mindful of the potential jank it introduces when we block the message loops in order to synchronize threads. Hmm...

The way I imagined this working is that we'd park the high-latency threads (like the parser thread) first and only block the main thread when we're actually read to trace the heap.  We'd never want low-latency threads (like the compositor or the audio thread) to touch GarbageCollected objects so they'd never need to block.  From a code organization perspective, we'd enforce this by preventing blink_platform.dll from depending on blink_heap.dll.

Maybe Mads has some more concrete thoughts?

Yoav Weiss

unread,
Jan 5, 2014, 4:21:33 PM1/5/14
to Adam Barth, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
 On Sat, Jan 4, 2014 at 1:26 PM, Elliott Sprehn <esp...@google.com> wrote:
Is this just for the preload scanner? MQs use a fixed dialect, we should just convert it all to enum tokens (and ints) and use a simple parser so there's no strings.

Looking further into MediaQueryExp, it uses AtomicString only for the media feature, so replacing it by an int sounds like a great idea. Since it needs to be able to quickly compare an incoming String to the existing media features, I was thinking of using the String's hash to do an initial comparison, and have some debug ifdefed code that would verify that no collisions occur between the features themselves (since there are currently 43 features, the chances for a collisions are most probably close to nothing). Does that make sense? 

On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting. 

Please forgive me if I'm being thick, but looking over the RefCounted code, I can see why you can't pass RefCounted objects between threads, but I can't see why you can't create, own and delete a RefCounted object in the Background HTML parser thread, which as far as I understand, this is what happens when running MediaQueryEvaluator on that thread. What am I missing?

[snip]

Here's an example input from the spec that we'd need to be able to handle on the background thread:
(max-width: 30em) 100%, (max-width: 50em) 50%, calc(33% - 100px)
We're going to need a significant fraction of the CSS machine running on the background thread to correctly evaluate that condition.

I think that we can try to simplify the resource dimensions calculation part (e.g. drop the `calc` part for now), if it can speed up implementation. Tab? 

Adam Barth

unread,
Jan 5, 2014, 5:02:00 PM1/5/14
to Yoav Weiss, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
On Sun, Jan 5, 2014 at 1:21 PM, Yoav Weiss <yo...@yoav.ws> wrote:
 On Sat, Jan 4, 2014 at 1:26 PM, Elliott Sprehn <esp...@google.com> wrote:
Is this just for the preload scanner? MQs use a fixed dialect, we should just convert it all to enum tokens (and ints) and use a simple parser so there's no strings.

Looking further into MediaQueryExp, it uses AtomicString only for the media feature, so replacing it by an int sounds like a great idea. Since it needs to be able to quickly compare an incoming String to the existing media features, I was thinking of using the String's hash to do an initial comparison, and have some debug ifdefed code that would verify that no collisions occur between the features themselves (since there are currently 43 features, the chances for a collisions are most probably close to nothing). Does that make sense?

Yes, we use a similar trick for HTML tag and attribute names.

On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting. 

Please forgive me if I'm being thick, but looking over the RefCounted code, I can see why you can't pass RefCounted objects between threads, but I can't see why you can't create, own and delete a RefCounted object in the Background HTML parser thread, which as far as I understand, this is what happens when running MediaQueryEvaluator on that thread. What am I missing?

CSSValues are similar to AtomicStrings in the sense that they're shared through a static.  In the case of CSSValues, the static is maintained by the CSSValuePool:


We've talked about other mechanisms for removing the CSSValuePool, including introducing the notion of an "immediate" CSS value, much like how many language VMs encode commonly used values in pointers, but moving these values into the Oilpan heap seemed like the better approach.

Adam

Yoav Weiss

unread,
Jan 5, 2014, 6:09:59 PM1/5/14
to Adam Barth, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
Is there an estimate when CSSValue will move to the Oilpan heap?
 


Adam

To unsubscribe from this group and stop receiving emails from it, send an email to blink-dev+...@chromium.org.

Adam Barth

unread,
Jan 5, 2014, 6:24:10 PM1/5/14
to Yoav Weiss, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
CSSValue is already in the Oilpan heap on the oilpan branch:


We've started landing Oilpan in trunk:


Initially, the oilpan code will be behind a compile time flag so that we can carefully evaluate the performance impact.  Landing Oilpan is pretty high on our list for the next couple of quarters, but I don't think anyone knows exactly how long it will take.

Adam

Mads Sig Ager

unread,
Jan 6, 2014, 4:17:10 AM1/6/14
to Adam Barth, Darin Fisher, Yoav Weiss, blink-dev
On Sun, Jan 5, 2014 at 9:27 AM, Adam Barth <aba...@chromium.org> wrote:
[+ager]

On Sat, Jan 4, 2014 at 11:55 PM, Darin Fisher <da...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 10:48 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 9:00 PM, Darin Fisher <da...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
On Sat, Jan 4, 2014 at 12:26 PM, Yoav Weiss <yo...@yoav.ws> wrote:
Following Adam Barth's response on the WHATWG list, I'd like to further understand the complexity of implementing off-the-main-thread MQ evaluation.

Similar past concerns have led me to prototype off-the-main-thread MQ evaluation a few months back. As far as I can tell, the only thing preventing such evaluation is the thread-safety of the MediaQueryExp class, and specifically its use of AtomicStrings.
Since I wrote the CL as a prototype, I've simply converted the class's AtomicString variables & members into String. I'm well aware that this is not ideal, and other ways to make it thread safe should be employed, but once this hurdle to thread safety is passed, everything else seemed to work.

I'd like to know if I'm missing any other components that need to be thread-safe in order to evaluate MQs.

Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting.  After Oilpan lands, CSSValues will be GarabageCollected, which will let us interact with them off the main thread.

Are you sure about this? I thought one of the design ideas with Oilpan was to enable precise GC to run from the message loop, where we could assume that it is not necessary to conservatively scan call stacks. It seems that this would require special treatment if any objects are to be shared across threads.

We can check with some Oilpan experts, but my understanding is that every thread that touches GarbageCollected objects will need to register with the heap.  The mark phase blocks until all the registered threads have reached safe points (e.g., the top of the event loop).  Finalization and sweeping proceeds in parallel on each thread.  There's some added complication for worker threads that can have long-running JavaScript that involves the ability to interrupt JavaScript execution.

Oh, I didn't realize the proposal was to have threads join at their message loops. That sounds rather non-ideal in the general case, but for the main isolate, I wonder how many threads will really need to be part of it. (I assume each isolate has its own heap.)

Each isolate has its own heap, but multiple threads can refer to the same C++ object, like an ExecutionContext or a transferred ArrayBuffer.  It's possible we could be careful about how we referenced these objects from multiple threads and trace each thread's heap separately.  We discussed this idea a bit in one of the Oilpan sync meetings, but there was some reason folks didn't think this was a good approach.

I'm not sure what exactly is meant by 'isolate' here? In the Oilpan system we currently have one heap for a renderer. The heap has thread-specific pages to ensure that no synchronization is needed when allocating and to make sure that all objects are finalized on the thread on which they were allocated. As Adam notes, there can be pointers between these thread-specific heaps and therefore they cannot in general be traced independently. We could setup completely independent heaps for threads that are truely isolated from the rest. However, I imagine that we might want to go the other way: allow more sharing (at least of immutable data) between threads so we do not have to copy data back and forth.

It's possible we won't want to register the parser thread with the heap, but my guess is that we'll want to be able to handle GarbageCollected objects on the parser thread so that we can malloc up Nodes and potentially do some tree building in the background.

If we do this kind of thing, we'll need to be very mindful of the potential jank it introduces when we block the message loops in order to synchronize threads. Hmm...

The way I imagined this working is that we'd park the high-latency threads (like the parser thread) first and only block the main thread when we're actually read to trace the heap.  We'd never want low-latency threads (like the compositor or the audio thread) to touch GarbageCollected objects so they'd never need to block.  From a code organization perspective, we'd enforce this by preventing blink_platform.dll from depending on blink_heap.dll.

Maybe Mads has some more concrete thoughts?

I agree with what Adam outlines here. Threads such as the audio thread should not touch garbage collected objects because there are hard real-time constraints. We cannot guarantee that a GC pause will be short enough for audio processing.

All threads operating on Oilpan heap-allocated objects must be registered with the heap. They must all reach a safepoint for marking. Safepoints are not restricted to the event loops. Safepoints are any points where the state of the heap is consistent and therefore we can have many safe points. As an example, if you perform a long running piece of work that does not touch heap-allocated objects that is a safepoint as well (the state of the heap is consistent and does not change for the duration of the operation). We can perform garbage collection on another thread while this thread continues its work that does not touch the heap. Then when we leave the safepoint we will block this thread so that it does not modify the heap while the other thread is marking. For threads in JavaScript, V8 has always had an interruption mechanism so when a thread is in JavaScript we use that mechanism to stop the thread. Therefore, we should be able to avoid jank while waiting for threads to reach safe points but it is definitely something we have to keep an eye on and add more safepoints if/when we see jank caused by this. The only problem with safepoints that are not at the event loop is that you have to scan the stacks of threads that are not at their event loops conservatively. The measurements that we have performed indicate that conservative scanning is not a problem. Also, we have the information about which threads used conservative scanning on the last GC and we can incorporate that into our GC heuristics to get occasional GCs at the event loop for all threads.

When it comes to jank it worries me more that we have a stop-the-world collector that blocks threads until marking is done. Getting threads to safepoints we can definitely make fast. Performing full marking will all threads blocked is what could become a problem. There are plenty of things that we can do in order to make pause times smaller. Simple things like finalizing objects in small steps and sweeping pages lazily we will look into as soon as we have the basic infrastructure in place. In the end, we might have to (and probably will) go incremental or concurrent.

Cheers,    -- Mads

Yoav Weiss

unread,
Jan 6, 2014, 11:48:29 AM1/6/14
to Adam Barth, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
So, hopefully, a few months from now, MQ eval would be implementable off the main thread?

If so, assuming that the use-cases the picture spec resolves are interesting to solve, a path forward may be to implement picture's source selection by joining the main thread (similar to my prototype implementation), and refactor it off-the-main-thread (along with <link rel=stylesheet>'s media evaluation) once oilpan lands.

I agree with you that other bits of the `sizes` syntax may require some more work (e.g. calc() ), and I think we could either try to simplify them or postpone their implementation to a later phase.


 

Adam Barth

unread,
Jan 6, 2014, 12:46:06 PM1/6/14
to Yoav Weiss, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
On Mon, Jan 6, 2014 at 8:48 AM, Yoav Weiss <yo...@yoav.ws> wrote:
On Mon, Jan 6, 2014 at 12:24 AM, Adam Barth <aba...@chromium.org> wrote:
On Sun, Jan 5, 2014 at 3:09 PM, Yoav Weiss <yo...@yoav.ws> wrote:
On Sun, Jan 5, 2014 at 11:02 PM, Adam Barth <aba...@chromium.org> wrote:
On Sun, Jan 5, 2014 at 1:21 PM, Yoav Weiss <yo...@yoav.ws> wrote:
 On Sat, Jan 4, 2014 at 1:26 PM, Elliott Sprehn <esp...@google.com> wrote:
Is this just for the preload scanner? MQs use a fixed dialect, we should just convert it all to enum tokens (and ints) and use a simple parser so there's no strings.

Looking further into MediaQueryExp, it uses AtomicString only for the media feature, so replacing it by an int sounds like a great idea. Since it needs to be able to quickly compare an incoming String to the existing media features, I was thinking of using the String's hash to do an initial comparison, and have some debug ifdefed code that would verify that no collisions occur between the features themselves (since there are currently 43 features, the chances for a collisions are most probably close to nothing). Does that make sense?

Yes, we use a similar trick for HTML tag and attribute names.

On Sat, Jan 4, 2014 at 2:56 PM, Adam Barth <aba...@chromium.org> wrote:
Currently we cannot represent CSSValues off the main thread because they're RefCounted and we don't want to use thread-safe ref counting. 

Please forgive me if I'm being thick, but looking over the RefCounted code, I can see why you can't pass RefCounted objects between threads, but I can't see why you can't create, own and delete a RefCounted object in the Background HTML parser thread, which as far as I understand, this is what happens when running MediaQueryEvaluator on that thread. What am I missing?

CSSValues are similar to AtomicStrings in the sense that they're shared through a static.  In the case of CSSValues, the static is maintained by the CSSValuePool:


We've talked about other mechanisms for removing the CSSValuePool, including introducing the notion of an "immediate" CSS value, much like how many language VMs encode commonly used values in pointers, but moving these values into the Oilpan heap seemed like the better approach.

Is there an estimate when CSSValue will move to the Oilpan heap?

CSSValue is already in the Oilpan heap on the oilpan branch:


We've started landing Oilpan in trunk:


Initially, the oilpan code will be behind a compile time flag so that we can carefully evaluate the performance impact.  Landing Oilpan is pretty high on our list for the next couple of quarters, but I don't think anyone knows exactly how long it will take.

So, hopefully, a few months from now, MQ eval would be implementable off the main thread?

The word "implementable" isn't particularly useful.  Everything is implementable.  The question is when the feature will actually be implemented.  I wouldn't expect it to be implemented in a few months.  As I wrote on the WhatWG thread, my guess would be more on the order of one or two years.

If so, assuming that the use-cases the picture spec resolves are interesting to solve, a path forward may be to implement picture's source selection by joining the main thread (similar to my prototype implementation), and refactor it off-the-main-thread (along with <link rel=stylesheet>'s media evaluation) once oilpan lands.

I don't think that's worth doing because we're not creating any value by baking the implementation into the platform.  If you're happy with a <picture> element that doesn't integrate with the preload scanner, you should just create a custom element yourself.

Adam

Yoav Weiss

unread,
Jan 6, 2014, 5:59:00 PM1/6/14
to Adam Barth, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
I guess I didn't make myself clear. Sorry about that. 
I'm not suggesting implementing <picture> without preload scanner integration. What I'm suggesting is implementing picture without doing off-main-thread MQ evaluation, by having the preloadScanner recognize <picture> and its <source> children, and send the `media` and `sizes` attributes to the main thread along with the URLs. Then, on the main thread, these MQs can be evaluated and the correct resource can be picked.
I admit this architecture is sub-optimal, and it prevents future improvements, such as having the preloadScanner communicate resources directly to the networking thread (Much like `media` evaluation on <link rel=stylesheet> prevents it today). My line of thought was that it can be a temporary stop-gap architecture, until MQ evaluation could be done off-main-thread.

Adam Barth

unread,
Jan 6, 2014, 6:06:42 PM1/6/14
to Yoav Weiss, Tab Atkins Jr., Elliott Sprehn, Darin Fisher, blink-dev, Mads Sig Ager
That's the opposite of the direction we're taking this code.  We're working on having the network stack deliver data directly to the parser thread (https://code.google.com/p/chromium/issues/detail?id=277124) and having the parser thread deliver preloads directly to the network stack (https://code.google.com/p/chromium/issues/detail?id=324307), all without joining the main thread.

Adam

Reply all
Reply to author
Forward
0 new messages