Hi all, We have recently started using the EmbedderHeapTracer APIs (upgrading to v8 6.2), and we've started to see some odd behavior. I was hoping someone would be able to say what it is that's going on.
We have a C++ Wrapper class for hosted and marshaled objects. Internally it stores two v8::Persistent<v8::Object> handles, both of which are weak, with a registered finalizer callback. The first handle's finalizer callback Reset()s the handle, and adds the Wrapper to a list of wrappers to be deleted in the GC epilogue. The second handle's finalizer callback ClearWeak()s the handle. When the GC epilogue happens, we walk the list of wrappers to delete and call the Wrapper destructor. This destructor Reset()s the second handle. The v8::Object the Wrapper wraps has two embedder fields, with the second one being a pointer to the Wrapper. What we are seeing is that, infrequently (once in maybe 600,000 created Wrapper objects), the following sequence of events occurs: 1. A Wrapper is created at address A 2. Several scavenge GCs occur, where we unconditionally mark all Wrappers as active 3. Mark/Sweep GC prologue 1. Trace prologue 1. V8 informs us of an object with its second embedder field pointing to address A 2. Trace epilogue 3. Weak finalizer callbacks are called for this object, we queue up the Wrapper for deletion 4. Mark/Sweep GC epilogue 1. We delete the Wrapper 5. Mark/Sweep GC prologue 1. Trace prologue 1. V8 informs us of an object with its second embedder field pointing to address A At this point, the Wrapper at address A has been deleted, so we access garbage memory. We've looked into the GC code, and it seems that objects with weak finalizer handles pointing at them are kept alive until the end of the current GC cycle. Additionally our second weak handle which we make strong until the destructor is called in the GC epilogue ensures that this is the case. But in that GC cycle we clear out the last handle to this object on our side, so we were under the impression that the object would no longer be reachable. It seems as though somehow v8 is materializing a reference to this object after we remove our final reference, causing it to be retraced after we have deleted the associated Wrapper. Is there any reason why v8 might be doing this? As a work-around, we are now clearing the embedder fields in the first weak finalizer callback where we add the object to the list of wrappers to delete. This means that even if v8 decides to keep a reference, it will not see it as a wrapper which should be traced, so we won't ever hear about it again. But we'd like to understand what the root issue is so that we can adjust our assumptions if necessary. Thanks, Daryl. -- -- v8-users mailing list v8-users@googlegroups.com http://groups.google.com/group/v8-users --- You received this message because you are subscribed to the Google Groups "v8-users" group. To unsubscribe from this group and stop receiving emails from it, send an email to v8-users+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.