Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / frame_host / render_frame_host_manager.cc
index c871e04..13a03b3 100644 (file)
@@ -9,24 +9,27 @@
 #include "base/command_line.h"
 #include "base/debug/trace_event.h"
 #include "base/logging.h"
+#include "base/stl_util.h"
 #include "content/browser/child_process_security_policy_impl.h"
 #include "content/browser/devtools/render_view_devtools_agent_host.h"
 #include "content/browser/frame_host/cross_process_frame_connector.h"
+#include "content/browser/frame_host/cross_site_transferring_request.h"
 #include "content/browser/frame_host/debug_urls.h"
 #include "content/browser/frame_host/interstitial_page_impl.h"
 #include "content/browser/frame_host/navigation_controller_impl.h"
 #include "content/browser/frame_host/navigation_entry_impl.h"
+#include "content/browser/frame_host/navigator.h"
 #include "content/browser/frame_host/render_frame_host_factory.h"
 #include "content/browser/frame_host/render_frame_host_impl.h"
-#include "content/browser/renderer_host/cross_site_transferring_request.h"
+#include "content/browser/frame_host/render_frame_proxy_host.h"
 #include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/renderer_host/render_view_host_factory.h"
 #include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_base.h"
 #include "content/browser/site_instance_impl.h"
 #include "content/browser/webui/web_ui_controller_factory_registry.h"
 #include "content/browser/webui/web_ui_impl.h"
 #include "content/common/view_messages.h"
-#include "content/port/browser/render_widget_host_view_port.h"
 #include "content/public/browser/content_browser_client.h"
 #include "content/public/browser/notification_service.h"
 #include "content/public/browser/notification_types.h"
@@ -44,19 +47,24 @@ RenderFrameHostManager::PendingNavigationParams::PendingNavigationParams(
     const std::vector<GURL>& transfer_url_chain,
     Referrer referrer,
     PageTransition page_transition,
-    int64 frame_id,
+    int render_frame_id,
     bool should_replace_current_entry)
     : global_request_id(global_request_id),
       cross_site_transferring_request(cross_site_transferring_request.Pass()),
       transfer_url_chain(transfer_url_chain),
       referrer(referrer),
       page_transition(page_transition),
-      frame_id(frame_id),
+      render_frame_id(render_frame_id),
       should_replace_current_entry(should_replace_current_entry) {
 }
 
 RenderFrameHostManager::PendingNavigationParams::~PendingNavigationParams() {}
 
+bool RenderFrameHostManager::ClearRFHsPendingShutdown(FrameTreeNode* node) {
+  node->render_manager()->pending_delete_hosts_.clear();
+  return true;
+}
+
 RenderFrameHostManager::RenderFrameHostManager(
     FrameTreeNode* frame_tree_node,
     RenderFrameHostDelegate* render_frame_delegate,
@@ -69,11 +77,11 @@ RenderFrameHostManager::RenderFrameHostManager(
       render_frame_delegate_(render_frame_delegate),
       render_view_delegate_(render_view_delegate),
       render_widget_delegate_(render_widget_delegate),
-      render_frame_host_(NULL),
-      pending_render_frame_host_(NULL),
       interstitial_page_(NULL),
       cross_process_frame_connector_(NULL),
-      weak_factory_(this) {}
+      weak_factory_(this) {
+  DCHECK(frame_tree_node_);
+}
 
 RenderFrameHostManager::~RenderFrameHostManager() {
   if (pending_render_frame_host_)
@@ -83,19 +91,10 @@ RenderFrameHostManager::~RenderFrameHostManager() {
     delete cross_process_frame_connector_;
 
   // We should always have a current RenderFrameHost except in some tests.
-  // TODO(creis): Now that we aren't using Shutdown, make render_frame_host_ and
-  // RenderFrameHostMap use scoped_ptrs.
-  RenderFrameHostImpl* render_frame_host = render_frame_host_;
-  render_frame_host_ = NULL;
-  if (render_frame_host)
-    delete render_frame_host;
+  render_frame_host_.reset();
 
   // Delete any swapped out RenderFrameHosts.
-  for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
-       iter != swapped_out_hosts_.end();
-       ++iter) {
-    delete iter->second;
-  }
+  STLDeleteValues(&proxy_hosts_);
 }
 
 void RenderFrameHostManager::Init(BrowserContext* browser_context,
@@ -108,9 +107,10 @@ void RenderFrameHostManager::Init(BrowserContext* browser_context,
   if (!site_instance)
     site_instance = SiteInstance::Create(browser_context);
 
-  // TODO(creis): Make render_frame_host_ a scoped_ptr.
-  render_frame_host_ = CreateRenderFrameHost(site_instance, view_routing_id,
-                                             frame_routing_id, false,
+  render_frame_host_ = CreateRenderFrameHost(site_instance,
+                                             view_routing_id,
+                                             frame_routing_id,
+                                             false,
                                              delegate_->IsHidden());
 
   // Keep track of renderer processes as they start to shut down or are
@@ -163,8 +163,7 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
     const NavigationEntryImpl& entry) {
   TRACE_EVENT0("browser", "RenderFrameHostManager:Navigate");
   // Create a pending RenderFrameHost to use for the navigation.
-  RenderFrameHostImpl* dest_render_frame_host =
-      UpdateRendererStateForNavigate(entry);
+  RenderFrameHostImpl* dest_render_frame_host = UpdateStateForNavigate(entry);
   if (!dest_render_frame_host)
     return NULL;  // We weren't able to create a pending render frame host.
 
@@ -184,7 +183,7 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
   if (!dest_render_frame_host->render_view_host()->IsRenderViewLive()) {
     // Recreate the opener chain.
     int opener_route_id = delegate_->CreateOpenerRenderViewsForRenderManager(
-        dest_render_frame_host->render_view_host()->GetSiteInstance());
+        dest_render_frame_host->GetSiteInstance());
     if (!InitRenderView(dest_render_frame_host->render_view_host(),
                         opener_route_id))
       return NULL;
@@ -268,54 +267,83 @@ bool RenderFrameHostManager::ShouldCloseTabOnUnresponsiveRenderer() {
   return false;
 }
 
-// TODO(creis): Remove this in favor of SwappedOutFrame.
-void RenderFrameHostManager::SwappedOut(RenderViewHost* render_view_host) {
-  // Make sure this is from our current RVH, and that we have a pending
-  // navigation from OnCrossSiteResponse.  (There may be no pending navigation
-  // for data URLs that don't make network requests, for example.)   If not,
-  // just return early and ignore.
-  if (render_view_host != render_frame_host_->render_view_host() ||
-      !pending_nav_params_.get()) {
-    pending_nav_params_.reset();
-    return;
-  }
+void RenderFrameHostManager::OnBeforeUnloadACK(
+    bool for_cross_site_transition,
+    bool proceed,
+    const base::TimeTicks& proceed_time) {
+  if (for_cross_site_transition) {
+    // Ignore if we're not in a cross-site navigation.
+    if (!cross_navigation_pending_)
+      return;
 
-  // Now that the unload handler has run, we need to either initiate the
-  // pending transfer (if there is one) or resume the paused response (if not).
-  // TODO(creis): The blank swapped out page is visible during this time, but
-  // we can shorten this by delivering the response directly, rather than
-  // forcing an identical request to be made.
-  if (pending_nav_params_->cross_site_transferring_request) {
-    // Treat the last URL in the chain as the destination and the remainder as
-    // the redirect chain.
-    CHECK(pending_nav_params_->transfer_url_chain.size());
-    GURL transfer_url = pending_nav_params_->transfer_url_chain.back();
-    pending_nav_params_->transfer_url_chain.pop_back();
+    if (proceed) {
+      // Ok to unload the current page, so proceed with the cross-site
+      // navigation.  Note that if navigations are not currently suspended, it
+      // might be because the renderer was deemed unresponsive and this call was
+      // already made by ShouldCloseTabOnUnresponsiveRenderer.  In that case, it
+      // is ok to do nothing here.
+      if (pending_render_frame_host_ &&
+          pending_render_frame_host_->render_view_host()->
+              are_navigations_suspended()) {
+        pending_render_frame_host_->render_view_host()->
+            SetNavigationsSuspended(false, proceed_time);
+      }
+    } else {
+      // Current page says to cancel.
+      CancelPending();
+      cross_navigation_pending_ = false;
+    }
+  } else {
+    // Non-cross site transition means closing the entire tab.
+    bool proceed_to_fire_unload;
+    delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time,
+                                                  &proceed_to_fire_unload);
 
-    // We don't know whether the original request had |user_action| set to true.
-    // However, since we force the navigation to be in the current tab, it
-    // doesn't matter.
-    render_view_host->GetDelegate()->RequestTransferURL(
-        transfer_url,
-        pending_nav_params_->transfer_url_chain,
-        pending_nav_params_->referrer,
-        pending_nav_params_->page_transition,
-        CURRENT_TAB,
-        pending_nav_params_->frame_id,
-        pending_nav_params_->global_request_id,
-        pending_nav_params_->should_replace_current_entry,
-        true);
-  } else if (pending_render_frame_host_) {
-    RenderProcessHostImpl* pending_process =
-        static_cast<RenderProcessHostImpl*>(
-            pending_render_frame_host_->GetProcess());
-    pending_process->ResumeDeferredNavigation(
-        pending_nav_params_->global_request_id);
+    if (proceed_to_fire_unload) {
+      // If we're about to close the tab and there's a pending RFH, cancel it.
+      // Otherwise, if the navigation in the pending RFH completes before the
+      // close in the current RFH, we'll lose the tab close.
+      if (pending_render_frame_host_) {
+        CancelPending();
+        cross_navigation_pending_ = false;
+      }
+
+      // This is not a cross-site navigation, the tab is being closed.
+      render_frame_host_->render_view_host()->ClosePage();
+    }
   }
-  pending_nav_params_.reset();
 }
 
-void RenderFrameHostManager::SwappedOutFrame(
+void RenderFrameHostManager::OnCrossSiteResponse(
+    RenderFrameHostImpl* pending_render_frame_host,
+    const GlobalRequestID& global_request_id,
+    scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request,
+    const std::vector<GURL>& transfer_url_chain,
+    const Referrer& referrer,
+    PageTransition page_transition,
+    bool should_replace_current_entry) {
+  // This should be called either when the pending RFH is ready to commit or
+  // when we realize that the current RFH's request requires a transfer.
+  DCHECK(pending_render_frame_host == pending_render_frame_host_ ||
+         pending_render_frame_host == render_frame_host_);
+
+  // TODO(creis): Eventually we will want to check all navigation responses
+  // here, but currently we pass information for a transfer if
+  // ShouldSwapProcessesForRedirect returned true in the network stack.
+  // In that case, we should set up a transfer after the unload handler runs.
+  // If |cross_site_transferring_request| is NULL, we will just run the unload
+  // handler and resume.
+  pending_nav_params_.reset(new PendingNavigationParams(
+      global_request_id, cross_site_transferring_request.Pass(),
+      transfer_url_chain, referrer, page_transition,
+      pending_render_frame_host->GetRoutingID(),
+      should_replace_current_entry));
+
+  // Run the unload handler of the current page.
+  SwapOutOldPage();
+}
+
+void RenderFrameHostManager::SwappedOut(
     RenderFrameHostImpl* render_frame_host) {
   // Make sure this is from our current RFH, and that we have a pending
   // navigation from OnCrossSiteResponse.  (There may be no pending navigation
@@ -326,15 +354,26 @@ void RenderFrameHostManager::SwappedOutFrame(
     return;
   }
 
-  // Sanity check that this is for the correct frame.
-  DCHECK_EQ(frame_tree_node_->frame_id(), pending_nav_params_->frame_id);
-
   // Now that the unload handler has run, we need to either initiate the
   // pending transfer (if there is one) or resume the paused response (if not).
   // TODO(creis): The blank swapped out page is visible during this time, but
   // we can shorten this by delivering the response directly, rather than
   // forcing an identical request to be made.
   if (pending_nav_params_->cross_site_transferring_request) {
+    // Sanity check that the params are for the correct frame and process.
+    // These should match the RenderFrameHost that made the request.
+    // If it started as a cross-process navigation via OpenURL, this is the
+    // pending one.  If it wasn't cross-process until the transfer, this is the
+    // current one.
+    int render_frame_id = pending_render_frame_host_ ?
+        pending_render_frame_host_->GetRoutingID() :
+        render_frame_host_->GetRoutingID();
+    DCHECK_EQ(render_frame_id, pending_nav_params_->render_frame_id);
+    int process_id = pending_render_frame_host_ ?
+        pending_render_frame_host_->GetProcess()->GetID() :
+        render_frame_host_->GetProcess()->GetID();
+    DCHECK_EQ(process_id, pending_nav_params_->global_request_id.child_id);
+
     // Treat the last URL in the chain as the destination and the remainder as
     // the redirect chain.
     CHECK(pending_nav_params_->transfer_url_chain.size());
@@ -344,16 +383,15 @@ void RenderFrameHostManager::SwappedOutFrame(
     // We don't know whether the original request had |user_action| set to true.
     // However, since we force the navigation to be in the current tab, it
     // doesn't matter.
-    // TODO(creis): Move RequestTransferURL to RenderFrameHost's navigator.
-    render_frame_host->render_view_host()->GetDelegate()->RequestTransferURL(
+    render_frame_host->frame_tree_node()->navigator()->RequestTransferURL(
+        render_frame_host,
         transfer_url,
         pending_nav_params_->transfer_url_chain,
         pending_nav_params_->referrer,
         pending_nav_params_->page_transition,
         CURRENT_TAB,
-        pending_nav_params_->frame_id,
         pending_nav_params_->global_request_id,
-        false,
+        pending_nav_params_->should_replace_current_entry,
         true);
   } else if (pending_render_frame_host_) {
     RenderProcessHostImpl* pending_process =
@@ -365,14 +403,13 @@ void RenderFrameHostManager::SwappedOutFrame(
   pending_nav_params_.reset();
 }
 
-// TODO(creis): This should take in a RenderFrameHost.
-void RenderFrameHostManager::DidNavigateMainFrame(
-    RenderViewHost* render_view_host) {
+void RenderFrameHostManager::DidNavigateFrame(
+    RenderFrameHostImpl* render_frame_host) {
   if (!cross_navigation_pending_) {
     DCHECK(!pending_render_frame_host_);
 
     // We should only hear this from our current renderer.
-    DCHECK(render_view_host == render_frame_host_->render_view_host());
+    DCHECK_EQ(render_frame_host_, render_frame_host);
 
     // Even when there is no pending RVH, there may be a pending Web UI.
     if (pending_web_ui())
@@ -380,18 +417,22 @@ void RenderFrameHostManager::DidNavigateMainFrame(
     return;
   }
 
-  if (render_view_host == pending_render_frame_host_->render_view_host()) {
+  if (render_frame_host == pending_render_frame_host_) {
     // The pending cross-site navigation completed, so show the renderer.
     // If it committed without sending network requests (e.g., data URLs),
     // then we still need to swap out the old RFH first and run its unload
-    // handler.  OK for that to happen in the background.
+    // handler, only if it hasn't happened yet.  OK for that to happen in the
+    // background.
     if (pending_render_frame_host_->render_view_host()->
-            HasPendingCrossSiteRequest())
+            HasPendingCrossSiteRequest() &&
+        pending_render_frame_host_->render_view_host()->rvh_state() ==
+            RenderViewHostImpl::STATE_DEFAULT) {
       SwapOutOldPage();
+    }
 
     CommitPending();
     cross_navigation_pending_ = false;
-  } else if (render_view_host == render_frame_host_->render_view_host()) {
+  } else if (render_frame_host == render_frame_host_) {
     // A navigation in the original page has taken place.  Cancel the pending
     // one.
     CancelPending();
@@ -405,11 +446,11 @@ void RenderFrameHostManager::DidNavigateMainFrame(
 // TODO(creis): Take in RenderFrameHost instead, since frames can have openers.
 void RenderFrameHostManager::DidDisownOpener(RenderViewHost* render_view_host) {
   // Notify all swapped out hosts, including the pending RVH.
-  for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
-       iter != swapped_out_hosts_.end();
+  for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
+       iter != proxy_hosts_.end();
        ++iter) {
-    DCHECK_NE(iter->second->render_view_host()->GetSiteInstance(),
-              current_host()->GetSiteInstance());
+    DCHECK_NE(iter->second->GetSiteInstance(),
+              current_frame_host()->GetSiteInstance());
     iter->second->render_view_host()->DisownOpener();
   }
 }
@@ -420,8 +461,8 @@ void RenderFrameHostManager::RendererProcessClosing(
   // swap them back in while the process is exiting.  Start by finding them,
   // since there could be more than one.
   std::list<int> ids_to_remove;
-  for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
-       iter != swapped_out_hosts_.end();
+  for (RenderFrameProxyHostMap::iterator iter = proxy_hosts_.begin();
+       iter != proxy_hosts_.end();
        ++iter) {
     if (iter->second->GetProcess() == render_process_host)
       ids_to_remove.push_back(iter->first);
@@ -429,90 +470,12 @@ void RenderFrameHostManager::RendererProcessClosing(
 
   // Now delete them.
   while (!ids_to_remove.empty()) {
-    delete swapped_out_hosts_[ids_to_remove.back()];
-    swapped_out_hosts_.erase(ids_to_remove.back());
+    delete proxy_hosts_[ids_to_remove.back()];
+    proxy_hosts_.erase(ids_to_remove.back());
     ids_to_remove.pop_back();
   }
 }
 
-void RenderFrameHostManager::ShouldClosePage(
-    bool for_cross_site_transition,
-    bool proceed,
-    const base::TimeTicks& proceed_time) {
-  if (for_cross_site_transition) {
-    // Ignore if we're not in a cross-site navigation.
-    if (!cross_navigation_pending_)
-      return;
-
-    if (proceed) {
-      // Ok to unload the current page, so proceed with the cross-site
-      // navigation.  Note that if navigations are not currently suspended, it
-      // might be because the renderer was deemed unresponsive and this call was
-      // already made by ShouldCloseTabOnUnresponsiveRenderer.  In that case, it
-      // is ok to do nothing here.
-      if (pending_render_frame_host_ &&
-          pending_render_frame_host_->render_view_host()->
-              are_navigations_suspended()) {
-        pending_render_frame_host_->render_view_host()->
-            SetNavigationsSuspended(false, proceed_time);
-      }
-    } else {
-      // Current page says to cancel.
-      CancelPending();
-      cross_navigation_pending_ = false;
-    }
-  } else {
-    // Non-cross site transition means closing the entire tab.
-    bool proceed_to_fire_unload;
-    delegate_->BeforeUnloadFiredFromRenderManager(proceed, proceed_time,
-                                                  &proceed_to_fire_unload);
-
-    if (proceed_to_fire_unload) {
-      // If we're about to close the tab and there's a pending RFH, cancel it.
-      // Otherwise, if the navigation in the pending RFH completes before the
-      // close in the current RFH, we'll lose the tab close.
-      if (pending_render_frame_host_) {
-        CancelPending();
-        cross_navigation_pending_ = false;
-      }
-
-      // This is not a cross-site navigation, the tab is being closed.
-      render_frame_host_->render_view_host()->ClosePage();
-    }
-  }
-}
-
-// TODO(creis): Take in a RenderFrameHost from CSRH.
-void RenderFrameHostManager::OnCrossSiteResponse(
-    RenderViewHost* pending_render_view_host,
-    const GlobalRequestID& global_request_id,
-    scoped_ptr<CrossSiteTransferringRequest> cross_site_transferring_request,
-    const std::vector<GURL>& transfer_url_chain,
-    const Referrer& referrer,
-    PageTransition page_transition,
-    int64 frame_id,
-    bool should_replace_current_entry) {
-  // This should be called either when the pending RVH is ready to commit or
-  // when we realize that the current RVH's request requires a transfer.
-  DCHECK(pending_render_view_host == render_frame_host_->render_view_host() ||
-         pending_render_view_host ==
-             pending_render_frame_host_->render_view_host());
-
-  // TODO(creis): Eventually we will want to check all navigation responses
-  // here, but currently we pass information for a transfer if
-  // ShouldSwapProcessesForRedirect returned true in the network stack.
-  // In that case, we should set up a transfer after the unload handler runs.
-  // If |cross_site_transferring_request| is NULL, we will just run the unload
-  // handler and resume.
-  pending_nav_params_.reset(new PendingNavigationParams(
-      global_request_id, cross_site_transferring_request.Pass(),
-      transfer_url_chain, referrer, page_transition, frame_id,
-      should_replace_current_entry));
-
-  // Run the unload handler of the current page.
-  SwapOutOldPage();
-}
-
 void RenderFrameHostManager::SwapOutOldPage() {
   // Should only see this while we have a pending renderer or transfer.
   CHECK(cross_navigation_pending_ || pending_nav_params_.get());
@@ -520,6 +483,7 @@ void RenderFrameHostManager::SwapOutOldPage() {
   // Tell the renderer to suppress any further modal dialogs so that we can swap
   // it out.  This must be done before canceling any current dialog, in case
   // there is a loop creating additional dialogs.
+  // TODO(creis): Handle modal dialogs in subframe processes.
   render_frame_host_->render_view_host()->SuppressDialogsUntilSwapOut();
 
   // Now close any modal dialogs that would prevent us from swapping out.  This
@@ -527,17 +491,26 @@ void RenderFrameHostManager::SwapOutOldPage() {
   // no longer on the stack when we send the SwapOut message.
   delegate_->CancelModalDialogsForRenderManager();
 
-  // Tell the old renderer it is being swapped out.  This will fire the unload
-  // handler (without firing the beforeunload handler a second time).  When the
-  // unload handler finishes and the navigation completes, we will send a
-  // message to the ResourceDispatcherHost, allowing the pending RVH's response
-  // to resume.
-  // Note: This must be done on the RFH or else we'll swap out the top-level
-  // page when subframes navigate.
-  if (frame_tree_node_->IsMainFrame())
-    render_frame_host_->render_view_host()->SwapOut();
-  else
-    render_frame_host_->SwapOut();
+  if (!frame_tree_node_->IsMainFrame()) {
+    // The RenderFrameHost being swapped out becomes the proxy for this
+    // frame in its parent's process. CrossProcessFrameConnector
+    // initialization only needs to happen on an initial cross-process
+    // navigation, when the RenderFrame leaves the same process as its parent.
+    // The same CrossProcessFrameConnector is used for subsequent cross-
+    // process navigations, but it will be destroyed if the Frame is
+    // navigated back to the same site instance as its parent.
+    // TODO(kenrb): This will change when RenderFrameProxyHost is created.
+    if (!cross_process_frame_connector_) {
+      cross_process_frame_connector_ =
+          new CrossProcessFrameConnector(render_frame_host_.get());
+    }
+  }
+
+  // Tell the old frame it is being swapped out.  This will fire the unload
+  // handler in the background (without firing the beforeunload handler a second
+  // time).  When the navigation completes, we will send a message to the
+  // ResourceDispatcherHost, allowing the pending RVH's response to resume.
+  render_frame_host_->SwapOut();
 
   // ResourceDispatcherHost has told us to run the onunload handler, which
   // means it is not a download or unsafe page, and we are going to perform the
@@ -574,34 +547,36 @@ void RenderFrameHostManager::Observe(
   }
 }
 
-bool RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance(
+bool RenderFrameHostManager::ClearProxiesInSiteInstance(
     int32 site_instance_id,
     FrameTreeNode* node) {
-  RenderFrameHostMap::iterator iter =
-      node->render_manager()->swapped_out_hosts_.find(site_instance_id);
-  if (iter != node->render_manager()->swapped_out_hosts_.end()) {
-    RenderFrameHostImpl* swapped_out_rfh = iter->second;
+  RenderFrameProxyHostMap::iterator iter =
+      node->render_manager()->proxy_hosts_.find(site_instance_id);
+  if (iter != node->render_manager()->proxy_hosts_.end()) {
+    RenderFrameProxyHost* proxy = iter->second;
     // If the RVH is pending swap out, it needs to switch state to
     // pending shutdown. Otherwise it is deleted.
-    if (swapped_out_rfh->render_view_host()->rvh_state() ==
+    if (proxy->render_view_host()->rvh_state() ==
         RenderViewHostImpl::STATE_PENDING_SWAP_OUT) {
+      scoped_ptr<RenderFrameHostImpl> swapped_out_rfh = proxy->PassFrameHost();
+
       swapped_out_rfh->SetPendingShutdown(base::Bind(
           &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance,
           node->render_manager()->weak_factory_.GetWeakPtr(),
           site_instance_id,
-          swapped_out_rfh));
+          swapped_out_rfh.get()));
       RFHPendingDeleteMap::iterator pending_delete_iter =
           node->render_manager()->pending_delete_hosts_.find(site_instance_id);
       if (pending_delete_iter ==
               node->render_manager()->pending_delete_hosts_.end() ||
-          pending_delete_iter->second.get() != iter->second) {
+          pending_delete_iter->second.get() != swapped_out_rfh) {
         node->render_manager()->pending_delete_hosts_[site_instance_id] =
-            linked_ptr<RenderFrameHostImpl>(swapped_out_rfh);
+            linked_ptr<RenderFrameHostImpl>(swapped_out_rfh.release());
       }
     } else {
-      delete swapped_out_rfh;
+      delete proxy;
     }
-    node->render_manager()->swapped_out_hosts_.erase(site_instance_id);
+    node->render_manager()->proxy_hosts_.erase(site_instance_id);
   }
 
   return true;
@@ -622,9 +597,12 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
     const NavigationEntryImpl* new_entry) const {
   DCHECK(new_entry);
 
-  // If new_entry already has a SiteInstance, assume it is correct and use it.
-  if (new_entry->site_instance())
-    return false;
+  // If new_entry already has a SiteInstance, assume it is correct.  We only
+  // need to force a swap if it is in a different BrowsingInstance.
+  if (new_entry->site_instance()) {
+    return !new_entry->site_instance()->IsRelatedSiteInstance(
+        render_frame_host_->GetSiteInstance());
+  }
 
   // Check for reasons to swap processes even if we are in a process model that
   // doesn't usually swap (e.g., process-per-tab).  Any time we return true,
@@ -639,7 +617,7 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
   const GURL& current_url = (current_entry) ?
       SiteInstanceImpl::GetEffectiveURL(browser_context,
                                         current_entry->GetURL()) :
-      render_frame_host_->render_view_host()->GetSiteInstance()->GetSiteURL();
+      render_frame_host_->GetSiteInstance()->GetSiteURL();
   const GURL& new_url = SiteInstanceImpl::GetEffectiveURL(browser_context,
                                                           new_entry->GetURL());
 
@@ -669,7 +647,7 @@ bool RenderFrameHostManager::ShouldSwapBrowsingInstancesForNavigation(
   // Check with the content client as well.  Important to pass current_url here,
   // which uses the SiteInstance's site if there is no current_entry.
   if (GetContentClient()->browser()->ShouldSwapBrowsingInstancesForNavigation(
-          render_frame_host_->render_view_host()->GetSiteInstance(),
+          render_frame_host_->GetSiteInstance(),
           current_url, new_url)) {
     return true;
   }
@@ -707,17 +685,20 @@ SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry(
       delegate_->GetControllerForRenderManager();
   BrowserContext* browser_context = controller.GetBrowserContext();
 
+  // If the entry has an instance already we should use it.
+  if (entry.site_instance()) {
+    // If we are forcing a swap, this should be in a different BrowsingInstance.
+    if (force_browsing_instance_swap) {
+      CHECK(!entry.site_instance()->IsRelatedSiteInstance(
+                render_frame_host_->GetSiteInstance()));
+    }
+    return entry.site_instance();
+  }
+
   // If a swap is required, we need to force the SiteInstance AND
   // BrowsingInstance to be different ones, using CreateForURL.
-  if (force_browsing_instance_swap) {
-    // We shouldn't be forcing a swap if an entry already has a SiteInstance.
-    CHECK(!entry.site_instance());
+  if (force_browsing_instance_swap)
     return SiteInstance::CreateForURL(browser_context, dest_url);
-  }
-
-  // If the entry has an instance already we should use it.
-  if (entry.site_instance())
-    return entry.site_instance();
 
   // (UGLY) HEURISTIC, process-per-site only:
   //
@@ -853,7 +834,7 @@ SiteInstance* RenderFrameHostManager::GetSiteInstanceForEntry(
   return current_instance->GetRelatedSiteInstance(dest_url);
 }
 
-RenderFrameHostImpl* RenderFrameHostManager::CreateRenderFrameHost(
+scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrameHost(
     SiteInstance* site_instance,
     int view_routing_id,
     int frame_routing_id,
@@ -882,16 +863,15 @@ RenderFrameHostImpl* RenderFrameHostManager::CreateRenderFrameHost(
     }
   }
 
-  // TODO(creis): Make render_frame_host a scoped_ptr.
   // TODO(creis): Pass hidden to RFH.
-  RenderFrameHostImpl* render_frame_host =
-      RenderFrameHostFactory::Create(render_view_host,
-                                     render_frame_delegate_,
-                                     frame_tree,
-                                     frame_tree_node_,
-                                     frame_routing_id,
-                                     swapped_out).release();
-  return render_frame_host;
+  scoped_ptr<RenderFrameHostImpl> render_frame_host =
+      make_scoped_ptr(RenderFrameHostFactory::Create(render_view_host,
+                                                     render_frame_delegate_,
+                                                     frame_tree,
+                                                     frame_tree_node_,
+                                                     frame_routing_id,
+                                                     swapped_out).release());
+  return render_frame_host.Pass();
 }
 
 int RenderFrameHostManager::CreateRenderFrame(
@@ -902,24 +882,30 @@ int RenderFrameHostManager::CreateRenderFrame(
   CHECK(instance);
   DCHECK(!swapped_out || hidden); // Swapped out views should always be hidden.
 
+  scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
+  int routing_id = MSG_ROUTING_NONE;
+
   // We are creating a pending or swapped out RFH here.  We should never create
   // it in the same SiteInstance as our current RFH.
-  CHECK_NE(render_frame_host_->render_view_host()->GetSiteInstance(), instance);
+  CHECK_NE(render_frame_host_->GetSiteInstance(), instance);
 
   // Check if we've already created an RFH for this SiteInstance.  If so, try
   // to re-use the existing one, which has already been initialized.  We'll
   // remove it from the list of swapped out hosts if it commits.
-  RenderFrameHostImpl* new_render_frame_host =
-      GetSwappedOutRenderFrameHost(instance);
+  RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
 
-  FrameTreeNode* parent_node = NULL;
-  if (frame_tree_node_)
-    parent_node = frame_tree_node_->parent();
+  FrameTreeNode* parent_node = frame_tree_node_->parent();
 
-  if (new_render_frame_host) {
+  if (proxy) {
+    routing_id = proxy->render_view_host()->GetRoutingID();
+    // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
     // Prevent the process from exiting while we're trying to use it.
     if (!swapped_out) {
+      new_render_frame_host = proxy->PassFrameHost();
       new_render_frame_host->GetProcess()->AddPendingView();
+
+      proxy_hosts_.erase(instance->GetId());
+      delete proxy;
     } else {
       // Detect if this is a cross-process child frame that is navigating
       // back to the same SiteInstance as its parent.
@@ -932,35 +918,20 @@ int RenderFrameHostManager::CreateRenderFrame(
     }
   } else {
     // Create a new RenderFrameHost if we don't find an existing one.
-    // TODO(creis): Make new_render_frame_host a scoped_ptr.
-    new_render_frame_host = CreateRenderFrameHost(instance, MSG_ROUTING_NONE,
-                                                  MSG_ROUTING_NONE, swapped_out,
-                                                  hidden);
-    if (parent_node && !cross_process_frame_connector_) {
-      // The proxy RenderFrameHost to the parent process is either the current
-      // RenderFrameHost, or it has been added to the swapped out list.
-      // TODO(kenrb): This will change when RenderFrameProxyHost is created.
-      RenderFrameHostImpl* proxy_to_parent = render_frame_host_;
-      if (render_frame_host_->render_view_host()->GetSiteInstance() !=
-          parent_node->render_manager()->current_host()->GetSiteInstance()) {
-        GetSwappedOutRenderFrameHost(
-            parent_node->render_manager()->current_host()->GetSiteInstance());
-      }
-      CHECK(proxy_to_parent);
-      cross_process_frame_connector_ =
-          new CrossProcessFrameConnector(proxy_to_parent);
-    }
+    new_render_frame_host = CreateRenderFrameHost(
+        instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, swapped_out, hidden);
+    RenderViewHostImpl* render_view_host =
+        new_render_frame_host->render_view_host();
 
-    // If the new RFH is swapped out already, store it.  Otherwise prevent the
-    // process from exiting while we're trying to navigate in it.
-    if (swapped_out) {
-      swapped_out_hosts_[instance->GetId()] = new_render_frame_host;
-    } else {
+    // Prevent the process from exiting while we're trying to navigate in it.
+    // Otherwise, if the new RFH is swapped out already, store it.
+    if (!swapped_out) {
       new_render_frame_host->GetProcess()->AddPendingView();
+    } else {
+      proxy_hosts_[instance->GetId()] = new RenderFrameProxyHost(
+          new_render_frame_host.Pass());
     }
 
-    RenderViewHostImpl* render_view_host =
-        new_render_frame_host->render_view_host();
     bool success = InitRenderView(render_view_host, opener_route_id);
     if (success && frame_tree_node_->IsMainFrame()) {
       // Don't show the main frame's view until we get a DidNavigate from it.
@@ -968,13 +939,14 @@ int RenderFrameHostManager::CreateRenderFrame(
     } else if (!swapped_out && pending_render_frame_host_) {
       CancelPending();
     }
+    routing_id = render_view_host->GetRoutingID();
   }
 
   // Use this as our new pending RFH if it isn't swapped out.
   if (!swapped_out)
-    pending_render_frame_host_ = new_render_frame_host;
+    pending_render_frame_host_ = new_render_frame_host.Pass();
 
-  return new_render_frame_host->render_view_host()->GetRoutingID();
+  return routing_id;
 }
 
 bool RenderFrameHostManager::InitRenderView(RenderViewHost* render_view_host,
@@ -1051,9 +1023,9 @@ void RenderFrameHostManager::CommitPending() {
 
   // Swap in the pending frame and make it active. Also ensure the FrameTree
   // stays in sync.
-  RenderFrameHostImpl* old_render_frame_host = render_frame_host_;
-  render_frame_host_ = pending_render_frame_host_;
-  pending_render_frame_host_ = NULL;
+  scoped_ptr<RenderFrameHostImpl> old_render_frame_host =
+      render_frame_host_.Pass();
+  render_frame_host_ = pending_render_frame_host_.Pass();
   if (is_main_frame)
     render_frame_host_->render_view_host()->AttachToFrameTree();
 
@@ -1073,7 +1045,7 @@ void RenderFrameHostManager::CommitPending() {
   // If the old view is live and top-level, hide it now that the new one is
   // visible.
   int32 old_site_instance_id =
-      old_render_frame_host->render_view_host()->GetSiteInstance()->GetId();
+      old_render_frame_host->GetSiteInstance()->GetId();
   if (old_render_frame_host->render_view_host()->GetView()) {
     if (is_main_frame) {
       old_render_frame_host->render_view_host()->GetView()->Hide();
@@ -1081,7 +1053,7 @@ void RenderFrameHostManager::CommitPending() {
           &RenderFrameHostManager::ClearPendingShutdownRFHForSiteInstance,
           weak_factory_.GetWeakPtr(),
           old_site_instance_id,
-          old_render_frame_host));
+          old_render_frame_host.get()));
     } else {
       // TODO(creis): We'll need to set this back to false if we navigate back.
       old_render_frame_host->set_swapped_out(true);
@@ -1095,8 +1067,7 @@ void RenderFrameHostManager::CommitPending() {
     delegate_->SetFocusToLocationBar(false);
   } else if (focus_render_view &&
              render_frame_host_->render_view_host()->GetView()) {
-    RenderWidgetHostViewPort::FromRWHV(
-        render_frame_host_->render_view_host()->GetView())->Focus();
+    render_frame_host_->render_view_host()->GetView()->Focus();
   }
 
   // Notify that we've swapped RenderFrameHosts. We do this before shutting down
@@ -1109,73 +1080,69 @@ void RenderFrameHostManager::CommitPending() {
         render_frame_host_->render_view_host());
   }
 
-  // If the pending frame was on the swapped out list, we can remove it.
-  swapped_out_hosts_.erase(render_frame_host_->render_view_host()->
-                               GetSiteInstance()->GetId());
-
-  if (old_render_frame_host->render_view_host()->IsRenderViewLive()) {
-    // If the old RFH is live, we are swapping it out and should keep track of
-    // it in case we navigate back to it, or it is waiting for the unload event
-    // to execute in the background.
-    // TODO(creis): Swap out the subframe in --site-per-process.
-    if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess))
-      DCHECK(old_render_frame_host->is_swapped_out() ||
-             !RenderViewHostImpl::IsRVHStateActive(
-                  old_render_frame_host->render_view_host()->rvh_state()));
-    // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
-    // sure we don't get different rvh instances for the same site instance
-    // in the same rvhmgr.
-    // TODO(creis): Clean this up.
-    RenderFrameHostMap::iterator iter =
-        swapped_out_hosts_.find(old_site_instance_id);
-    if (iter != swapped_out_hosts_.end() &&
-        iter->second != old_render_frame_host) {
-      // Delete the RFH that will be replaced in the map to avoid a leak.
-      delete iter->second;
-    }
-    // If the RenderViewHost backing the RenderFrameHost is pending shutdown,
-    // the RenderFrameHost should be put in the map of RenderFrameHosts pending
-    // shutdown. Otherwise, it is stored in the map of swapped out
-    // RenderFrameHosts.
-    if (old_render_frame_host->render_view_host()->rvh_state() ==
-            RenderViewHostImpl::STATE_PENDING_SHUTDOWN) {
-      swapped_out_hosts_.erase(old_site_instance_id);
-      RFHPendingDeleteMap::iterator pending_delete_iter =
-          pending_delete_hosts_.find(old_site_instance_id);
-      if (pending_delete_iter == pending_delete_hosts_.end() ||
-          pending_delete_iter->second.get() != old_render_frame_host) {
-        pending_delete_hosts_[old_site_instance_id] =
-            linked_ptr<RenderFrameHostImpl>(old_render_frame_host);
-      }
-    } else {
-      swapped_out_hosts_[old_site_instance_id] = old_render_frame_host;
-    }
+  // If the old RFH is not live, just return as there is no work to do.
+  if (!old_render_frame_host->render_view_host()->IsRenderViewLive()) {
+    return;
+  }
 
+  // If the old RFH is live, we are swapping it out and should keep track of
+  // it in case we navigate back to it, or it is waiting for the unload event
+  // to execute in the background.
+  // TODO(creis): Swap out the subframe in --site-per-process.
+  if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess))
+    DCHECK(old_render_frame_host->is_swapped_out() ||
+           !RenderViewHostImpl::IsRVHStateActive(
+               old_render_frame_host->render_view_host()->rvh_state()));
+  // Temp fix for http://crbug.com/90867 until we do a better cleanup to make
+  // sure we don't get different rvh instances for the same site instance
+  // in the same rvhmgr.
+  // TODO(creis): Clean this up.
+  RenderFrameProxyHostMap::iterator iter =
+      proxy_hosts_.find(old_site_instance_id);
+  if (iter != proxy_hosts_.end() &&
+      iter->second->render_frame_host() != old_render_frame_host) {
+    // Delete the proxy that will be replaced in the map to avoid a leak.
+    delete iter->second;
+  }
+
+  // If the RenderViewHost backing the RenderFrameHost is pending shutdown,
+  // the RenderFrameHost should be put in the map of RenderFrameHosts pending
+  // shutdown. Otherwise, it is stored in the map of proxy hosts.
+  if (old_render_frame_host->render_view_host()->rvh_state() ==
+          RenderViewHostImpl::STATE_PENDING_SHUTDOWN) {
+    proxy_hosts_.erase(old_site_instance_id);
+    RFHPendingDeleteMap::iterator pending_delete_iter =
+        pending_delete_hosts_.find(old_site_instance_id);
+    if (pending_delete_iter == pending_delete_hosts_.end() ||
+        pending_delete_iter->second.get() != old_render_frame_host) {
+      pending_delete_hosts_[old_site_instance_id] =
+          linked_ptr<RenderFrameHostImpl>(old_render_frame_host.release());
+    }
+  } else {
     // If there are no active views in this SiteInstance, it means that
     // this RFH was the last active one in the SiteInstance. Now that we
     // know that all RFHs are swapped out, we can delete all the RFHs and RVHs
     // in this SiteInstance.  We do this after ensuring the RFH is on the
     // swapped out list to simplify the deletion.
     if (!static_cast<SiteInstanceImpl*>(
-            old_render_frame_host->render_view_host()->GetSiteInstance())->
-                active_view_count()) {
+            old_render_frame_host->GetSiteInstance())->active_view_count()) {
+      old_render_frame_host.reset();
       ShutdownRenderFrameHostsInSiteInstance(old_site_instance_id);
-      // This is deleted while cleaning up the SiteInstance's views.
-      old_render_frame_host = NULL;
+    } else {
+      proxy_hosts_[old_site_instance_id] = new RenderFrameProxyHost(
+          old_render_frame_host.Pass());
     }
-  } else {
-    delete old_render_frame_host;
   }
 }
 
 void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance(
     int32 site_instance_id) {
   // First remove any swapped out RFH for this SiteInstance from our own list.
-  ClearSwappedOutRFHsInSiteInstance(site_instance_id, frame_tree_node_);
+  ClearProxiesInSiteInstance(site_instance_id, frame_tree_node_);
 
   // Use the safe RenderWidgetHost iterator for now to find all RenderViewHosts
   // in the SiteInstance, then tell their respective FrameTrees to remove all
-  // swapped out RenderFrameHosts corresponding to them.
+  // RenderFrameProxyHosts corresponding to them.
   // TODO(creis): Replace this with a RenderFrameHostIterator that protects
   // against use-after-frees if a later element is deleted before getting to it.
   scoped_ptr<RenderWidgetHostIterator> widgets(
@@ -1190,13 +1157,13 @@ void RenderFrameHostManager::ShutdownRenderFrameHostsInSiteInstance(
       // |rvh| to Shutdown.
       FrameTree* tree = rvh->GetDelegate()->GetFrameTree();
       tree->ForEach(base::Bind(
-          &RenderFrameHostManager::ClearSwappedOutRFHsInSiteInstance,
+          &RenderFrameHostManager::ClearProxiesInSiteInstance,
           site_instance_id));
     }
   }
 }
 
-RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
+RenderFrameHostImpl* RenderFrameHostManager::UpdateStateForNavigate(
     const NavigationEntryImpl& entry) {
   // If we are currently navigating cross-process, we want to get back to normal
   // and then navigate as usual.
@@ -1209,8 +1176,7 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
   // render_frame_host_'s SiteInstance and new_instance will not be deleted
   // before the end of this method, so we don't have to worry about their ref
   // counts dropping to zero.
-  SiteInstance* current_instance =
-      render_frame_host_->render_view_host()->GetSiteInstance();
+  SiteInstance* current_instance = render_frame_host_->GetSiteInstance();
   SiteInstance* new_instance = current_instance;
 
   // We do not currently swap processes for navigations in webview tag guests.
@@ -1271,10 +1237,10 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
         // cross-navigating (Note that we don't care about on{before}unload
         // handlers if the current RFH isn't live.)
         CommitPending();
-        return render_frame_host_;
+        return render_frame_host_.get();
       } else {
         NOTREACHED();
-        return render_frame_host_;
+        return render_frame_host_.get();
       }
     }
     // Otherwise, it's safe to treat this as a pending cross-site transition.
@@ -1319,11 +1285,11 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
     // Unless we are transferring an existing request, we should now
     // tell the old render view to run its beforeunload handler, since it
     // doesn't otherwise know that the cross-site request is happening.  This
-    // will trigger a call to ShouldClosePage with the reply.
+    // will trigger a call to OnBeforeUnloadACK with the reply.
     if (!is_transfer)
-      render_frame_host_->render_view_host()->FirePageBeforeUnload(true);
+      render_frame_host_->DispatchBeforeUnload(true);
 
-    return pending_render_frame_host_;
+    return pending_render_frame_host_.get();
   }
 
   // Otherwise the same SiteInstance can be used.  Navigate render_frame_host_.
@@ -1355,12 +1321,12 @@ RenderFrameHostImpl* RenderFrameHostManager::UpdateRendererStateForNavigate(
             render_frame_host_->render_view_host()->GetRoutingID()));
   }
 
-  return render_frame_host_;
+  return render_frame_host_.get();
 }
 
 void RenderFrameHostManager::CancelPending() {
-  RenderFrameHostImpl* pending_render_frame_host = pending_render_frame_host_;
-  pending_render_frame_host_ = NULL;
+  scoped_ptr<RenderFrameHostImpl> pending_render_frame_host =
+      pending_render_frame_host_.Pass();
 
   RenderViewDevToolsAgentHost::OnCancelPendingNavigation(
       pending_render_frame_host->render_view_host(),
@@ -1369,91 +1335,62 @@ void RenderFrameHostManager::CancelPending() {
   // We no longer need to prevent the process from exiting.
   pending_render_frame_host->GetProcess()->RemovePendingView();
 
-  // The pending RFH may already be on the swapped out list if we started to
-  // swap it back in and then canceled.  If so, make sure it gets swapped out
-  // again.  If it's not on the swapped out list (e.g., aborting a pending
-  // load), then it's safe to shut down.
-  if (IsOnSwappedOutList(pending_render_frame_host)) {
+  // If the SiteInstance for the pending RFH is being used by others, don't
+  // delete the RFH, just swap it out and it can be reused at a later point.
+  SiteInstanceImpl* site_instance = static_cast<SiteInstanceImpl*>(
+      pending_render_frame_host->GetSiteInstance());
+  if (site_instance->active_view_count() > 1) {
     // Any currently suspended navigations are no longer needed.
     pending_render_frame_host->render_view_host()->CancelSuspendedNavigations();
 
-    // TODO(creis): We need to swap out the RFH.
-    pending_render_frame_host->render_view_host()->SwapOut();
+    pending_render_frame_host->SwapOut();
+
+    proxy_hosts_[site_instance->GetId()] = new RenderFrameProxyHost(
+        pending_render_frame_host.Pass());
   } else {
-    // We won't be coming back, so shut this one down.
-    delete pending_render_frame_host;
+    // We won't be coming back, so delete this one.
+    pending_render_frame_host.reset();
   }
 
   pending_web_ui_.reset();
   pending_and_current_web_ui_.reset();
 }
 
-void RenderFrameHostManager::RenderViewDeleted(RenderViewHost* rvh) {
-  // We are doing this in order to work around and to track a crasher
-  // (http://crbug.com/23411) where it seems that pending_render_frame_host_ is
-  // deleted (not sure from where) but not NULLed.
-  if (pending_render_frame_host_ &&
-      rvh == pending_render_frame_host_->render_view_host()) {
-    // If you hit this NOTREACHED, please report it in the following bug
-    // http://crbug.com/23411 Make sure to include what you were doing when it
-    // happened  (navigating to a new page, closing a tab...) and if you can
-    // reproduce.
-    NOTREACHED();
-    pending_render_frame_host_ = NULL;
-  }
-
-  // Make sure deleted RVHs are not kept in the swapped out list while we are
-  // still alive.  (If render_frame_host_ is null, we're already being deleted.)
-  if (!render_frame_host_)
-    return;
-
-  // We can't look it up by SiteInstance ID, which may no longer be valid.
-  for (RenderFrameHostMap::iterator iter = swapped_out_hosts_.begin();
-       iter != swapped_out_hosts_.end();
-       ++iter) {
-    if (iter->second->render_view_host() == rvh) {
-      swapped_out_hosts_.erase(iter);
-      break;
-    }
-  }
-}
-
 bool RenderFrameHostManager::IsRVHOnSwappedOutList(
     RenderViewHostImpl* rvh) const {
-  RenderFrameHostImpl* render_frame_host = GetSwappedOutRenderFrameHost(
+  RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(
       rvh->GetSiteInstance());
-  if (!render_frame_host)
+  if (!proxy)
     return false;
-  return IsOnSwappedOutList(render_frame_host);
+  return IsOnSwappedOutList(proxy->render_frame_host());
 }
 
 bool RenderFrameHostManager::IsOnSwappedOutList(
     RenderFrameHostImpl* rfh) const {
-  if (!rfh->render_view_host()->GetSiteInstance())
+  if (!rfh->GetSiteInstance())
     return false;
 
-  RenderFrameHostMap::const_iterator iter = swapped_out_hosts_.find(
-      rfh->render_view_host()->GetSiteInstance()->GetId());
-  if (iter == swapped_out_hosts_.end())
+  RenderFrameProxyHostMap::const_iterator iter = proxy_hosts_.find(
+      rfh->GetSiteInstance()->GetId());
+  if (iter == proxy_hosts_.end())
     return false;
 
-  return iter->second == rfh;
+  return iter->second->render_frame_host() == rfh;
 }
 
 RenderViewHostImpl* RenderFrameHostManager::GetSwappedOutRenderViewHost(
    SiteInstance* instance) const {
-  RenderFrameHostImpl* render_frame_host =
-      GetSwappedOutRenderFrameHost(instance);
-  if (render_frame_host)
-    return render_frame_host->render_view_host();
+  RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
+  if (proxy)
+    return proxy->render_view_host();
   return NULL;
 }
 
-RenderFrameHostImpl* RenderFrameHostManager::GetSwappedOutRenderFrameHost(
+RenderFrameProxyHost* RenderFrameHostManager::GetRenderFrameProxyHost(
     SiteInstance* instance) const {
-  RenderFrameHostMap::const_iterator iter =
-      swapped_out_hosts_.find(instance->GetId());
-  if (iter != swapped_out_hosts_.end())
+  RenderFrameProxyHostMap::const_iterator iter =
+      proxy_hosts_.find(instance->GetId());
+  if (iter != proxy_hosts_.end())
     return iter->second;
 
   return NULL;