Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2)

Side by Side Diff: content/renderer/render_frame_impl.cc

Issue 1409693009: Fix leaking of RenderFrames. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Handle main frame navigating to existing process. Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 653 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 // WasShown and WasHidden, separating page-level visibility from 664 // WasShown and WasHidden, separating page-level visibility from
665 // frame-level visibility. 665 // frame-level visibility.
666 render_frame->render_widget_->RegisterRenderFrame(render_frame); 666 render_frame->render_widget_->RegisterRenderFrame(render_frame);
667 } 667 }
668 } 668 }
669 669
670 render_frame->Initialize(); 670 render_frame->Initialize();
671 } 671 }
672 672
673 // static 673 // static
674 void RenderFrameImpl::DetachFrame(int routing_id) {
675 RenderFrameImpl* frame = RenderFrameImpl::FromRoutingID(routing_id);
676 frame->set_in_browser_initiated_detach();
677 frame->GetWebFrame()->detach();
678 }
679
680 // static
674 RenderFrame* RenderFrame::FromWebFrame(blink::WebFrame* web_frame) { 681 RenderFrame* RenderFrame::FromWebFrame(blink::WebFrame* web_frame) {
675 return RenderFrameImpl::FromWebFrame(web_frame); 682 return RenderFrameImpl::FromWebFrame(web_frame);
676 } 683 }
677 684
678 // static 685 // static
679 RenderFrameImpl* RenderFrameImpl::FromWebFrame(blink::WebFrame* web_frame) { 686 RenderFrameImpl* RenderFrameImpl::FromWebFrame(blink::WebFrame* web_frame) {
680 FrameMap::iterator iter = g_frame_map.Get().find(web_frame); 687 FrameMap::iterator iter = g_frame_map.Get().find(web_frame);
681 if (iter != g_frame_map.Get().end()) 688 if (iter != g_frame_map.Get().end())
682 return iter->second; 689 return iter->second;
683 return NULL; 690 return NULL;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 } 733 }
727 734
728 return nullptr; 735 return nullptr;
729 } 736 }
730 737
731 // RenderFrameImpl ---------------------------------------------------------- 738 // RenderFrameImpl ----------------------------------------------------------
732 RenderFrameImpl::RenderFrameImpl(const CreateParams& params) 739 RenderFrameImpl::RenderFrameImpl(const CreateParams& params)
733 : frame_(NULL), 740 : frame_(NULL),
734 is_main_frame_(true), 741 is_main_frame_(true),
735 is_local_root_(false), 742 is_local_root_(false),
743 in_browser_initiated_detach_(false),
744 is_inserted_in_frame_tree_(false),
736 render_view_(params.render_view->AsWeakPtr()), 745 render_view_(params.render_view->AsWeakPtr()),
737 routing_id_(params.routing_id), 746 routing_id_(params.routing_id),
738 is_swapped_out_(false), 747 is_swapped_out_(false),
739 render_frame_proxy_(NULL), 748 render_frame_proxy_(NULL),
740 is_detaching_(false), 749 is_detaching_(false),
741 proxy_routing_id_(MSG_ROUTING_NONE), 750 proxy_routing_id_(MSG_ROUTING_NONE),
742 #if defined(ENABLE_PLUGINS) 751 #if defined(ENABLE_PLUGINS)
743 plugin_power_saver_helper_(nullptr), 752 plugin_power_saver_helper_(nullptr),
744 #endif 753 #endif
745 cookie_jar_(this), 754 cookie_jar_(this),
(...skipping 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 2340
2332 // Create the RenderFrame and WebLocalFrame, linking the two. 2341 // Create the RenderFrame and WebLocalFrame, linking the two.
2333 RenderFrameImpl* child_render_frame = RenderFrameImpl::Create( 2342 RenderFrameImpl* child_render_frame = RenderFrameImpl::Create(
2334 render_view_.get(), child_routing_id); 2343 render_view_.get(), child_routing_id);
2335 blink::WebLocalFrame* web_frame = 2344 blink::WebLocalFrame* web_frame =
2336 WebLocalFrame::create(scope, child_render_frame); 2345 WebLocalFrame::create(scope, child_render_frame);
2337 child_render_frame->SetWebFrame(web_frame); 2346 child_render_frame->SetWebFrame(web_frame);
2338 2347
2339 // Add the frame to the frame tree and initialize it. 2348 // Add the frame to the frame tree and initialize it.
2340 parent->appendChild(web_frame); 2349 parent->appendChild(web_frame);
2350 child_render_frame->is_inserted_in_frame_tree_ = true;
2341 child_render_frame->Initialize(); 2351 child_render_frame->Initialize();
2342 2352
2343 return web_frame; 2353 return web_frame;
2344 } 2354 }
2345 2355
2346 void RenderFrameImpl::didChangeOpener(blink::WebFrame* opener) { 2356 void RenderFrameImpl::didChangeOpener(blink::WebFrame* opener) {
2347 // Only active frames are able to disown their opener. 2357 // Only active frames are able to disown their opener.
2348 if (!opener && is_swapped_out_) 2358 if (!opener && is_swapped_out_)
2349 return; 2359 return;
2350 2360
(...skipping 11 matching lines...) Expand all
2362 // the parent frame. This is different from createChildFrame() which is 2372 // the parent frame. This is different from createChildFrame() which is
2363 // called on the parent frame. 2373 // called on the parent frame.
2364 CHECK(!is_detaching_); 2374 CHECK(!is_detaching_);
2365 DCHECK(!frame_ || frame_ == frame); 2375 DCHECK(!frame_ || frame_ == frame);
2366 2376
2367 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, FrameDetached()); 2377 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, FrameDetached());
2368 FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers(), 2378 FOR_EACH_OBSERVER(RenderViewObserver, render_view_->observers(),
2369 FrameDetached(frame)); 2379 FrameDetached(frame));
2370 2380
2371 // We only notify the browser process when the frame is being detached for 2381 // We only notify the browser process when the frame is being detached for
2372 // removal. If the frame is being detached for swap, we don't need to do this 2382 // removal and it was initiated from the renderer process.
2373 // since we are not modifiying the frame tree. 2383 if (!in_browser_initiated_detach_ && type == DetachType::Remove)
2374 if (type == DetachType::Remove)
2375 Send(new FrameHostMsg_Detach(routing_id_)); 2384 Send(new FrameHostMsg_Detach(routing_id_));
2376 2385
2377 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be 2386 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be
2378 // sent before setting |is_detaching_| to true. 2387 // sent before setting |is_detaching_| to true.
2379 is_detaching_ = true; 2388 is_detaching_ = true;
2380 2389
2381 // Clean up the associated RenderWidget for the frame, if there is one. 2390 // Clean up the associated RenderWidget for the frame, if there is one.
2382 if (render_widget_) { 2391 if (render_widget_) {
2383 render_widget_->UnregisterRenderFrame(this); 2392 render_widget_->UnregisterRenderFrame(this);
2384 render_widget_->CloseForFrame(); 2393 render_widget_->CloseForFrame();
2385 } 2394 }
2386 2395
2387 // We need to clean up subframes by removing them from the map and deleting 2396 // We need to clean up subframes by removing them from the map and deleting
2388 // the RenderFrameImpl. In contrast, the main frame is owned by its 2397 // the RenderFrameImpl. In contrast, the main frame is owned by its
2389 // containing RenderViewHost (so that they have the same lifetime), so only 2398 // containing RenderViewHost (so that they have the same lifetime), so only
2390 // removal from the map is needed and no deletion. 2399 // removal from the map is needed and no deletion.
2391 FrameMap::iterator it = g_frame_map.Get().find(frame); 2400 FrameMap::iterator it = g_frame_map.Get().find(frame);
2392 CHECK(it != g_frame_map.Get().end()); 2401 CHECK(it != g_frame_map.Get().end());
2393 CHECK_EQ(it->second, this); 2402 CHECK_EQ(it->second, this);
2394 g_frame_map.Get().erase(it); 2403 g_frame_map.Get().erase(it);
2395 2404
2396 // Only remove the frame from the renderer's frame tree if the frame is 2405 // Only remove the frame from the renderer's frame tree if the frame is
2397 // being detached for removal. In the case of a swap, the frame needs to 2406 // being detached for removal and is already inserted in the frame tree.
2398 // remain in the tree so WebFrame::swap() can replace it with the new frame. 2407 // In the case of a swap, the frame needs to remain in the tree so
2399 if (!is_main_frame_ && type == DetachType::Remove) 2408 // WebFrame::swap() can replace it with the new frame.
2409 if (!is_main_frame_ && is_inserted_in_frame_tree_ &&
2410 type == DetachType::Remove) {
2400 frame->parent()->removeChild(frame); 2411 frame->parent()->removeChild(frame);
2412 }
2401 2413
2402 // |frame| is invalid after here. Be sure to clear frame_ as well, since this 2414 // |frame| is invalid after here. Be sure to clear frame_ as well, since this
2403 // object may not be deleted immediately and other methods may try to access 2415 // object may not be deleted immediately and other methods may try to access
2404 // it. 2416 // it.
2405 frame->close(); 2417 frame->close();
2406 frame_ = nullptr; 2418 frame_ = nullptr;
2407 2419
2408 delete this; 2420 delete this;
2409 // Object is invalid after this point. 2421 // Object is invalid after this point.
2410 } 2422 }
(...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after
2795 WebURLResponseExtraDataImpl* extra_data = GetExtraDataFromResponse( 2807 WebURLResponseExtraDataImpl* extra_data = GetExtraDataFromResponse(
2796 frame->dataSource()->response()); 2808 frame->dataSource()->response());
2797 is_using_lofi_ = extra_data && extra_data->is_using_lofi(); 2809 is_using_lofi_ = extra_data && extra_data->is_using_lofi();
2798 2810
2799 if (proxy_routing_id_ != MSG_ROUTING_NONE) { 2811 if (proxy_routing_id_ != MSG_ROUTING_NONE) {
2800 RenderFrameProxy* proxy = 2812 RenderFrameProxy* proxy =
2801 RenderFrameProxy::FromRoutingID(proxy_routing_id_); 2813 RenderFrameProxy::FromRoutingID(proxy_routing_id_);
2802 CHECK(proxy); 2814 CHECK(proxy);
2803 proxy->web_frame()->swap(frame_); 2815 proxy->web_frame()->swap(frame_);
2804 proxy_routing_id_ = MSG_ROUTING_NONE; 2816 proxy_routing_id_ = MSG_ROUTING_NONE;
2817 is_inserted_in_frame_tree_ = true;
Charlie Reis 2015/11/04 21:28:30 Is it correct to put this behind a proxy_routing_i
nasko 2015/12/10 21:26:52 Unless it navigates back to its parent's frame pro
2805 2818
2806 // If this is the main frame going from a remote frame to a local frame, 2819 // If this is the main frame going from a remote frame to a local frame,
2807 // it needs to set RenderViewImpl's pointer for the main frame to itself 2820 // it needs to set RenderViewImpl's pointer for the main frame to itself
2808 // and ensure RenderWidget is no longer in swapped out mode. 2821 // and ensure RenderWidget is no longer in swapped out mode.
2809 if (is_main_frame_) { 2822 if (is_main_frame_) {
2810 CHECK(!render_view_->main_render_frame_); 2823 CHECK(!render_view_->main_render_frame_);
2811 render_view_->main_render_frame_ = this; 2824 render_view_->main_render_frame_ = this;
2812 if (render_view_->is_swapped_out()) 2825 if (render_view_->is_swapped_out())
2813 render_view_->SetSwappedOut(false); 2826 render_view_->SetSwappedOut(false);
2814 } 2827 }
(...skipping 2480 matching lines...) Expand 10 before | Expand all | Expand 10 after
5295 mojo::ServiceProviderPtr service_provider; 5308 mojo::ServiceProviderPtr service_provider;
5296 mojo::URLRequestPtr request(mojo::URLRequest::New()); 5309 mojo::URLRequestPtr request(mojo::URLRequest::New());
5297 request->url = mojo::String::From(url); 5310 request->url = mojo::String::From(url);
5298 mojo_shell_->ConnectToApplication(request.Pass(), GetProxy(&service_provider), 5311 mojo_shell_->ConnectToApplication(request.Pass(), GetProxy(&service_provider),
5299 nullptr, nullptr, 5312 nullptr, nullptr,
5300 base::Bind(&OnGotContentHandlerID)); 5313 base::Bind(&OnGotContentHandlerID));
5301 return service_provider.Pass(); 5314 return service_provider.Pass();
5302 } 5315 }
5303 5316
5304 } // namespace content 5317 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698