 Chromium Code Reviews
 Chromium Code Reviews Issue 1142123002:
  Remove swapped-out usage in --site-per-process.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master
    
  
    Issue 1142123002:
  Remove swapped-out usage in --site-per-process.  (Closed) 
  Base URL: https://chromium.googlesource.com/chromium/src.git@master| OLD | NEW | 
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be | 
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. | 
| 4 | 4 | 
| 5 #include "content/renderer/render_frame_impl.h" | 5 #include "content/renderer/render_frame_impl.h" | 
| 6 | 6 | 
| 7 #include <map> | 7 #include <map> | 
| 8 #include <string> | 8 #include <string> | 
| 9 | 9 | 
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" | 
| (...skipping 519 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 530 | 530 | 
| 531 // static | 531 // static | 
| 532 void RenderFrameImpl::CreateFrame( | 532 void RenderFrameImpl::CreateFrame( | 
| 533 int routing_id, | 533 int routing_id, | 
| 534 int parent_routing_id, | 534 int parent_routing_id, | 
| 535 int previous_sibling_routing_id, | 535 int previous_sibling_routing_id, | 
| 536 int proxy_routing_id, | 536 int proxy_routing_id, | 
| 537 const FrameReplicationState& replicated_state, | 537 const FrameReplicationState& replicated_state, | 
| 538 CompositorDependencies* compositor_deps, | 538 CompositorDependencies* compositor_deps, | 
| 539 const FrameMsg_NewFrame_WidgetParams& widget_params) { | 539 const FrameMsg_NewFrame_WidgetParams& widget_params) { | 
| 540 // TODO(nasko): For now, this message is only sent for subframes, as the | |
| 541 // top level frame is created when the RenderView is created through the | |
| 542 // ViewMsg_New IPC. | |
| 543 CHECK_NE(MSG_ROUTING_NONE, parent_routing_id); | |
| 544 | |
| 545 blink::WebLocalFrame* web_frame; | 540 blink::WebLocalFrame* web_frame; | 
| 546 RenderFrameImpl* render_frame; | 541 RenderFrameImpl* render_frame; | 
| 547 if (proxy_routing_id == MSG_ROUTING_NONE) { | 542 if (proxy_routing_id == MSG_ROUTING_NONE) { | 
| 548 RenderFrameProxy* parent_proxy = | 543 RenderFrameProxy* parent_proxy = | 
| 549 RenderFrameProxy::FromRoutingID(parent_routing_id); | 544 RenderFrameProxy::FromRoutingID(parent_routing_id); | 
| 550 // If the browser is sending a valid parent routing id, it should already | 545 // If the browser is sending a valid parent routing id, it should already | 
| 551 // be created and registered. | 546 // be created and registered. | 
| 552 CHECK(parent_proxy); | 547 CHECK(parent_proxy); | 
| 553 blink::WebRemoteFrame* parent_web_frame = parent_proxy->web_frame(); | 548 blink::WebRemoteFrame* parent_web_frame = parent_proxy->web_frame(); | 
| 554 | 549 | 
| (...skipping 16 matching lines...) Expand all Loading... | |
| 571 CHECK(proxy); | 566 CHECK(proxy); | 
| 572 render_frame = RenderFrameImpl::Create(proxy->render_view(), routing_id); | 567 render_frame = RenderFrameImpl::Create(proxy->render_view(), routing_id); | 
| 573 web_frame = | 568 web_frame = | 
| 574 blink::WebLocalFrame::create(replicated_state.scope, render_frame); | 569 blink::WebLocalFrame::create(replicated_state.scope, render_frame); | 
| 575 render_frame->proxy_routing_id_ = proxy_routing_id; | 570 render_frame->proxy_routing_id_ = proxy_routing_id; | 
| 576 web_frame->initializeToReplaceRemoteFrame( | 571 web_frame->initializeToReplaceRemoteFrame( | 
| 577 proxy->web_frame(), WebString::fromUTF8(replicated_state.name), | 572 proxy->web_frame(), WebString::fromUTF8(replicated_state.name), | 
| 578 replicated_state.sandbox_flags); | 573 replicated_state.sandbox_flags); | 
| 579 } | 574 } | 
| 580 render_frame->SetWebFrame(web_frame); | 575 render_frame->SetWebFrame(web_frame); | 
| 576 CHECK_IMPLIES(parent_routing_id == MSG_ROUTING_NONE, !web_frame->parent()); | |
| 581 | 577 | 
| 582 if (widget_params.routing_id != MSG_ROUTING_NONE) { | 578 if (widget_params.routing_id != MSG_ROUTING_NONE) { | 
| 583 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 579 CHECK(base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| 584 switches::kSitePerProcess)); | 580 switches::kSitePerProcess)); | 
| 585 render_frame->render_widget_ = RenderWidget::CreateForFrame( | 581 render_frame->render_widget_ = RenderWidget::CreateForFrame( | 
| 586 widget_params.routing_id, widget_params.surface_id, | 582 widget_params.routing_id, widget_params.surface_id, | 
| 587 widget_params.hidden, render_frame->render_view_->screen_info(), | 583 widget_params.hidden, render_frame->render_view_->screen_info(), | 
| 588 compositor_deps, web_frame); | 584 compositor_deps, web_frame); | 
| 589 // TODO(kenrb): Observing shouldn't be necessary when we sort out | 585 // TODO(kenrb): Observing shouldn't be necessary when we sort out | 
| 590 // WasShown and WasHidden, separating page-level visibility from | 586 // WasShown and WasHidden, separating page-level visibility from | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 689 if (!is_subframe_) { | 685 if (!is_subframe_) { | 
| 690 // RenderFrameProxy is "owned" by RenderFrameImpl in the case it is | 686 // RenderFrameProxy is "owned" by RenderFrameImpl in the case it is | 
| 691 // the main frame. Ensure it is deleted along with this object. | 687 // the main frame. Ensure it is deleted along with this object. | 
| 692 if (render_frame_proxy_) { | 688 if (render_frame_proxy_) { | 
| 693 // The following method calls back into this object and clears | 689 // The following method calls back into this object and clears | 
| 694 // |render_frame_proxy_|. | 690 // |render_frame_proxy_|. | 
| 695 render_frame_proxy_->frameDetached(); | 691 render_frame_proxy_->frameDetached(); | 
| 696 } | 692 } | 
| 697 | 693 | 
| 698 // Ensure the RenderView doesn't point to this object, once it is destroyed. | 694 // Ensure the RenderView doesn't point to this object, once it is destroyed. | 
| 699 CHECK_EQ(render_view_->main_render_frame_, this); | 695 // TODO(nasko): Restore this check once we don't leak this object on | 
| 696 // frame swap. | |
| 697 //CHECK_EQ(render_view_->main_render_frame_, this); | |
| 
Charlie Reis
2015/06/04 00:02:11
What's the plan here?  Will Lucas's CL fix it?
 
nasko
2015/06/04 14:57:13
Enable the check once Lucas's CLs land. Yes, that
 | |
| 700 render_view_->main_render_frame_ = nullptr; | 698 render_view_->main_render_frame_ = nullptr; | 
| 701 } | 699 } | 
| 702 | 700 | 
| 703 render_view_->UnregisterRenderFrame(this); | 701 render_view_->UnregisterRenderFrame(this); | 
| 704 g_routing_id_frame_map.Get().erase(routing_id_); | 702 g_routing_id_frame_map.Get().erase(routing_id_); | 
| 705 RenderThread::Get()->RemoveRoute(routing_id_); | 703 RenderThread::Get()->RemoveRoute(routing_id_); | 
| 706 } | 704 } | 
| 707 | 705 | 
| 708 void RenderFrameImpl::SetWebFrame(blink::WebLocalFrame* web_frame) { | 706 void RenderFrameImpl::SetWebFrame(blink::WebLocalFrame* web_frame) { | 
| 709 DCHECK(!frame_); | 707 DCHECK(!frame_); | 
| (...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1141 // willCheckAndDispatchMessageEvent() that needs the proxy. | 1139 // willCheckAndDispatchMessageEvent() that needs the proxy. | 
| 1142 if (proxy) | 1140 if (proxy) | 
| 1143 set_render_frame_proxy(proxy); | 1141 set_render_frame_proxy(proxy); | 
| 1144 | 1142 | 
| 1145 // Now that we're swapped out and filtering IPC messages, stop loading to | 1143 // Now that we're swapped out and filtering IPC messages, stop loading to | 
| 1146 // ensure that no other in-progress navigation continues. We do this here | 1144 // ensure that no other in-progress navigation continues. We do this here | 
| 1147 // to avoid sending a DidStopLoading message to the browser process. | 1145 // to avoid sending a DidStopLoading message to the browser process. | 
| 1148 // TODO(creis): Should we be stopping all frames here and using | 1146 // TODO(creis): Should we be stopping all frames here and using | 
| 1149 // StopAltErrorPageFetcher with RenderView::OnStop, or just stopping this | 1147 // StopAltErrorPageFetcher with RenderView::OnStop, or just stopping this | 
| 1150 // frame? | 1148 // frame? | 
| 1151 OnStop(); | 1149 if (!is_site_per_process) | 
| 
Charlie Reis
2015/06/04 00:02:11
Are we planning to remove this OnStop entirely?  (
 
nasko
2015/06/04 14:57:13
I don't know for certain, but Daniel felt that it
 | |
| 1150 OnStop(); | |
| 1152 | 1151 | 
| 1153 // Transfer settings such as initial drawing parameters to the remote frame, | 1152 // Transfer settings such as initial drawing parameters to the remote frame, | 
| 1154 // if one is created, that will replace this frame. | 1153 // if one is created, that will replace this frame. | 
| 1155 if (!is_main_frame && proxy) | 1154 if (!is_main_frame && proxy) | 
| 1156 proxy->web_frame()->initializeFromFrame(frame_); | 1155 proxy->web_frame()->initializeFromFrame(frame_); | 
| 1157 | 1156 | 
| 1158 // Replace the page with a blank dummy URL. The unload handler will not be | 1157 // Replace the page with a blank dummy URL. The unload handler will not be | 
| 1159 // run a second time, thanks to a check in FrameLoader::stopLoading. | 1158 // run a second time, thanks to a check in FrameLoader::stopLoading. | 
| 1160 // TODO(creis): Need to add a better way to do this that avoids running the | 1159 // TODO(creis): Need to add a better way to do this that avoids running the | 
| 1161 // beforeunload handler. For now, we just run it a second time silently. | 1160 // beforeunload handler. For now, we just run it a second time silently. | 
| 1162 if (!is_site_per_process || is_main_frame) | 1161 if (!is_site_per_process) | 
| 1163 NavigateToSwappedOutURL(); | 1162 NavigateToSwappedOutURL(); | 
| 1164 | 1163 | 
| 1165 // Let WebKit know that this view is hidden so it can drop resources and | 1164 // Let WebKit know that this view is hidden so it can drop resources and | 
| 1166 // stop compositing. | 1165 // stop compositing. | 
| 1167 // TODO(creis): Support this for subframes as well. | 1166 // TODO(creis): Support this for subframes as well. | 
| 1168 if (is_main_frame) { | 1167 if (is_main_frame) { | 
| 1169 render_view_->webview()->setVisibilityState( | 1168 render_view_->webview()->setVisibilityState( | 
| 1170 blink::WebPageVisibilityStateHidden, false); | 1169 blink::WebPageVisibilityStateHidden, false); | 
| 1171 } | 1170 } | 
| 1172 } | 1171 } | 
| 1173 | 1172 | 
| 1174 // It is now safe to show modal dialogs again. | 1173 // It is now safe to show modal dialogs again. | 
| 1175 // TODO(creis): Deal with modal dialogs from subframes. | 1174 // TODO(creis): Deal with modal dialogs from subframes. | 
| 1176 if (is_main_frame) | 1175 if (is_main_frame) | 
| 1177 render_view_->suppress_dialogs_until_swap_out_ = false; | 1176 render_view_->suppress_dialogs_until_swap_out_ = false; | 
| 1178 | 1177 | 
| 1179 Send(new FrameHostMsg_SwapOut_ACK(routing_id_)); | 1178 Send(new FrameHostMsg_SwapOut_ACK(routing_id_)); | 
| 1180 | 1179 | 
| 1180 RenderViewImpl* render_view = render_view_.get(); | |
| 1181 | |
| 1181 // Now that all of the cleanup is complete and the browser side is notified, | 1182 // Now that all of the cleanup is complete and the browser side is notified, | 
| 1182 // start using the RenderFrameProxy, if one is created. | 1183 // start using the RenderFrameProxy, if one is created. | 
| 1183 if (proxy) { | 1184 if (proxy) { | 
| 1184 if (!is_main_frame) { | 1185 if (is_site_per_process || !is_main_frame) { | 
| 1185 frame_->swap(proxy->web_frame()); | 1186 frame_->swap(proxy->web_frame()); | 
| 1186 | 1187 | 
| 1187 if (is_loading) | 1188 if (is_loading) | 
| 1188 proxy->OnDidStartLoading(); | 1189 proxy->OnDidStartLoading(); | 
| 1189 | |
| 1190 if (is_site_per_process) { | |
| 1191 // TODO(nasko): delete the frame here, since we've replaced it with a | |
| 1192 // proxy. | |
| 1193 } | |
| 1194 } | 1190 } | 
| 1195 } | 1191 } | 
| 1196 | 1192 | 
| 1197 // In --site-per-process, initialize the WebRemoteFrame with the replication | 1193 // In --site-per-process, initialize the WebRemoteFrame with the replication | 
| 1198 // state passed by the process that is now rendering the frame. | 1194 // state passed by the process that is now rendering the frame. | 
| 1199 // TODO(alexmos): We cannot yet do this for swapped-out main frames, because | 1195 // TODO(alexmos): We cannot yet do this for swapped-out main frames, because | 
| 1200 // in that case we leave the LocalFrame as the main frame visible to Blink | 1196 // in that case we leave the LocalFrame as the main frame visible to Blink | 
| 1201 // and don't call swap() above. Because swap() is what creates a RemoteFrame | 1197 // and don't call swap() above. Because swap() is what creates a RemoteFrame | 
| 1202 // in proxy->web_frame(), the RemoteFrame will not exist for main frames. | 1198 // in proxy->web_frame(), the RemoteFrame will not exist for main frames. | 
| 1203 // When we do an unconditional swap for all frames, we can remove | 1199 // When we do an unconditional swap for all frames, we can remove | 
| 1204 // !is_main_frame below. | 1200 // !is_main_frame below. | 
| 1205 if (is_site_per_process && proxy && !is_main_frame) | 1201 if (is_site_per_process && proxy) | 
| 1206 proxy->SetReplicatedState(replicated_frame_state); | 1202 proxy->SetReplicatedState(replicated_frame_state); | 
| 1207 | 1203 | 
| 1208 // Safe to exit if no one else is using the process. | 1204 // Safe to exit if no one else is using the process. | 
| 1209 if (is_main_frame) | 1205 // TODO(nasko): Remove the dependency on RenderViewImpl here and ref count | 
| 1210 render_view_->WasSwappedOut(); | 1206 // the process based on the lifetime of this RenderFrameImpl object. | 
| 1207 if (is_main_frame) { | |
| 1208 render_view->WasSwappedOut(); | |
| 1209 | |
| 1210 // TODO(nasko): Currently, this RenderFrame is leaked due to issues in | |
| 
Charlie Reis
2015/06/04 00:02:11
Hmm.  Will Lucas's CL fix this for us?
 
nasko
2015/06/04 14:57:13
Indeed it is supposed to. This is why I cache the
 
Charlie Reis
2015/06/04 22:27:31
Ok.  Please add a reference to Lucas's bug number,
 
nasko
2015/06/04 23:38:36
Done.
 | |
| 1211 // Blink, therefore the destructor won't be invoked to destroy this | |
| 1212 // object. In the meantime, set the main frame of the RenderView to null | |
| 1213 // here. | |
| 1214 if (is_site_per_process) { | |
| 1215 CHECK_EQ(render_view_->main_render_frame_, this); | |
| 1216 render_view->main_render_frame_ = nullptr; | |
| 1217 } | |
| 1218 } | |
| 1211 } | 1219 } | 
| 1212 | 1220 | 
| 1213 void RenderFrameImpl::OnContextMenuClosed( | 1221 void RenderFrameImpl::OnContextMenuClosed( | 
| 1214 const CustomContextMenuContext& custom_context) { | 1222 const CustomContextMenuContext& custom_context) { | 
| 1215 if (custom_context.request_id) { | 1223 if (custom_context.request_id) { | 
| 1216 // External request, should be in our map. | 1224 // External request, should be in our map. | 
| 1217 ContextMenuClient* client = | 1225 ContextMenuClient* client = | 
| 1218 pending_context_menus_.Lookup(custom_context.request_id); | 1226 pending_context_menus_.Lookup(custom_context.request_id); | 
| 1219 if (client) { | 1227 if (client) { | 
| 1220 client->OnMenuClosed(custom_context.request_id); | 1228 client->OnMenuClosed(custom_context.request_id); | 
| (...skipping 1349 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2570 static_cast<NavigationStateImpl*>(document_state->navigation_state()); | 2578 static_cast<NavigationStateImpl*>(document_state->navigation_state()); | 
| 2571 | 2579 | 
| 2572 if (proxy_routing_id_ != MSG_ROUTING_NONE) { | 2580 if (proxy_routing_id_ != MSG_ROUTING_NONE) { | 
| 2573 RenderFrameProxy* proxy = | 2581 RenderFrameProxy* proxy = | 
| 2574 RenderFrameProxy::FromRoutingID(proxy_routing_id_); | 2582 RenderFrameProxy::FromRoutingID(proxy_routing_id_); | 
| 2575 CHECK(proxy); | 2583 CHECK(proxy); | 
| 2576 proxy->web_frame()->swap(frame_); | 2584 proxy->web_frame()->swap(frame_); | 
| 2577 proxy_routing_id_ = MSG_ROUTING_NONE; | 2585 proxy_routing_id_ = MSG_ROUTING_NONE; | 
| 2578 | 2586 | 
| 2579 // If this is the main frame going from a remote frame to a local frame, | 2587 // If this is the main frame going from a remote frame to a local frame, | 
| 2580 // it needs to set RenderViewImpl's pointer for the main frame to itself. | 2588 // it needs to set RenderViewImpl's pointer for the main frame to itself | 
| 2589 // and ensure RenderWidget is no longer in swapped out mode. | |
| 2581 if (!is_subframe_) { | 2590 if (!is_subframe_) { | 
| 2582 CHECK(!render_view_->main_render_frame_); | 2591 CHECK(!render_view_->main_render_frame_); | 
| 2583 render_view_->main_render_frame_ = this; | 2592 render_view_->main_render_frame_ = this; | 
| 2593 if (render_view_->is_swapped_out()) | |
| 2594 render_view_->SetSwappedOut(false); | |
| 2584 } | 2595 } | 
| 2585 } | 2596 } | 
| 2586 | 2597 | 
| 2587 // When we perform a new navigation, we need to update the last committed | 2598 // When we perform a new navigation, we need to update the last committed | 
| 2588 // session history entry with state for the page we are leaving. Do this | 2599 // session history entry with state for the page we are leaving. Do this | 
| 2589 // before updating the HistoryController state. | 2600 // before updating the HistoryController state. | 
| 2590 render_view_->UpdateSessionHistory(frame); | 2601 render_view_->UpdateSessionHistory(frame); | 
| 2591 | 2602 | 
| 2592 render_view_->history_controller()->UpdateForCommit( | 2603 render_view_->history_controller()->UpdateForCommit( | 
| 2593 this, item, commit_type, navigation_state->WasWithinSamePage()); | 2604 this, item, commit_type, navigation_state->WasWithinSamePage()); | 
| (...skipping 1748 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4342 } | 4353 } | 
| 4343 | 4354 | 
| 4344 Send(new FrameHostMsg_OpenURL(routing_id_, params)); | 4355 Send(new FrameHostMsg_OpenURL(routing_id_, params)); | 
| 4345 } | 4356 } | 
| 4346 | 4357 | 
| 4347 void RenderFrameImpl::NavigateInternal( | 4358 void RenderFrameImpl::NavigateInternal( | 
| 4348 const CommonNavigationParams& common_params, | 4359 const CommonNavigationParams& common_params, | 
| 4349 const StartNavigationParams& start_params, | 4360 const StartNavigationParams& start_params, | 
| 4350 const RequestNavigationParams& request_params, | 4361 const RequestNavigationParams& request_params, | 
| 4351 scoped_ptr<StreamOverrideParameters> stream_params) { | 4362 scoped_ptr<StreamOverrideParameters> stream_params) { | 
| 4363 if (proxy_routing_id_ != MSG_ROUTING_NONE) { | |
| 
nasko
2015/06/04 14:57:13
This code is sufficiently similar to the code in d
 
Charlie Reis
2015/06/04 22:27:31
Ah, I didn't notice-- thanks for pointing it out.
 
nasko
2015/06/04 23:38:36
Indeed this isn't needed. For some reason I've add
 | |
| 4364 RenderFrameProxy* proxy = | |
| 4365 RenderFrameProxy::FromRoutingID(proxy_routing_id_); | |
| 4366 CHECK(proxy); | |
| 4367 proxy->web_frame()->swap(frame_); | |
| 4368 proxy_routing_id_ = MSG_ROUTING_NONE; | |
| 4369 | |
| 4370 // If this is the main frame going from a remote frame to a local frame, | |
| 4371 // it needs to set RenderViewImpl's pointer for the main frame to itself. | |
| 4372 if (!is_subframe_) { | |
| 4373 CHECK(!render_view_->main_render_frame_); | |
| 4374 render_view_->main_render_frame_ = this; | |
| 4375 } | |
| 4376 } | |
| 4377 | |
| 4352 bool browser_side_navigation = | 4378 bool browser_side_navigation = | 
| 4353 base::CommandLine::ForCurrentProcess()->HasSwitch( | 4379 base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| 4354 switches::kEnableBrowserSideNavigation); | 4380 switches::kEnableBrowserSideNavigation); | 
| 4355 bool is_reload = IsReload(common_params.navigation_type); | 4381 bool is_reload = IsReload(common_params.navigation_type); | 
| 4356 bool is_history_navigation = request_params.page_state.IsValid(); | 4382 bool is_history_navigation = request_params.page_state.IsValid(); | 
| 4357 WebURLRequest::CachePolicy cache_policy = | 4383 WebURLRequest::CachePolicy cache_policy = | 
| 4358 WebURLRequest::UseProtocolCachePolicy; | 4384 WebURLRequest::UseProtocolCachePolicy; | 
| 4359 if (!RenderFrameImpl::PrepareRenderViewForNavigation( | 4385 if (!RenderFrameImpl::PrepareRenderViewForNavigation( | 
| 4360 common_params.url, is_history_navigation, request_params, &is_reload, | 4386 common_params.url, is_history_navigation, request_params, &is_reload, | 
| 4361 &cache_policy)) { | 4387 &cache_policy)) { | 
| (...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 4887 #elif defined(ENABLE_BROWSER_CDMS) | 4913 #elif defined(ENABLE_BROWSER_CDMS) | 
| 4888 cdm_manager_, | 4914 cdm_manager_, | 
| 4889 #endif | 4915 #endif | 
| 4890 this); | 4916 this); | 
| 4891 } | 4917 } | 
| 4892 | 4918 | 
| 4893 return cdm_factory_; | 4919 return cdm_factory_; | 
| 4894 } | 4920 } | 
| 4895 | 4921 | 
| 4896 } // namespace content | 4922 } // namespace content | 
| OLD | NEW |