| Index: Source/core/dom/Document.cpp
|
| diff --git a/Source/core/dom/Document.cpp b/Source/core/dom/Document.cpp
|
| index 3d916086c7aeadfd863d30e4d1bf2a538772acdf..56203732bc1f5132cde33a1d48691e506bdb9391 100644
|
| --- a/Source/core/dom/Document.cpp
|
| +++ b/Source/core/dom/Document.cpp
|
| @@ -71,6 +71,7 @@
|
| #include "core/dom/Element.h"
|
| #include "core/dom/ElementDataCache.h"
|
| #include "core/dom/ElementTraversal.h"
|
| +#include "core/dom/EventHandlerRegistry.h"
|
| #include "core/dom/ExceptionCode.h"
|
| #include "core/dom/ExecutionContextTask.h"
|
| #include "core/dom/MainThreadTaskRunner.h"
|
| @@ -379,7 +380,9 @@ DocumentVisibilityObserver::DocumentVisibilityObserver(Document& document)
|
|
|
| DocumentVisibilityObserver::~DocumentVisibilityObserver()
|
| {
|
| +#if !ENABLE(OILPAN)
|
| unregisterObserver();
|
| +#endif
|
| }
|
|
|
| void DocumentVisibilityObserver::unregisterObserver()
|
| @@ -524,8 +527,14 @@ Document::~Document()
|
| ASSERT(!renderView());
|
| ASSERT(m_ranges.isEmpty());
|
| ASSERT(!parentTreeScope());
|
| +#if !ENABLE(OILPAN)
|
| ASSERT(!hasGuardRefCount());
|
| + // With Oilpan, either the document outlives the visibility observers
|
| + // or the visibility observers and the document die in the same GC round.
|
| + // When they die in the same GC round, the list of visibility observers
|
| + // will not be empty on Document destruction.
|
| ASSERT(m_visibilityObservers.isEmpty());
|
| +#endif
|
|
|
| if (m_templateDocument)
|
| m_templateDocument->m_templateDocumentHost = 0; // balanced in ensureTemplateDocument().
|
| @@ -546,8 +555,10 @@ Document::~Document()
|
| if (this == topDocument())
|
| clearAXObjectCache();
|
|
|
| +#if !ENABLE(OILPAN)
|
| if (m_styleSheetList)
|
| m_styleSheetList->detachFromDocument();
|
| +#endif
|
|
|
| if (m_importsController) {
|
| m_importsController->wasDetachedFrom(*this);
|
| @@ -561,8 +572,10 @@ Document::~Document()
|
| if (m_styleEngine)
|
| m_styleEngine->detachFromDocument();
|
|
|
| +#if !ENABLE(OILPAN)
|
| if (m_elemSheet)
|
| m_elemSheet->clearOwnerNode();
|
| +#endif
|
|
|
| // It's possible for multiple Documents to end up referencing the same ResourceFetcher (e.g., SVGImages
|
| // load the initial empty document and the SVGDocument with the same DocumentLoader).
|
| @@ -1427,8 +1440,8 @@ void Document::didChangeVisibilityState()
|
| dispatchEvent(Event::create(EventTypeNames::webkitvisibilitychange));
|
|
|
| PageVisibilityState state = pageVisibilityState();
|
| - HashSet<DocumentVisibilityObserver*>::const_iterator observerEnd = m_visibilityObservers.end();
|
| - for (HashSet<DocumentVisibilityObserver*>::const_iterator it = m_visibilityObservers.begin(); it != observerEnd; ++it)
|
| + DocumentVisibilityObserverSet::const_iterator observerEnd = m_visibilityObservers.end();
|
| + for (DocumentVisibilityObserverSet::const_iterator it = m_visibilityObservers.begin(); it != observerEnd; ++it)
|
| (*it)->didChangeVisibilityState(state);
|
| }
|
|
|
| @@ -4830,7 +4843,7 @@ void Document::detachRange(Range* range)
|
| m_ranges.remove(range);
|
| }
|
|
|
| -void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, bool& is2d, RefPtr<CanvasRenderingContext2D>& context2d, bool& is3d, RefPtr<WebGLRenderingContext>& context3d)
|
| +void Document::getCSSCanvasContext(const String& type, const String& name, int width, int height, bool& is2d, RefPtrWillBeRawPtr<CanvasRenderingContext2D>& context2d, bool& is3d, RefPtrWillBeRawPtr<WebGLRenderingContext>& context3d)
|
| {
|
| HTMLCanvasElement& element = getCSSCanvasElement(name);
|
| element.setSize(IntSize(width, height));
|
| @@ -5033,10 +5046,33 @@ void Document::decrementLoadEventDelayCount()
|
| ASSERT(m_loadEventDelayCount);
|
| --m_loadEventDelayCount;
|
|
|
| - if (frame() && !m_loadEventDelayCount && !m_loadEventDelayTimer.isActive())
|
| + if (!m_loadEventDelayCount)
|
| + checkLoadEventSoon();
|
| +}
|
| +
|
| +void Document::checkLoadEventSoon()
|
| +{
|
| + if (frame() && !m_loadEventDelayTimer.isActive())
|
| m_loadEventDelayTimer.startOneShot(0, FROM_HERE);
|
| }
|
|
|
| +bool Document::isDelayingLoadEvent()
|
| +{
|
| +#if ENABLE(OILPAN)
|
| + // Always delay load events until after garbage collection.
|
| + // This way we don't have to explicitly delay load events via
|
| + // incrementLoadEventDelayCount and decrementLoadEventDelayCount in
|
| + // Node destructors.
|
| + if (ThreadState::current()->isSweepInProgress()) {
|
| + if (!m_loadEventDelayCount)
|
| + checkLoadEventSoon();
|
| + return true;
|
| + }
|
| +#endif
|
| + return m_loadEventDelayCount;
|
| +}
|
| +
|
| +
|
| void Document::loadEventDelayTimerFired(Timer<Document>*)
|
| {
|
| if (frame())
|
| @@ -5590,9 +5626,40 @@ void Document::invalidateNodeListCaches(const QualifiedName* attrName)
|
| (*it)->invalidateCacheForAttribute(attrName);
|
| }
|
|
|
| +void Document::clearWeakMembers(Visitor* visitor)
|
| +{
|
| + if (m_axObjectCache)
|
| + m_axObjectCache->clearWeakMembers(visitor);
|
| +
|
| + if (m_markers)
|
| + m_markers->clearWeakMembers(visitor);
|
| +
|
| + // FIXME: Oilpan: Use a weak counted set instead.
|
| + if (m_touchEventTargets) {
|
| + Vector<Node*> deadNodes;
|
| + for (TouchEventTargetSet::iterator it = m_touchEventTargets->begin(); it != m_touchEventTargets->end(); ++it) {
|
| + if (!visitor->isAlive(it->key))
|
| + deadNodes.append(it->key);
|
| + }
|
| + for (unsigned i = 0; i < deadNodes.size(); ++i)
|
| + didClearTouchEventHandlers(deadNodes[i]);
|
| + }
|
| +
|
| + EventHandlerRegistry* registry = static_cast<EventHandlerRegistry*>(DocumentSupplement::from(this, EventHandlerRegistry::supplementName()));
|
| + // FIXME: Oilpan: This is pretty funky. The current code disables all modifications of the
|
| + // EventHandlerRegistry when the document becomes inactive. To keep that behavior we only
|
| + // perform weak processing of the registry when the document is active.
|
| + if (registry && isActive())
|
| + registry->clearWeakMembers(visitor);
|
| +}
|
| +
|
| void Document::trace(Visitor* visitor)
|
| {
|
| + visitor->trace(m_styleSheetList);
|
| + visitor->trace(m_visibilityObservers);
|
| + visitor->registerWeakMembers<Document, &Document::clearWeakMembers>(this);
|
| Supplementable<Document>::trace(visitor);
|
| + TreeScope::trace(visitor);
|
| ContainerNode::trace(visitor);
|
| }
|
|
|
|
|