Changeset 51392 in webkit


Ignore:
Timestamp:
Nov 25, 2009 12:04:19 PM (14 years ago)
Author:
eric@webkit.org
Message:

2009-11-25 Drew Wilson <atwilson@chromium.org>

Reviewed by David Levin.

MessagePorts always look remotely entangled even when closed.
https://bugs.webkit.org/show_bug.cgi?id=31698

Tests: Existing tests suffice, Chromium soak test passes now.

  • bindings/v8/custom/V8CustomBinding.h: Removed kMessagePortEntangledPortIndex which is no longer used.
  • bindings/v8/V8GCController.cpp: (WebCore::GCPrologueVisitor::visitDOMWrapper): Simplified GC code to reflect the Chromium MessagePort implementation (locallyEntangledPort() always returns false). (WebCore::GCEpilogueVisitor::visitDOMWrapper): Cleaned up epilogue code to handle the case where the port gets closed in mid-GC (due to the parent context being freed).
  • dom/MessagePort.cpp: (WebCore::MessagePort::MessagePort): (WebCore::MessagePort::close): Now sets the closed flag. (WebCore::MessagePort::disentanglePorts): Updated to use new isCloned() API instead of relying on isEntangled(), which was incorrect.
  • dom/MessagePort.h: Added a m_closed flag and updated isEntangled() to check it. (WebCore::MessagePort::isEntangled): Now returns false if the port has been closed. (WebCore::MessagePort::isCloned): Added new API to differentiate between cloned and closed ports (closed ports can still be passed to postMessage).
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r51388 r51392  
     12009-11-25  Drew Wilson  <atwilson@chromium.org>
     2
     3        Reviewed by David Levin.
     4
     5        MessagePorts always look remotely entangled even when closed.
     6        https://bugs.webkit.org/show_bug.cgi?id=31698
     7
     8        Tests: Existing tests suffice, Chromium soak test passes now.
     9
     10        * bindings/v8/custom/V8CustomBinding.h:
     11        Removed kMessagePortEntangledPortIndex which is no longer used.
     12        * bindings/v8/V8GCController.cpp:
     13        (WebCore::GCPrologueVisitor::visitDOMWrapper):
     14        Simplified GC code to reflect the Chromium MessagePort implementation
     15        (locallyEntangledPort() always returns false).
     16        (WebCore::GCEpilogueVisitor::visitDOMWrapper):
     17        Cleaned up epilogue code to handle the case where the port gets closed
     18        in mid-GC (due to the parent context being freed).
     19        * dom/MessagePort.cpp:
     20        (WebCore::MessagePort::MessagePort):
     21        (WebCore::MessagePort::close):
     22        Now sets the closed flag.
     23        (WebCore::MessagePort::disentanglePorts):
     24        Updated to use new isCloned() API instead of relying on isEntangled(), which was incorrect.
     25        * dom/MessagePort.h:
     26        Added a m_closed flag and updated isEntangled() to check it.
     27        (WebCore::MessagePort::isEntangled):
     28        Now returns false if the port has been closed.
     29        (WebCore::MessagePort::isCloned):
     30        Added new API to differentiate between cloned and closed ports (closed ports can still be passed to postMessage).
     31
    1322009-11-25  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
    233
  • trunk/WebCore/bindings/v8/V8GCController.cpp

    r50752 r51392  
    205205    // GC even though their entaglement most likely is still the same.
    206206    if (type == V8ClassIndex::MESSAGEPORT) {
    207         // Get the port and its entangled port.
     207        // Mark each port as in-use if it's entangled. For simplicity's sake, we assume all ports are remotely entangled,
     208        // since the Chromium port implementation can't tell the difference.
    208209        MessagePort* port1 = static_cast<MessagePort*>(object);
    209         MessagePort* port2 = port1->locallyEntangledPort();
    210 
    211         // If we are remotely entangled, then mark this object as reachable
    212         // (we can't determine reachability directly as the remote object is
    213         // out-of-proc).
    214         if (port1->isEntangled() && !port2)
     210        if (port1->isEntangled())
    215211            wrapper.ClearWeak();
    216 
    217         if (port2) {
    218             // As ports are always entangled in pairs only perform the entanglement
    219             // once for each pair (see ASSERT in MessagePort::unentangle()).
    220             if (port1 < port2) {
    221                 v8::Handle<v8::Value> port1Wrapper = V8DOMWrapper::jsWrapperForActiveDOMObject(port1);
    222                 v8::Handle<v8::Value> port2Wrapper = V8DOMWrapper::jsWrapperForActiveDOMObject(port2);
    223                 ASSERT(port1Wrapper->IsObject());
    224                 v8::Handle<v8::Object>::Cast(port1Wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, port2Wrapper);
    225                 ASSERT(port2Wrapper->IsObject());
    226                 v8::Handle<v8::Object>::Cast(port2Wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, port1Wrapper);
    227             }
    228         } else {
    229             // Remove the wrapper entanglement when a port is not entangled.
    230             if (V8DOMWrapper::domObjectHasJSWrapper(port1)) {
    231                 v8::Handle<v8::Value> wrapper = V8DOMWrapper::jsWrapperForActiveDOMObject(port1);
    232                 ASSERT(wrapper->IsObject());
    233                 v8::Handle<v8::Object>::Cast(wrapper)->SetInternalField(V8Custom::kMessagePortEntangledPortIndex, v8::Undefined());
    234             }
    235         }
    236212    }
    237213}
     
    406382        if (type == V8ClassIndex::MESSAGEPORT) {
    407383            MessagePort* port1 = static_cast<MessagePort*>(object);
    408             MessagePort* port2 = port1->locallyEntangledPort();
    409             if (port1->isEntangled() && !port2) {
    410                 // We marked this port as reachable in GCPrologueVisitor.  Undo this now since the
    411                 // port could be not reachable in the future if it gets disentangled (and also
    412                 // GCPrologueVisitor expects to see all handles marked as weak).
     384            // We marked this port as reachable in GCPrologueVisitor.  Undo this now since the
     385            // port could be not reachable in the future if it gets disentangled (and also
     386            // GCPrologueVisitor expects to see all handles marked as weak).
     387            if (!wrapper.IsWeak() && !wrapper.IsNearDeath())
    413388                wrapper.MakeWeak(port1, &DOMDataStore::weakActiveDOMObjectCallback);
    414             }
    415389        }
    416390    }
  • trunk/WebCore/bindings/v8/custom/V8CustomBinding.h

    r51348 r51392  
    121121
    122122        static const int kMessagePortRequestCacheIndex = kDefaultWrapperInternalFieldCount + 0;
    123         static const int kMessagePortEntangledPortIndex = kDefaultWrapperInternalFieldCount + 1;
    124         static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 2;
     123        static const int kMessagePortInternalFieldCount = kDefaultWrapperInternalFieldCount + 1;
    125124
    126125#if ENABLE(WORKERS)
  • trunk/WebCore/dom/MessagePort.cpp

    r49214 r51392  
    4242    : m_entangledChannel(0)
    4343    , m_started(false)
     44    , m_closed(false)
    4445    , m_scriptExecutionContext(&scriptExecutionContext)
    4546{
     
    132133void MessagePort::close()
    133134{
     135    m_closed = true;
    134136    if (!m_entangledChannel)
    135137        return;
     
    201203    for (unsigned int i = 0; i < ports->size(); ++i) {
    202204        MessagePort* port = (*ports)[i].get();
    203         if (!port || !port->isEntangled() || portSet.contains(port)) {
     205        if (!port || port->isCloned() || portSet.contains(port)) {
    204206            ec = INVALID_STATE_ERR;
    205207            return 0;
  • trunk/WebCore/dom/MessagePort.h

    r49214 r51392  
    104104        // NOTE: This is used solely to enable a GC optimization. Some platforms may not be able to determine ownership of the remote port (since it may live cross-process) - those platforms may always return null.
    105105        MessagePort* locallyEntangledPort();
    106         bool isEntangled() { return m_entangledChannel; }
     106        // A port starts out its life entangled, and remains entangled until it is closed or is cloned.
     107        bool isEntangled() { return !m_closed && !isCloned(); }
     108        // A port is cloned if its entangled channel has been removed and sent to a new owner via postMessage().
     109        bool isCloned() { return !m_entangledChannel; }
    107110
    108111    private:
     
    117120
    118121        bool m_started;
     122        bool m_closed;
    119123
    120124        ScriptExecutionContext* m_scriptExecutionContext;
Note: See TracChangeset for help on using the changeset viewer.