Web Inspector: Native Memory Instrumentation: fix instrumentation for already instrum...
[WebKit-https.git] / Source / WebCore / loader / Prerenderer.cpp
1 /*
2  * Copyright (C) 2012 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  */
31
32 #include "config.h"
33 #include "Prerenderer.h"
34
35 #if ENABLE(LINK_PRERENDER)
36
37 #include "Document.h"
38 #include "Frame.h"
39 #include "FrameLoader.h"
40 #include "PrerenderHandle.h"
41 #include "PrerendererClient.h"
42 #include "ReferrerPolicy.h"
43 #include "SecurityPolicy.h"
44 #include "WebCoreMemoryInstrumentation.h"
45
46 #include <wtf/MemoryInstrumentationVector.h>
47 #include <wtf/PassOwnPtr.h>
48 #include <wtf/PassRefPtr.h>
49 #include <wtf/RefPtr.h>
50 #include <wtf/text/WTFString.h>
51
52 namespace WebCore {
53
54 // static
55 PassOwnPtr<Prerenderer> Prerenderer::create(Document* document)
56 {
57     Prerenderer* prerenderer = new Prerenderer(document);
58     prerenderer->suspendIfNeeded();
59     return adoptPtr(prerenderer);
60 }
61
62 Prerenderer::Prerenderer(Document* document)
63     : ActiveDOMObject(document, this)
64     , m_initializedClient(false)
65     , m_client(0)
66 {
67 }
68
69 Prerenderer::~Prerenderer()
70 {
71 }
72
73 PassRefPtr<PrerenderHandle> Prerenderer::render(PrerenderClient* prerenderClient, const KURL& url)
74 {
75     // Prerenders are unlike requests in most ways (for instance, they pass down fragments, and they don't return data),
76     // but they do have referrers.
77     const ReferrerPolicy referrerPolicy = document()->referrerPolicy();
78     
79     if (!document()->frame())
80         return 0;
81
82     const String referrer = SecurityPolicy::generateReferrerHeader(referrerPolicy, url, document()->frame()->loader()->outgoingReferrer());
83
84     RefPtr<PrerenderHandle> prerenderHandle = PrerenderHandle::create(prerenderClient, url, referrer, referrerPolicy);
85
86     if (client())
87         client()->willAddPrerender(prerenderHandle.get());
88     prerenderHandle->add();
89
90     m_activeHandles.append(prerenderHandle);
91     return prerenderHandle;
92 }
93
94 void Prerenderer::stop()
95 {
96     while (!m_activeHandles.isEmpty()) {
97         RefPtr<PrerenderHandle> handle = m_activeHandles[0].release();
98         m_activeHandles.remove(0);
99         handle->abandon();
100     }
101     while (!m_suspendedHandles.isEmpty()) {
102         RefPtr<PrerenderHandle> handle = m_suspendedHandles[0].release();
103         m_suspendedHandles.remove(0);
104         handle->abandon();
105     }
106 }
107
108 void Prerenderer::suspend(ReasonForSuspension reason)
109 {
110     if (reason == DocumentWillBecomeInactive || reason == PageWillBeSuspended) {
111         while (!m_activeHandles.isEmpty()) {
112             RefPtr<PrerenderHandle> handle = m_activeHandles[0].release();
113             m_activeHandles.remove(0);
114             handle->suspend();
115             m_suspendedHandles.append(handle);
116         }
117     }
118 }
119
120 void Prerenderer::resume()
121 {
122     while (!m_suspendedHandles.isEmpty()) {
123         RefPtr<PrerenderHandle> handle = m_suspendedHandles[0].release();
124         m_suspendedHandles.remove(0);
125         handle->resume();
126         m_activeHandles.append(handle);
127     }
128 }
129
130 Document* Prerenderer::document()
131 {
132     ASSERT(scriptExecutionContext()->isDocument());
133     return static_cast<Document*>(scriptExecutionContext());
134 }
135
136 PrerendererClient* Prerenderer::client()
137 {
138     if (!m_initializedClient) {
139         // We can't initialize the client in our contructor, because the platform might not have
140         // provided our supplement by then.
141         m_initializedClient = true;
142         m_client = PrerendererClient::from(document()->page());
143     }
144     return m_client;
145 }
146
147 void Prerenderer::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
148 {
149     MemoryClassInfo info(memoryObjectInfo, this, WebCoreMemoryTypes::DOM);
150     ActiveDOMObject::reportMemoryUsage(memoryObjectInfo);
151     info.ignoreMember(m_client);
152     info.addMember(m_activeHandles);
153     info.addMember(m_suspendedHandles);
154 }
155
156 }
157
158 #endif // ENABLE(LINK_PRERENDER)