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

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

Issue 117603002: Always create FrameTreeNodes and RenderFrameHosts for every frame. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix prerendering. Created 6 years, 11 months 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 | Annotate | Revision Log
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_view_impl.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/command_line.h" 10 #include "base/command_line.h"
11 #include "base/debug/alias.h"
11 #include "base/i18n/char_iterator.h" 12 #include "base/i18n/char_iterator.h"
12 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
13 #include "base/time/time.h" 14 #include "base/time/time.h"
14 #include "content/child/appcache/appcache_dispatcher.h" 15 #include "content/child/appcache/appcache_dispatcher.h"
15 #include "content/child/plugin_messages.h" 16 #include "content/child/plugin_messages.h"
16 #include "content/child/quota_dispatcher.h" 17 #include "content/child/quota_dispatcher.h"
17 #include "content/child/request_extra_data.h" 18 #include "content/child/request_extra_data.h"
18 #include "content/child/service_worker/web_service_worker_provider_impl.h" 19 #include "content/child/service_worker/web_service_worker_provider_impl.h"
19 #include "content/common/frame_messages.h" 20 #include "content/common/frame_messages.h"
20 #include "content/common/socket_stream_handle_data.h" 21 #include "content/common/socket_stream_handle_data.h"
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 using blink::WebView; 90 using blink::WebView;
90 using base::Time; 91 using base::Time;
91 using base::TimeDelta; 92 using base::TimeDelta;
92 using webkit_glue::WebURLResponseExtraDataImpl; 93 using webkit_glue::WebURLResponseExtraDataImpl;
93 94
94 namespace content { 95 namespace content {
95 96
96 namespace { 97 namespace {
97 98
98 typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap; 99 typedef std::map<blink::WebFrame*, RenderFrameImpl*> FrameMap;
99 base::LazyInstance<FrameMap> g_child_frame_map = LAZY_INSTANCE_INITIALIZER; 100 base::LazyInstance<FrameMap> g_frame_map = LAZY_INSTANCE_INITIALIZER;
100 101
101 } // namespace 102 } // namespace
102 103
103 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) = 104 static RenderFrameImpl* (*g_create_render_frame_impl)(RenderViewImpl*, int32) =
104 NULL; 105 NULL;
105 106
106 // static 107 // static
107 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view, 108 RenderFrameImpl* RenderFrameImpl::Create(RenderViewImpl* render_view,
108 int32 routing_id) { 109 int32 routing_id) {
109 DCHECK(routing_id != MSG_ROUTING_NONE); 110 DCHECK(routing_id != MSG_ROUTING_NONE);
110 111
111 if (g_create_render_frame_impl) 112 if (g_create_render_frame_impl)
112 return g_create_render_frame_impl(render_view, routing_id); 113 return g_create_render_frame_impl(render_view, routing_id);
113 else 114 else
114 return new RenderFrameImpl(render_view, routing_id); 115 return new RenderFrameImpl(render_view, routing_id);
115 } 116 }
116 117
117 RenderFrameImpl* RenderFrameImpl::FindByWebFrame(blink::WebFrame* web_frame) { 118 RenderFrameImpl* RenderFrameImpl::FindByWebFrame(blink::WebFrame* web_frame) {
118 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { 119 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) {
119 FrameMap::iterator iter = g_child_frame_map.Get().find(web_frame); 120 FrameMap::iterator iter = g_frame_map.Get().find(web_frame);
120 if (iter != g_child_frame_map.Get().end()) 121 if (iter != g_frame_map.Get().end())
121 return iter->second; 122 return iter->second;
122 } 123 }
123 124
124 return NULL; 125 return NULL;
125 } 126 }
126 127
127 // static 128 // static
128 void RenderFrameImpl::InstallCreateHook( 129 void RenderFrameImpl::InstallCreateHook(
129 RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) { 130 RenderFrameImpl* (*create_render_frame_impl)(RenderViewImpl*, int32)) {
130 CHECK(!g_create_render_frame_impl); 131 CHECK(!g_create_render_frame_impl);
(...skipping 16 matching lines...) Expand all
147 148
148 GetContentClient()->renderer()->RenderFrameCreated(this); 149 GetContentClient()->renderer()->RenderFrameCreated(this);
149 } 150 }
150 151
151 RenderFrameImpl::~RenderFrameImpl() { 152 RenderFrameImpl::~RenderFrameImpl() {
152 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone()); 153 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, RenderFrameGone());
153 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct()); 154 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, OnDestruct());
154 RenderThread::Get()->RemoveRoute(routing_id_); 155 RenderThread::Get()->RemoveRoute(routing_id_);
155 } 156 }
156 157
158 // TODO(nasko): Overload the delete operator to overwrite the freed
159 // RenderFrameImpl object and help detect potential use-after-free bug.
160 // See https://crbug.com/245126#c34.
161 void RenderFrameImpl::operator delete(void* ptr) {
162 memset(ptr, 0xAF, sizeof(RenderFrameImpl));
163 }
164
157 void RenderFrameImpl::MainWebFrameCreated(blink::WebFrame* frame) { 165 void RenderFrameImpl::MainWebFrameCreated(blink::WebFrame* frame) {
166 std::pair<FrameMap::iterator, bool> result = g_frame_map.Get().insert(
167 std::make_pair(frame, this));
168 CHECK(result.second) << "Inserting a duplicate item.";
169
158 FOR_EACH_OBSERVER(RenderFrameObserver, observers_, 170 FOR_EACH_OBSERVER(RenderFrameObserver, observers_,
159 WebFrameCreated(frame)); 171 WebFrameCreated(frame));
160 } 172 }
161 173
162 void RenderFrameImpl::SetWebFrame(blink::WebFrame* web_frame) { 174 void RenderFrameImpl::SetWebFrame(blink::WebFrame* web_frame) {
163 DCHECK(!frame_); 175 DCHECK(!frame_);
164 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) 176 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess))
165 frame_ = web_frame; 177 frame_ = web_frame;
166 } 178 }
167 179
(...skipping 489 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 make_scoped_ptr(client)); 669 make_scoped_ptr(client));
658 } 670 }
659 671
660 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) { 672 void RenderFrameImpl::didAccessInitialDocument(blink::WebFrame* frame) {
661 render_view_->didAccessInitialDocument(frame); 673 render_view_->didAccessInitialDocument(frame);
662 } 674 }
663 675
664 blink::WebFrame* RenderFrameImpl::createChildFrame( 676 blink::WebFrame* RenderFrameImpl::createChildFrame(
665 blink::WebFrame* parent, 677 blink::WebFrame* parent,
666 const blink::WebString& name) { 678 const blink::WebString& name) {
667 RenderFrameImpl* child_render_frame = this;
668 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier(); 679 long long child_frame_identifier = WebFrame::generateEmbedderIdentifier();
669 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { 680 // Synchronously notify the browser of a child frame creation to get the
670 // Synchronously notify the browser of a child frame creation to get the 681 // routing_id for the RenderFrame.
671 // routing_id for the RenderFrame. 682 int routing_id = MSG_ROUTING_NONE;
672 int routing_id; 683 Send(new FrameHostMsg_CreateChildFrame(routing_id_,
673 Send(new FrameHostMsg_CreateChildFrame(routing_id_, 684 parent->identifier(),
674 parent->identifier(), 685 child_frame_identifier,
675 child_frame_identifier, 686 base::UTF16ToUTF8(name),
676 base::UTF16ToUTF8(name), 687 &routing_id));
677 &routing_id)); 688 CHECK_NE(routing_id, MSG_ROUTING_NONE);
678 child_render_frame = RenderFrameImpl::Create(render_view_, routing_id); 689 RenderFrameImpl* child_render_frame = RenderFrameImpl::Create(render_view_,
679 } 690 routing_id);
680 691 // TODO(nasko): Over-conservative check for debugging.
692 CHECK(child_render_frame);
681 blink::WebFrame* web_frame = WebFrame::create(child_render_frame, 693 blink::WebFrame* web_frame = WebFrame::create(child_render_frame,
682 child_frame_identifier); 694 child_frame_identifier);
695 // TODO(nasko): Over-conservative check for debugging.
696 CHECK(web_frame);
697 child_render_frame->SetWebFrame(web_frame);
683 698
684 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { 699 std::pair<FrameMap::iterator, bool> result = g_frame_map.Get().insert(
685 child_render_frame->SetWebFrame(web_frame); 700 std::make_pair(web_frame, child_render_frame));
686 g_child_frame_map.Get().insert( 701 CHECK(result.second) << "Inserting a duplicate item.";
687 std::make_pair(web_frame, child_render_frame));
688 } else {
689 FOR_EACH_OBSERVER(RenderFrameObserver, observers_,
690 WebFrameCreated(web_frame));
691 }
692 702
703 FOR_EACH_OBSERVER(RenderFrameObserver, observers_,
704 WebFrameCreated(web_frame));
693 return web_frame; 705 return web_frame;
694 } 706 }
695 707
696 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) { 708 void RenderFrameImpl::didDisownOpener(blink::WebFrame* frame) {
697 render_view_->didDisownOpener(frame); 709 render_view_->didDisownOpener(frame);
698 } 710 }
699 711
700 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) { 712 void RenderFrameImpl::frameDetached(blink::WebFrame* frame) {
701 // NOTE: This function is called on the frame that is being detached and not 713 // NOTE: This function is called on the frame that is being detached and not
702 // the parent frame. This is different from createChildFrame() which is 714 // the parent frame. This is different from createChildFrame() which is
703 // called on the parent frame. 715 // called on the parent frame.
704 CHECK(!is_detaching_); 716 CHECK(!is_detaching_);
717 // TODO(nasko): Remove all debug::Alias lines after diagnosing failures.
718 base::debug::Alias(frame);
719
720 bool is_subframe = !!frame->parent();
721 base::debug::Alias(&is_subframe);
705 722
706 int64 parent_frame_id = -1; 723 int64 parent_frame_id = -1;
707 if (frame->parent()) 724 base::debug::Alias(&parent_frame_id);
725 if (is_subframe)
708 parent_frame_id = frame->parent()->identifier(); 726 parent_frame_id = frame->parent()->identifier();
709 727
710 Send(new FrameHostMsg_Detach(routing_id_, parent_frame_id, 728 Send(new FrameHostMsg_Detach(routing_id_, parent_frame_id,
711 frame->identifier())); 729 frame->identifier()));
712 730
713 // Currently multiple WebCore::Frames can send frameDetached to a single 731 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be
714 // RenderFrameImpl. This is legacy behavior from when RenderViewImpl served 732 // sent before setting |is_detaching_| to true. In contrast, Observers
715 // as a shared WebFrameClient for multiple Webcore::Frame objects. It also 733 // should only be notified afterwards so they cannot call back into here and
716 // prevents this class from entering the |is_detaching_| state because 734 // have IPCs fired off.
717 // even though one WebCore::Frame may have detached itself, others will 735 is_detaching_ = true;
718 // still need to use this object.
719 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) {
720 // The |is_detaching_| flag disables Send(). FrameHostMsg_Detach must be
721 // sent before setting |is_detaching_| to true. In contrast, Observers
722 // should only be notified afterwards so they cannot call back into and
723 // have IPCs fired off.
724 is_detaching_ = true;
725 }
726 736
727 // Call back to RenderViewImpl for observers to be notified. 737 // Call back to RenderViewImpl for observers to be notified.
728 // TODO(nasko): Remove once we have RenderFrameObserver. 738 // TODO(nasko): Remove once we have RenderFrameObserver.
729 render_view_->frameDetached(frame); 739 render_view_->frameDetached(frame);
730 740
741 // We need to clean up subframes by removing them from the map and deleting
742 // the RenderFrameImpl. In contrast, the main frame is owned by its
743 // containing RenderViewHost (so that they have the same lifetime), so only
744 // removal from the map is needed and no deletion.
745 FrameMap::iterator it = g_frame_map.Get().find(frame);
746 CHECK(it != g_frame_map.Get().end());
747 CHECK_EQ(it->second, this);
748 g_frame_map.Get().erase(it);
749
750 // |frame| is invalid after here.
731 frame->close(); 751 frame->close();
732 752
733 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSitePerProcess)) { 753 if (is_subframe) {
734 // If the frame does not have a parent, it is the main frame. The main 754 delete this;
735 // frame is owned by the containing RenderViewHost so it does not require 755 // Object is invalid after this point.
736 // any cleanup here.
737 if (frame->parent()) {
738 FrameMap::iterator it = g_child_frame_map.Get().find(frame);
739 DCHECK(it != g_child_frame_map.Get().end());
740 DCHECK_EQ(it->second, this);
741 g_child_frame_map.Get().erase(it);
742 delete this;
743 // Object is invalid after this point.
744 }
745 } 756 }
746 } 757 }
747 758
748 void RenderFrameImpl::willClose(blink::WebFrame* frame) { 759 void RenderFrameImpl::willClose(blink::WebFrame* frame) {
749 // Call back to RenderViewImpl for observers to be notified. 760 // Call back to RenderViewImpl for observers to be notified.
750 // TODO(nasko): Remove once we have RenderFrameObserver. 761 // TODO(nasko): Remove once we have RenderFrameObserver.
751 render_view_->willClose(frame); 762 render_view_->willClose(frame);
752 } 763 }
753 764
754 void RenderFrameImpl::didChangeName(blink::WebFrame* frame, 765 void RenderFrameImpl::didChangeName(blink::WebFrame* frame,
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after
1431 void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) { 1442 void RenderFrameImpl::AddObserver(RenderFrameObserver* observer) {
1432 observers_.AddObserver(observer); 1443 observers_.AddObserver(observer);
1433 } 1444 }
1434 1445
1435 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) { 1446 void RenderFrameImpl::RemoveObserver(RenderFrameObserver* observer) {
1436 observer->RenderFrameGone(); 1447 observer->RenderFrameGone();
1437 observers_.RemoveObserver(observer); 1448 observers_.RemoveObserver(observer);
1438 } 1449 }
1439 1450
1440 } // namespace content 1451 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/render_frame_impl.h ('k') | content/renderer/render_view_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698