<!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>[197592] trunk</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/197592">197592</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2016-03-04 15:29:31 -0800 (Fri, 04 Mar 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>[WK2] Gather resource load statistics
https://bugs.webkit.org/show_bug.cgi?id=154278
&lt;rdar://problem/24702892&gt;

Reviewed by Andy Estes.

Source/WebCore:

Tested (now under WK2) by http/tests/navigation/statistics.html

Split part of the ResourceLoadObserver into a new class (ResourceLoadStatisticsStore)
that manages the collection of ResourceLoadStatistic objects, and that can be used
in the UIProcess without touching various WebProcess-specific WebCore classes.

Have the WebProcess only fire a message to the UIProcess if data has been modified. Otherwise,
no messages should be sent. When new data is encountered, start a 5 second timer. If more
data is found during this delay, just accumulate it. When the timer fires, all data is sent
and the timer stops until a new batch of data arrives.

* CMakeLists.txt: Add the new ResourceLoadStatisticsStore class.
* WebCore.xcodeproj/project.pbxproj: Adjust visibility of ResourceLoadStatistics header,
and add new ResourceLoadStatisticsStore class.
* loader/ResourceLoadObserver.cpp:
(WebCore::ResourceLoadObserver::setResourceLoadStatisticsEnabled): Deleted.
(WebCore::ResourceLoadObserver::resourceLoadStatisticsEnabled): Deleted.
(WebCore::ResourceLoadObserver::setStatisticsStore): Added.
(WebCore::ResourceLoadObserver::logFrameNavigation): Tell the ResourceLoadStatisticsStore to fire its 'data changed'
handler if necessary.
(WebCore::ResourceLoadObserver::logSubresourceLoading): Ditto.
(WebCore::ResourceLoadObserver::logUserInteraction): Ditto.
(WebCore::ResourceLoadObserver::statisticsForOrigin): Use new ResourceLoadStatisticsStore.
(WebCore::ResourceLoadObserver::isPrevalentResource): Deleted.
(WebCore::ResourceLoadObserver::resourceStatisticsForPrimaryDomain): Deleted.
(WebCore::ResourceLoadObserver::writeDataToDisk): Deleted.
(WebCore::ResourceLoadObserver::setStatisticsStorageDirectory): Deleted.
(WebCore::ResourceLoadObserver::persistentStoragePath): Deleted.
(WebCore::ResourceLoadObserver::readDataFromDiskIfNeeded): Deleted.
(WebCore::ResourceLoadObserver::createDecoderFromDisk): Deleted.
(WebCore::ResourceLoadObserver::writeEncoderToDisk): Deleted.
* loader/ResourceLoadObserver.h:
* loader/ResourceLoadStatistics.cpp:
(WebCore::ResourceLoadStatistics::encode): Get rid of unneeded argument.
(WebCore::ResourceLoadStatistics::decode): Ditto.
(WebCore::mergeHashCountedSet): Added helper function.
(WebCore::ResourceLoadStatistics::merge): Added.
* loader/ResourceLoadStatistics.h:
(WebCore::ResourceLoadStatistics::ResourceLoadStatistics):
* loader/ResourceLoadStatisticsStore.cpp: Added.
(WebCore::ResourceLoadStatisticsStore::create):
(WebCore::ResourceLoadStatisticsStore::ResourceLoadStatisticsStore):
(WebCore::ResourceLoadStatisticsStore::isPrevalentResource):
(WebCore::ResourceLoadStatisticsStore::resourceStatisticsForPrimaryDomain):
(WebCore::ResourceLoadStatisticsStore::writeDataToDisk):
(WebCore::ResourceLoadStatisticsStore::setStatisticsStorageDirectory):
(WebCore::ResourceLoadStatisticsStore::persistentStoragePath):
(WebCore::ResourceLoadStatisticsStore::readDataFromDiskIfNeeded):
(WebCore::ResourceLoadStatisticsStore::createDecoderFromDisk):
(WebCore::ResourceLoadStatisticsStore::writeEncoderToDisk):
(WebCore::ResourceLoadStatisticsStore::statisticsForOrigin):
(WebCore::ResourceLoadStatisticsStore::takeStatistics):
(WebCore::ResourceLoadStatisticsStore::mergeStatistics):
(WebCore::ResourceLoadStatisticsStore::setNotificationCallback):
(WebCore::ResourceLoadStatisticsStore::fireDataModificationHandler):
* loader/ResourceLoadStatisticsStore.h: Added.

Source/WebKit/mac:

Switch to maintaining a global WebCore::ResourceLoadStatisticsStore in the WebKit process,
and hand it off to the WebCore layer to use during data gathering. The ResourceLoadStatisticsStore
is now responsible for reading/writing to disk, and tracking the collection of load data.

* WebView/WebView.mm:
(WebKitInitializeApplicationStatisticsStoragePathIfNecessary): Initialize singleton
ResourceLoadStatisticsStore object for tracking state.
(-[WebView _preferencesChanged:]): Revise for new singleton.
(+[WebView _applicationWillTerminate]): Ditto.

Source/WebKit2:

Revise the WebProcess to notify the UIProcess about resource load statistics. These
updates are not time-critical, and do not need to be done in concert with the actual
load. As resource loads are made, each WebProcess notifies the UIProcess of the new
load counts, then clears its local state. These statistics are then aggregated in
the UIProcess.

* CMakeLists.txt: Add new ResourceLoadStatisticsState files to build.
* DerivedSources.make: Ditto.
* Platform/IPC/ArgumentCoders.h: Update to support HashCountedSets.
* PlatformEfl.cmake: Add new ResourceLoadStatisticsState files to build.
* PlatformGTK.cmake: Ditto.
* PlatformMac.cmake: Ditto.
* Shared/API/APIObject.h: Add new ResourceLoadStatistics type.
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder&lt;ExceptionDetails&gt;::decode): Support new ResourceLoadStatistics type.
(IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::encode): Added.
(IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::decode): Added.
* Shared/WebCoreArgumentCoders.h:
* Shared/WebProcessCreationParameters.cpp:
(WebKit::WebProcessCreationParameters::encode): Handle 'resourceLoadStatisticsEnabled' flag.
(WebKit::WebProcessCreationParameters::decode): Ditto.
* Shared/WebProcessCreationParameters.h:
* UIProcess/API/APIProcessPoolConfiguration.cpp:
(API::ProcessPoolConfiguration::ProcessPoolConfiguration): Add storage location for the
resource load statistics.
(API::ProcessPoolConfiguration::copy): Handle the new storage location and the feature flag.
* UIProcess/API/APIProcessPoolConfiguration.h:
* UIProcess/API/APIWebsiteDataStore.cpp:
(API::WebsiteDataStore::defaultResourceLoadStatisticsDirectory): Added stub.
* UIProcess/API/APIWebsiteDataStore.h:
* UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm:
(API::WebsiteDataStore::defaultResourceLoadStatisticsDirectory): Added.
(API::WebsiteDataStore::defaultDataStoreConfiguration): Added support for the new resource
load statistics storage location.
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _initializeWithConfiguration:]): Sync Process Pool configuration parameters
with the state of our websiteData object's &quot;ResourceLoadStatisticsEnabled&quot; flag, so that
new processes are created in the right state.
* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(-[WKWebsiteDataStore _resourceLoadStatisticsEnabled]): Added.
(-[WKWebsiteDataStore _setResourceLoadStatisticsEnabled:]): Added.
* UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::createNewWebProcess): Handle new flag for enabling resource
load statistics.
* UIProcess/WebResourceLoadStatisticsStore.cpp: Added.
(WebKit::WebResourceLoadStatisticsStore::create):
(WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
(WebKit::WebResourceLoadStatisticsStore::~WebResourceLoadStatisticsStore):
(WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):
(WebKit::WebResourceLoadStatisticsStore::setResourceLoadStatisticsEnabled):
(WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsEnabled):
(WebKit::WebResourceLoadStatisticsStore::readDataFromDiskIfNeeded):
(WebKit::WebResourceLoadStatisticsStore::writeToDisk):
(WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate):
* UIProcess/WebResourceLoadStatisticsStore.h: Added.
(WebKit::WebResourceLoadStatisticsStore::coreStore):
* UIProcess/WebResourceLoadStatisticsStore.messages.in: Added.
* UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
(WebKit::WebsiteDataStore::platformInitialize): Register a termination handler
to close down the resource load statistics store.
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::WebsiteDataStore): Initialize the new WebResourceLoadStatisticsStore
member.
(WebKit::WebsiteDataStore::webProcessWillOpenConnection): Register the WebResourceLoadStatisticsStore
object as a work queue message receiver
(WebKit::WebsiteDataStore::webProcessDidCloseConnection): Unregister WebResourceLoadStatisticsStore.
(WebKit::WebsiteDataStore::resourceLoadStatisticsEnabled): Added.
(WebKit::WebsiteDataStore::setResourceLoadStatisticsEnabled): Ditto.
* UIProcess/WebsiteData/WebsiteDataStore.h:
(WebKit::WebsiteDataStore::resourceLoadStatisticsStore): Added.
* WebKit2.xcodeproj/project.pbxproj: Add new ResourceLoadStatisticsState files to build.
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::initializeWebProcess): Take into account the new parameter
specifying whether resource load statistics are being captured.
(WebKit::WebProcess::WebProcess): Initialized statistics changed notification timer.
(WebKit::WebProcess::statisticsChangedTimerFired): Added. Send bundles of site load
statistics to the UIProcess on a set interval. Clear out local cache after each send.
(WebKit::WebProcess::setResourceLoadStatisticsEnabled): Added.
* WebProcess/WebProcess.h:
* WebProcess/WebProcess.messages.in: Add new SetResourceLoadStatisticsEnabled message.

Tools:

* MiniBrowser/mac/AppDelegate.m:
(defaultConfiguration): Retrieve state of the ResourceLoadStatisticsEnabled setting.
* MiniBrowser/mac/SettingsController.m:
(-[SettingsController _populateMenu]): Move setting from WK1-only to be
universally applicable.
* MiniBrowser/mac/WK2BrowserWindowController.m:
(-[WK2BrowserWindowController didChangeSettings]): Recognize when the
Resource Load Statistics flag has changed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreCMakeListstxt">trunk/Source/WebCore/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadObservercpp">trunk/Source/WebCore/loader/ResourceLoadObserver.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadObserverh">trunk/Source/WebCore/loader/ResourceLoadObserver.h</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticscpp">trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticsh">trunk/Source/WebCore/loader/ResourceLoadStatistics.h</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacWebViewWebViewmm">trunk/Source/WebKit/mac/WebView/WebView.mm</a></li>
<li><a href="#trunkSourceWebKit2CMakeListstxt">trunk/Source/WebKit2/CMakeLists.txt</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2DerivedSourcesmake">trunk/Source/WebKit2/DerivedSources.make</a></li>
<li><a href="#trunkSourceWebKit2PlatformIPCArgumentCodersh">trunk/Source/WebKit2/Platform/IPC/ArgumentCoders.h</a></li>
<li><a href="#trunkSourceWebKit2PlatformEflcmake">trunk/Source/WebKit2/PlatformEfl.cmake</a></li>
<li><a href="#trunkSourceWebKit2PlatformGTKcmake">trunk/Source/WebKit2/PlatformGTK.cmake</a></li>
<li><a href="#trunkSourceWebKit2PlatformMaccmake">trunk/Source/WebKit2/PlatformMac.cmake</a></li>
<li><a href="#trunkSourceWebKit2SharedAPIAPIObjecth">trunk/Source/WebKit2/Shared/API/APIObject.h</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCoderscpp">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedWebCoreArgumentCodersh">trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h</a></li>
<li><a href="#trunkSourceWebKit2SharedWebProcessCreationParameterscpp">trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedWebProcessCreationParametersh">trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIProcessPoolConfigurationh">trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIWebsiteDataStorecpp">trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIAPIWebsiteDataStoreh">trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaAPIWebsiteDataStoreCocoamm">trunk/Source/WebKit2/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebsiteDataStoremm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStore.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebsiteDataStorePrivateh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIeflAPIWebsiteDataStoreEflcpp">trunk/Source/WebKit2/UIProcess/API/efl/APIWebsiteDataStoreEfl.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPIgtkAPIWebsiteDataStoreGtkcpp">trunk/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessPoolcpp">trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebProcessPoolh">trunk/Source/WebKit2/UIProcess/WebProcessPool.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebsiteDataCocoaWebsiteDataStoreCocoamm">trunk/Source/WebKit2/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStorecpp">trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStoreh">trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h</a></li>
<li><a href="#trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj">trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcessh">trunk/Source/WebKit2/WebProcess/WebProcess.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcessmessagesin">trunk/Source/WebKit2/WebProcess/WebProcess.messages.in</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsMiniBrowsermacAppDelegatem">trunk/Tools/MiniBrowser/mac/AppDelegate.m</a></li>
<li><a href="#trunkToolsMiniBrowsermacSettingsControllerm">trunk/Tools/MiniBrowser/mac/SettingsController.m</a></li>
<li><a href="#trunkToolsMiniBrowsermacWK2BrowserWindowControllerm">trunk/Tools/MiniBrowser/mac/WK2BrowserWindowController.m</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticsStorecpp">trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceLoadStatisticsStoreh">trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStorecpp">trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStoreh">trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStoremessagesin">trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.messages.in</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreCMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/CMakeLists.txt (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/CMakeLists.txt        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebCore/CMakeLists.txt        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1924,6 +1924,7 @@
</span><span class="cx">     loader/ResourceLoadNotifier.cpp
</span><span class="cx">     loader/ResourceLoadObserver.cpp
</span><span class="cx">     loader/ResourceLoadStatistics.cpp
</span><ins>+    loader/ResourceLoadStatisticsStore.cpp
</ins><span class="cx">     loader/ResourceLoader.cpp
</span><span class="cx">     loader/SinkDocument.cpp
</span><span class="cx">     loader/SubframeLoader.cpp
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebCore/ChangeLog        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,3 +1,68 @@
</span><ins>+2016-03-04  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        [WK2] Gather resource load statistics
+        https://bugs.webkit.org/show_bug.cgi?id=154278
+        &lt;rdar://problem/24702892&gt;
+
+        Reviewed by Andy Estes.
+
+        Tested (now under WK2) by http/tests/navigation/statistics.html
+
+        Split part of the ResourceLoadObserver into a new class (ResourceLoadStatisticsStore)
+        that manages the collection of ResourceLoadStatistic objects, and that can be used
+        in the UIProcess without touching various WebProcess-specific WebCore classes.
+
+        Have the WebProcess only fire a message to the UIProcess if data has been modified. Otherwise,
+        no messages should be sent. When new data is encountered, start a 5 second timer. If more
+        data is found during this delay, just accumulate it. When the timer fires, all data is sent
+        and the timer stops until a new batch of data arrives.
+
+        * CMakeLists.txt: Add the new ResourceLoadStatisticsStore class.
+        * WebCore.xcodeproj/project.pbxproj: Adjust visibility of ResourceLoadStatistics header,
+        and add new ResourceLoadStatisticsStore class.
+        * loader/ResourceLoadObserver.cpp:
+        (WebCore::ResourceLoadObserver::setResourceLoadStatisticsEnabled): Deleted.
+        (WebCore::ResourceLoadObserver::resourceLoadStatisticsEnabled): Deleted.
+        (WebCore::ResourceLoadObserver::setStatisticsStore): Added.
+        (WebCore::ResourceLoadObserver::logFrameNavigation): Tell the ResourceLoadStatisticsStore to fire its 'data changed'
+        handler if necessary.
+        (WebCore::ResourceLoadObserver::logSubresourceLoading): Ditto.
+        (WebCore::ResourceLoadObserver::logUserInteraction): Ditto.
+        (WebCore::ResourceLoadObserver::statisticsForOrigin): Use new ResourceLoadStatisticsStore.
+        (WebCore::ResourceLoadObserver::isPrevalentResource): Deleted.
+        (WebCore::ResourceLoadObserver::resourceStatisticsForPrimaryDomain): Deleted.
+        (WebCore::ResourceLoadObserver::writeDataToDisk): Deleted.
+        (WebCore::ResourceLoadObserver::setStatisticsStorageDirectory): Deleted.
+        (WebCore::ResourceLoadObserver::persistentStoragePath): Deleted.
+        (WebCore::ResourceLoadObserver::readDataFromDiskIfNeeded): Deleted.
+        (WebCore::ResourceLoadObserver::createDecoderFromDisk): Deleted.
+        (WebCore::ResourceLoadObserver::writeEncoderToDisk): Deleted.
+        * loader/ResourceLoadObserver.h:
+        * loader/ResourceLoadStatistics.cpp:
+        (WebCore::ResourceLoadStatistics::encode): Get rid of unneeded argument.
+        (WebCore::ResourceLoadStatistics::decode): Ditto.
+        (WebCore::mergeHashCountedSet): Added helper function.
+        (WebCore::ResourceLoadStatistics::merge): Added.
+        * loader/ResourceLoadStatistics.h:
+        (WebCore::ResourceLoadStatistics::ResourceLoadStatistics):
+        * loader/ResourceLoadStatisticsStore.cpp: Added.
+        (WebCore::ResourceLoadStatisticsStore::create):
+        (WebCore::ResourceLoadStatisticsStore::ResourceLoadStatisticsStore):
+        (WebCore::ResourceLoadStatisticsStore::isPrevalentResource):
+        (WebCore::ResourceLoadStatisticsStore::resourceStatisticsForPrimaryDomain):
+        (WebCore::ResourceLoadStatisticsStore::writeDataToDisk):
+        (WebCore::ResourceLoadStatisticsStore::setStatisticsStorageDirectory):
+        (WebCore::ResourceLoadStatisticsStore::persistentStoragePath):
+        (WebCore::ResourceLoadStatisticsStore::readDataFromDiskIfNeeded):
+        (WebCore::ResourceLoadStatisticsStore::createDecoderFromDisk):
+        (WebCore::ResourceLoadStatisticsStore::writeEncoderToDisk):
+        (WebCore::ResourceLoadStatisticsStore::statisticsForOrigin):
+        (WebCore::ResourceLoadStatisticsStore::takeStatistics):
+        (WebCore::ResourceLoadStatisticsStore::mergeStatistics):
+        (WebCore::ResourceLoadStatisticsStore::setNotificationCallback):
+        (WebCore::ResourceLoadStatisticsStore::fireDataModificationHandler):
+        * loader/ResourceLoadStatisticsStore.h: Added.
+
</ins><span class="cx"> 2016-03-04  Konstantin Tokarev  &lt;annulen@yandex.ru&gt;
</span><span class="cx"> 
</span><span class="cx">         Added missing override specifiers under Source/WebCore.
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -2682,7 +2682,7 @@
</span><span class="cx">                 7A74ECBB101839A600BF939E /* InspectorDOMStorageAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A74ECB9101839A600BF939E /* InspectorDOMStorageAgent.h */; };
</span><span class="cx">                 7A74ECBD101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */; };
</span><span class="cx">                 7A929CA61C598A9E004DF226 /* ResourceLoadStatistics.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A929CA11C598378004DF226 /* ResourceLoadStatistics.cpp */; };
</span><del>-                7A929CA71C598AA9004DF226 /* ResourceLoadStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A929CA21C598378004DF226 /* ResourceLoadStatistics.h */; };
</del><ins>+                7A929CA71C598AA9004DF226 /* ResourceLoadStatistics.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A929CA21C598378004DF226 /* ResourceLoadStatistics.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 7A93868518DCC14500B8263D /* VTTScanner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A93868218DCC14500B8263D /* VTTScanner.cpp */; };
</span><span class="cx">                 7A93868618DCC14500B8263D /* VTTScanner.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A93868318DCC14500B8263D /* VTTScanner.h */; };
</span><span class="cx">                 7AA3A699194A64E7001CBD24 /* TileController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AA3A695194A64E7001CBD24 /* TileController.cpp */; };
</span><span class="lines">@@ -2701,6 +2701,8 @@
</span><span class="cx">                 7AB0B1C11211A62200A76940 /* InspectorDatabaseAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AB0B1BF1211A62200A76940 /* InspectorDatabaseAgent.h */; };
</span><span class="cx">                 7ACD88D314C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7ACD88D114C08BD60084EDD2 /* InspectorIndexedDBAgent.cpp */; };
</span><span class="cx">                 7ACD88D414C08BD60084EDD2 /* InspectorIndexedDBAgent.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ACD88D214C08BD60084EDD2 /* InspectorIndexedDBAgent.h */; };
</span><ins>+                7AD3CDD91C8A002F00F12698 /* ResourceLoadStatisticsStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A7CC8361C87506800366243 /* ResourceLoadStatisticsStore.cpp */; };
+                7AD3CDDA1C8A01A400F12698 /* ResourceLoadStatisticsStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A7CC8371C87506800366243 /* ResourceLoadStatisticsStore.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 7ADE722610CBBB9B006B3B3A /* ContextMenuProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = 7ADE722510CBBB9B006B3B3A /* ContextMenuProvider.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7AE335F11ACB09E200E401EF /* WheelEventTestTrigger.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7AE335EF1ACB09E200E401EF /* WheelEventTestTrigger.cpp */; };
</span><span class="cx">                 7AE335F21ACB09E200E401EF /* WheelEventTestTrigger.h in Headers */ = {isa = PBXBuildFile; fileRef = 7AE335F01ACB09E200E401EF /* WheelEventTestTrigger.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="lines">@@ -10297,6 +10299,8 @@
</span><span class="cx">                 7A74ECB8101839A500BF939E /* InspectorDOMStorageAgent.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorDOMStorageAgent.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7A74ECB9101839A600BF939E /* InspectorDOMStorageAgent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorDOMStorageAgent.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7A74ECBC101839DA00BF939E /* JSInspectorFrontendHostCustom.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSInspectorFrontendHostCustom.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7A7CC8361C87506800366243 /* ResourceLoadStatisticsStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadStatisticsStore.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7A7CC8371C87506800366243 /* ResourceLoadStatisticsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadStatisticsStore.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7A929CA11C598378004DF226 /* ResourceLoadStatistics.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadStatistics.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7A929CA21C598378004DF226 /* ResourceLoadStatistics.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadStatistics.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7A93868218DCC14500B8263D /* VTTScanner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VTTScanner.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -22723,6 +22727,8 @@
</span><span class="cx">                                 6B693A2D1C51A82E00B03BEF /* ResourceLoadObserver.h */,
</span><span class="cx">                                 7A929CA11C598378004DF226 /* ResourceLoadStatistics.cpp */,
</span><span class="cx">                                 7A929CA21C598378004DF226 /* ResourceLoadStatistics.h */,
</span><ins>+                                7A7CC8361C87506800366243 /* ResourceLoadStatisticsStore.cpp */,
+                                7A7CC8371C87506800366243 /* ResourceLoadStatisticsStore.h */,
</ins><span class="cx">                                 51327D5F11A33A2B004F9D65 /* SinkDocument.cpp */,
</span><span class="cx">                                 51327D5E11A33A2B004F9D65 /* SinkDocument.h */,
</span><span class="cx">                                 D000ED2511C1B9CD00C47726 /* SubframeLoader.cpp */,
</span><span class="lines">@@ -26424,6 +26430,7 @@
</span><span class="cx">                                 65DF31F409D1CC60000BE325 /* JSCharacterData.h in Headers */,
</span><span class="cx">                                 BCC065880F3CE2A700CD2D87 /* JSClientRect.h in Headers */,
</span><span class="cx">                                 BCC0658A0F3CE2A700CD2D87 /* JSClientRectList.h in Headers */,
</span><ins>+                                7AD3CDDA1C8A01A400F12698 /* ResourceLoadStatisticsStore.h in Headers */,
</ins><span class="cx">                                 51FB5504113E3E9100821176 /* JSCloseEvent.h in Headers */,
</span><span class="cx">                                 A584FE3C1864E2D800843B10 /* JSCommandLineAPIHost.h in Headers */,
</span><span class="cx">                                 93F9B6E10BA0FB7200854064 /* JSComment.h in Headers */,
</span><span class="lines">@@ -29839,6 +29846,7 @@
</span><span class="cx">                                 A8EA7D320A19385500A8EF5F /* HTMLMapElement.cpp in Sources */,
</span><span class="cx">                                 A8EA7CAC0A192B9C00A8EF5F /* HTMLMarqueeElement.cpp in Sources */,
</span><span class="cx">                                 E44613A40CD6331000FADA75 /* HTMLMediaElement.cpp in Sources */,
</span><ins>+                                7AD3CDD91C8A002F00F12698 /* ResourceLoadStatisticsStore.cpp in Sources */,
</ins><span class="cx">                                 C968B2E81B1E778100EF1F81 /* HTMLMediaElementMediaSession.cpp in Sources */,
</span><span class="cx">                                 0779BF0D18453168000B6AE7 /* HTMLMediaElementMediaStream.cpp in Sources */,
</span><span class="cx">                                 A8EA79F80A1916DF00A8EF5F /* HTMLMenuElement.cpp in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadObservercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadObserver.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadObserver.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebCore/loader/ResourceLoadObserver.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -27,11 +27,11 @@
</span><span class="cx"> #include &quot;ResourceLoadObserver.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;Document.h&quot;
</span><del>-#include &quot;KeyedCoding.h&quot;
</del><span class="cx"> #include &quot;Logging.h&quot;
</span><span class="cx"> #include &quot;NetworkStorageSession.h&quot;
</span><span class="cx"> #include &quot;PlatformStrategies.h&quot;
</span><span class="cx"> #include &quot;ResourceLoadStatistics.h&quot;
</span><ins>+#include &quot;ResourceLoadStatisticsStore.h&quot;
</ins><span class="cx"> #include &quot;SecurityOrigin.h&quot;
</span><span class="cx"> #include &quot;Settings.h&quot;
</span><span class="cx"> #include &quot;SharedBuffer.h&quot;
</span><span class="lines">@@ -39,8 +39,6 @@
</span><span class="cx"> #include &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> #include &lt;wtf/text/StringBuilder.h&gt;
</span><span class="cx"> 
</span><del>-#define LOG_STATISTICS_TO_FILE 0
-
</del><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> ResourceLoadObserver&amp; ResourceLoadObserver::sharedObserver()
</span><span class="lines">@@ -48,7 +46,12 @@
</span><span class="cx">     static NeverDestroyed&lt;ResourceLoadObserver&gt; resourceLoadObserver;
</span><span class="cx">     return resourceLoadObserver;
</span><span class="cx"> }
</span><del>-    
</del><ins>+
+void ResourceLoadObserver::setStatisticsStore(Ref&lt;ResourceLoadStatisticsStore&gt;&amp;&amp; store)
+{
+    m_store = WTFMove(store);
+}
+
</ins><span class="cx"> void ResourceLoadObserver::logFrameNavigation(bool isRedirect, const URL&amp; sourceURL, const URL&amp; targetURL, bool isMainFrame, const URL&amp; mainFrameURL)
</span><span class="cx"> {
</span><span class="cx">     if (!Settings::resourceLoadStatisticsEnabled())
</span><span class="lines">@@ -71,7 +74,7 @@
</span><span class="cx">         return;
</span><span class="cx">     
</span><span class="cx">     auto targetOrigin = SecurityOrigin::create(targetURL);
</span><del>-    auto&amp; targetStatistics = resourceStatisticsForPrimaryDomain(targetPrimaryDomain);
</del><ins>+    auto&amp; targetStatistics = m_store-&gt;resourceStatisticsForPrimaryDomain(targetPrimaryDomain);
</ins><span class="cx">     
</span><span class="cx">     if (isMainFrame)
</span><span class="cx">         targetStatistics.topFrameHasBeenNavigatedToBefore = true;
</span><span class="lines">@@ -83,9 +86,9 @@
</span><span class="cx">     }
</span><span class="cx">     
</span><span class="cx">     if (isRedirect) {
</span><del>-        auto&amp; redirectingOriginResourceStatistics = resourceStatisticsForPrimaryDomain(sourcePrimaryDomain);
</del><ins>+        auto&amp; redirectingOriginResourceStatistics = m_store-&gt;resourceStatisticsForPrimaryDomain(sourcePrimaryDomain);
</ins><span class="cx">         
</span><del>-        if (isPrevalentResource(targetPrimaryDomain))
</del><ins>+        if (m_store-&gt;isPrevalentResource(targetPrimaryDomain))
</ins><span class="cx">             redirectingOriginResourceStatistics.redirectedToOtherPrevalentResourceOrigins.add(targetPrimaryDomain);
</span><span class="cx">         
</span><span class="cx">         if (isMainFrame) {
</span><span class="lines">@@ -105,7 +108,7 @@
</span><span class="cx">             else
</span><span class="cx">                 ++targetStatistics.subframeSubResourceCount;
</span><span class="cx">         } else {
</span><del>-            auto&amp; sourceOriginResourceStatistics = resourceStatisticsForPrimaryDomain(sourcePrimaryDomain);
</del><ins>+            auto&amp; sourceOriginResourceStatistics = m_store-&gt;resourceStatisticsForPrimaryDomain(sourcePrimaryDomain);
</ins><span class="cx"> 
</span><span class="cx">             if (isMainFrame) {
</span><span class="cx">                 ++sourceOriginResourceStatistics.topFrameHasBeenNavigatedFrom;
</span><span class="lines">@@ -117,7 +120,8 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    targetStatistics.checkAndSetAsPrevalentResourceIfNecessary(m_resourceStatisticsMap.size());
</del><ins>+    targetStatistics.checkAndSetAsPrevalentResourceIfNecessary(m_store-&gt;size());
+    m_store-&gt;fireDataModificationHandler();
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> void ResourceLoadObserver::logSubresourceLoading(bool isRedirect, const URL&amp; sourceURL, const URL&amp; targetURL, const URL&amp; mainFrameURL)
</span><span class="lines">@@ -138,15 +142,15 @@
</span><span class="cx">     if (targetPrimaryDomain == mainFramePrimaryDomain || targetPrimaryDomain == sourcePrimaryDomain)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    auto&amp; targetStatistics = resourceStatisticsForPrimaryDomain(targetPrimaryDomain);
</del><ins>+    auto&amp; targetStatistics = m_store-&gt;resourceStatisticsForPrimaryDomain(targetPrimaryDomain);
</ins><span class="cx"> 
</span><span class="cx">     auto mainFrameOrigin = SecurityOrigin::create(mainFrameURL);
</span><span class="cx">     targetStatistics.subresourceUnderTopFrameOrigins.add(mainFramePrimaryDomain);
</span><span class="cx"> 
</span><span class="cx">     if (isRedirect) {
</span><del>-        auto&amp; redirectingOriginStatistics = resourceStatisticsForPrimaryDomain(sourcePrimaryDomain);
</del><ins>+        auto&amp; redirectingOriginStatistics = m_store-&gt;resourceStatisticsForPrimaryDomain(sourcePrimaryDomain);
</ins><span class="cx">         
</span><del>-        if (isPrevalentResource(targetPrimaryDomain))
</del><ins>+        if (m_store-&gt;isPrevalentResource(targetPrimaryDomain))
</ins><span class="cx">             redirectingOriginStatistics.redirectedToOtherPrevalentResourceOrigins.add(targetPrimaryDomain);
</span><span class="cx">         
</span><span class="cx">         ++redirectingOriginStatistics.subresourceHasBeenRedirectedFrom;
</span><span class="lines">@@ -167,7 +171,8 @@
</span><span class="cx">         targetStatistics.subresourceHasBeenSubresourceCountDividedByTotalNumberOfOriginsVisited = static_cast&lt;double&gt;(targetStatistics.subresourceHasBeenSubresourceCount) / totalVisited;
</span><span class="cx">     }
</span><span class="cx">     
</span><del>-    targetStatistics.checkAndSetAsPrevalentResourceIfNecessary(m_resourceStatisticsMap.size());
</del><ins>+    targetStatistics.checkAndSetAsPrevalentResourceIfNecessary(m_store-&gt;size());
+    m_store-&gt;fireDataModificationHandler();
</ins><span class="cx"> }
</span><span class="cx">     
</span><span class="cx"> void ResourceLoadObserver::logUserInteraction(const Document&amp; document)
</span><span class="lines">@@ -175,27 +180,11 @@
</span><span class="cx">     if (!Settings::resourceLoadStatisticsEnabled())
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    auto&amp; statistics = resourceStatisticsForPrimaryDomain(primaryDomain(document.url()));
</del><ins>+    auto&amp; statistics = m_store-&gt;resourceStatisticsForPrimaryDomain(primaryDomain(document.url()));
</ins><span class="cx">     statistics.hadUserInteraction = true;
</span><ins>+    m_store-&gt;fireDataModificationHandler();
</ins><span class="cx"> }
</span><span class="cx">     
</span><del>-bool ResourceLoadObserver::isPrevalentResource(const String&amp; primaryDomain) const
-{
-    auto mapEntry = m_resourceStatisticsMap.find(primaryDomain);
-    if (mapEntry == m_resourceStatisticsMap.end())
-        return false;
-
-    return mapEntry-&gt;value.isPrevalentResource;
-}
-    
-ResourceLoadStatistics&amp; ResourceLoadObserver::resourceStatisticsForPrimaryDomain(const String&amp; primaryDomain)
-{
-    if (!m_resourceStatisticsMap.contains(primaryDomain))
-        m_resourceStatisticsMap.set(primaryDomain, ResourceLoadStatistics());
-    
-    return m_resourceStatisticsMap.find(primaryDomain)-&gt;value;
-}
-
</del><span class="cx"> String ResourceLoadObserver::primaryDomain(const URL&amp; url)
</span><span class="cx"> {
</span><span class="cx">     String host = url.host();
</span><span class="lines">@@ -238,136 +227,9 @@
</span><span class="cx">     return primaryDomain;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-typedef HashMap&lt;String, ResourceLoadStatistics&gt;::KeyValuePairType StatisticsValue;
-
-void ResourceLoadObserver::writeDataToDisk()
</del><ins>+String ResourceLoadObserver::statisticsForOrigin(const String&amp; origin)
</ins><span class="cx"> {
</span><del>-    if (!Settings::resourceLoadStatisticsEnabled())
-        return;
-    
-    auto encoder = KeyedEncoder::encoder();
-    encoder-&gt;encodeUInt32(&quot;originsVisited&quot;, m_resourceStatisticsMap.size());
-    
-    encoder-&gt;encodeObjects(&quot;browsingStatistics&quot;, m_resourceStatisticsMap.begin(), m_resourceStatisticsMap.end(), [this](KeyedEncoder&amp; encoderInner, const StatisticsValue&amp; origin) {
-        origin.value.encode(encoderInner, origin.key);
-    });
-    
-    writeEncoderToDisk(*encoder.get(), &quot;full_browsing_session&quot;);
</del><ins>+    return m_store-&gt;statisticsForOrigin(origin);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadObserver::writeDataToDisk(const String&amp; origin, const ResourceLoadStatistics&amp; resourceStatistics) const
-{
-    if (!Settings::resourceLoadStatisticsEnabled())
-        return;
-
-    auto encoder = KeyedEncoder::encoder();
-    encoder-&gt;encodeUInt32(&quot;originsVisited&quot;, 1);
-    
-    encoder-&gt;encodeObject(origin, resourceStatistics, [this, &amp;origin](KeyedEncoder&amp; encoder, const ResourceLoadStatistics&amp; resourceStatistics) {
-        resourceStatistics.encode(encoder, origin);
-    });
-    
-    String label = origin;
-    label.replace('/', '_');
-    label.replace(':', '+');
-    writeEncoderToDisk(*encoder.get(), label);
</del><span class="cx"> }
</span><del>-
-void ResourceLoadObserver::setStatisticsStorageDirectory(const String&amp; path)
-{
-    m_storagePath = path;
-}
-
-String ResourceLoadObserver::persistentStoragePath(const String&amp; label) const
-{
-    if (m_storagePath.isEmpty())
-        return emptyString();
-
-    // TODO Decide what to call this file
-    return pathByAppendingComponent(m_storagePath, label + &quot;_resourceLog.plist&quot;);
-}
-
-void ResourceLoadObserver::readDataFromDiskIfNeeded()
-{
-    if (!Settings::resourceLoadStatisticsEnabled())
-        return;
-
-    if (m_resourceStatisticsMap.size())
-        return;
-
-    auto decoder = createDecoderFromDisk(&quot;full_browsing_session&quot;);
-    if (!decoder)
-        return;
-
-    unsigned visitedOrigins = 0;
-    decoder-&gt;decodeUInt32(&quot;originsVisited&quot;, visitedOrigins);
-        
-    Vector&lt;String&gt; loadedOrigins;
-    decoder-&gt;decodeObjects(&quot;browsingStatistics&quot;, loadedOrigins, [this](KeyedDecoder&amp; decoderInner, String&amp; origin) {
-        if (!decoderInner.decodeString(&quot;PrevalentResourceOrigin&quot;, origin))
-            return false;
-
-        ResourceLoadStatistics statistics;
-        if (!statistics.decode(decoderInner, origin))
-            return false;
-
-        m_resourceStatisticsMap.set(origin, statistics);
-            
-        return true;
-    });
-        
-    ASSERT(visitedOrigins == static_cast&lt;size_t&gt;(loadedOrigins.size()));
-}
-
-std::unique_ptr&lt;KeyedDecoder&gt; ResourceLoadObserver::createDecoderFromDisk(const String&amp; label) const
-{
-    String resourceLog = persistentStoragePath(label);
-    if (resourceLog.isEmpty())
-        return nullptr;
-    
-    RefPtr&lt;SharedBuffer&gt; rawData = SharedBuffer::createWithContentsOfFile(resourceLog);
-    if (!rawData)
-        return nullptr;
-    
-    return KeyedDecoder::decoder(reinterpret_cast&lt;const uint8_t*&gt;(rawData-&gt;data()), rawData-&gt;size());
-}
-    
-void ResourceLoadObserver::writeEncoderToDisk(KeyedEncoder&amp; encoder, const String&amp; label) const
-{
-#if LOG_STATISTICS_TO_FILE
-    RefPtr&lt;SharedBuffer&gt; rawData = encoder.finishEncoding();
-    if (!rawData)
-        return;
-    
-    String resourceLog = persistentStoragePath(label);
-    if (resourceLog.isEmpty())
-        return;
-
-    if (!m_storagePath.isEmpty())
-        makeAllDirectories(m_storagePath);
-
-    auto handle = openFile(resourceLog, OpenForWrite);
-    if (!handle)
-        return;
-    
-    int64_t writtenBytes = writeToFile(handle, rawData-&gt;data(), rawData-&gt;size());
-    closeFile(handle);
-    
-    if (writtenBytes != static_cast&lt;int64_t&gt;(rawData-&gt;size()))
-        WTFLogAlways(&quot;ResourceLoadStatistics: We only wrote %lld out of %d bytes to disk&quot;, writtenBytes, rawData-&gt;size());
-#else
-    UNUSED_PARAM(encoder);
-    UNUSED_PARAM(label);
-#endif
-}
-
-String ResourceLoadObserver::statisticsForOrigin(const String&amp; origin)
-{
-    if (!m_resourceStatisticsMap.contains(origin))
-        return emptyString();
-    
-    auto&amp; statistics = m_resourceStatisticsMap.find(origin)-&gt;value;
-    return &quot;Statistics for &quot; + origin + &quot;:\n&quot; + statistics.toString();
-}
-    
-}
</del></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadObserverh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadObserver.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadObserver.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebCore/loader/ResourceLoadObserver.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -26,14 +26,13 @@
</span><span class="cx"> #ifndef ResourceLoadObserver_h
</span><span class="cx"> #define ResourceLoadObserver_h
</span><span class="cx"> 
</span><ins>+#include &quot;ResourceLoadStatisticsStore.h&quot;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/text/WTFString.h&gt;
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class Document;
</span><del>-class KeyedDecoder;
-class KeyedEncoder;
</del><span class="cx"> class URL;
</span><span class="cx"> 
</span><span class="cx"> struct ResourceLoadStatistics;
</span><span class="lines">@@ -47,29 +46,15 @@
</span><span class="cx">     void logSubresourceLoading(bool isRedirect, const URL&amp; sourceURL, const URL&amp; targetURL, const URL&amp; mainFrameURL);
</span><span class="cx">     void logUserInteraction(const Document&amp;);
</span><span class="cx"> 
</span><del>-    WEBCORE_EXPORT void writeDataToDisk();
-    WEBCORE_EXPORT void readDataFromDiskIfNeeded();
-    WEBCORE_EXPORT void setStatisticsStorageDirectory(const String&amp;);
</del><ins>+    WEBCORE_EXPORT void setStatisticsStore(Ref&lt;ResourceLoadStatisticsStore&gt;&amp;&amp;);
</ins><span class="cx"> 
</span><span class="cx">     WEBCORE_EXPORT String statisticsForOrigin(const String&amp;);
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    ResourceLoadStatistics&amp; resourceStatisticsForPrimaryDomain(const String&amp;);
-    
</del><span class="cx">     static String primaryDomain(const URL&amp;);
</span><span class="cx"> 
</span><del>-    bool isPrevalentResource(const String&amp;) const;
-
-    String persistentStoragePath(const String&amp; label) const;
-
-    void writeDataToDisk(const String&amp; origin, const ResourceLoadStatistics&amp;) const;
-
-    std::unique_ptr&lt;KeyedDecoder&gt; createDecoderFromDisk(const String&amp; label) const;
-    void writeEncoderToDisk(KeyedEncoder&amp;, const String&amp; label) const;
-
</del><ins>+    RefPtr&lt;ResourceLoadStatisticsStore&gt; m_store;
</ins><span class="cx">     HashMap&lt;String, size_t&gt; m_originsVisitedMap;
</span><del>-    HashMap&lt;String, ResourceLoadStatistics&gt; m_resourceStatisticsMap;
-    String m_storagePath;
</del><span class="cx"> };
</span><span class="cx">     
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebCore/loader/ResourceLoadStatistics.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -76,9 +76,9 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ResourceLoadStatistics::encode(KeyedEncoder&amp; encoder, const String&amp; origin) const
</del><ins>+void ResourceLoadStatistics::encode(KeyedEncoder&amp; encoder) const
</ins><span class="cx"> {
</span><del>-    encoder.encodeString(&quot;PrevalentResourceOrigin&quot;, origin);
</del><ins>+    encoder.encodeString(&quot;PrevalentResourceOrigin&quot;, highLevelDomain);
</ins><span class="cx">     
</span><span class="cx">     // User interaction
</span><span class="cx">     encoder.encodeBool(&quot;hadUserInteraction&quot;, hadUserInteraction);
</span><span class="lines">@@ -130,14 +130,11 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ResourceLoadStatistics::decode(KeyedDecoder&amp; decoder, const String&amp; origin)
</del><ins>+bool ResourceLoadStatistics::decode(KeyedDecoder&amp; decoder)
</ins><span class="cx"> {
</span><del>-    String storedOrigin;
-    if (!decoder.decodeString(&quot;PrevalentResourceOrigin&quot;, storedOrigin))
</del><ins>+    if (!decoder.decodeString(&quot;PrevalentResourceOrigin&quot;, highLevelDomain))
</ins><span class="cx">         return false;
</span><span class="cx">     
</span><del>-    ASSERT_UNUSED(origin, storedOrigin == origin);
-    
</del><span class="cx">     // User interaction
</span><span class="cx">     if (!decoder.decodeBool(&quot;hadUserInteraction&quot;, hadUserInteraction))
</span><span class="cx">         return false;
</span><span class="lines">@@ -307,4 +304,47 @@
</span><span class="cx">     return builder.toString();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template &lt;typename T&gt;
+static void mergeHashCountedSet(HashCountedSet&lt;T&gt;&amp; to, const HashCountedSet&lt;T&gt;&amp; from)
+{
+    for (auto&amp; entry : from)
+        to.add(entry.key, entry.value);
</ins><span class="cx"> }
</span><ins>+
+void ResourceLoadStatistics::merge(const ResourceLoadStatistics&amp; other)
+{
+    ASSERT(other.highLevelDomain == highLevelDomain);
+
+    hadUserInteraction |= other.hadUserInteraction;
+    
+    // Top frame stats
+    topFrameHasBeenRedirectedTo += other.topFrameHasBeenRedirectedTo;
+    topFrameHasBeenRedirectedFrom += other.topFrameHasBeenRedirectedFrom;
+    topFrameInitialLoadCount += other.topFrameInitialLoadCount;
+    topFrameHasBeenNavigatedTo += other.topFrameHasBeenNavigatedTo;
+    topFrameHasBeenNavigatedFrom += other.topFrameHasBeenNavigatedFrom;
+    topFrameHasBeenNavigatedToBefore |= other.topFrameHasBeenNavigatedToBefore;
+    
+    // Subframe stats
+    mergeHashCountedSet(subframeUnderTopFrameOrigins, other.subframeUnderTopFrameOrigins);
+    subframeHasBeenRedirectedTo += other.subframeHasBeenRedirectedTo;
+    subframeHasBeenRedirectedFrom += other.subframeHasBeenRedirectedFrom;
+    mergeHashCountedSet(subframeUniqueRedirectsTo, other.subframeUniqueRedirectsTo);
+    subframeSubResourceCount += other.subframeSubResourceCount;
+    subframeHasBeenNavigatedTo += other.subframeHasBeenNavigatedTo;
+    subframeHasBeenNavigatedFrom += other.subframeHasBeenNavigatedFrom;
+    subframeHasBeenLoadedBefore |= other.subframeHasBeenLoadedBefore;
+    
+    // Subresource stats
+    mergeHashCountedSet(subresourceUnderTopFrameOrigins, other.subresourceUnderTopFrameOrigins);
+    subresourceHasBeenSubresourceCount += other.subresourceHasBeenSubresourceCount;
+    subresourceHasBeenRedirectedFrom += other.subresourceHasBeenRedirectedFrom;
+    subresourceHasBeenRedirectedTo += other.subresourceHasBeenRedirectedTo;
+    mergeHashCountedSet(subresourceUniqueRedirectsTo, other.subresourceUniqueRedirectsTo);
+    
+    // Prevalent resource stats
+    mergeHashCountedSet(redirectedToOtherPrevalentResourceOrigins, other.redirectedToOtherPrevalentResourceOrigins);
+    isPrevalentResource |= other.isPrevalentResource;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceLoadStatistics.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatistics.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebCore/loader/ResourceLoadStatistics.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -35,16 +35,27 @@
</span><span class="cx"> class KeyedEncoder;
</span><span class="cx"> 
</span><span class="cx"> struct ResourceLoadStatistics {
</span><ins>+    ResourceLoadStatistics(const String&amp; primaryDomain)
+        : highLevelDomain(primaryDomain)
+    {
+    }
+
+    ResourceLoadStatistics() = default;
+
</ins><span class="cx">     bool checkAndSetAsPrevalentResourceIfNecessary(unsigned originsVisitedSoFar);
</span><span class="cx"> 
</span><span class="cx">     bool hasPrevalentRedirection() const;
</span><span class="cx">     bool hasPrevalentResourceCharacteristics() const;
</span><span class="cx"> 
</span><del>-    void encode(KeyedEncoder&amp;, const String&amp; origin) const;
-    bool decode(KeyedDecoder&amp;, const String&amp; origin);
</del><ins>+    void encode(KeyedEncoder&amp;) const;
+    bool decode(KeyedDecoder&amp;);
</ins><span class="cx"> 
</span><span class="cx">     String toString() const;
</span><span class="cx"> 
</span><ins>+    void merge(const ResourceLoadStatistics&amp;);
+
+    String highLevelDomain;
+
</ins><span class="cx">     // User interaction
</span><span class="cx">     bool hadUserInteraction { false };
</span><span class="cx">     
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticsStorecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp (0 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp                                (rev 0)
+++ trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -0,0 +1,210 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 &quot;config.h&quot;
+#include &quot;ResourceLoadStatisticsStore.h&quot;
+
+#include &quot;KeyedCoding.h&quot;
+#include &quot;Logging.h&quot;
+#include &quot;NetworkStorageSession.h&quot;
+#include &quot;PlatformStrategies.h&quot;
+#include &quot;ResourceLoadStatistics.h&quot;
+#include &quot;SecurityOrigin.h&quot;
+#include &quot;SharedBuffer.h&quot;
+#include &quot;URL.h&quot;
+#include &lt;wtf/NeverDestroyed.h&gt;
+#include &lt;wtf/text/StringBuilder.h&gt;
+
+#define LOG_STATISTICS_TO_FILE 0
+
+namespace WebCore {
+
+Ref&lt;ResourceLoadStatisticsStore&gt; ResourceLoadStatisticsStore::create(const String&amp; resourceLoadStatisticsDirectory)
+{
+    return adoptRef(*new ResourceLoadStatisticsStore(resourceLoadStatisticsDirectory));
+}
+
+Ref&lt;ResourceLoadStatisticsStore&gt; ResourceLoadStatisticsStore::create()
+{
+    return adoptRef(*new ResourceLoadStatisticsStore());
+}
+    
+ResourceLoadStatisticsStore::ResourceLoadStatisticsStore(const String&amp; resourceLoadStatisticsDirectory)
+    : m_storagePath(resourceLoadStatisticsDirectory)
+{
+}
+    
+bool ResourceLoadStatisticsStore::isPrevalentResource(const String&amp; primaryDomain) const
+{
+    auto mapEntry = m_resourceStatisticsMap.find(primaryDomain);
+    if (mapEntry == m_resourceStatisticsMap.end())
+        return false;
+
+    return mapEntry-&gt;value.isPrevalentResource;
+}
+    
+ResourceLoadStatistics&amp; ResourceLoadStatisticsStore::resourceStatisticsForPrimaryDomain(const String&amp; primaryDomain)
+{
+    auto addResult = m_resourceStatisticsMap.ensure(primaryDomain, [&amp;primaryDomain] {
+        return ResourceLoadStatistics(primaryDomain);
+    });
+
+    return addResult.iterator-&gt;value;
+}
+
+typedef HashMap&lt;String, ResourceLoadStatistics&gt;::KeyValuePairType StatisticsValue;
+
+void ResourceLoadStatisticsStore::writeDataToDisk()
+{
+    auto encoder = KeyedEncoder::encoder();
+    
+    encoder-&gt;encodeObjects(&quot;browsingStatistics&quot;, m_resourceStatisticsMap.begin(), m_resourceStatisticsMap.end(), [this](KeyedEncoder&amp; encoderInner, const StatisticsValue&amp; origin) {
+        origin.value.encode(encoderInner);
+    });
+    
+    writeEncoderToDisk(*encoder.get(), &quot;full_browsing_session&quot;);
+}
+
+void ResourceLoadStatisticsStore::setStatisticsStorageDirectory(const String&amp; path)
+{
+    m_storagePath = path;
+    readDataFromDiskIfNeeded();
+}
+
+String ResourceLoadStatisticsStore::persistentStoragePath(const String&amp; label) const
+{
+    if (m_storagePath.isEmpty())
+        return emptyString();
+
+    // TODO Decide what to call this file
+    return pathByAppendingComponent(m_storagePath, label + &quot;_resourceLog.plist&quot;);
+}
+
+void ResourceLoadStatisticsStore::readDataFromDiskIfNeeded()
+{
+    if (m_resourceStatisticsMap.size())
+        return;
+
+    auto decoder = createDecoderFromDisk(&quot;full_browsing_session&quot;);
+    if (!decoder)
+        return;
+
+    Vector&lt;ResourceLoadStatistics&gt; loadedStatistics;
+    bool succeeded = decoder-&gt;decodeObjects(&quot;browsingStatistics&quot;, loadedStatistics, [this](KeyedDecoder&amp; decoderInner, ResourceLoadStatistics&amp; statistics) {
+        return statistics.decode(decoderInner);
+    });
+
+    if (!succeeded)
+        return;
+
+    for (auto&amp; statistics : loadedStatistics)
+        m_resourceStatisticsMap.set(statistics.highLevelDomain, statistics);
+}
+
+std::unique_ptr&lt;KeyedDecoder&gt; ResourceLoadStatisticsStore::createDecoderFromDisk(const String&amp; label) const
+{
+    String resourceLog = persistentStoragePath(label);
+    if (resourceLog.isEmpty())
+        return nullptr;
+    
+    RefPtr&lt;SharedBuffer&gt; rawData = SharedBuffer::createWithContentsOfFile(resourceLog);
+    if (!rawData)
+        return nullptr;
+    
+    return KeyedDecoder::decoder(reinterpret_cast&lt;const uint8_t*&gt;(rawData-&gt;data()), rawData-&gt;size());
+}
+    
+void ResourceLoadStatisticsStore::writeEncoderToDisk(KeyedEncoder&amp; encoder, const String&amp; label) const
+{
+#if LOG_STATISTICS_TO_FILE
+    RefPtr&lt;SharedBuffer&gt; rawData = encoder.finishEncoding();
+    if (!rawData)
+        return;
+    
+    String resourceLog = persistentStoragePath(label);
+    if (resourceLog.isEmpty())
+        return;
+
+    if (!m_storagePath.isEmpty())
+        makeAllDirectories(m_storagePath);
+
+    auto handle = openFile(resourceLog, OpenForWrite);
+    if (!handle)
+        return;
+    
+    int64_t writtenBytes = writeToFile(handle, rawData-&gt;data(), rawData-&gt;size());
+    closeFile(handle);
+    
+    if (writtenBytes != static_cast&lt;int64_t&gt;(rawData-&gt;size()))
+        WTFLogAlways(&quot;ResourceLoadStatistics: We only wrote %lld out of %d bytes to disk&quot;, writtenBytes, rawData-&gt;size());
+#else
+    UNUSED_PARAM(encoder);
+    UNUSED_PARAM(label);
+#endif
+}
+
+String ResourceLoadStatisticsStore::statisticsForOrigin(const String&amp; origin)
+{
+    auto iter = m_resourceStatisticsMap.find(origin);
+    if (iter == m_resourceStatisticsMap.end())
+        return emptyString();
+    
+    return &quot;Statistics for &quot; + origin + &quot;:\n&quot; + iter-&gt;value.toString();
+}
+
+Vector&lt;ResourceLoadStatistics&gt; ResourceLoadStatisticsStore::takeStatistics()
+{
+    Vector&lt;ResourceLoadStatistics&gt; statistics;
+    statistics.reserveInitialCapacity(m_resourceStatisticsMap.size());
+    for (auto&amp; statistic : m_resourceStatisticsMap.values())
+        statistics.uncheckedAppend(WTFMove(statistic));
+
+    m_resourceStatisticsMap.clear();
+
+    return statistics;
+}
+
+void ResourceLoadStatisticsStore::mergeStatistics(const Vector&lt;ResourceLoadStatistics&gt;&amp; statistics)
+{
+    for (auto&amp; statistic : statistics) {
+        auto result = m_resourceStatisticsMap.ensure(statistic.highLevelDomain, [&amp;statistic] {
+            return ResourceLoadStatistics(statistic.highLevelDomain);
+        });
+        
+        result.iterator-&gt;value.merge(statistic);
+    }
+}
+
+void ResourceLoadStatisticsStore::setNotificationCallback(std::function&lt;void()&gt; handler)
+{
+    m_dataAddedHandler = WTFMove(handler);
+}
+
+void ResourceLoadStatisticsStore::fireDataModificationHandler()
+{
+    m_dataAddedHandler();
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceLoadStatisticsStoreh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h (0 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h                                (rev 0)
+++ trunk/Source/WebCore/loader/ResourceLoadStatisticsStore.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -0,0 +1,79 @@
</span><ins>+/*
+ * Copyright (C) 2016 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. ``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
+ * 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 ResourceLoadStatisticsStore_h
+#define ResourceLoadStatisticsStore_h
+
+#include &quot;ResourceLoadStatistics.h&quot;
+
+namespace WebCore {
+
+class KeyedDecoder;
+class KeyedEncoder;
+class URL;
+
+struct ResourceLoadStatistics;
+
+class ResourceLoadStatisticsStore : public RefCounted&lt;ResourceLoadStatisticsStore&gt; {
+public:
+    WEBCORE_EXPORT static Ref&lt;ResourceLoadStatisticsStore&gt; create(const String&amp; resourceLoadStatisticsDirectory);
+    WEBCORE_EXPORT static Ref&lt;ResourceLoadStatisticsStore&gt; create();
+
+    WEBCORE_EXPORT void writeDataToDisk();
+    WEBCORE_EXPORT void readDataFromDiskIfNeeded();
+    WEBCORE_EXPORT void setStatisticsStorageDirectory(const String&amp;);
+
+    WEBCORE_EXPORT String statisticsForOrigin(const String&amp;);
+
+    bool isEmpty() const { return m_resourceStatisticsMap.isEmpty(); }
+    size_t size() const { return m_resourceStatisticsMap.size(); }
+
+    ResourceLoadStatistics&amp; resourceStatisticsForPrimaryDomain(const String&amp;);
+
+    bool isPrevalentResource(const String&amp;) const;
+    
+    WEBCORE_EXPORT void mergeStatistics(const Vector&lt;ResourceLoadStatistics&gt;&amp;);
+    WEBCORE_EXPORT Vector&lt;ResourceLoadStatistics&gt; takeStatistics();
+
+    WEBCORE_EXPORT void setNotificationCallback(std::function&lt;void()&gt; handler);
+
+    void fireDataModificationHandler();
+
+private:
+    ResourceLoadStatisticsStore() = default;
+    ResourceLoadStatisticsStore(const String&amp; resourceLoadStatisticsDirectory);
+    String persistentStoragePath(const String&amp; label) const;
+
+    std::unique_ptr&lt;KeyedDecoder&gt; createDecoderFromDisk(const String&amp; label) const;
+    void writeEncoderToDisk(KeyedEncoder&amp;, const String&amp; label) const;
+
+    HashMap&lt;String, ResourceLoadStatistics&gt; m_resourceStatisticsMap;
+    String m_storagePath;
+    std::function&lt;void()&gt; m_dataAddedHandler;
+};
+    
+} // namespace WebCore
+
+#endif /* ResourceLoadStatisticsStore_h */
</ins></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/ChangeLog        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit/mac/ChangeLog        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2016-03-04  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        [WK2] Gather resource load statistics
+        https://bugs.webkit.org/show_bug.cgi?id=154278
+        &lt;rdar://problem/24702892&gt;
+
+        Reviewed by Andy Estes.
+
+        Switch to maintaining a global WebCore::ResourceLoadStatisticsStore in the WebKit process,
+        and hand it off to the WebCore layer to use during data gathering. The ResourceLoadStatisticsStore
+        is now responsible for reading/writing to disk, and tracking the collection of load data.
+
+        * WebView/WebView.mm:
+        (WebKitInitializeApplicationStatisticsStoragePathIfNecessary): Initialize singleton
+        ResourceLoadStatisticsStore object for tracking state.
+        (-[WebView _preferencesChanged:]): Revise for new singleton.
+        (+[WebView _applicationWillTerminate]): Ditto.
+
</ins><span class="cx"> 2016-02-29  Ada Chan  &lt;adachan@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Adopt the new version of AVOutputDeviceMenuController's showMenuForRect method.
</span></span></pre></div>
<a id="trunkSourceWebKitmacWebViewWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/WebView/WebView.mm (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit/mac/WebView/WebView.mm        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit/mac/WebView/WebView.mm        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -252,6 +252,8 @@
</span><span class="cx"> #import &lt;WebCore/MobileGestaltSPI.h&gt;
</span><span class="cx"> #import &lt;WebCore/NetworkStateNotifier.h&gt;
</span><span class="cx"> #import &lt;WebCore/PlatformScreen.h&gt;
</span><ins>+#import &lt;WebCore/ResourceLoadStatistics.h&gt;
+#import &lt;WebCore/ResourceLoadStatisticsStore.h&gt;
</ins><span class="cx"> #import &lt;WebCore/RuntimeApplicationChecksIOS.h&gt;
</span><span class="cx"> #import &lt;WebCore/SQLiteDatabaseTracker.h&gt;
</span><span class="cx"> #import &lt;WebCore/SmartReplace.h&gt;
</span><span class="lines">@@ -606,6 +608,7 @@
</span><span class="cx"> #define timedLayoutSize 4096
</span><span class="cx"> 
</span><span class="cx"> static NSMutableSet *schemesWithRepresentationsSet;
</span><ins>+static WebCore::ResourceLoadStatisticsStore* resourceLoadStatisticsStore;
</ins><span class="cx"> 
</span><span class="cx"> #if !PLATFORM(IOS)
</span><span class="cx"> NSString *_WebCanGoBackKey =            @&quot;canGoBack&quot;;
</span><span class="lines">@@ -764,7 +767,9 @@
</span><span class="cx">     ASSERT(appName);
</span><span class="cx">     
</span><span class="cx">     NSString *supportDirectory = [NSString _webkit_localStorageDirectoryWithBundleIdentifier:appName];
</span><del>-    ResourceLoadObserver::sharedObserver().setStatisticsStorageDirectory(supportDirectory);
</del><ins>+
+    resourceLoadStatisticsStore = &amp;WebCore::ResourceLoadStatisticsStore::create(supportDirectory).leakRef();
+    ResourceLoadObserver::sharedObserver().setStatisticsStore(*resourceLoadStatisticsStore);
</ins><span class="cx">     
</span><span class="cx">     initialized = YES;
</span><span class="cx"> }
</span><span class="lines">@@ -2472,7 +2477,7 @@
</span><span class="cx">     settings.setHiddenPageCSSAnimationSuspensionEnabled([preferences hiddenPageCSSAnimationSuspensionEnabled]);
</span><span class="cx"> 
</span><span class="cx">     settings.setResourceLoadStatisticsEnabled([preferences resourceLoadStatisticsEnabled]);
</span><del>-    ResourceLoadObserver::sharedObserver().readDataFromDiskIfNeeded();
</del><ins>+    resourceLoadStatisticsStore-&gt;readDataFromDiskIfNeeded();
</ins><span class="cx"> 
</span><span class="cx"> #if ENABLE(GAMEPAD)
</span><span class="cx">     RuntimeEnabledFeatures::sharedFeatures().setGamepadsEnabled([preferences gamepadsEnabled]);
</span><span class="lines">@@ -4842,7 +4847,7 @@
</span><span class="cx"> {   
</span><span class="cx">     applicationIsTerminating = YES;
</span><span class="cx"> 
</span><del>-    ResourceLoadObserver::sharedObserver().writeDataToDisk();
</del><ins>+    resourceLoadStatisticsStore-&gt;writeDataToDisk();
</ins><span class="cx"> 
</span><span class="cx">     if (fastDocumentTeardownEnabled())
</span><span class="cx">         [self closeAllWebViews];
</span></span></pre></div>
<a id="trunkSourceWebKit2CMakeListstxt"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/CMakeLists.txt (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/CMakeLists.txt        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/CMakeLists.txt        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -667,6 +667,7 @@
</span><span class="cx">     UIProcess/WebPasteboardProxy.messages.in
</span><span class="cx">     UIProcess/WebProcessPool.messages.in
</span><span class="cx">     UIProcess/WebProcessProxy.messages.in
</span><ins>+    UIProcess/WebResourceLoadStatisticsStore.messages.in
</ins><span class="cx">     UIProcess/WebVibrationProxy.messages.in
</span><span class="cx"> 
</span><span class="cx">     UIProcess/Databases/DatabaseProcessProxy.messages.in
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/ChangeLog        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,3 +1,93 @@
</span><ins>+2016-03-04  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        [WK2] Gather resource load statistics
+        https://bugs.webkit.org/show_bug.cgi?id=154278
+        &lt;rdar://problem/24702892&gt;
+
+        Reviewed by Andy Estes.
+
+        Revise the WebProcess to notify the UIProcess about resource load statistics. These
+        updates are not time-critical, and do not need to be done in concert with the actual
+        load. As resource loads are made, each WebProcess notifies the UIProcess of the new
+        load counts, then clears its local state. These statistics are then aggregated in
+        the UIProcess.
+
+        * CMakeLists.txt: Add new ResourceLoadStatisticsState files to build.
+        * DerivedSources.make: Ditto.
+        * Platform/IPC/ArgumentCoders.h: Update to support HashCountedSets.
+        * PlatformEfl.cmake: Add new ResourceLoadStatisticsState files to build.
+        * PlatformGTK.cmake: Ditto.
+        * PlatformMac.cmake: Ditto.
+        * Shared/API/APIObject.h: Add new ResourceLoadStatistics type.
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder&lt;ExceptionDetails&gt;::decode): Support new ResourceLoadStatistics type.
+        (IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::encode): Added.
+        (IPC::ArgumentCoder&lt;ResourceLoadStatistics&gt;::decode): Added.
+        * Shared/WebCoreArgumentCoders.h:
+        * Shared/WebProcessCreationParameters.cpp:
+        (WebKit::WebProcessCreationParameters::encode): Handle 'resourceLoadStatisticsEnabled' flag.
+        (WebKit::WebProcessCreationParameters::decode): Ditto.
+        * Shared/WebProcessCreationParameters.h:
+        * UIProcess/API/APIProcessPoolConfiguration.cpp:
+        (API::ProcessPoolConfiguration::ProcessPoolConfiguration): Add storage location for the
+        resource load statistics.
+        (API::ProcessPoolConfiguration::copy): Handle the new storage location and the feature flag.
+        * UIProcess/API/APIProcessPoolConfiguration.h:
+        * UIProcess/API/APIWebsiteDataStore.cpp:
+        (API::WebsiteDataStore::defaultResourceLoadStatisticsDirectory): Added stub.
+        * UIProcess/API/APIWebsiteDataStore.h:
+        * UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm:
+        (API::WebsiteDataStore::defaultResourceLoadStatisticsDirectory): Added.
+        (API::WebsiteDataStore::defaultDataStoreConfiguration): Added support for the new resource
+        load statistics storage location.
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _initializeWithConfiguration:]): Sync Process Pool configuration parameters
+        with the state of our websiteData object's &quot;ResourceLoadStatisticsEnabled&quot; flag, so that
+        new processes are created in the right state.
+        * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+        (-[WKWebsiteDataStore _resourceLoadStatisticsEnabled]): Added.
+        (-[WKWebsiteDataStore _setResourceLoadStatisticsEnabled:]): Added.
+        * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::createNewWebProcess): Handle new flag for enabling resource
+        load statistics.
+        * UIProcess/WebResourceLoadStatisticsStore.cpp: Added.
+        (WebKit::WebResourceLoadStatisticsStore::create):
+        (WebKit::WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore):
+        (WebKit::WebResourceLoadStatisticsStore::~WebResourceLoadStatisticsStore):
+        (WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated):
+        (WebKit::WebResourceLoadStatisticsStore::setResourceLoadStatisticsEnabled):
+        (WebKit::WebResourceLoadStatisticsStore::resourceLoadStatisticsEnabled):
+        (WebKit::WebResourceLoadStatisticsStore::readDataFromDiskIfNeeded):
+        (WebKit::WebResourceLoadStatisticsStore::writeToDisk):
+        (WebKit::WebResourceLoadStatisticsStore::applicationWillTerminate):
+        * UIProcess/WebResourceLoadStatisticsStore.h: Added.
+        (WebKit::WebResourceLoadStatisticsStore::coreStore):
+        * UIProcess/WebResourceLoadStatisticsStore.messages.in: Added.
+        * UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
+        (WebKit::WebsiteDataStore::platformInitialize): Register a termination handler
+        to close down the resource load statistics store.
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::WebsiteDataStore): Initialize the new WebResourceLoadStatisticsStore
+        member.
+        (WebKit::WebsiteDataStore::webProcessWillOpenConnection): Register the WebResourceLoadStatisticsStore
+        object as a work queue message receiver
+        (WebKit::WebsiteDataStore::webProcessDidCloseConnection): Unregister WebResourceLoadStatisticsStore.
+        (WebKit::WebsiteDataStore::resourceLoadStatisticsEnabled): Added.
+        (WebKit::WebsiteDataStore::setResourceLoadStatisticsEnabled): Ditto.
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+        (WebKit::WebsiteDataStore::resourceLoadStatisticsStore): Added.
+        * WebKit2.xcodeproj/project.pbxproj: Add new ResourceLoadStatisticsState files to build.
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::initializeWebProcess): Take into account the new parameter
+        specifying whether resource load statistics are being captured.
+        (WebKit::WebProcess::WebProcess): Initialized statistics changed notification timer.
+        (WebKit::WebProcess::statisticsChangedTimerFired): Added. Send bundles of site load
+        statistics to the UIProcess on a set interval. Clear out local cache after each send.
+        (WebKit::WebProcess::setResourceLoadStatisticsEnabled): Added.
+        * WebProcess/WebProcess.h:
+        * WebProcess/WebProcess.messages.in: Add new SetResourceLoadStatisticsEnabled message.
+
</ins><span class="cx"> 2016-03-04  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Temporarily use bundle identifier as part of user directory suffix
</span></span></pre></div>
<a id="trunkSourceWebKit2DerivedSourcesmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/DerivedSources.make (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/DerivedSources.make        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/DerivedSources.make        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -131,6 +131,7 @@
</span><span class="cx">     WebProcessPool \
</span><span class="cx">     WebProcessProxy \
</span><span class="cx">     WebResourceLoader \
</span><ins>+    WebResourceLoadStatisticsStore \
</ins><span class="cx">     WebUserContentController \
</span><span class="cx">     WebUserContentControllerProxy \
</span><span class="cx">     WebVideoFullscreenManager \
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformIPCArgumentCodersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Platform/IPC/ArgumentCoders.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Platform/IPC/ArgumentCoders.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/Platform/IPC/ArgumentCoders.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -30,6 +30,7 @@
</span><span class="cx"> #include &quot;ArgumentEncoder.h&quot;
</span><span class="cx"> #include &lt;utility&gt;
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><ins>+#include &lt;wtf/HashCountedSet.h&gt;
</ins><span class="cx"> #include &lt;wtf/HashMap.h&gt;
</span><span class="cx"> #include &lt;wtf/HashSet.h&gt;
</span><span class="cx"> #include &lt;wtf/OptionSet.h&gt;
</span><span class="lines">@@ -300,6 +301,47 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+template&lt;typename KeyArg, typename HashArg, typename KeyTraitsArg&gt; struct ArgumentCoder&lt;HashCountedSet&lt;KeyArg, HashArg, KeyTraitsArg&gt;&gt; {
+    typedef HashCountedSet&lt;KeyArg, HashArg, KeyTraitsArg&gt; HashCountedSetType;
+    
+    static void encode(ArgumentEncoder&amp; encoder, const HashCountedSetType&amp; hashCountedSet)
+    {
+        encoder &lt;&lt; static_cast&lt;uint64_t&gt;(hashCountedSet.size());
+        
+        for (auto entry : hashCountedSet) {
+            encoder &lt;&lt; entry.key;
+            encoder &lt;&lt; entry.value;
+        }
+    }
+    
+    static bool decode(ArgumentDecoder&amp; decoder, HashCountedSetType&amp; hashCountedSet)
+    {
+        uint64_t hashCountedSetSize;
+        if (!decoder.decode(hashCountedSetSize))
+            return false;
+        
+        HashCountedSetType tempHashCountedSet;
+        for (uint64_t i = 0; i &lt; hashCountedSetSize; ++i) {
+            KeyArg key;
+            if (!decoder.decode(key))
+                return false;
+            
+            unsigned count;
+            if (!decoder.decode(count))
+                return false;
+            
+            if (!tempHashCountedSet.add(key, count).isNewEntry) {
+                // The hash counted set already has the specified key, bail.
+                decoder.markInvalid();
+                return false;
+            }
+        }
+        
+        hashCountedSet.swap(tempHashCountedSet);
+        return true;
+    }
+};
+
</ins><span class="cx"> template&lt;&gt; struct ArgumentCoder&lt;std::chrono::system_clock::time_point&gt; {
</span><span class="cx">     static void encode(ArgumentEncoder&amp;, const std::chrono::system_clock::time_point&amp;);
</span><span class="cx">     static bool decode(ArgumentDecoder&amp;, std::chrono::system_clock::time_point&amp;);
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformEflcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformEfl.cmake (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformEfl.cmake        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/PlatformEfl.cmake        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -66,6 +66,7 @@
</span><span class="cx">     UIProcess/BackingStore.cpp
</span><span class="cx">     UIProcess/DefaultUndoController.cpp
</span><span class="cx">     UIProcess/LegacySessionStateCodingNone.cpp
</span><ins>+    UIProcess/WebResourceLoadStatisticsStore.cpp
</ins><span class="cx"> 
</span><span class="cx">     UIProcess/API/C/CoordinatedGraphics/WKView.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformGTKcmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformGTK.cmake (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformGTK.cmake        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/PlatformGTK.cmake        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -94,6 +94,7 @@
</span><span class="cx">     UIProcess/DefaultUndoController.cpp
</span><span class="cx">     UIProcess/DrawingAreaProxyImpl.cpp
</span><span class="cx">     UIProcess/LegacySessionStateCodingNone.cpp
</span><ins>+    UIProcess/WebResourceLoadStatisticsStore.cpp
</ins><span class="cx"> 
</span><span class="cx">     UIProcess/API/C/cairo/WKIconDatabaseCairo.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2PlatformMaccmake"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/PlatformMac.cmake (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/PlatformMac.cmake        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/PlatformMac.cmake        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -138,6 +138,7 @@
</span><span class="cx">     Shared/mac/WebMemorySampler.mac.mm
</span><span class="cx"> 
</span><span class="cx">     UIProcess/ViewGestureController.cpp
</span><ins>+    UIProcess/WebResourceLoadStatisticsStore.cpp
</ins><span class="cx"> 
</span><span class="cx">     UIProcess/Automation/WebAutomationSession.cpp
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedAPIAPIObjecth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/API/APIObject.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/API/APIObject.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/Shared/API/APIObject.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -138,6 +138,7 @@
</span><span class="cx">         ProcessPoolConfiguration,
</span><span class="cx">         PluginSiteDataManager,
</span><span class="cx">         Preferences,
</span><ins>+        ResourceLoadStatisticsStore,
</ins><span class="cx">         RunBeforeUnloadConfirmPanelResultListener,
</span><span class="cx">         RunJavaScriptAlertResultListener,
</span><span class="cx">         RunJavaScriptConfirmResultListener,
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCoderscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2011-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -52,6 +52,7 @@
</span><span class="cx"> #include &lt;WebCore/ProtectionSpace.h&gt;
</span><span class="cx"> #include &lt;WebCore/Region.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceError.h&gt;
</span><ins>+#include &lt;WebCore/ResourceLoadStatistics.h&gt;
</ins><span class="cx"> #include &lt;WebCore/ResourceRequest.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceResponse.h&gt;
</span><span class="cx"> #include &lt;WebCore/ScrollingConstraints.h&gt;
</span><span class="lines">@@ -2044,4 +2045,125 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void ArgumentCoder&lt;ResourceLoadStatistics&gt;::encode(ArgumentEncoder&amp; encoder, const WebCore::ResourceLoadStatistics&amp; statistics)
+{
+    encoder &lt;&lt; statistics.highLevelDomain;
+    
+    // User interaction
+    encoder &lt;&lt; statistics.hadUserInteraction;
+    
+    // Top frame stats
+    encoder &lt;&lt; statistics.topFrameHasBeenNavigatedToBefore;
+    encoder &lt;&lt; statistics.topFrameHasBeenRedirectedTo;
+    encoder &lt;&lt; statistics.topFrameHasBeenRedirectedFrom;
+    encoder &lt;&lt; statistics.topFrameInitialLoadCount;
+    encoder &lt;&lt; statistics.topFrameHasBeenNavigatedTo;
+    encoder &lt;&lt; statistics.topFrameHasBeenNavigatedFrom;
+    
+    // Subframe stats
+    encoder &lt;&lt; statistics.subframeHasBeenLoadedBefore;
+    encoder &lt;&lt; statistics.subframeHasBeenRedirectedTo;
+    encoder &lt;&lt; statistics.subframeHasBeenRedirectedFrom;
+    encoder &lt;&lt; statistics.subframeSubResourceCount;
+    encoder &lt;&lt; statistics.subframeUnderTopFrameOrigins;
+    encoder &lt;&lt; statistics.subframeUniqueRedirectsTo;
+    encoder &lt;&lt; statistics.subframeHasBeenNavigatedTo;
+    encoder &lt;&lt; statistics.subframeHasBeenNavigatedFrom;
+    
+    // Subresource stats
+    encoder &lt;&lt; statistics.subresourceHasBeenRedirectedFrom;
+    encoder &lt;&lt; statistics.subresourceHasBeenRedirectedTo;
+    encoder &lt;&lt; statistics.subresourceHasBeenSubresourceCount;
+    encoder &lt;&lt; statistics.subresourceHasBeenSubresourceCountDividedByTotalNumberOfOriginsVisited;
+    encoder &lt;&lt; statistics.subresourceUnderTopFrameOrigins;
+    encoder &lt;&lt; statistics.subresourceUniqueRedirectsTo;
+    
+    // Prevalent Resource
+    encoder &lt;&lt; statistics.redirectedToOtherPrevalentResourceOrigins;
+    encoder &lt;&lt; statistics.isPrevalentResource;
+}
+
+bool ArgumentCoder&lt;ResourceLoadStatistics&gt;::decode(ArgumentDecoder&amp; decoder, WebCore::ResourceLoadStatistics&amp; statistics)
+{
+    if (!decoder.decode(statistics.highLevelDomain))
+        return false;
+    
+    // User interaction
+    if (!decoder.decode(statistics.hadUserInteraction))
+        return false;
+    
+    // Top frame stats
+    if (!decoder.decode(statistics.topFrameHasBeenNavigatedToBefore))
+        return false;
+    
+    if (!decoder.decode(statistics.topFrameHasBeenRedirectedTo))
+        return false;
+    
+    if (!decoder.decode(statistics.topFrameHasBeenRedirectedFrom))
+        return false;
+    
+    if (!decoder.decode(statistics.topFrameInitialLoadCount))
+        return false;
+    
+    if (!decoder.decode(statistics.topFrameHasBeenNavigatedTo))
+        return false;
+    
+    if (!decoder.decode(statistics.topFrameHasBeenNavigatedFrom))
+        return false;
+    
+    // Subframe stats
+    if (!decoder.decode(statistics.subframeHasBeenLoadedBefore))
+        return false;
+    
+    if (!decoder.decode(statistics.subframeHasBeenRedirectedTo))
+        return false;
+    
+    if (!decoder.decode(statistics.subframeHasBeenRedirectedFrom))
+        return false;
+    
+    if (!decoder.decode(statistics.subframeSubResourceCount))
+        return false;
+    
+    if (!decoder.decode(statistics.subframeUnderTopFrameOrigins))
+        return false;
+
+    if (!decoder.decode(statistics.subframeUniqueRedirectsTo))
+        return false;
+    
+    if (!decoder.decode(statistics.subframeHasBeenNavigatedTo))
+        return false;
+    
+    if (!decoder.decode(statistics.subframeHasBeenNavigatedFrom))
+        return false;
+    
+    // Subresource stats
+    if (!decoder.decode(statistics.subresourceHasBeenRedirectedFrom))
+        return false;
+    
+    if (!decoder.decode(statistics.subresourceHasBeenRedirectedTo))
+        return false;
+    
+    if (!decoder.decode(statistics.subresourceHasBeenSubresourceCount))
+        return false;
+    
+    if (!decoder.decode(statistics.subresourceHasBeenSubresourceCountDividedByTotalNumberOfOriginsVisited))
+        return false;
+    
+    if (!decoder.decode(statistics.subresourceUnderTopFrameOrigins))
+        return false;
+
+    if (!decoder.decode(statistics.subresourceUniqueRedirectsTo))
+        return false;
+    
+    // Prevalent Resource
+    if (!decoder.decode(statistics.redirectedToOtherPrevalentResourceOrigins))
+        return false;
+    
+    if (!decoder.decode(statistics.isPrevalentResource))
+        return false;
+    
+    return true;
+}
+
+
</ins><span class="cx"> } // namespace IPC
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebCoreArgumentCodersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -80,6 +80,7 @@
</span><span class="cx"> struct PasteboardWebContent;
</span><span class="cx"> struct PluginInfo;
</span><span class="cx"> struct RecentSearch;
</span><ins>+struct ResourceLoadStatistics;
</ins><span class="cx"> struct ScrollableAreaParameters;
</span><span class="cx"> struct TextCheckingResult;
</span><span class="cx"> struct TextIndicatorData;
</span><span class="lines">@@ -455,6 +456,11 @@
</span><span class="cx">     static bool decode(ArgumentDecoder&amp;, WebCore::ExceptionDetails&amp;);
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+template&lt;&gt; struct ArgumentCoder&lt;WebCore::ResourceLoadStatistics&gt; {
+    static void encode(ArgumentEncoder&amp;, const WebCore::ResourceLoadStatistics&amp;);
+    static bool decode(ArgumentDecoder&amp;, WebCore::ResourceLoadStatistics&amp;);
+};
+
</ins><span class="cx"> } // namespace IPC
</span><span class="cx"> 
</span><span class="cx"> #if USE(APPLE_INTERNAL_SDK)
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebProcessCreationParameterscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/Shared/WebProcessCreationParameters.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -96,6 +96,7 @@
</span><span class="cx">     encoder &lt;&lt; shouldEnableMemoryPressureReliefLogging;
</span><span class="cx">     encoder &lt;&lt; shouldSuppressMemoryPressureHandler;
</span><span class="cx">     encoder &lt;&lt; shouldUseFontSmoothing;
</span><ins>+    encoder &lt;&lt; resourceLoadStatisticsEnabled;
</ins><span class="cx">     encoder &lt;&lt; fontWhitelist;
</span><span class="cx">     encoder &lt;&lt; iconDatabaseEnabled;
</span><span class="cx">     encoder &lt;&lt; shouldRewriteConstAsVar;
</span><span class="lines">@@ -213,6 +214,8 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(parameters.shouldUseFontSmoothing))
</span><span class="cx">         return false;
</span><ins>+    if (!decoder.decode(parameters.resourceLoadStatisticsEnabled))
+        return false;
</ins><span class="cx">     if (!decoder.decode(parameters.fontWhitelist))
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(parameters.iconDatabaseEnabled))
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedWebProcessCreationParametersh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/Shared/WebProcessCreationParameters.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -107,6 +107,7 @@
</span><span class="cx">     bool shouldEnableMemoryPressureReliefLogging;
</span><span class="cx">     bool shouldSuppressMemoryPressureHandler { false };
</span><span class="cx">     bool shouldUseFontSmoothing;
</span><ins>+    bool resourceLoadStatisticsEnabled { false };
</ins><span class="cx"> 
</span><span class="cx">     Vector&lt;String&gt; fontWhitelist;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIProcessPoolConfigurationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/APIProcessPoolConfiguration.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -103,6 +103,7 @@
</span><span class="cx">     WTF::String m_localStorageDirectory;
</span><span class="cx">     WTF::String m_webSQLDatabaseDirectory;
</span><span class="cx">     WTF::String m_mediaKeysStorageDirectory;
</span><ins>+    WTF::String m_resourceLoadStatisticsDirectory;
</ins><span class="cx">     Vector&lt;WTF::String&gt; m_cachePartitionedURLSchemes;
</span><span class="cx">     Vector&lt;WTF::String&gt; m_alwaysRevalidatedURLSchemes;
</span><span class="cx">     bool m_fullySynchronousModeIsAllowedForTesting { false };
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIWebsiteDataStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -120,6 +120,12 @@
</span><span class="cx">     return String();
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String WebsiteDataStore::defaultResourceLoadStatisticsDirectory()
+{
+    // FIXME: Implement.
+    return String();
+}
+
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIAPIWebsiteDataStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/APIWebsiteDataStore.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -51,6 +51,7 @@
</span><span class="cx">     static String defaultLocalStorageDirectory();
</span><span class="cx">     static String defaultMediaKeysStorageDirectory();
</span><span class="cx">     static String defaultWebSQLDatabaseDirectory();
</span><ins>+    static String defaultResourceLoadStatisticsDirectory();
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     WebsiteDataStore(WebKit::WebsiteDataStore::Configuration);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaAPIWebsiteDataStoreCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/APIWebsiteDataStoreCocoa.mm        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -77,6 +77,11 @@
</span><span class="cx">     return websiteDataDirectoryFileSystemRepresentation(&quot;WebSQL&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String WebsiteDataStore::defaultResourceLoadStatisticsDirectory()
+{
+    return websiteDataDirectoryFileSystemRepresentation(&quot;ResourceLoadStatistics&quot;);
+}
+
</ins><span class="cx"> String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String&amp; directoryName)
</span><span class="cx"> {
</span><span class="cx">     static dispatch_once_t onceToken;
</span><span class="lines">@@ -143,6 +148,7 @@
</span><span class="cx">     configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory();
</span><span class="cx">     configuration.localStorageDirectory = defaultLocalStorageDirectory();
</span><span class="cx">     configuration.mediaKeysStorageDirectory = defaultMediaKeysStorageDirectory();
</span><ins>+    configuration.resourceLoadStatisticsDirectory = defaultResourceLoadStatisticsDirectory();
</ins><span class="cx"> 
</span><span class="cx">     return configuration;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014, 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -357,6 +357,7 @@
</span><span class="cx">     [_configuration _validate];
</span><span class="cx"> 
</span><span class="cx">     WebKit::WebProcessPool&amp; processPool = *[_configuration processPool]-&gt;_processPool;
</span><ins>+    processPool.setResourceLoadStatisticsEnabled(configuration.websiteDataStore._resourceLoadStatisticsEnabled);
</ins><span class="cx">     
</span><span class="cx">     auto pageConfiguration = API::PageConfiguration::create();
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebsiteDataStoremm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStore.mm        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStore.mm        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014, 2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -164,6 +164,16 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (BOOL)_resourceLoadStatisticsEnabled
+{
+    return _websiteDataStore-&gt;websiteDataStore().resourceLoadStatisticsEnabled();
+}
+
+- (void)_setResourceLoadStatisticsEnabled:(BOOL)enabled
+{
+    _websiteDataStore-&gt;websiteDataStore().setResourceLoadStatisticsEnabled(enabled);
+}
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> #endif // WK_API_ENABLED
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebsiteDataStorePrivateh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -37,6 +37,8 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_fetchDataRecordsOfTypes:(WK_SET(NSString *) *)dataTypes withOptions:(_WKWebsiteDataStoreFetchOptions)options completionHandler:(void (^)(WK_ARRAY(WKWebsiteDataRecord *) *))completionHandler;
</span><span class="cx"> 
</span><ins>+@property (nonatomic, setter=_setResourceLoadStatisticsEnabled:) BOOL _resourceLoadStatisticsEnabled WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
+
</ins><span class="cx"> @end
</span><span class="cx"> 
</span><span class="cx"> NS_ASSUME_NONNULL_END
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIeflAPIWebsiteDataStoreEflcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/efl/APIWebsiteDataStoreEfl.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/efl/APIWebsiteDataStoreEfl.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/efl/APIWebsiteDataStoreEfl.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -67,6 +67,11 @@
</span><span class="cx">     return websiteDataDirectoryFileSystemRepresentation(&quot;WebKitEfl&quot; EINA_PATH_SEP_S &quot;Databases&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String WebsiteDataStore::defaultResourceLoadStatisticsDirectory()
+{
+    return websiteDataDirectoryFileSystemRepresentation(&quot;WebKitEfl&quot; EINA_PATH_SEP_S &quot;ResourceLoadStatistics&quot;);
+}
+
</ins><span class="cx"> String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String&amp; directoryName)
</span><span class="cx"> {
</span><span class="cx">     return WebCore::pathByAppendingComponent(String::fromUTF8(efreet_cache_home_get()), directoryName);
</span><span class="lines">@@ -87,6 +92,7 @@
</span><span class="cx">     configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory();
</span><span class="cx">     configuration.localStorageDirectory = defaultLocalStorageDirectory();
</span><span class="cx">     configuration.mediaKeysStorageDirectory = defaultMediaKeysStorageDirectory();
</span><ins>+    configuration.resourceLoadStatisticsDirectory = defaultResourceLoadStatisticsDirectory();
</ins><span class="cx"> 
</span><span class="cx">     return configuration;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPIgtkAPIWebsiteDataStoreGtkcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/API/gtk/APIWebsiteDataStoreGtk.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -65,6 +65,11 @@
</span><span class="cx">     return websiteDataDirectoryFileSystemRepresentation(&quot;webkitgtk&quot; G_DIR_SEPARATOR_S &quot;databases&quot;);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+String WebsiteDataStore::defaultResourceLoadStatisticsDirectory()
+{
+    return websiteDataDirectoryFileSystemRepresentation(&quot;webkitgtk&quot; G_DIR_SEPARATOR_S &quot;ResourceLoadStatistics&quot;);
+}
+
</ins><span class="cx"> String WebsiteDataStore::cacheDirectoryFileSystemRepresentation(const String&amp; directoryName)
</span><span class="cx"> {
</span><span class="cx">     return WebCore::pathByAppendingComponent(WebCore::filenameToString(g_get_user_cache_dir()), directoryName);
</span><span class="lines">@@ -85,6 +90,7 @@
</span><span class="cx">     configuration.webSQLDatabaseDirectory = defaultWebSQLDatabaseDirectory();
</span><span class="cx">     configuration.localStorageDirectory = defaultLocalStorageDirectory();
</span><span class="cx">     configuration.mediaKeysStorageDirectory = defaultMediaKeysStorageDirectory();
</span><ins>+    configuration.resourceLoadStatisticsDirectory = defaultResourceLoadStatisticsDirectory();
</ins><span class="cx"> 
</span><span class="cx">     return configuration;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessPoolcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -621,6 +621,8 @@
</span><span class="cx">     parameters.shouldEnableMemoryPressureReliefLogging = true;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    parameters.resourceLoadStatisticsEnabled = resourceLoadStatisticsEnabled();
+
</ins><span class="cx">     // Add any platform specific parameters
</span><span class="cx">     platformInitializeWebProcess(parameters);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebProcessPoolh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebProcessPool.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebProcessPool.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/WebProcessPool.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010, 2011, 2012, 2013 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -363,6 +363,9 @@
</span><span class="cx">     static String legacyPlatformDefaultNetworkCacheDirectory();
</span><span class="cx">     static bool isNetworkCacheEnabled();
</span><span class="cx"> 
</span><ins>+    bool resourceLoadStatisticsEnabled() { return m_resourceLoadStatisticsEnabled; }
+    void setResourceLoadStatisticsEnabled(bool enabled) { m_resourceLoadStatisticsEnabled = enabled; }
+
</ins><span class="cx"> private:
</span><span class="cx">     void platformInitialize();
</span><span class="cx"> 
</span><span class="lines">@@ -514,6 +517,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     bool m_memoryCacheDisabled;
</span><ins>+    bool m_resourceLoadStatisticsEnabled { false };
</ins><span class="cx"> 
</span><span class="cx">     UserObservablePageCounter m_userObservablePageCounter;
</span><span class="cx">     ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStorecpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp (0 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -0,0 +1,97 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 &quot;config.h&quot;
+#include &quot;WebResourceLoadStatisticsStore.h&quot;
+
+#include &quot;WebProcessMessages.h&quot;
+#include &quot;WebProcessPool.h&quot;
+#include &quot;WebResourceLoadStatisticsStoreMessages.h&quot;
+#include &lt;WebCore/ResourceLoadStatisticsStore.h&gt;
+
+using namespace WebCore;
+
+namespace WebKit {
+
+Ref&lt;WebResourceLoadStatisticsStore&gt; WebResourceLoadStatisticsStore::create(const String&amp; resourceLoadStatisticsDirectory)
+{
+    return adoptRef(*new WebResourceLoadStatisticsStore(resourceLoadStatisticsDirectory));
+}
+
+WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String&amp; resourceLoadStatisticsDirectory)
+    : m_resourceStatisticsStore(WebCore::ResourceLoadStatisticsStore::create(resourceLoadStatisticsDirectory))
+{
+}
+
+WebResourceLoadStatisticsStore::~WebResourceLoadStatisticsStore()
+{
+}
+
+void WebResourceLoadStatisticsStore::resourceLoadStatisticsUpdated(const Vector&lt;WebCore::ResourceLoadStatistics&gt;&amp; origins)
+{
+    coreStore().mergeStatistics(origins);
+}
+
+void WebResourceLoadStatisticsStore::setResourceLoadStatisticsEnabled(bool enabled)
+{
+    if (enabled == m_resourceLoadStatisticsEnabled)
+        return;
+
+    m_resourceLoadStatisticsEnabled = enabled;
+
+    readDataFromDiskIfNeeded();
+}
+
+bool WebResourceLoadStatisticsStore::resourceLoadStatisticsEnabled() const
+{
+    return m_resourceLoadStatisticsEnabled;
+}
+
+void WebResourceLoadStatisticsStore::readDataFromDiskIfNeeded()
+{
+    if (!m_resourceLoadStatisticsEnabled)
+        return;
+
+    coreStore().readDataFromDiskIfNeeded();
+}
+
+void WebResourceLoadStatisticsStore::writeToDisk()
+{
+    if (!m_resourceLoadStatisticsEnabled)
+        return;
+    
+    coreStore().writeDataToDisk();
+}
+
+void WebResourceLoadStatisticsStore::applicationWillTerminate()
+{
+    if (!m_resourceLoadStatisticsEnabled)
+        return;
+
+    // FIXME(154642): TEMPORARY CODE: This should not be done in one long operation when exiting.
+    writeToDisk();
+}
+
+} // namespace WebKit
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStoreh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h (0 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -0,0 +1,75 @@
</span><ins>+/*
+ * Copyright (C) 2016 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 WebResourceLoadStatisticsStore_h
+#define WebResourceLoadStatisticsStore_h
+
+#include &quot;APIObject.h&quot;
+#include &quot;Connection.h&quot;
+#include &lt;WebCore/ResourceLoadStatisticsStore.h&gt;
+#include &lt;wtf/HashMap.h&gt;
+#include &lt;wtf/Vector.h&gt;
+#include &lt;wtf/text/WTFString.h&gt;
+
+namespace WebCore {
+struct ResourceLoadStatistics;
+}
+
+namespace WebKit {
+
+class WebProcessPool;
+
+class WebResourceLoadStatisticsStore : public IPC::Connection::WorkQueueMessageReceiver {
+public:
+    static Ref&lt;WebResourceLoadStatisticsStore&gt; create(const String&amp;);
+    virtual ~WebResourceLoadStatisticsStore();
+    
+    void setResourceLoadStatisticsEnabled(bool);
+    bool resourceLoadStatisticsEnabled() const;
+    
+    void resourceLoadStatisticsUpdated(const Vector&lt;WebCore::ResourceLoadStatistics&gt;&amp; origins);
+
+    void applicationWillTerminate();
+
+    void writeToDisk();
+    void readDataFromDiskIfNeeded();
+
+    void mergeStatistics(const Vector&lt;WebCore::ResourceLoadStatistics&gt;&amp;);
+
+    WebCore::ResourceLoadStatisticsStore&amp; coreStore() { return m_resourceStatisticsStore.get(); }
+    
+private:
+    explicit WebResourceLoadStatisticsStore(const String&amp;);
+    
+    // IPC::MessageReceiver
+    void didReceiveMessage(IPC::Connection&amp;, IPC::MessageDecoder&amp;) override;
+    
+    Ref&lt;WebCore::ResourceLoadStatisticsStore&gt; m_resourceStatisticsStore;
+    bool m_resourceLoadStatisticsEnabled { false };
+};
+
+} // namespace WebKit
+
+#endif // WebResourceLoadStatisticsStore_h
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebResourceLoadStatisticsStoremessagesin"></a>
<div class="addfile"><h4>Added: trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.messages.in (0 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.messages.in                                (rev 0)
+++ trunk/Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.messages.in        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -0,0 +1,25 @@
</span><ins>+# Copyright (C) 2016 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.
+
+messages -&gt; WebResourceLoadStatisticsStore {
+    ResourceLoadStatisticsUpdated(Vector&lt;WebCore::ResourceLoadStatistics&gt; origins)
+}
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebsiteDataCocoaWebsiteDataStoreCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2015 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2015-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #import &quot;WebsiteDataStore.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #import &quot;StorageManager.h&quot;
</span><ins>+#import &quot;WebResourceLoadStatisticsStore.h&quot;
</ins><span class="cx"> #import &lt;WebCore/SearchPopupMenuCocoa.h&gt;
</span><span class="cx"> #import &lt;wtf/NeverDestroyed.h&gt;
</span><span class="cx"> 
</span><span class="lines">@@ -61,11 +62,14 @@
</span><span class="cx">         terminationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:notificationName object:nil queue:nil usingBlock:^(NSNotification *note) {
</span><span class="cx">             for (auto&amp; dataStore : dataStoresWithStorageManagers())
</span><span class="cx">                 dataStore-&gt;m_storageManager-&gt;applicationWillTerminate();
</span><ins>+
+            m_resourceLoadStatistics-&gt;applicationWillTerminate();
</ins><span class="cx">         }];
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     ASSERT(!dataStoresWithStorageManagers().contains(this));
</span><span class="cx">     dataStoresWithStorageManagers().append(this);
</span><ins>+    m_resourceLoadStatistics-&gt;readDataFromDiskIfNeeded();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebsiteDataStore::platformDestroy()
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStorecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -30,7 +30,10 @@
</span><span class="cx"> #include &quot;APIWebsiteDataRecord.h&quot;
</span><span class="cx"> #include &quot;NetworkProcessMessages.h&quot;
</span><span class="cx"> #include &quot;StorageManager.h&quot;
</span><ins>+#include &quot;WebProcessMessages.h&quot;
</ins><span class="cx"> #include &quot;WebProcessPool.h&quot;
</span><ins>+#include &quot;WebResourceLoadStatisticsStore.h&quot;
+#include &quot;WebResourceLoadStatisticsStoreMessages.h&quot;
</ins><span class="cx"> #include &quot;WebsiteData.h&quot;
</span><span class="cx"> #include &lt;WebCore/ApplicationCacheStorage.h&gt;
</span><span class="cx"> #include &lt;WebCore/DatabaseTracker.h&gt;
</span><span class="lines">@@ -77,6 +80,7 @@
</span><span class="cx">     , m_webSQLDatabaseDirectory(WTFMove(configuration.webSQLDatabaseDirectory))
</span><span class="cx">     , m_mediaKeysStorageDirectory(WTFMove(configuration.mediaKeysStorageDirectory))
</span><span class="cx">     , m_storageManager(StorageManager::create(WTFMove(configuration.localStorageDirectory)))
</span><ins>+    , m_resourceLoadStatistics(WebResourceLoadStatisticsStore::create(WTFMove(configuration.resourceLoadStatisticsDirectory)))
</ins><span class="cx">     , m_queue(WorkQueue::create(&quot;com.apple.WebKit.WebsiteDataStore&quot;))
</span><span class="cx"> {
</span><span class="cx">     platformInitialize();
</span><span class="lines">@@ -976,6 +980,8 @@
</span><span class="cx"> {
</span><span class="cx">     if (m_storageManager)
</span><span class="cx">         m_storageManager-&gt;processWillOpenConnection(webProcessProxy, connection);
</span><ins>+
+    connection.addWorkQueueMessageReceiver(Messages::WebResourceLoadStatisticsStore::messageReceiverName(), &amp;m_queue.get(), m_resourceLoadStatistics.get());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebsiteDataStore::webPageWillOpenConnection(WebPageProxy&amp; webPageProxy, IPC::Connection&amp; connection)
</span><span class="lines">@@ -992,6 +998,8 @@
</span><span class="cx"> 
</span><span class="cx"> void WebsiteDataStore::webProcessDidCloseConnection(WebProcessProxy&amp; webProcessProxy, IPC::Connection&amp; connection)
</span><span class="cx"> {
</span><ins>+    connection.removeWorkQueueMessageReceiver(Messages::WebResourceLoadStatisticsStore::messageReceiverName());
+
</ins><span class="cx">     if (m_storageManager)
</span><span class="cx">         m_storageManager-&gt;processDidCloseConnection(webProcessProxy, connection);
</span><span class="cx"> }
</span><span class="lines">@@ -1094,4 +1102,25 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool WebsiteDataStore::resourceLoadStatisticsEnabled() const
+{
+    return m_resourceLoadStatistics ? m_resourceLoadStatistics-&gt;resourceLoadStatisticsEnabled() : false;
</ins><span class="cx"> }
</span><ins>+
+void WebsiteDataStore::setResourceLoadStatisticsEnabled(bool enabled)
+{
+    if (!m_resourceLoadStatistics)
+        return;
+
+    if (enabled == resourceLoadStatisticsEnabled())
+        return;
+
+    m_resourceLoadStatistics-&gt;setResourceLoadStatisticsEnabled(enabled);
+
+    for (auto&amp; processPool : WebProcessPool::allProcessPools()) {
+        processPool-&gt;setResourceLoadStatisticsEnabled(enabled);
+        processPool-&gt;sendToAllProcesses(Messages::WebProcess::SetResourceLoadStatisticsEnabled(enabled));
+    }
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebsiteDataWebsiteDataStoreh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/UIProcess/WebsiteData/WebsiteDataStore.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2014-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -46,6 +46,7 @@
</span><span class="cx"> class StorageManager;
</span><span class="cx"> class WebPageProxy;
</span><span class="cx"> class WebProcessPool;
</span><ins>+class WebResourceLoadStatisticsStore;
</ins><span class="cx"> enum class WebsiteDataFetchOption;
</span><span class="cx"> enum class WebsiteDataType;
</span><span class="cx"> struct WebsiteDataRecord;
</span><span class="lines">@@ -63,6 +64,7 @@
</span><span class="cx">         String webSQLDatabaseDirectory;
</span><span class="cx">         String localStorageDirectory;
</span><span class="cx">         String mediaKeysStorageDirectory;
</span><ins>+        String resourceLoadStatisticsDirectory;
</ins><span class="cx">     };
</span><span class="cx">     static Ref&lt;WebsiteDataStore&gt; createNonPersistent();
</span><span class="cx">     static Ref&lt;WebsiteDataStore&gt; create(Configuration);
</span><span class="lines">@@ -73,6 +75,9 @@
</span><span class="cx">     bool isPersistent() const { return !m_sessionID.isEphemeral(); }
</span><span class="cx">     WebCore::SessionID sessionID() const { return m_sessionID; }
</span><span class="cx"> 
</span><ins>+    bool resourceLoadStatisticsEnabled() const;
+    void setResourceLoadStatisticsEnabled(bool);
+
</ins><span class="cx">     static void cloneSessionData(WebPageProxy&amp; sourcePage, WebPageProxy&amp; newPage);
</span><span class="cx"> 
</span><span class="cx">     void fetchData(OptionSet&lt;WebsiteDataType&gt;, OptionSet&lt;WebsiteDataFetchOption&gt;, std::function&lt;void (Vector&lt;WebsiteDataRecord&gt;)&gt; completionHandler);
</span><span class="lines">@@ -116,6 +121,7 @@
</span><span class="cx">     const String m_webSQLDatabaseDirectory;
</span><span class="cx">     const String m_mediaKeysStorageDirectory;
</span><span class="cx">     const RefPtr&lt;StorageManager&gt; m_storageManager;
</span><ins>+    const RefPtr&lt;WebResourceLoadStatisticsStore&gt; m_resourceLoadStatistics;
</ins><span class="cx"> 
</span><span class="cx">     Ref&lt;WorkQueue&gt; m_queue;
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKit2WebKit2xcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1041,6 +1041,9 @@
</span><span class="cx">                 75A8D2E1187DEC1A00C39C9E /* APISession.h in Headers */ = {isa = PBXBuildFile; fileRef = 75A8D2DE187DE87400C39C9E /* APISession.h */; };
</span><span class="cx">                 75A8D2E2187DEC1E00C39C9E /* APISession.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 75A8D2DD187DE87400C39C9E /* APISession.cpp */; };
</span><span class="cx">                 762B748D120BC75C00819339 /* WKPreferencesRefPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 762B7484120BBA2D00819339 /* WKPreferencesRefPrivate.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                7A791EFA1C7CFCF100C4C52B /* WebResourceLoadStatisticsStoreMessageReceiver.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A791EF91C7CFB3700C4C52B /* WebResourceLoadStatisticsStoreMessageReceiver.cpp */; };
+                7A791EFB1C7CFD0100C4C52B /* WebResourceLoadStatisticsStoreMessages.h in Headers */ = {isa = PBXBuildFile; fileRef = 7A791EF81C7CFB1000C4C52B /* WebResourceLoadStatisticsStoreMessages.h */; };
+                7A791EFC1C7D08C500C4C52B /* WebResourceLoadStatisticsStore.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7A9CD8C01C77984900D9F6C7 /* WebResourceLoadStatisticsStore.cpp */; };
</ins><span class="cx">                 7C135AA8173B0BCA00586AE2 /* WKPluginInformation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7C135AA6173B0BCA00586AE2 /* WKPluginInformation.cpp */; };
</span><span class="cx">                 7C135AA9173B0BCA00586AE2 /* WKPluginInformation.h in Headers */ = {isa = PBXBuildFile; fileRef = 7C135AA7173B0BCA00586AE2 /* WKPluginInformation.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><span class="cx">                 7C135AAC173B0CFF00586AE2 /* PluginInformationMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7C135AAA173B0CFF00586AE2 /* PluginInformationMac.mm */; };
</span><span class="lines">@@ -3043,6 +3046,12 @@
</span><span class="cx">                 75A8D2DE187DE87400C39C9E /* APISession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = APISession.h; path = UIProcess/API/APISession.h; sourceTree = SOURCE_ROOT; };
</span><span class="cx">                 762B7481120BBA0100819339 /* FontSmoothingLevel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FontSmoothingLevel.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 762B7484120BBA2D00819339 /* WKPreferencesRefPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPreferencesRefPrivate.h; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><ins>+                7A791EF81C7CFB1000C4C52B /* WebResourceLoadStatisticsStoreMessages.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebResourceLoadStatisticsStoreMessages.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7A791EF91C7CFB3700C4C52B /* WebResourceLoadStatisticsStoreMessageReceiver.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebResourceLoadStatisticsStoreMessageReceiver.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+        
+                7A9CD8C01C77984900D9F6C7 /* WebResourceLoadStatisticsStore.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebResourceLoadStatisticsStore.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7A9CD8C11C77984900D9F6C7 /* WebResourceLoadStatisticsStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebResourceLoadStatisticsStore.h; sourceTree = &quot;&lt;group&gt;&quot;; };
+                7A9CD8C21C779AD600D9F6C7 /* WebResourceLoadStatisticsStore.messages.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = WebResourceLoadStatisticsStore.messages.in; sourceTree = &quot;&lt;group&gt;&quot;; };
</ins><span class="cx">                 7C0BB9A818DCDE890006C086 /* WebContent-iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = &quot;WebContent-iOS.entitlements&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C0BB9A918DCDF5A0006C086 /* Network-iOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = &quot;Network-iOS.entitlements&quot;; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="cx">                 7C135AA6173B0BCA00586AE2 /* WKPluginInformation.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WKPluginInformation.cpp; sourceTree = &quot;&lt;group&gt;&quot;; };
</span><span class="lines">@@ -5801,6 +5810,9 @@
</span><span class="cx">                                 86E67A22190F411800004AB7 /* ProcessThrottler.cpp */,
</span><span class="cx">                                 86E67A21190F411800004AB7 /* ProcessThrottler.h */,
</span><span class="cx">                                 83048AE51ACA45DC0082C832 /* ProcessThrottlerClient.h */,
</span><ins>+                                7A9CD8C01C77984900D9F6C7 /* WebResourceLoadStatisticsStore.cpp */,
+                                7A9CD8C11C77984900D9F6C7 /* WebResourceLoadStatisticsStore.h */,
+                                7A9CD8C21C779AD600D9F6C7 /* WebResourceLoadStatisticsStore.messages.in */,
</ins><span class="cx">                                 BC111B08112F5E3C00337BAB /* ResponsivenessTimer.cpp */,
</span><span class="cx">                                 1A30066C1110F4F70031937C /* ResponsivenessTimer.h */,
</span><span class="cx">                                 51A4D5A816CAC4FF000E615E /* StatisticsRequest.cpp */,
</span><span class="lines">@@ -6822,6 +6834,8 @@
</span><span class="cx">                                 1AC1338418590C4600F3EC05 /* RemoteObjectRegistryMessages.h */,
</span><span class="cx">                                 0F5947A5187B517600437857 /* RemoteScrollingCoordinatorMessageReceiver.cpp */,
</span><span class="cx">                                 0F5947A6187B517600437857 /* RemoteScrollingCoordinatorMessages.h */,
</span><ins>+                                7A791EF91C7CFB3700C4C52B /* WebResourceLoadStatisticsStoreMessageReceiver.cpp */,
+                                7A791EF81C7CFB1000C4C52B /* WebResourceLoadStatisticsStoreMessages.h */,
</ins><span class="cx">                                 E18E6911169B667B009B6670 /* SecItemShimMessageReceiver.cpp */,
</span><span class="cx">                                 E18E6912169B667B009B6670 /* SecItemShimMessages.h */,
</span><span class="cx">                                 E18E6913169B667B009B6670 /* SecItemShimProxyMessageReceiver.cpp */,
</span><span class="lines">@@ -7434,6 +7448,7 @@
</span><span class="cx">                                 1A0EC75E124BC7B2007EF4A5 /* PluginProcessProxy.h in Headers */,
</span><span class="cx">                                 1A043B5E124D5E9D00FFBFB5 /* PluginProcessProxyMessages.h in Headers */,
</span><span class="cx">                                 1A043DC1124FF87500FFBFB5 /* PluginProxy.h in Headers */,
</span><ins>+                                7A791EFB1C7CFD0100C4C52B /* WebResourceLoadStatisticsStoreMessages.h in Headers */,
</ins><span class="cx">                                 1A8EFA711252B84100F7067F /* PluginProxyMessages.h in Headers */,
</span><span class="cx">                                 1A4A9F3312B844E2008FE984 /* PluginQuirks.h in Headers */,
</span><span class="cx">                                 7CD622781739D863005BD7FF /* PluginSandboxProfile.h in Headers */,
</span><span class="lines">@@ -8844,6 +8859,7 @@
</span><span class="cx">                                 1A2D84A4127F6AD1001EB962 /* NPVariantData.cpp in Sources */,
</span><span class="cx">                                 BC8ACA1416670D89004C1941 /* ObjCObjectGraph.mm in Sources */,
</span><span class="cx">                                 BCCF673312C7F15C008F9C35 /* OriginAndDatabases.cpp in Sources */,
</span><ins>+                                7A791EFA1C7CFCF100C4C52B /* WebResourceLoadStatisticsStoreMessageReceiver.cpp in Sources */,
</ins><span class="cx">                                 7C387434172F5615001BD88A /* PageBanner.cpp in Sources */,
</span><span class="cx">                                 5C052F261C6D3BD30076E919 /* AuthenticationManagerCocoa.mm in Sources */,
</span><span class="cx">                                 7C6D37FC172F555F009D2847 /* PageBannerMac.mm in Sources */,
</span><span class="lines">@@ -9223,6 +9239,7 @@
</span><span class="cx">                                 EDCA71B7128DDA8C00201B26 /* WKBundlePageOverlay.cpp in Sources */,
</span><span class="cx">                                 BC60C57A1240A546008C5E29 /* WKBundleRangeHandle.cpp in Sources */,
</span><span class="cx">                                 BC14DF9E120B635F00826C0C /* WKBundleScriptWorld.cpp in Sources */,
</span><ins>+                                7A791EFC1C7D08C500C4C52B /* WebResourceLoadStatisticsStore.cpp in Sources */,
</ins><span class="cx">                                 5C1427121C23F89E00D41183 /* DownloadMac.mm in Sources */,
</span><span class="cx">                                 BC4075F5124FF0270068F20A /* WKCertificateInfo.cpp in Sources */,
</span><span class="cx">                                 BC407628124FF0400068F20A /* WKCertificateInfoMac.mm in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2009, 2010, 2012, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2009-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -58,6 +58,7 @@
</span><span class="cx"> #include &quot;WebProcessMessages.h&quot;
</span><span class="cx"> #include &quot;WebProcessPoolMessages.h&quot;
</span><span class="cx"> #include &quot;WebProcessProxyMessages.h&quot;
</span><ins>+#include &quot;WebResourceLoadStatisticsStoreMessages.h&quot;
</ins><span class="cx"> #include &quot;WebsiteData.h&quot;
</span><span class="cx"> #include &quot;WebsiteDataType.h&quot;
</span><span class="cx"> #include &lt;JavaScriptCore/JSLock.h&gt;
</span><span class="lines">@@ -86,6 +87,9 @@
</span><span class="cx"> #include &lt;WebCore/PageGroup.h&gt;
</span><span class="cx"> #include &lt;WebCore/PlatformMediaSessionManager.h&gt;
</span><span class="cx"> #include &lt;WebCore/ResourceHandle.h&gt;
</span><ins>+#include &lt;WebCore/ResourceLoadObserver.h&gt;
+#include &lt;WebCore/ResourceLoadStatistics.h&gt;
+#include &lt;WebCore/ResourceLoadStatisticsStore.h&gt;
</ins><span class="cx"> #include &lt;WebCore/RuntimeApplicationChecks.h&gt;
</span><span class="cx"> #include &lt;WebCore/RuntimeEnabledFeatures.h&gt;
</span><span class="cx"> #include &lt;WebCore/SchemeRegistry.h&gt;
</span><span class="lines">@@ -166,9 +170,11 @@
</span><span class="cx">     , m_hasRichContentServices(false)
</span><span class="cx"> #endif
</span><span class="cx">     , m_nonVisibleProcessCleanupTimer(*this, &amp;WebProcess::nonVisibleProcessCleanupTimerFired)
</span><ins>+    , m_statisticsChangedTimer(*this, &amp;WebProcess::statisticsChangedTimerFired)
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     , m_webSQLiteDatabaseTracker(*this)
</span><span class="cx"> #endif
</span><ins>+    , m_resourceLoadStatisticsStorage(WebCore::ResourceLoadStatisticsStore::create())
</ins><span class="cx"> {
</span><span class="cx">     // Initialize our platform strategies.
</span><span class="cx">     WebPlatformStrategies::initialize();
</span><span class="lines">@@ -198,6 +204,14 @@
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     PageCache::singleton().setShouldClearBackingStores(true);
</span><span class="cx"> #endif
</span><ins>+
+    ResourceLoadObserver::sharedObserver().setStatisticsStore(m_resourceLoadStatisticsStorage.copyRef());
+    m_resourceLoadStatisticsStorage-&gt;setNotificationCallback([this] {
+        if (m_statisticsChangedTimer.isActive())
+            return;
+        
+        m_statisticsChangedTimer.startOneShot(std::chrono::seconds(5));
+    });
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> WebProcess::~WebProcess()
</span><span class="lines">@@ -321,6 +335,8 @@
</span><span class="cx"> 
</span><span class="cx">     setDefaultRequestTimeoutInterval(parameters.defaultRequestTimeoutInterval);
</span><span class="cx"> 
</span><ins>+    setResourceLoadStatisticsEnabled(parameters.resourceLoadStatisticsEnabled);
+
</ins><span class="cx">     if (parameters.shouldAlwaysUseComplexTextCodePath)
</span><span class="cx">         setAlwaysUsesComplexTextCodePath(true);
</span><span class="cx"> 
</span><span class="lines">@@ -1285,6 +1301,19 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebProcess::statisticsChangedTimerFired()
+{
+    if (m_resourceLoadStatisticsStorage-&gt;isEmpty())
+        return;
+
+    parentProcessConnection()-&gt;send(Messages::WebResourceLoadStatisticsStore::ResourceLoadStatisticsUpdated(m_resourceLoadStatisticsStorage-&gt;takeStatistics()), 0);
+}
+
+void WebProcess::setResourceLoadStatisticsEnabled(bool enabled)
+{
+    WebCore::Settings::setResourceLoadStatisticsEnabled(enabled);
+}
+
</ins><span class="cx"> RefPtr&lt;API::Object&gt; WebProcess::transformHandlesToObjects(API::Object* object)
</span><span class="cx"> {
</span><span class="cx">     struct Transformer final : UserData::Transformer {
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcessh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.h (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.h        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.h        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -37,6 +37,7 @@
</span><span class="cx"> #include &quot;ViewUpdateDispatcher.h&quot;
</span><span class="cx"> #include &quot;VisitedLinkTable.h&quot;
</span><span class="cx"> #include &lt;WebCore/HysteresisActivity.h&gt;
</span><ins>+#include &lt;WebCore/ResourceLoadStatisticsStore.h&gt;
</ins><span class="cx"> #include &lt;WebCore/SessionID.h&gt;
</span><span class="cx"> #include &lt;WebCore/Timer.h&gt;
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><span class="lines">@@ -170,6 +171,7 @@
</span><span class="cx">     void pageWillLeaveWindow(uint64_t pageID);
</span><span class="cx"> 
</span><span class="cx">     void nonVisibleProcessCleanupTimerFired();
</span><ins>+    void statisticsChangedTimerFired();
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(COCOA)
</span><span class="cx">     void destroyRenderingResources();
</span><span class="lines">@@ -232,6 +234,7 @@
</span><span class="cx">     void setDefaultRequestTimeoutInterval(double);
</span><span class="cx">     void setAlwaysUsesComplexTextCodePath(bool);
</span><span class="cx">     void setShouldUseFontSmoothing(bool);
</span><ins>+    void setResourceLoadStatisticsEnabled(bool);
</ins><span class="cx">     void userPreferredLanguagesChanged(const Vector&lt;String&gt;&amp;) const;
</span><span class="cx">     void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled);
</span><span class="cx"> 
</span><span class="lines">@@ -362,11 +365,14 @@
</span><span class="cx"> 
</span><span class="cx">     HashSet&lt;uint64_t&gt; m_pagesInWindows;
</span><span class="cx">     WebCore::Timer m_nonVisibleProcessCleanupTimer;
</span><ins>+    WebCore::Timer m_statisticsChangedTimer;
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     WebSQLiteDatabaseTracker m_webSQLiteDatabaseTracker;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+    Ref&lt;WebCore::ResourceLoadStatisticsStore&gt; m_resourceLoadStatisticsStorage;
+
</ins><span class="cx">     ShouldAcknowledgeWhenReadyToSuspend m_shouldAcknowledgeWhenReadyToSuspend;
</span><span class="cx">     bool m_suppressMemoryPressureHandler { false };
</span><span class="cx"> };
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcessmessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.messages.in (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebProcess.messages.in        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.messages.in        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-# Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+# Copyright (C) 2010, 2016 Apple Inc. All rights reserved.
</ins><span class="cx"> #
</span><span class="cx"> # Redistribution and use in source and binary forms, with or without
</span><span class="cx"> # modification, are permitted provided that the following conditions
</span><span class="lines">@@ -42,6 +42,7 @@
</span><span class="cx">     SetDefaultRequestTimeoutInterval(double timeoutInterval)
</span><span class="cx">     SetAlwaysUsesComplexTextCodePath(bool alwaysUseComplexText)
</span><span class="cx">     SetShouldUseFontSmoothing(bool useFontSmoothing)
</span><ins>+    SetResourceLoadStatisticsEnabled(bool resourceLoadStatisticsEnabled);
</ins><span class="cx">     UserPreferredLanguagesChanged(Vector&lt;String&gt; languages)
</span><span class="cx">     FullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled)
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Tools/ChangeLog        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,3 +1,20 @@
</span><ins>+2016-03-04  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        [WK2] Gather resource load statistics
+        https://bugs.webkit.org/show_bug.cgi?id=154278
+        &lt;rdar://problem/24702892&gt;
+
+        Reviewed by Andy Estes.
+
+        * MiniBrowser/mac/AppDelegate.m:
+        (defaultConfiguration): Retrieve state of the ResourceLoadStatisticsEnabled setting.
+        * MiniBrowser/mac/SettingsController.m:
+        (-[SettingsController _populateMenu]): Move setting from WK1-only to be
+        universally applicable.
+        * MiniBrowser/mac/WK2BrowserWindowController.m:
+        (-[WK2BrowserWindowController didChangeSettings]): Recognize when the
+        Resource Load Statistics flag has changed.
+
</ins><span class="cx"> 2016-03-04  Alex Christensen  &lt;achristensen@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Remove vcxproj build system
</span></span></pre></div>
<a id="trunkToolsMiniBrowsermacAppDelegatem"></a>
<div class="modfile"><h4>Modified: trunk/Tools/MiniBrowser/mac/AppDelegate.m (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/mac/AppDelegate.m        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Tools/MiniBrowser/mac/AppDelegate.m        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> #import &lt;WebKit/WKProcessPoolPrivate.h&gt;
</span><span class="cx"> #import &lt;WebKit/WKUserContentControllerPrivate.h&gt;
</span><span class="cx"> #import &lt;WebKit/WKWebViewConfigurationPrivate.h&gt;
</span><ins>+#import &lt;WebKit/WKWebsiteDataStorePrivate.h&gt;
</ins><span class="cx"> #import &lt;WebKit/WebKit.h&gt;
</span><span class="cx"> #import &lt;WebKit/_WKProcessPoolConfiguration.h&gt;
</span><span class="cx"> #import &lt;WebKit/_WKUserContentExtensionStore.h&gt;
</span><span class="lines">@@ -83,6 +84,7 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     configuration.suppressesIncrementalRendering = [SettingsController shared].incrementalRenderingSuppressed;
</span><ins>+    configuration.websiteDataStore._resourceLoadStatisticsEnabled = [SettingsController shared].resourceLoadStatisticsEnabled;
</ins><span class="cx">     return configuration;
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkToolsMiniBrowsermacSettingsControllerm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/MiniBrowser/mac/SettingsController.m (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/mac/SettingsController.m        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Tools/MiniBrowser/mac/SettingsController.m        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -113,6 +113,7 @@
</span><span class="cx">     [self _addItemWithTitle:@&quot;Suppress Incremental Rendering in New Windows&quot; action:@selector(toggleIncrementalRenderingSuppressed:) indented:NO];
</span><span class="cx">     [self _addItemWithTitle:@&quot;Enable Accelerated Drawing&quot; action:@selector(toggleAcceleratedDrawingEnabled:) indented:NO];
</span><span class="cx">     [self _addItemWithTitle:@&quot;Enable Display List Drawing&quot; action:@selector(toggleDisplayListDrawingEnabled:) indented:NO];
</span><ins>+    [self _addItemWithTitle:@&quot;Enable Resource Load Statistics&quot; action:@selector(toggleResourceLoadStatisticsEnabled:) indented:NO];
</ins><span class="cx"> 
</span><span class="cx">     [self _addHeaderWithTitle:@&quot;WebKit2-only Settings&quot;];
</span><span class="cx"> 
</span><span class="lines">@@ -141,7 +142,6 @@
</span><span class="cx"> 
</span><span class="cx">     [self _addHeaderWithTitle:@&quot;WebKit1-only Settings&quot;];
</span><span class="cx">     [self _addItemWithTitle:@&quot;Enable Subpixel CSSOM Metrics&quot; action:@selector(toggleEnableSubPixelCSSOMMetrics:) indented:YES];
</span><del>-    [self _addItemWithTitle:@&quot;Enable Resource Load Statistics&quot; action:@selector(toggleResourceLoadStatisticsEnabled:) indented:NO];
</del><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
</span></span></pre></div>
<a id="trunkToolsMiniBrowsermacWK2BrowserWindowControllerm"></a>
<div class="modfile"><h4>Modified: trunk/Tools/MiniBrowser/mac/WK2BrowserWindowController.m (197591 => 197592)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/MiniBrowser/mac/WK2BrowserWindowController.m        2016-03-04 23:28:22 UTC (rev 197591)
+++ trunk/Tools/MiniBrowser/mac/WK2BrowserWindowController.m        2016-03-04 23:29:31 UTC (rev 197592)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2010 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2010-2016 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -346,6 +346,8 @@
</span><span class="cx">     preferences._resourceUsageOverlayVisible = settings.resourceUsageOverlayVisible;
</span><span class="cx">     preferences._displayListDrawingEnabled = settings.displayListDrawingEnabled;
</span><span class="cx"> 
</span><ins>+    _webView.configuration.websiteDataStore._resourceLoadStatisticsEnabled = settings.resourceLoadStatisticsEnabled;
+
</ins><span class="cx">     BOOL useTransparentWindows = settings.useTransparentWindows;
</span><span class="cx">     if (useTransparentWindows != !_webView._drawsBackground) {
</span><span class="cx">         [self.window setOpaque:!useTransparentWindows];
</span></span></pre>
</div>
</div>

</body>
</html>