<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[192111] trunk/Source/WebKit2</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/192111">192111</a></dd>
<dt>Author</dt> <dd>cdumez@apple.com</dd>
<dt>Date</dt> <dd>2015-11-06 11:29:24 -0800 (Fri, 06 Nov 2015)</dd>
</dl>
<h3>Log Message</h3>
<pre>[WK2][SpeculativeRevalidation] Save to disk cache relationship between resources
https://bugs.webkit.org/show_bug.cgi?id=150951
<rdar://problem/23092196>
Reviewed by Darin Adler.
This patch is a first step towards speculative revalidation support in
the WebKit network cache. It maps sub-resources to the main resource
that caused them to be requested. We then write this information to the
network cache, as a list of subresource keys for each main resource,
even if the main resource is not cacheable.
To map sub-resources to main resources, we track the loads happening
in each frame and store the key of the main resource for the frame,
as well as the key of each sub-resource later loaded in the frame. We
use a HysteresisActivity to detect when loads settle down in each frame
(no loads happen for a while) and we then write the information to the
disk. If a new main resource is loaded in a frame where we were already
tracking a load, we save the data to disk before tracking the new load,
instead of waiting for the HysteresisActivity to detect the end of the
load.
The feature is currently behind a compile-time flag that is enabled on
Mac and iOS only. It is also behind a runtime flag (NSUserDefaults)
that is disabled by default.
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::start):
Pass frameID in addition to the pageID. We need to globally identify
frames (using <pageID, frameID> pair) to be able to track loads in
each frame.
* NetworkProcess/cache/NetworkCache.cpp:
(WebKit::NetworkCache::Cache::initialize):
Only initialize the SpeculativeLoader if the
enableNetworkCacheSpeculativeRevalidation run-time flag is set.
(WebKit::NetworkCache::Cache::retrieve):
Register the load with the SpeculativeLoader.
* NetworkProcess/cache/NetworkCacheKey.h:
(WebKit::NetworkCache::Key::Key):
(WebKit::NetworkCache::Key::isHashTableDeletedValue):
(WebKit::NetworkCache::Key::range):
(WTF::NetworkCacheKeyHash::hash):
(WTF::NetworkCacheKeyHash::equal):
(WTF::HashTraits<WebKit::NetworkCache::Key>::isEmptyValue):
Add needed HashTraits for NetworkCache::Key so it can be used as key in
HashMap / HashSet.
* NetworkProcess/cache/NetworkCacheSpeculativeLoader.cpp: Added.
* NetworkProcess/cache/NetworkCacheSpeculativeLoader.h: Added.
Add new NetworkCacheSpeculativeLoader class that takes care of tracking
loads in each frame to map subresources to main resources and then write
this information to the network disk cache. In the future, this class we
also take care of triggering speculative revalidations, thus the naming.
* NetworkProcess/cocoa/NetworkProcessCocoa.mm:
(WebKit::NetworkProcess::platformInitializeNetworkProcessCocoa):
* NetworkProcess/soup/NetworkProcessSoup.cpp:
(WebKit::NetworkProcess::platformInitializeNetworkProcess):
* Shared/Network/NetworkProcessCreationParameters.cpp:
(WebKit::NetworkProcessCreationParameters::encode):
(WebKit::NetworkProcessCreationParameters::decode):
* Shared/Network/NetworkProcessCreationParameters.h:
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::registerUserDefaultsIfNeeded):
(WebKit::WebProcessPool::platformInitializeNetworkProcess):
Add new NetworkProcess parameter to control at runtime if speculative loading
should be enabled or not. It is disabled by default.
* WebKit2.xcodeproj/project.pbxproj:
Add new files to XCode project.
* config.h:
Add ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION build flag for the new
feature that is enable by default on COCOA.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcessNetworkResourceLoadercpp">trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCachecpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheEntrycpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheEntryh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheKeycpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheKeyh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscocoaNetworkProcessCocoamm">trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkProcessCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesssoupNetworkProcessSoupcpp">trunk/Source/WebKit2/NetworkProcess/soup/NetworkProcessSoup.cpp</a></li>
<li><a href="#trunkSourceWebKit2PlatformLoggingh">trunk/Source/WebKit2/Platform/Logging.h</a></li>
<li><a href="#trunkSourceWebKit2SharedNetworkNetworkProcessCreationParameterscpp">trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedNetworkNetworkProcessCreationParametersh">trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessCocoaWebProcessPoolCocoamm">trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2configh">trunk/Source/WebKit2/config.h</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadercpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoaderh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.h</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntrycpp">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp</a></li>
<li><a href="#trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntryh">trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/ChangeLog        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -1,5 +1,85 @@
</span><span class="cx"> 2015-11-06 Chris Dumez <cdumez@apple.com>
</span><span class="cx">
</span><ins>+ [WK2][SpeculativeRevalidation] Save to disk cache relationship between resources
+ https://bugs.webkit.org/show_bug.cgi?id=150951
+ <rdar://problem/23092196>
+
+ Reviewed by Darin Adler.
+
+ This patch is a first step towards speculative revalidation support in
+ the WebKit network cache. It maps sub-resources to the main resource
+ that caused them to be requested. We then write this information to the
+ network cache, as a list of subresource keys for each main resource,
+ even if the main resource is not cacheable.
+
+ To map sub-resources to main resources, we track the loads happening
+ in each frame and store the key of the main resource for the frame,
+ as well as the key of each sub-resource later loaded in the frame. We
+ use a HysteresisActivity to detect when loads settle down in each frame
+ (no loads happen for a while) and we then write the information to the
+ disk. If a new main resource is loaded in a frame where we were already
+ tracking a load, we save the data to disk before tracking the new load,
+ instead of waiting for the HysteresisActivity to detect the end of the
+ load.
+
+ The feature is currently behind a compile-time flag that is enabled on
+ Mac and iOS only. It is also behind a runtime flag (NSUserDefaults)
+ that is disabled by default.
+
+ * NetworkProcess/NetworkResourceLoader.cpp:
+ (WebKit::NetworkResourceLoader::start):
+ Pass frameID in addition to the pageID. We need to globally identify
+ frames (using <pageID, frameID> pair) to be able to track loads in
+ each frame.
+
+ * NetworkProcess/cache/NetworkCache.cpp:
+ (WebKit::NetworkCache::Cache::initialize):
+ Only initialize the SpeculativeLoader if the
+ enableNetworkCacheSpeculativeRevalidation run-time flag is set.
+
+ (WebKit::NetworkCache::Cache::retrieve):
+ Register the load with the SpeculativeLoader.
+
+ * NetworkProcess/cache/NetworkCacheKey.h:
+ (WebKit::NetworkCache::Key::Key):
+ (WebKit::NetworkCache::Key::isHashTableDeletedValue):
+ (WebKit::NetworkCache::Key::range):
+ (WTF::NetworkCacheKeyHash::hash):
+ (WTF::NetworkCacheKeyHash::equal):
+ (WTF::HashTraits<WebKit::NetworkCache::Key>::isEmptyValue):
+ Add needed HashTraits for NetworkCache::Key so it can be used as key in
+ HashMap / HashSet.
+
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoader.cpp: Added.
+ * NetworkProcess/cache/NetworkCacheSpeculativeLoader.h: Added.
+ Add new NetworkCacheSpeculativeLoader class that takes care of tracking
+ loads in each frame to map subresources to main resources and then write
+ this information to the network disk cache. In the future, this class we
+ also take care of triggering speculative revalidations, thus the naming.
+
+ * NetworkProcess/cocoa/NetworkProcessCocoa.mm:
+ (WebKit::NetworkProcess::platformInitializeNetworkProcessCocoa):
+ * NetworkProcess/soup/NetworkProcessSoup.cpp:
+ (WebKit::NetworkProcess::platformInitializeNetworkProcess):
+ * Shared/Network/NetworkProcessCreationParameters.cpp:
+ (WebKit::NetworkProcessCreationParameters::encode):
+ (WebKit::NetworkProcessCreationParameters::decode):
+ * Shared/Network/NetworkProcessCreationParameters.h:
+ * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+ (WebKit::registerUserDefaultsIfNeeded):
+ (WebKit::WebProcessPool::platformInitializeNetworkProcess):
+ Add new NetworkProcess parameter to control at runtime if speculative loading
+ should be enabled or not. It is disabled by default.
+
+ * WebKit2.xcodeproj/project.pbxproj:
+ Add new files to XCode project.
+
+ * config.h:
+ Add ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION build flag for the new
+ feature that is enable by default on COCOA.
+
+2015-11-06 Chris Dumez <cdumez@apple.com>
+
</ins><span class="cx"> Unreviewed, remove empty #if block landed by mistake in r192038.
</span><span class="cx">
</span><span class="cx"> * NetworkProcess/NetworkLoad.cpp:
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcessNetworkResourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -128,7 +128,7 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> RefPtr<NetworkResourceLoader> loader(this);
</span><del>- NetworkCache::singleton().retrieve(originalRequest(), m_parameters.webPageID, [loader](std::unique_ptr<NetworkCache::Entry> entry) {
</del><ins>+ NetworkCache::singleton().retrieve(originalRequest(), m_parameters.webPageID, m_parameters.webFrameID, [loader](std::unique_ptr<NetworkCache::Entry> entry) {
</ins><span class="cx"> if (loader->hasOneRef()) {
</span><span class="cx"> // The loader has been aborted and is only held alive by this lambda.
</span><span class="cx"> return;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -29,6 +29,7 @@
</span><span class="cx"> #if ENABLE(NETWORK_CACHE)
</span><span class="cx">
</span><span class="cx"> #include "Logging.h"
</span><ins>+#include "NetworkCacheSpeculativeLoader.h"
</ins><span class="cx"> #include "NetworkCacheStatistics.h"
</span><span class="cx"> #include "NetworkCacheStorage.h"
</span><span class="cx"> #include <WebCore/CacheValidation.h>
</span><span class="lines">@@ -71,11 +72,16 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>-bool Cache::initialize(const String& cachePath, bool enableEfficacyLogging)
</del><ins>+bool Cache::initialize(const String& cachePath, const Parameters& parameters)
</ins><span class="cx"> {
</span><span class="cx"> m_storage = Storage::open(cachePath);
</span><span class="cx">
</span><del>- if (enableEfficacyLogging)
</del><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ if (parameters.enableNetworkCacheSpeculativeRevalidation)
+ m_speculativeLoader = std::make_unique<SpeculativeLoader>(*m_storage);
+#endif
+
+ if (parameters.enableEfficacyLogging)
</ins><span class="cx"> m_statistics = Statistics::open(cachePath);
</span><span class="cx">
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="lines">@@ -337,7 +343,7 @@
</span><span class="cx"> return StoreDecision::Yes;
</span><span class="cx"> }
</span><span class="cx">
</span><del>-void Cache::retrieve(const WebCore::ResourceRequest& originalRequest, uint64_t webPageID, std::function<void (std::unique_ptr<Entry>)> completionHandler)
</del><ins>+void Cache::retrieve(const WebCore::ResourceRequest& originalRequest, uint64_t webPageID, uint64_t webFrameID, std::function<void (std::unique_ptr<Entry>)> completionHandler)
</ins><span class="cx"> {
</span><span class="cx"> ASSERT(isEnabled());
</span><span class="cx"> ASSERT(originalRequest.url().protocolIsInHTTPFamily());
</span><span class="lines">@@ -348,6 +354,14 @@
</span><span class="cx"> m_statistics->recordRetrievalRequest(webPageID);
</span><span class="cx">
</span><span class="cx"> Key storageKey = makeCacheKey(originalRequest);
</span><ins>+
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ if (m_speculativeLoader)
+ m_speculativeLoader->registerLoad(webPageID, webFrameID, originalRequest, storageKey);
+#else
+ UNUSED_PARAM(webFrameID);
+#endif
+
</ins><span class="cx"> auto retrieveDecision = makeRetrieveDecision(originalRequest);
</span><span class="cx"> if (retrieveDecision != RetrieveDecision::Yes) {
</span><span class="cx"> if (m_statistics)
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCache.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -44,6 +44,7 @@
</span><span class="cx"> namespace NetworkCache {
</span><span class="cx">
</span><span class="cx"> class Cache;
</span><ins>+class SpeculativeLoader;
</ins><span class="cx"> class Statistics;
</span><span class="cx">
</span><span class="cx"> Cache& singleton();
</span><span class="lines">@@ -87,13 +88,19 @@
</span><span class="cx"> WTF_MAKE_NONCOPYABLE(Cache);
</span><span class="cx"> friend class WTF::NeverDestroyed<Cache>;
</span><span class="cx"> public:
</span><del>- bool initialize(const String& cachePath, bool enableEfficacyLogging);
</del><ins>+ struct Parameters {
+ bool enableEfficacyLogging;
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ bool enableNetworkCacheSpeculativeRevalidation;
+#endif
+ };
+ bool initialize(const String& cachePath, const Parameters&);
</ins><span class="cx"> void setCapacity(size_t);
</span><span class="cx">
</span><span class="cx"> bool isEnabled() const { return !!m_storage; }
</span><span class="cx">
</span><span class="cx"> // Completion handler may get called back synchronously on failure.
</span><del>- void retrieve(const WebCore::ResourceRequest&, uint64_t webPageID, std::function<void (std::unique_ptr<Entry>)>);
</del><ins>+ void retrieve(const WebCore::ResourceRequest&, uint64_t webPageID, uint64_t webFrameID, std::function<void (std::unique_ptr<Entry>)>);
</ins><span class="cx"> void store(const WebCore::ResourceRequest&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, std::function<void (MappedBody&)>);
</span><span class="cx"> void update(const WebCore::ResourceRequest&, uint64_t webPageID, const Entry&, const WebCore::ResourceResponse& validatingResponse);
</span><span class="cx">
</span><span class="lines">@@ -116,6 +123,9 @@
</span><span class="cx"> void deleteDumpFile();
</span><span class="cx">
</span><span class="cx"> std::unique_ptr<Storage> m_storage;
</span><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ std::unique_ptr<SpeculativeLoader> m_speculativeLoader;
+#endif
</ins><span class="cx"> std::unique_ptr<Statistics> m_statistics;
</span><span class="cx"> };
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheEntrycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -79,7 +79,7 @@
</span><span class="cx">
</span><span class="cx"> std::unique_ptr<Entry> Entry::decodeStorageRecord(const Storage::Record& storageEntry)
</span><span class="cx"> {
</span><del>- std::unique_ptr<Entry> entry(new Entry(storageEntry));
</del><ins>+ auto entry = std::make_unique<Entry>(storageEntry);
</ins><span class="cx">
</span><span class="cx"> Decoder decoder(storageEntry.header.data(), storageEntry.header.size());
</span><span class="cx"> if (!decoder.decode(entry->m_response))
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheEntryh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheEntry.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> WTF_MAKE_NONCOPYABLE(Entry); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="cx"> Entry(const Key&, const WebCore::ResourceResponse&, RefPtr<WebCore::SharedBuffer>&&, const Vector<std::pair<String, String>>& varyingRequestHeaders);
</span><ins>+ explicit Entry(const Storage::Record&);
</ins><span class="cx">
</span><span class="cx"> Storage::Record encodeAsStorageRecord() const;
</span><span class="cx"> static std::unique_ptr<Entry> decodeStorageRecord(const Storage::Record&);
</span><span class="lines">@@ -68,7 +69,6 @@
</span><span class="cx"> void asJSON(StringBuilder&, const Storage::RecordInfo&) const;
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- Entry(const Storage::Record&);
</del><span class="cx"> void initializeBufferFromStorageRecord() const;
</span><span class="cx"> #if ENABLE(SHAREABLE_RESOURCE)
</span><span class="cx"> void initializeShareableResourceHandleFromStorageRecord() const;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheKeycpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -54,6 +54,11 @@
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+Key::Key(WTF::HashTableDeletedValueType)
+ : m_identifier(WTF::HashTableDeletedValue)
+{
+}
+
</ins><span class="cx"> Key& Key::operator=(const Key& other)
</span><span class="cx"> {
</span><span class="cx"> m_partition = other.m_partition.isolatedCopy();
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheKeyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheKey.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -49,11 +49,15 @@
</span><span class="cx"> Key& operator=(const Key&);
</span><span class="cx"> Key& operator=(Key&&) = default;
</span><span class="cx">
</span><ins>+ Key(WTF::HashTableDeletedValueType);
+ bool isHashTableDeletedValue() const { return m_identifier.isHashTableDeletedValue(); }
+
</ins><span class="cx"> bool isNull() const { return m_identifier.isNull(); }
</span><span class="cx">
</span><span class="cx"> const String& partition() const { return m_partition; }
</span><span class="cx"> const String& identifier() const { return m_identifier; }
</span><span class="cx"> const String& type() const { return m_type; }
</span><ins>+ const String& range() const { return m_range; }
</ins><span class="cx">
</span><span class="cx"> HashType hash() const { return m_hash; }
</span><span class="cx">
</span><span class="lines">@@ -81,5 +85,36 @@
</span><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+namespace WTF {
+
+struct NetworkCacheKeyHash {
+ static unsigned hash(const WebKit::NetworkCache::Key& key)
+ {
+ static_assert(SHA1::hashSize >= sizeof(unsigned), "Hash size must be greater than sizeof(unsigned)");
+ return *reinterpret_cast<const unsigned*>(key.hash().data());
+ }
+
+ static bool equal(const WebKit::NetworkCache::Key& a, const WebKit::NetworkCache::Key& b)
+ {
+ return a == b;
+ }
+
+ static const bool safeToCompareToEmptyOrDeleted = false;
+};
+
+template<typename T> struct DefaultHash;
+template<> struct DefaultHash<WebKit::NetworkCache::Key> {
+ typedef NetworkCacheKeyHash Hash;
+};
+
+template<> struct HashTraits<WebKit::NetworkCache::Key> : SimpleClassHashTraits<WebKit::NetworkCache::Key> {
+ static const bool emptyValueIsZero = false;
+
+ static const bool hasIsEmptyValueFunction = true;
+ static bool isEmptyValue(const WebKit::NetworkCache::Key& key) { return key.isNull(); }
+};
+
+} // namespace WTF
+
</ins><span class="cx"> #endif
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoadercpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.cpp (0 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.cpp         (rev 0)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -0,0 +1,145 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+#include "NetworkCacheSpeculativeLoader.h"
+
+#include "Logging.h"
+#include "NetworkCacheSubresourcesEntry.h"
+#include <WebCore/HysteresisActivity.h>
+#include <wtf/NeverDestroyed.h>
+#include <wtf/RunLoop.h>
+
+namespace WebKit {
+
+namespace NetworkCache {
+
+using namespace WebCore;
+
+static const AtomicString& subresourcesType()
+{
+ ASSERT(RunLoop::isMain());
+ static NeverDestroyed<const AtomicString> resource("subresources", AtomicString::ConstructFromLiteral);
+ return resource;
+}
+
+static inline Key makeSubresourcesKey(const Key& resourceKey)
+{
+ return Key(resourceKey.partition(), subresourcesType(), resourceKey.range(), resourceKey.identifier());
+}
+
+class SpeculativeLoader::PendingFrameLoad {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ PendingFrameLoad(const Key& mainResourceKey, std::function<void()> completionHandler)
+ : m_mainResourceKey(mainResourceKey)
+ , m_completionHandler(completionHandler)
+ , m_loadHysteresisActivity([this](HysteresisState state) { if (state == HysteresisState::Stopped) m_completionHandler(); })
+ { }
+
+ void registerSubresource(const Key& subresourceKey)
+ {
+ ASSERT(RunLoop::isMain());
+ m_subresourceKeys.add(subresourceKey);
+ m_loadHysteresisActivity.impulse();
+ }
+
+ Optional<Storage::Record> encodeAsSubresourcesRecord()
+ {
+ ASSERT(RunLoop::isMain());
+ if (m_subresourceKeys.isEmpty())
+ return { };
+
+ auto subresourcesStorageKey = makeSubresourcesKey(m_mainResourceKey);
+ Vector<Key> subresourceKeys;
+ copyToVector(m_subresourceKeys, subresourceKeys);
+
+#if !LOG_DISABLED
+ LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) Saving to disk list of subresources for '%s':", m_mainResourceKey.identifier().utf8().data());
+ for (auto& subresourceKey : subresourceKeys)
+ LOG(NetworkCacheSpeculativePreloading, "(NetworkProcess) * Subresource: '%s'.", subresourceKey.identifier().utf8().data());
+#endif
+
+ return SubresourcesEntry(subresourcesStorageKey, WTF::move(subresourceKeys)).encodeAsStorageRecord();
+ }
+
+ void markAsCompleted()
+ {
+ ASSERT(RunLoop::isMain());
+ m_completionHandler();
+ }
+
+private:
+ Key m_mainResourceKey;
+ HashSet<Key> m_subresourceKeys;
+ std::function<void()> m_completionHandler;
+ HysteresisActivity m_loadHysteresisActivity;
+};
+
+SpeculativeLoader::SpeculativeLoader(Storage& storage)
+ : m_storage(storage)
+{
+}
+
+SpeculativeLoader::~SpeculativeLoader()
+{
+}
+
+void SpeculativeLoader::registerLoad(uint64_t webPageID, uint64_t webFrameID, const ResourceRequest& request, const Key& resourceKey)
+{
+ ASSERT(RunLoop::isMain());
+
+ if (!request.url().protocolIsInHTTPFamily() || request.httpMethod() != "GET")
+ return;
+
+ auto frameKey = std::make_pair(webPageID, webFrameID);
+ auto isMainResource = request.requester() == ResourceRequest::Requester::Main;
+ if (isMainResource) {
+ // Mark previous load in this frame as completed if necessary.
+ if (auto* pendingFrameLoad = m_pendingFrameLoads.get(frameKey))
+ pendingFrameLoad->markAsCompleted();
+
+ // Start tracking loads in this frame.
+ m_pendingFrameLoads.add(frameKey, std::make_unique<PendingFrameLoad>(resourceKey, [this, frameKey]() {
+ auto frameLoad = m_pendingFrameLoads.take(frameKey);
+ auto optionalRecord = frameLoad->encodeAsSubresourcesRecord();
+ if (!optionalRecord)
+ return;
+ m_storage.store(optionalRecord.value(), [](const Data&) { });
+ }));
+ return;
+ }
+
+ if (auto* pendingFrameLoad = m_pendingFrameLoads.get(frameKey))
+ pendingFrameLoad->registerSubresource(resourceKey);
+}
+
+} // namespace NetworkCache
+
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSpeculativeLoaderhfromrev192110trunkSourceWebKit2PlatformLoggingh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.h (from rev 192110, trunk/Source/WebKit2/Platform/Logging.h) (0 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.h         (rev 0)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSpeculativeLoader.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NetworkCacheSpeculativeLoader_h
+#define NetworkCacheSpeculativeLoader_h
+
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+
+#include "NetworkCacheStorage.h"
+#include <WebCore/ResourceRequest.h>
+#include <wtf/HashMap.h>
+
+namespace WebKit {
+
+namespace NetworkCache {
+
+class SpeculativeLoader {
+public:
+ explicit SpeculativeLoader(Storage&);
+ ~SpeculativeLoader();
+
+ void registerLoad(uint64_t webPageID, uint64_t webFrameID, const WebCore::ResourceRequest&, const Key& resourceKey);
+
+private:
+ Storage& m_storage;
+
+ class PendingFrameLoad;
+ using GlobalFrameID = std::pair<uint64_t /*webPageID*/, uint64_t /*webFrameID*/>;
+ HashMap<GlobalFrameID, std::unique_ptr<PendingFrameLoad>> m_pendingFrameLoads;
+};
+
+} // namespace NetworkCache
+
+} // namespace WebKit
+
+#endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+
+#endif // NetworkCacheSpeculativeLoader_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntrycpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp (0 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp         (rev 0)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -0,0 +1,83 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+#include "NetworkCacheSubresourcesEntry.h"
+
+#include "Logging.h"
+#include "NetworkCacheCoders.h"
+#include "NetworkCacheDecoder.h"
+#include "NetworkCacheEncoder.h"
+
+namespace WebKit {
+namespace NetworkCache {
+
+Storage::Record SubresourcesEntry::encodeAsStorageRecord() const
+{
+ Encoder encoder;
+ encoder << m_subresourceKeys;
+
+ encoder.encodeChecksum();
+
+ return { m_key, m_timeStamp, { encoder.buffer(), encoder.bufferSize() } , { } };
+}
+
+std::unique_ptr<SubresourcesEntry> SubresourcesEntry::decodeStorageRecord(const Storage::Record& storageEntry)
+{
+ auto entry = std::make_unique<SubresourcesEntry>(storageEntry);
+
+ Decoder decoder(storageEntry.header.data(), storageEntry.header.size());
+ if (!decoder.decode(entry->m_subresourceKeys))
+ return nullptr;
+
+ if (!decoder.verifyChecksum()) {
+ LOG(NetworkCache, "(NetworkProcess) checksum verification failure\n");
+ return nullptr;
+ }
+
+ return entry;
+}
+
+SubresourcesEntry::SubresourcesEntry(const Storage::Record& storageEntry)
+ : m_key(storageEntry.key)
+ , m_timeStamp(storageEntry.timeStamp)
+{
+ ASSERT(m_key.type() == "subresources");
+}
+
+SubresourcesEntry::SubresourcesEntry(const Key& key, Vector<Key>&& subresourceKeys)
+ : m_key(key)
+ , m_timeStamp(std::chrono::system_clock::now())
+ , m_subresourceKeys(WTF::move(subresourceKeys))
+{
+ ASSERT(m_key.type() == "subresources");
+}
+
+} // namespace WebKit
+} // namespace NetworkCache
+
+#endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscacheNetworkCacheSubresourcesEntryhfromrev192110trunkSourceWebKit2PlatformLoggingh"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h (from rev 192110, trunk/Source/WebKit2/Platform/Logging.h) (0 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h         (rev 0)
+++ trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheSubresourcesEntry.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -0,0 +1,60 @@
</span><ins>+/*
+ * Copyright (C) 2015 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef NetworkCacheSubresourcesEntry_h
+#define NetworkCacheSubresourcesEntry_h
+
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+
+#include "NetworkCacheStorage.h"
+
+namespace WebKit {
+namespace NetworkCache {
+
+class SubresourcesEntry {
+ WTF_MAKE_NONCOPYABLE(SubresourcesEntry); WTF_MAKE_FAST_ALLOCATED;
+public:
+ SubresourcesEntry(const Key&, Vector<Key>&& subresourceKeys);
+ explicit SubresourcesEntry(const Storage::Record&);
+
+ Storage::Record encodeAsStorageRecord() const;
+ static std::unique_ptr<SubresourcesEntry> decodeStorageRecord(const Storage::Record&);
+
+ const Key& key() const { return m_key; }
+ std::chrono::system_clock::time_point timeStamp() const { return m_timeStamp; }
+ const Vector<Key>& subresourceKeys() const { return m_subresourceKeys; }
+
+private:
+ Key m_key;
+ std::chrono::system_clock::time_point m_timeStamp;
+ Storage::Record m_sourceStorageRecord;
+ Vector<Key> m_subresourceKeys;
+};
+
+} // namespace WebKit
+} // namespace NetworkCache
+
+#endif // ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+#endif // NetworkCacheSubresourcesEntry_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesscocoaNetworkProcessCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkProcessCocoa.mm (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkProcessCocoa.mm        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/cocoa/NetworkProcessCocoa.mm        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -95,10 +95,18 @@
</span><span class="cx"> if (!m_diskCacheDirectory.isNull()) {
</span><span class="cx"> SandboxExtension::consumePermanently(parameters.diskCacheDirectoryExtensionHandle);
</span><span class="cx"> #if ENABLE(NETWORK_CACHE)
</span><del>- if (parameters.shouldEnableNetworkCache && NetworkCache::singleton().initialize(m_diskCacheDirectory, parameters.shouldEnableNetworkCacheEfficacyLogging)) {
- RetainPtr<NSURLCache> urlCache(adoptNS([[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]));
- [NSURLCache setSharedURLCache:urlCache.get()];
- return;
</del><ins>+ if (parameters.shouldEnableNetworkCache) {
+ NetworkCache::Cache::Parameters cacheParameters = {
+ parameters.shouldEnableNetworkCacheEfficacyLogging
+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ , parameters.shouldEnableNetworkCacheSpeculativeRevalidation
+#endif
+ };
+ if (NetworkCache::singleton().initialize(m_diskCacheDirectory, cacheParameters)) {
+ auto urlCache(adoptNS([[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil]));
+ [NSURLCache setSharedURLCache:urlCache.get()];
+ return;
+ }
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> String nsURLCacheDirectory = m_diskCacheDirectory;
</span></span></pre></div>
<a id="trunkSourceWebKit2NetworkProcesssoupNetworkProcessSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/NetworkProcess/soup/NetworkProcessSoup.cpp (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/NetworkProcess/soup/NetworkProcessSoup.cpp        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/NetworkProcess/soup/NetworkProcessSoup.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -74,7 +74,7 @@
</span><span class="cx"> // Clear the old soup cache if it exists.
</span><span class="cx"> SoupNetworkSession::defaultSession().clearCache(WebCore::directoryName(m_diskCacheDirectory));
</span><span class="cx">
</span><del>- NetworkCache::singleton().initialize(m_diskCacheDirectory, parameters.shouldEnableNetworkCacheEfficacyLogging);
</del><ins>+ NetworkCache::singleton().initialize(m_diskCacheDirectory, { parameters.shouldEnableNetworkCacheEfficacyLogging });
</ins><span class="cx"> #else
</span><span class="cx"> // We used to use the given cache directory for the soup cache, but now we use a subdirectory to avoid
</span><span class="cx"> // conflicts with other cache files in the same directory. Remove the old cache files if they still exist.
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformLoggingh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Platform/Logging.h (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/Logging.h        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/Platform/Logging.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> M(Network) \
</span><span class="cx"> M(NetworkCache) \
</span><span class="cx"> M(NetworkCacheStorage) \
</span><ins>+ M(NetworkCacheSpeculativePreloading) \
</ins><span class="cx"> M(NetworkScheduling) \
</span><span class="cx"> M(Plugins) \
</span><span class="cx"> M(Printing) \
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedNetworkNetworkProcessCreationParameterscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.cpp (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.cpp        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.cpp        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -51,7 +51,10 @@
</span><span class="cx"> #if ENABLE(NETWORK_CACHE)
</span><span class="cx"> encoder << shouldEnableNetworkCache;
</span><span class="cx"> encoder << shouldEnableNetworkCacheEfficacyLogging;
</span><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ encoder << shouldEnableNetworkCacheSpeculativeRevalidation;
</ins><span class="cx"> #endif
</span><ins>+#endif
</ins><span class="cx"> #if ENABLE(SECCOMP_FILTERS)
</span><span class="cx"> encoder << cookieStorageDirectory;
</span><span class="cx"> #endif
</span><span class="lines">@@ -104,7 +107,11 @@
</span><span class="cx"> return false;
</span><span class="cx"> if (!decoder.decode(result.shouldEnableNetworkCacheEfficacyLogging))
</span><span class="cx"> return false;
</span><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ if (!decoder.decode(result.shouldEnableNetworkCacheSpeculativeRevalidation))
+ return false;
</ins><span class="cx"> #endif
</span><ins>+#endif
</ins><span class="cx"> #if ENABLE(SECCOMP_FILTERS)
</span><span class="cx"> if (!decoder.decode(result.cookieStorageDirectory))
</span><span class="cx"> return false;
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedNetworkNetworkProcessCreationParametersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.h (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.h        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/Shared/Network/NetworkProcessCreationParameters.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -60,7 +60,10 @@
</span><span class="cx"> #if ENABLE(NETWORK_CACHE)
</span><span class="cx"> bool shouldEnableNetworkCache;
</span><span class="cx"> bool shouldEnableNetworkCacheEfficacyLogging;
</span><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ bool shouldEnableNetworkCacheSpeculativeRevalidation;
</ins><span class="cx"> #endif
</span><ins>+#endif
</ins><span class="cx"> #if ENABLE(SECCOMP_FILTERS)
</span><span class="cx"> String cookieStorageDirectory;
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessCocoaWebProcessPoolCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/WebProcessPoolCocoa.mm        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -84,7 +84,10 @@
</span><span class="cx"> #if ENABLE(NETWORK_CACHE)
</span><span class="cx"> static NSString * const WebKitNetworkCacheEnabledDefaultsKey = @"WebKitNetworkCacheEnabled";
</span><span class="cx"> static NSString * const WebKitNetworkCacheEfficacyLoggingEnabledDefaultsKey = @"WebKitNetworkCacheEfficacyLoggingEnabled";
</span><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+static NSString * const WebKitNetworkCacheSpeculativeRevalidationEnabledDefaultsKey = @"WebKitNetworkCacheResourceRevalidationEnabled";
</ins><span class="cx"> #endif
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> namespace WebKit {
</span><span class="cx">
</span><span class="lines">@@ -106,7 +109,10 @@
</span><span class="cx"> #if ENABLE(NETWORK_CACHE)
</span><span class="cx"> [registrationDictionary setObject:[NSNumber numberWithBool:YES] forKey:WebKitNetworkCacheEnabledDefaultsKey];
</span><span class="cx"> [registrationDictionary setObject:[NSNumber numberWithBool:NO] forKey:WebKitNetworkCacheEfficacyLoggingEnabledDefaultsKey];
</span><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ [registrationDictionary setObject:[NSNumber numberWithBool:NO] forKey:WebKitNetworkCacheSpeculativeRevalidationEnabledDefaultsKey];
</ins><span class="cx"> #endif
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> [[NSUserDefaults standardUserDefaults] registerDefaults:registrationDictionary];
</span><span class="cx"> }
</span><span class="lines">@@ -254,7 +260,10 @@
</span><span class="cx"> #if ENABLE(NETWORK_CACHE)
</span><span class="cx"> parameters.shouldEnableNetworkCache = isNetworkCacheEnabled();
</span><span class="cx"> parameters.shouldEnableNetworkCacheEfficacyLogging = [defaults boolForKey:WebKitNetworkCacheEfficacyLoggingEnabledDefaultsKey];
</span><ins>+#if ENABLE(NETWORK_CACHE_SPECULATIVE_REVALIDATION)
+ parameters.shouldEnableNetworkCacheSpeculativeRevalidation = [defaults boolForKey:WebKitNetworkCacheSpeculativeRevalidationEnabledDefaultsKey];
</ins><span class="cx"> #endif
</span><ins>+#endif
</ins><span class="cx">
</span><span class="cx"> #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
</span><span class="cx"> RetainPtr<CFDataRef> cookieStorageData = adoptCF(CFHTTPCookieStorageCreateIdentifyingData(kCFAllocatorDefault, [[NSHTTPCookieStorage sharedHTTPCookieStorage] _cookieStorage]));
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -1176,6 +1176,10 @@
</span><span class="cx">                 7CF47FFF17276AE3008ACB91 /* WKBundlePageBannerMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CF47FFD17276AE3008ACB91 /* WKBundlePageBannerMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7EC4F0FB18E4ACBB008056AF /* NetworkProcessCocoa.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7EC4F0F918E4A945008056AF /* NetworkProcessCocoa.mm */; };
</span><span class="cx">                 83048AE61ACA45DC0082C832 /* ProcessThrottlerClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83048AE51ACA45DC0082C832 /* ProcessThrottlerClient.h */; };
</span><ins>+                8310428B1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h in Headers */ = {isa = PBXBuildFile; fileRef = 831042891BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h */; };
+                8310428C1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */; };
+                832AE2521BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.h */; };
+                832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.cpp */; };
</ins><span class="cx">                 834B250F1A831A8D00CFB150 /* NetworkCacheFileSystem.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */; };
</span><span class="cx">                 834B25121A842C8700CFB150 /* NetworkCacheStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */; };
</span><span class="cx">                 8360349F1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8360349D1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp */; };
</span><span class="lines">@@ -3410,6 +3414,10 @@
</span><span class="cx">                 7CF47FFD17276AE3008ACB91 /* WKBundlePageBannerMac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKBundlePageBannerMac.h; sourceTree = "<group>"; };
</span><span class="cx">                 7EC4F0F918E4A945008056AF /* NetworkProcessCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = NetworkProcessCocoa.mm; path = NetworkProcess/cocoa/NetworkProcessCocoa.mm; sourceTree = "<group>"; };
</span><span class="cx">                 83048AE51ACA45DC0082C832 /* ProcessThrottlerClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessThrottlerClient.h; sourceTree = "<group>"; };
</span><ins>+                831042891BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSubresourcesEntry.h; sourceTree = "<group>"; };
+                8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSubresourcesEntry.cpp; sourceTree = "<group>"; };
+                832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoader.h; sourceTree = "<group>"; };
+                832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoader.cpp; sourceTree = "<group>"; };
</ins><span class="cx">                 834B250E1A831A8D00CFB150 /* NetworkCacheFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheFileSystem.h; sourceTree = "<group>"; };
</span><span class="cx">                 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheStatistics.h; sourceTree = "<group>"; };
</span><span class="cx">                 8360349D1ACB34D600626549 /* WebSQLiteDatabaseTracker.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSQLiteDatabaseTracker.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -7573,10 +7581,14 @@
</span><span class="cx">                                 E42E060D1AA750E500B11699 /* NetworkCacheIOChannelCocoa.mm */,
</span><span class="cx">                                 E4436EC01A0CFDB200EAD204 /* NetworkCacheKey.cpp */,
</span><span class="cx">                                 E4436EC11A0CFDB200EAD204 /* NetworkCacheKey.h */,
</span><ins>+                                832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.cpp */,
+                                832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.h */,
</ins><span class="cx">                                 83BDCCB81AC5FDB6003F6441 /* NetworkCacheStatistics.cpp */,
</span><span class="cx">                                 834B25101A842C8700CFB150 /* NetworkCacheStatistics.h */,
</span><span class="cx">                                 E4436EC31A0CFDB200EAD204 /* NetworkCacheStorage.cpp */,
</span><span class="cx">                                 E4436EC21A0CFDB200EAD204 /* NetworkCacheStorage.h */,
</span><ins>+                                8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */,
+                                831042891BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h */,
</ins><span class="cx">                         );
</span><span class="cx">                         name = cache;
</span><span class="cx">                         path = NetworkProcess/cache;
</span><span class="lines">@@ -7714,6 +7726,7 @@
</span><span class="cx">                                 75A8D2E1187DEC1A00C39C9E /* APISession.h in Headers */,
</span><span class="cx">                                 1AFDE6621954E9B100C48FFA /* APISessionState.h in Headers */,
</span><span class="cx">                                 1A4D664818A2D91A00D82E21 /* APIUIClient.h in Headers */,
</span><ins>+                                832AE2521BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.h in Headers */,
</ins><span class="cx">                                 BCDB86C11200FB97007254BE /* APIURL.h in Headers */,
</span><span class="cx">                                 BCE2315D122C30CA00D5C35A /* APIURLRequest.h in Headers */,
</span><span class="cx">                                 BC90A1D2122DD55E00CC8C50 /* APIURLResponse.h in Headers */,
</span><span class="lines">@@ -8315,6 +8328,7 @@
</span><span class="cx">                                 293EBEAB1627D9C9005F89F1 /* WKDOMText.h in Headers */,
</span><span class="cx">                                 BC017D2116263308007054F5 /* WKDOMTextIterator.h in Headers */,
</span><span class="cx">                                 1AB7D78D1288CD9A00CFD08C /* WKDownload.h in Headers */,
</span><ins>+                                8310428B1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h in Headers */,
</ins><span class="cx">                                 1AF4592F19464B2000F9D4A2 /* WKError.h in Headers */,
</span><span class="cx">                                 BCFD548C132D82680055D816 /* WKErrorCF.h in Headers */,
</span><span class="cx">                                 37B5045219EEF31300CE2CF8 /* WKErrorPrivate.h in Headers */,
</span><span class="lines">@@ -9525,6 +9539,7 @@
</span><span class="cx">                                 7C89D2971A6753B2003A5FDE /* APIPageConfiguration.cpp in Sources */,
</span><span class="cx">                                 1A3A73CF1A48C7F1007231B3 /* APIPageGroupHandle.cpp in Sources */,
</span><span class="cx">                                 1AC1336E18565D2B00F3EC05 /* APIPageHandle.cpp in Sources */,
</span><ins>+                                832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoader.cpp in Sources */,
</ins><span class="cx">                                 7CE4D21F1A4914CA00C7F152 /* APIProcessPoolConfiguration.cpp in Sources */,
</span><span class="cx">                                 FED3C1DC1B447EAC00E0EB7F /* APISerializedScriptValueCocoa.mm in Sources */,
</span><span class="cx">                                 A182D5B41BE6BD250087A7CC /* AccessibilityIOS.mm in Sources */,
</span><span class="lines">@@ -9759,6 +9774,7 @@
</span><span class="cx">                                 1A8EF4CC1252403700F7067F /* PluginControllerProxy.cpp in Sources */,
</span><span class="cx">                                 1A2D91A61281D739001EB962 /* PluginControllerProxyMac.mm in Sources */,
</span><span class="cx">                                 1A8EF96E1252AF6B00F7067F /* PluginControllerProxyMessageReceiver.cpp in Sources */,
</span><ins>+                                8310428C1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp in Sources */,
</ins><span class="cx">                                 1A17977F137EE82C00F97D45 /* PluginCreationParameters.cpp in Sources */,
</span><span class="cx">                                 7C3F8C90173AF52D007B7F39 /* PluginInformation.cpp in Sources */,
</span><span class="cx">                                 7C135AAC173B0CFF00586AE2 /* PluginInformationMac.mm in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2configh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/config.h (192110 => 192111)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/config.h        2015-11-06 19:18:31 UTC (rev 192110)
+++ trunk/Source/WebKit2/config.h        2015-11-06 19:29:24 UTC (rev 192111)
</span><span class="lines">@@ -98,6 +98,14 @@
</span><span class="cx"> #endif
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+#ifndef ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION
+#if ENABLE(NETWORK_CACHE) && PLATFORM(COCOA)
+#define ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION 1
+#else
+#define ENABLE_NETWORK_CACHE_SPECULATIVE_REVALIDATION 0
+#endif
+#endif
+
</ins><span class="cx"> #ifndef HAVE_SAFARI_SERVICES_FRAMEWORK
</span><span class="cx"> #if PLATFORM(IOS) && (!defined TARGET_OS_IOS || TARGET_OS_IOS)
</span><span class="cx"> #define HAVE_SAFARI_SERVICES_FRAMEWORK 1
</span></span></pre>
</div>
</div>
</body>
</html>