I work on a product which embeds Chromium.  In addition, we host complex 
C++ objects in V8 directly.  Our V8 binding layer supports the tracing of 
objects to determine references to other objects, rather than simply 
holding on to all objects with strong 'v8::Persistent's.  Up until Chromium 
56 / V8 5.6, we were doing this tracing in the GC prologue, using 
'Isolate::SetReference' to inform V8 of all the edges.

As we look to upgrade past Chromium 59 / V8 5.9, 'Isolate::SetReference' 
has been removed in favor of the 'EmbedderHeapTracer' APIs.

One issue we have with the switch, is that Chromium already sets the 
'EmbedderHeapTracer' to its own 'ScriptWrappableVisitor' tracer.  In order 
to work we need to come up with a way to work along side Chromium.

To quickly recap on how the tracing works, when an embedder hosts an object 
it can set internal fields.  When V8 is tracing objects, if it discovers an 
object which has the first and second internal fields both set, it 
considers it as a wrapper that needs to be traced with the 
'EmbedderHeapTracer'.  These internal fields let you store information 
necessary to perform the tracing.

In Chromium, the first field is a pointer to a 'WrapperTypeInfo' object, 
and the second field is a pointer to a 'ScriptWrappable' object.  The 
'RegisterV8References' implementation in Chromium's tracer expects to only 
ever be called with these Chromium objects.  As such, it does a 
reinterpret_cast to a 'WrapperTypeInfo *' on the first field.  If the 
'gin_embedder' field of that object is 'kEmbedderBlink', it does a 
reinterpret_cast to a 'ScriptWrappable *', and traces that object.

If we were to integrate with Chromium's 'EmbedderHeapTracer', we would have 
to set up our objects to have objects which match the layout of Chromium's 
'WrapperTypeInfo', pretend that the are 'kEmbedderBlink' objects, and 
somehow get it to call our trace methods instead of Chromiums (the exact 
way this is done seems to vary wildly over the latest 10 or so versions of 
Chromium).

This seems like a rabbit hole full of issues I'd rather avoid.

Another option I see is to change V8 to support multiple 
'EmbedderHeapTracer's.  Each 'EmbedderHeapTracer' would be informed of all 
the wrappers that V8 found, and each one would be responsible for tracing 
its own objects.  From testing with Chromium 62 / V8 6.2, this seems to 
work, even if there are references between objects from the two embedders.  
Consider an object graph as follows:

  (root) -> (E1 O1) -> (E1 O2) -> (E2 O1) -> (E2 O2) -> (E1 O3)

Where E1/E2 represents the different embedders, and O1/O2/O3 represents 
different objects.

V8 would discover the wrapper (E1 O1) and inform the 
'EmbedderHeapTracer's.  E1's tracer would trace (E1 O1), and (E2 O2).  E1's 
tracer doesn't know how to trace (E2 O1), but it informs V8 that it's 
alive.  V8 then informs the tracers about (E2 O1).  E2's tracer traces (E2 
O1), and (E2 O2).  Again, E2's tracer doesn't know how to trace (E1 O3), 
but it informs V8 that it's alive.  V8 then informs the tracers about (E1 
O3).  E1's tracer traces it, and the tracing is complete.

There are a few more details which I am missing out relating to changes in 
Chromium which would be required to get it to ignore objects, but those 
should be fairly straight forward.

Is there anything I am overlooking which would prevent multiple 
'EmbedderHeapTracer's from being a viable option?

Many thanks for your input,
Daryl.

-- 
-- 
v8-dev mailing list
v8-dev@googlegroups.com
http://groups.google.com/group/v8-dev
--- 
You received this message because you are subscribed to the Google Groups 
"v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to