On Fri, Nov 20, 2009 at 1:20 AM, Drew Wilson <atwil...@chromium.org> wrote:
> I'm investigating a leak in the MessagePort/MessageChannel code. Basically,
> if I have a page that looks like this:
> <script>
> new MessageChannel();
> </script>
> We leak two MessagePorts every time we reload the page.
> The WebCore::MessageChannel impl object has two RefPtrs to two MessagePort
> objects. When I reload the page, the MessageChannel DOMWrapper V8 object is
> GC'd, leading to the MessageChannel impl object getting deref'd and freed.
> The problem is that the V8 MessageChannel constructor has this code:
>
>     // Create references from the MessageChannel wrapper to the two
>     // MessagePort wrappers to make sure that the MessagePort wrappers
>     // stay alive as long as the MessageChannel wrapper is around.
>     messageChannel->SetInternalField(kMessageChannelPort1Index,
> V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, obj->port1()));
>     messageChannel->SetInternalField(kMessageChannelPort2Index,
> V8DOMWrapper::convertToV8Object(V8ClassIndex::MESSAGEPORT, obj->port2()));
>     // Setup the standard wrapper object internal fields.
>     V8DOMWrapper::setDOMWrapper(messageChannel,
> V8ClassIndex::MESSAGECHANNEL, obj.get());
> Those two MessagePort DOMWrappers don't seem to get freed, so they hold a
> reference to the underlying MessagePort impl objects.
> There are a few things I don't understand here:
> 1) I don't get why we need to explicitly keep a special reference to the
> MessagePorts here in internal fields - we don't seem to do that for other
> DOM Wrappers that have references like this (e.g. SharedWorker.port).

There are a few corner-cases where we have to create additional links
in JS world to prevent things from being collected. Another example of
this are hidden dependencies that are used to keep event listeners on
DOM objects alive. IIRC, there is another part of this in
V8GCController dealing with message ports. Perhaps these two parts
conflict.

> 2) Is there a good way to figure out why the garbage collector isn't
> collecting these references also, short of stepping through the V8 GC code?
> How do people typically track this stuff?
> Any pointers would be much appreciated.

You could try using DevTools heap profiler. Alternatively in debug
mode there is TracePathToObject() (see
http://code.google.com/p/v8/source/browse/branches/bleeding_edge/src/heap.cc#3853).

Is there a bug on this? I'm happy to have a look and fix it.


-- Vitaly

-- 
Chromium Developers mailing list: chromium-dev@googlegroups.com 
View archives, change email options, or unsubscribe: 
    http://groups.google.com/group/chromium-dev

Reply via email to