| Index: Source/core/loader/DocumentLoader.cpp
 | 
| diff --git a/Source/core/loader/DocumentLoader.cpp b/Source/core/loader/DocumentLoader.cpp
 | 
| index 538b97b3a3e1acad8c52c4e5fd7acd7bffa47683..235ef45b884323dbe693b305f73e7519b47df661 100644
 | 
| --- a/Source/core/loader/DocumentLoader.cpp
 | 
| +++ b/Source/core/loader/DocumentLoader.cpp
 | 
| @@ -100,20 +100,30 @@ DocumentLoader::DocumentLoader(LocalFrame* frame, const ResourceRequest& req, co
 | 
|  FrameLoader* DocumentLoader::frameLoader() const
 | 
|  {
 | 
|      if (!m_frame)
 | 
| -        return 0;
 | 
| +        return nullptr;
 | 
|      return &m_frame->loader();
 | 
|  }
 | 
|  
 | 
|  ResourceLoader* DocumentLoader::mainResourceLoader() const
 | 
|  {
 | 
| -    return m_mainResource ? m_mainResource->loader() : 0;
 | 
| +    return m_mainResource ? m_mainResource->loader() : nullptr;
 | 
|  }
 | 
|  
 | 
|  DocumentLoader::~DocumentLoader()
 | 
|  {
 | 
|      ASSERT(!m_frame || !isLoading());
 | 
| -    clearMainResourceHandle();
 | 
| -    m_applicationCacheHost->dispose();
 | 
| +    ASSERT(!m_mainResource);
 | 
| +    ASSERT(!m_applicationCacheHost);
 | 
| +}
 | 
| +
 | 
| +DEFINE_TRACE(DocumentLoader)
 | 
| +{
 | 
| +    visitor->trace(m_frame);
 | 
| +    visitor->trace(m_fetcher);
 | 
| +    // TODO(sof): start tracing ResourcePtr<>s (and m_mainResource.)
 | 
| +    visitor->trace(m_writer);
 | 
| +    visitor->trace(m_archive);
 | 
| +    visitor->trace(m_applicationCacheHost);
 | 
|  }
 | 
|  
 | 
|  unsigned long DocumentLoader::mainResourceIdentifier() const
 | 
| @@ -125,7 +135,7 @@ Document* DocumentLoader::document() const
 | 
|  {
 | 
|      if (m_frame && m_frame->loader().documentLoader() == this)
 | 
|          return m_frame->document();
 | 
| -    return 0;
 | 
| +    return nullptr;
 | 
|  }
 | 
|  
 | 
|  const ResourceRequest& DocumentLoader::originalRequest() const
 | 
| @@ -190,7 +200,8 @@ void DocumentLoader::mainReceivedError(const ResourceError& error)
 | 
|  {
 | 
|      ASSERT(!error.isNull());
 | 
|      ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame));
 | 
| -    m_applicationCacheHost->failedLoadingMainResource();
 | 
| +    if (m_applicationCacheHost)
 | 
| +        m_applicationCacheHost->failedLoadingMainResource();
 | 
|      if (!frameLoader())
 | 
|          return;
 | 
|      m_mainDocumentError = error;
 | 
| @@ -205,8 +216,8 @@ void DocumentLoader::mainReceivedError(const ResourceError& error)
 | 
|  // but not loads initiated by child frames' data sources -- that's the WebFrame's job.
 | 
|  void DocumentLoader::stopLoading()
 | 
|  {
 | 
| -    RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame);
 | 
| -    RefPtr<DocumentLoader> protectLoader(this);
 | 
| +    RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame.get());
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protectLoader(this);
 | 
|  
 | 
|      m_fetcher->stopFetching();
 | 
|      if (isLoading())
 | 
| @@ -234,7 +245,7 @@ void DocumentLoader::notifyFinished(Resource* resource)
 | 
|      ASSERT_UNUSED(resource, m_mainResource == resource);
 | 
|      ASSERT(m_mainResource);
 | 
|  
 | 
| -    RefPtr<DocumentLoader> protect(this);
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protect(this);
 | 
|  
 | 
|      if (!m_mainResource->errorOccurred() && !m_mainResource->wasCanceled()) {
 | 
|          finishedLoading(m_mainResource->loadFinishTime());
 | 
| @@ -248,7 +259,7 @@ void DocumentLoader::finishedLoading(double finishTime)
 | 
|  {
 | 
|      ASSERT(!mainResourceLoader() || !mainResourceLoader()->defersLoading() || InspectorInstrumentation::isDebuggerPaused(m_frame));
 | 
|  
 | 
| -    RefPtr<DocumentLoader> protect(this);
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protect(this);
 | 
|  
 | 
|      double responseEndTime = finishTime;
 | 
|      if (!responseEndTime)
 | 
| @@ -436,7 +447,7 @@ void DocumentLoader::responseReceived(Resource* resource, const ResourceResponse
 | 
|  {
 | 
|      ASSERT_UNUSED(resource, m_mainResource == resource);
 | 
|      ASSERT_UNUSED(handle, !handle);
 | 
| -    RefPtr<DocumentLoader> protect(this);
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protect(this);
 | 
|      ASSERT(frame());
 | 
|  
 | 
|      m_applicationCacheHost->didReceiveResponseForMainResource(response);
 | 
| @@ -541,8 +552,8 @@ void DocumentLoader::dataReceived(Resource* resource, const char* data, unsigned
 | 
|  
 | 
|      // Both unloading the old page and parsing the new page may execute JavaScript which destroys the datasource
 | 
|      // by starting a new load, so retain temporarily.
 | 
| -    RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame);
 | 
| -    RefPtr<DocumentLoader> protectLoader(this);
 | 
| +    RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame.get());
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protectLoader(this);
 | 
|  
 | 
|      m_applicationCacheHost->mainResourceDataReceived(data, length);
 | 
|      m_timeOfLastDataReceived = monotonicallyIncreasingTime();
 | 
| @@ -578,17 +589,24 @@ bool DocumentLoader::loadingMultipartContent() const
 | 
|  void DocumentLoader::detachFromFrame()
 | 
|  {
 | 
|      ASSERT(m_frame);
 | 
| -    RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame);
 | 
| -    RefPtr<DocumentLoader> protectLoader(this);
 | 
| +    RefPtrWillBeRawPtr<LocalFrame> protectFrame(m_frame.get());
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protectLoader(this);
 | 
|  
 | 
|      // It never makes sense to have a document loader that is detached from its
 | 
|      // frame have any loads active, so go ahead and kill all the loads.
 | 
|      stopLoading();
 | 
|  
 | 
| +    // If that load cancellation triggered another detach, leave.
 | 
| +    // (fast/frames/detach-frame-nested-no-crash.html is an example of this.)
 | 
| +    if (!m_frame)
 | 
| +        return;
 | 
| +
 | 
|      m_fetcher->clearContext();
 | 
| -    m_applicationCacheHost->setApplicationCache(0);
 | 
| +    m_applicationCacheHost->detachFromDocumentLoader();
 | 
| +    m_applicationCacheHost.clear();
 | 
|      WeakIdentifierMap<DocumentLoader>::notifyObjectDestroyed(this);
 | 
| -    m_frame = 0;
 | 
| +    clearMainResourceHandle();
 | 
| +    m_frame = nullptr;
 | 
|  }
 | 
|  
 | 
|  void DocumentLoader::clearMainResourceLoader()
 | 
| @@ -601,7 +619,7 @@ void DocumentLoader::clearMainResourceHandle()
 | 
|      if (!m_mainResource)
 | 
|          return;
 | 
|      m_mainResource->removeClient(this);
 | 
| -    m_mainResource = 0;
 | 
| +    m_mainResource = nullptr;
 | 
|  }
 | 
|  
 | 
|  bool DocumentLoader::maybeCreateArchive()
 | 
| @@ -691,7 +709,7 @@ bool DocumentLoader::maybeLoadEmpty()
 | 
|  
 | 
|  void DocumentLoader::startLoadingMainResource()
 | 
|  {
 | 
| -    RefPtr<DocumentLoader> protect(this);
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protect(this);
 | 
|      m_mainDocumentError = ResourceError();
 | 
|      timing().markNavigationStart();
 | 
|      ASSERT(!m_mainResource);
 | 
| @@ -723,6 +741,8 @@ void DocumentLoader::startLoadingMainResource()
 | 
|          // If the load was aborted by clearing m_request, it's possible the ApplicationCacheHost
 | 
|          // is now in a state where starting an empty load will be inconsistent. Replace it with
 | 
|          // a new ApplicationCacheHost.
 | 
| +        if (m_applicationCacheHost)
 | 
| +            m_applicationCacheHost->detachFromDocumentLoader();
 | 
|          m_applicationCacheHost = ApplicationCacheHost::create(this);
 | 
|          maybeLoadEmpty();
 | 
|          return;
 | 
| @@ -741,7 +761,7 @@ void DocumentLoader::startLoadingMainResource()
 | 
|  
 | 
|  void DocumentLoader::cancelMainResourceLoad(const ResourceError& resourceError)
 | 
|  {
 | 
| -    RefPtr<DocumentLoader> protect(this);
 | 
| +    RefPtrWillBeRawPtr<DocumentLoader> protect(this);
 | 
|      ResourceError error = resourceError.isNull() ? ResourceError::cancelledError(m_request.url()) : resourceError;
 | 
|  
 | 
|      if (mainResourceLoader())
 | 
| 
 |