| Index: content/browser/frame_host/render_frame_host_impl.cc | 
| diff --git a/content/browser/frame_host/render_frame_host_impl.cc b/content/browser/frame_host/render_frame_host_impl.cc | 
| index e57bde68e4829cdaf80a02109f7ab186fcc6b4f7..d3908bc20f3629fd0596f02348df0ce0d12e923e 100644 | 
| --- a/content/browser/frame_host/render_frame_host_impl.cc | 
| +++ b/content/browser/frame_host/render_frame_host_impl.cc | 
| @@ -213,6 +213,7 @@ RenderFrameHostImpl::RenderFrameHostImpl(SiteInstance* site_instance, | 
| g_routing_id_frame_map.Get().insert(std::make_pair( | 
| RenderFrameHostID(GetProcess()->GetID(), routing_id_), | 
| this)); | 
| +  site_instance_->AddObserver(this); | 
|  | 
| if (is_swapped_out) { | 
| rfh_state_ = STATE_SWAPPED_OUT; | 
| @@ -258,6 +259,8 @@ RenderFrameHostImpl::~RenderFrameHostImpl() { | 
| g_routing_id_frame_map.Get().erase( | 
| RenderFrameHostID(GetProcess()->GetID(), routing_id_)); | 
|  | 
| +  site_instance_->RemoveObserver(this); | 
| + | 
| if (delegate_ && render_frame_created_) | 
| delegate_->RenderFrameDeleted(this); | 
|  | 
| @@ -513,7 +516,6 @@ bool RenderFrameHostImpl::OnMessageReceived(const IPC::Message &msg) { | 
| OnDidFailLoadWithError) | 
| IPC_MESSAGE_HANDLER_GENERIC(FrameHostMsg_DidCommitProvisionalLoad, | 
| OnDidCommitProvisionalLoad(msg)) | 
| -    IPC_MESSAGE_HANDLER(FrameHostMsg_DidDropNavigation, OnDidDropNavigation) | 
| IPC_MESSAGE_HANDLER(FrameHostMsg_UpdateState, OnUpdateState) | 
| IPC_MESSAGE_HANDLER(FrameHostMsg_OpenURL, OnOpenURL) | 
| IPC_MESSAGE_HANDLER(FrameHostMsg_DocumentOnLoadCompleted, | 
| @@ -686,6 +688,13 @@ gfx::NativeViewAccessible | 
| return NULL; | 
| } | 
|  | 
| +void RenderFrameHostImpl::RenderProcessGone(SiteInstanceImpl* site_instance) { | 
| +  DCHECK(site_instance == site_instance_.get()); | 
| + | 
| +  // The render process is gone, this frame can no longer be loading. | 
| +  ResetLoadingState(); | 
| +} | 
| + | 
| bool RenderFrameHostImpl::CreateRenderFrame(int proxy_routing_id, | 
| int opener_routing_id, | 
| int parent_routing_id, | 
| @@ -1037,15 +1046,6 @@ void RenderFrameHostImpl::OnDidCommitProvisionalLoad(const IPC::Message& msg) { | 
| pending_commit_ = false; | 
| } | 
|  | 
| -void RenderFrameHostImpl::OnDidDropNavigation() { | 
| -  // At the end of Navigate(), the FrameTreeNode's DidStartLoading is called to | 
| -  // force the spinner to start, even if the renderer didn't yet begin the load. | 
| -  // If it turns out that the renderer dropped the navigation, the spinner needs | 
| -  // to be turned off. | 
| -  frame_tree_node_->DidStopLoading(); | 
| -  navigation_handle_.reset(); | 
| -} | 
| - | 
| void RenderFrameHostImpl::OnUpdateState(const PageState& state) { | 
| // TODO(creis): Verify the state's ISN matches the last committed FNE. | 
|  | 
| @@ -1307,6 +1307,8 @@ void RenderFrameHostImpl::OnSwappedOut() { | 
| return; | 
| } | 
|  | 
| +  ResetLoadingState(); | 
| + | 
| // If this RFH wasn't pending deletion, then it is now swapped out. | 
| SetState(RenderFrameHostImpl::STATE_SWAPPED_OUT); | 
| } | 
| @@ -1692,21 +1694,6 @@ void RenderFrameHostImpl::OnToggleFullscreen(bool enter_fullscreen) { | 
| } | 
|  | 
| void RenderFrameHostImpl::OnDidStartLoading(bool to_different_document) { | 
| -  // Any main frame load to a new document should reset the load since it will | 
| -  // replace the current page and any frames. | 
| -  if (to_different_document && !GetParent()) | 
| -    is_loading_ = false; | 
| - | 
| -  // This method should never be called when the frame is loading. | 
| -  // Unfortunately, it can happen if a history navigation happens during a | 
| -  // BeforeUnload or Unload event. | 
| -  // TODO(fdegans): Change this to a DCHECK after LoadEventProgress has been | 
| -  // refactored in Blink. See crbug.com/466089 | 
| -  if (is_loading_) { | 
| -    LOG(WARNING) << "OnDidStartLoading was called twice."; | 
| -    return; | 
| -  } | 
| - | 
| frame_tree_node_->DidStartLoading(to_different_document); | 
| is_loading_ = true; | 
| } | 
| @@ -1903,8 +1890,10 @@ void RenderFrameHostImpl::Navigate( | 
| // | 
| // Blink doesn't send throb notifications for JavaScript URLs, so it is not | 
| // done here either. | 
| -  if (!common_params.url.SchemeIs(url::kJavaScriptScheme)) | 
| +  if (!common_params.url.SchemeIs(url::kJavaScriptScheme)) { | 
| frame_tree_node_->DidStartLoading(true); | 
| +    is_loading_ = true; | 
| +  } | 
| } | 
|  | 
| void RenderFrameHostImpl::NavigateToInterstitialURL(const GURL& data_url) { | 
| @@ -2245,6 +2234,18 @@ RenderFrameHostImpl::GetMojoImageDownloader() { | 
| return mojo_image_downloader_; | 
| } | 
|  | 
| +void RenderFrameHostImpl::ResetLoadingState() { | 
| +  if (is_loading()) { | 
| +    // When pending deletion, just set the loading state to not loading. | 
| +    // Otherwise, OnDidStopLoading will take care of that, as well as sending | 
| +    // notification to the FrameTreeNode about the change in loading state. | 
| +    if (rfh_state_ != STATE_DEFAULT) | 
| +      is_loading_ = false; | 
| +    else | 
| +      OnDidStopLoading(); | 
| +  } | 
| +} | 
| + | 
| bool RenderFrameHostImpl::IsSameSiteInstance( | 
| RenderFrameHostImpl* other_render_frame_host) { | 
| // As a sanity check, make sure the frame belongs to the same BrowserContext. | 
|  |