| Index: content/browser/frame_host/render_frame_host_manager.cc
 | 
| diff --git a/content/browser/frame_host/render_frame_host_manager.cc b/content/browser/frame_host/render_frame_host_manager.cc
 | 
| index 7c0cf4031c210c79e7951c7a85c7ac178895af47..952b0b0fd17d83e732369f61780de207194629c2 100644
 | 
| --- a/content/browser/frame_host/render_frame_host_manager.cc
 | 
| +++ b/content/browser/frame_host/render_frame_host_manager.cc
 | 
| @@ -204,7 +204,8 @@ RenderFrameHostImpl* RenderFrameHostManager::Navigate(
 | 
|      // soon anyway, and we don't have the NavigationEntry for this host.
 | 
|      delegate_->CreateRenderViewForRenderManager(
 | 
|          render_frame_host_->render_view_host(), MSG_ROUTING_NONE,
 | 
| -        MSG_ROUTING_NONE, frame_tree_node_->IsMainFrame());
 | 
| +        MSG_ROUTING_NONE, frame_tree_node_->current_replication_state(),
 | 
| +        frame_tree_node_->IsMainFrame());
 | 
|    }
 | 
|  
 | 
|    // If the renderer crashed, then try to create a new one to satisfy this
 | 
| @@ -609,18 +610,16 @@ void RenderFrameHostManager::SwapOutOldFrame(
 | 
|    // SwapOut creates a RenderFrameProxy, so set the proxy to be initialized.
 | 
|    proxy->set_render_frame_proxy_created(true);
 | 
|  
 | 
| -  bool is_main_frame = frame_tree_node_->IsMainFrame();
 | 
|    if (base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
| -          switches::kSitePerProcess) &&
 | 
| -      !is_main_frame) {
 | 
| -    // In --site-per-process, subframes delete their RFH rather than storing it
 | 
| +          switches::kSitePerProcess)) {
 | 
| +    // In --site-per-process, frames delete their RFH rather than storing it
 | 
|      // in the proxy.  Schedule it for deletion once the SwapOutACK comes in.
 | 
|      // TODO(creis): This will be the default when we remove swappedout://.
 | 
|      MoveToPendingDeleteHosts(old_render_frame_host.Pass());
 | 
|    } else {
 | 
|      // We shouldn't get here for subframes, since we only swap subframes when
 | 
|      // --site-per-process is used.
 | 
| -    DCHECK(is_main_frame);
 | 
| +    DCHECK(frame_tree_node_->IsMainFrame());
 | 
|  
 | 
|      // The old RenderFrameHost will stay alive inside the proxy so that existing
 | 
|      // JavaScript window references to it stay valid.
 | 
| @@ -635,6 +634,8 @@ void RenderFrameHostManager::DiscardUnusedFrame(
 | 
|  
 | 
|    // 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.
 | 
| +  // In --site-per-process, RenderFrameHosts are not kept around and are
 | 
| +  // deleted when not used, replaced by RenderFrameProxyHosts.
 | 
|    SiteInstanceImpl* site_instance = render_frame_host->GetSiteInstance();
 | 
|    if (site_instance->HasSite() && site_instance->active_frame_count() > 1) {
 | 
|      // Any currently suspended navigations are no longer needed.
 | 
| @@ -650,9 +651,14 @@ void RenderFrameHostManager::DiscardUnusedFrame(
 | 
|      if (!render_frame_host->is_swapped_out())
 | 
|        render_frame_host->SwapOut(proxy, false);
 | 
|  
 | 
| -    if (frame_tree_node_->IsMainFrame())
 | 
| +    if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
| +          switches::kSitePerProcess)) {
 | 
| +      DCHECK(frame_tree_node_->IsMainFrame());
 | 
|        proxy->TakeFrameHostOwnership(render_frame_host.Pass());
 | 
| -  } else {
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
| +  if (render_frame_host) {
 | 
|      // We won't be coming back, so delete this one.
 | 
|      ShutdownProxiesIfLastActiveFrameInSiteInstance(render_frame_host.get());
 | 
|      render_frame_host.reset();
 | 
| @@ -920,7 +926,9 @@ bool RenderFrameHostManager::ClearProxiesInSiteInstance(
 | 
|      if (node->IsMainFrame() &&
 | 
|          proxy->render_frame_host() &&
 | 
|          proxy->render_frame_host()->rfh_state() ==
 | 
| -        RenderFrameHostImpl::STATE_PENDING_SWAP_OUT) {
 | 
| +            RenderFrameHostImpl::STATE_PENDING_SWAP_OUT) {
 | 
| +      DCHECK(!base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
| +          switches::kSitePerProcess));
 | 
|        scoped_ptr<RenderFrameHostImpl> swapped_out_rfh =
 | 
|            proxy->PassFrameHostOwnership();
 | 
|        node->render_manager()->MoveToPendingDeleteHosts(swapped_out_rfh.Pass());
 | 
| @@ -1458,14 +1466,15 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
 | 
|      int flags,
 | 
|      int* view_routing_id_ptr) {
 | 
|    bool swapped_out = !!(flags & CREATE_RF_SWAPPED_OUT);
 | 
| +  bool is_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
| +      switches::kSitePerProcess);
 | 
| +
 | 
|    CHECK(instance);
 | 
| -  // Swapped out views should always be hidden.
 | 
| -  DCHECK(!swapped_out || (flags & CREATE_RF_HIDDEN));
 | 
| +  CHECK_IMPLIES(is_site_per_process, !swapped_out);
 | 
| +  CHECK_IMPLIES(!is_site_per_process, frame_tree_node_->IsMainFrame());
 | 
|  
 | 
| -  // TODO(nasko): Remove the following CHECK once cross-process navigation no
 | 
| -  // longer relies on swapped out RFH for the top-level frame.
 | 
| -  if (!frame_tree_node_->IsMainFrame())
 | 
| -    CHECK(!swapped_out);
 | 
| +  // Swapped out views should always be hidden.
 | 
| +  DCHECK_IMPLIES(swapped_out, (flags & CREATE_RF_HIDDEN));
 | 
|  
 | 
|    scoped_ptr<RenderFrameHostImpl> new_render_frame_host;
 | 
|    bool success = true;
 | 
| @@ -1481,6 +1490,7 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
 | 
|    // remove it from the list of proxy hosts below if it will be active.
 | 
|    RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
 | 
|    if (proxy && proxy->render_frame_host()) {
 | 
| +    CHECK(!is_site_per_process);
 | 
|      if (view_routing_id_ptr)
 | 
|        *view_routing_id_ptr = proxy->GetRenderViewHost()->GetRoutingID();
 | 
|      // Delete the existing RenderFrameProxyHost, but reuse the RenderFrameHost.
 | 
| @@ -1527,7 +1537,13 @@ scoped_ptr<RenderFrameHostImpl> RenderFrameHostManager::CreateRenderFrame(
 | 
|          // will be created later and hidden.
 | 
|          if (render_view_host->GetView())
 | 
|            render_view_host->GetView()->Hide();
 | 
| -      } else if (!swapped_out) {
 | 
| +      }
 | 
| +      // With --site-per-process, RenderViewHost for |instance| might exist
 | 
| +      // prior to calling CreateRenderFrame, due to a subframe in
 | 
| +      // |instance|. In such a case, InitRenderView will not create the
 | 
| +      // RenderFrame in the renderer process and it needs to be done
 | 
| +      // explicitly.
 | 
| +      if (is_site_per_process) {
 | 
|          // Init the RFH, so a RenderFrame is created in the renderer.
 | 
|          DCHECK(new_render_frame_host);
 | 
|          success = InitRenderFrame(new_render_frame_host.get());
 | 
| @@ -1569,17 +1585,40 @@ int RenderFrameHostManager::CreateRenderFrameProxy(SiteInstance* instance) {
 | 
|    CHECK(instance);
 | 
|    CHECK_NE(instance, render_frame_host_->GetSiteInstance());
 | 
|  
 | 
| +  bool is_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
| +      switches::kSitePerProcess);
 | 
| +  RenderViewHostImpl* render_view_host = nullptr;
 | 
| +
 | 
| +  // Ensure a RenderViewHost exists for |instance|, as it creates the page
 | 
| +  // level structure in Blink.
 | 
| +  if (is_site_per_process) {
 | 
| +    render_view_host =
 | 
| +        frame_tree_node_->frame_tree()->GetRenderViewHost(instance);
 | 
| +    if (!render_view_host) {
 | 
| +      CHECK(frame_tree_node_->IsMainFrame());
 | 
| +      render_view_host = frame_tree_node_->frame_tree()->CreateRenderViewHost(
 | 
| +          instance, MSG_ROUTING_NONE, MSG_ROUTING_NONE, true, true);
 | 
| +    }
 | 
| +  }
 | 
| +
 | 
|    RenderFrameProxyHost* proxy = GetRenderFrameProxyHost(instance);
 | 
|    if (proxy && proxy->is_render_frame_proxy_live())
 | 
|      return proxy->GetRoutingID();
 | 
|  
 | 
|    if (!proxy) {
 | 
|      proxy = new RenderFrameProxyHost(
 | 
| -        instance, frame_tree_node_->frame_tree()->GetRenderViewHost(instance),
 | 
| -        frame_tree_node_);
 | 
| +        instance, render_view_host, frame_tree_node_);
 | 
|      proxy_hosts_[instance->GetId()] = proxy;
 | 
|    }
 | 
| -  proxy->InitRenderFrameProxy();
 | 
| +
 | 
| +  if (is_site_per_process && frame_tree_node_->IsMainFrame()) {
 | 
| +    InitRenderView(
 | 
| +        render_view_host, MSG_ROUTING_NONE, proxy->GetRoutingID(), true);
 | 
| +    proxy->set_render_frame_proxy_created(true);
 | 
| +  } else {
 | 
| +    proxy->InitRenderFrameProxy();
 | 
| +  }
 | 
| +
 | 
|    return proxy->GetRoutingID();
 | 
|  }
 | 
|  
 | 
| @@ -1613,15 +1652,15 @@ bool RenderFrameHostManager::InitRenderView(
 | 
|      int opener_route_id,
 | 
|      int proxy_routing_id,
 | 
|      bool for_main_frame_navigation) {
 | 
| -  // We may have initialized this RenderViewHost for another RenderFrameHost.
 | 
| -  if (render_view_host->IsRenderViewLive())
 | 
| -    return true;
 | 
| -
 | 
|    // Ensure the renderer process is initialized before creating the
 | 
|    // RenderView.
 | 
|    if (!render_view_host->GetProcess()->Init())
 | 
|      return false;
 | 
|  
 | 
| +  // We may have initialized this RenderViewHost for another RenderFrameHost.
 | 
| +  if (render_view_host->IsRenderViewLive())
 | 
| +    return true;
 | 
| +
 | 
|    // If the ongoing navigation is to a WebUI and the RenderView is not in a
 | 
|    // guest process, tell the RenderViewHost about any bindings it will need
 | 
|    // enabled.
 | 
| @@ -1644,10 +1683,12 @@ bool RenderFrameHostManager::InitRenderView(
 | 
|      }
 | 
|    }
 | 
|  
 | 
| -  return delegate_->CreateRenderViewForRenderManager(render_view_host,
 | 
| -                                                     opener_route_id,
 | 
| -                                                     proxy_routing_id,
 | 
| -                                                     for_main_frame_navigation);
 | 
| +  return delegate_->CreateRenderViewForRenderManager(
 | 
| +      render_view_host,
 | 
| +      opener_route_id,
 | 
| +      proxy_routing_id,
 | 
| +      frame_tree_node_->current_replication_state(),
 | 
| +      for_main_frame_navigation);
 | 
|  }
 | 
|  
 | 
|  bool RenderFrameHostManager::InitRenderFrame(
 | 
| @@ -1717,6 +1758,9 @@ void RenderFrameHostManager::CommitPending() {
 | 
|    bool browser_side_navigation =
 | 
|        base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
|            switches::kEnableBrowserSideNavigation);
 | 
| +  bool is_site_per_process = base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
| +      switches::kSitePerProcess);
 | 
| +
 | 
|    // First check whether we're going to want to focus the location bar after
 | 
|    // this commit.  We do this now because the navigation hasn't formally
 | 
|    // committed yet, so if we've already cleared |pending_web_ui_| the call chain
 | 
| @@ -1818,6 +1862,17 @@ void RenderFrameHostManager::CommitPending() {
 | 
|    delegate_->NotifySwappedFromRenderManager(
 | 
|        old_render_frame_host.get(), render_frame_host_.get(), is_main_frame);
 | 
|  
 | 
| +  // The RenderViewHost keeps track of the main RenderFrameHost routing id.
 | 
| +  // If this is committing a main frame navigation, update it and set the
 | 
| +  // routing id in the RenderViewHost associated with the old RenderFrameHost
 | 
| +  // to MSG_ROUTING_NONE.
 | 
| +  if (is_main_frame && is_site_per_process) {
 | 
| +    render_frame_host_->render_view_host()->set_main_frame_routing_id(
 | 
| +        render_frame_host_->routing_id());
 | 
| +    old_render_frame_host->render_view_host()->set_main_frame_routing_id(
 | 
| +        MSG_ROUTING_NONE);
 | 
| +  }
 | 
| +
 | 
|    // Swap out the old frame now that the new one is visible.
 | 
|    // This will swap it out and then put it on the proxy list (if there are other
 | 
|    // active views in its SiteInstance) or schedule it for deletion when the swap
 | 
| @@ -1826,9 +1881,7 @@ void RenderFrameHostManager::CommitPending() {
 | 
|    // the proxy.
 | 
|    SwapOutOldFrame(old_render_frame_host.Pass());
 | 
|  
 | 
| -  if (base::CommandLine::ForCurrentProcess()->HasSwitch(
 | 
| -          switches::kSitePerProcess) &&
 | 
| -      !is_main_frame) {
 | 
| +  if (is_site_per_process) {
 | 
|      // Since the new RenderFrameHost is now committed, there must be no proxies
 | 
|      // for its SiteInstance. Delete any existing ones.
 | 
|      RenderFrameProxyHostMap::iterator iter =
 | 
| 
 |