Unreviewed, rolling out r219453.
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Jul 2017 22:04:05 +0000 (22:04 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 13 Jul 2017 22:04:05 +0000 (22:04 +0000)
Seems to cause some crashes on the bots

Reverted changeset:

"Moved filesystem code out of WebResourceLoadStatisticsStore
class"
https://bugs.webkit.org/show_bug.cgi?id=174435
http://trac.webkit.org/changeset/219453

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@219467 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit2/CMakeLists.txt
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/Cocoa/WebResourceLoadStatisticsStoreCocoa.mm
Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp [deleted file]
Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.h [deleted file]
Source/WebKit2/UIProcess/Storage/ios/ResourceLoadStatisticsPersistentStorageIOS.mm [deleted file]
Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.cpp
Source/WebKit2/UIProcess/WebResourceLoadStatisticsStore.h
Source/WebKit2/WebKit2.xcodeproj/project.pbxproj

index b87c913..15e71f1 100644 (file)
@@ -434,7 +434,6 @@ set(WebKit2_SOURCES
 
     UIProcess/Storage/LocalStorageDatabase.cpp
     UIProcess/Storage/LocalStorageDatabaseTracker.cpp
-    UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp
 
     UIProcess/UserContent/WebScriptMessageHandler.cpp
     UIProcess/UserContent/WebUserContentControllerProxy.cpp
index 203e515..9635c59 100644 (file)
@@ -1,3 +1,16 @@
+2017-07-13  Chris Dumez  <cdumez@apple.com>
+
+        Unreviewed, rolling out r219453.
+
+        Seems to cause some crashes on the bots
+
+        Reverted changeset:
+
+        "Moved filesystem code out of WebResourceLoadStatisticsStore
+        class"
+        https://bugs.webkit.org/show_bug.cgi?id=174435
+        http://trac.webkit.org/changeset/219453
+
 2017-07-13  Jeremy Jones  <jeremyj@apple.com>
 
         Fix style. Use #pragma once in VideoFullscreen and PlaybackSession headers.
index 0a5d695..0c0f8a2 100644 (file)
@@ -32,6 +32,13 @@ using namespace WebCore;
 
 namespace WebKit {
 
+void WebResourceLoadStatisticsStore::platformExcludeFromBackup() const
+{
+#if PLATFORM(IOS)
+    [[NSURL fileURLWithPath:(NSString *)m_statisticsStoragePath] setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
+#endif
+}
+
 void WebResourceLoadStatisticsStore::registerUserDefaultsIfNeeded()
 {
     static dispatch_once_t initOnce;
diff --git a/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp b/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.cpp
deleted file mode 100644 (file)
index 7357906..0000000
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * Copyright (C) 2017 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
- * THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "ResourceLoadStatisticsPersistentStorage.h"
-
-#include "Logging.h"
-#include "WebResourceLoadStatisticsStore.h"
-#include <WebCore/FileMonitor.h>
-#include <WebCore/FileSystem.h>
-#include <WebCore/KeyedCoding.h>
-#include <WebCore/SharedBuffer.h>
-#include <wtf/RunLoop.h>
-#include <wtf/WorkQueue.h>
-#include <wtf/threads/BinarySemaphore.h>
-
-namespace WebKit {
-
-constexpr Seconds minimumWriteInterval { 5_min };
-
-using namespace WebCore;
-
-static bool hasFileChangedSince(const String& path, WallTime since)
-{
-    ASSERT(!RunLoop::isMain());
-    time_t modificationTime;
-    if (!getFileModificationTime(path, modificationTime))
-        return true;
-
-    return WallTime::fromRawSeconds(modificationTime) > since;
-}
-
-static std::unique_ptr<KeyedDecoder> createDecoderForFile(const String& path)
-{
-    ASSERT(!RunLoop::isMain());
-    auto handle = openAndLockFile(path, OpenForRead);
-    if (handle == invalidPlatformFileHandle)
-        return nullptr;
-
-    long long fileSize = 0;
-    if (!getFileSize(handle, fileSize)) {
-        unlockAndCloseFile(handle);
-        return nullptr;
-    }
-
-    size_t bytesToRead;
-    if (!WTF::convertSafely(fileSize, bytesToRead)) {
-        unlockAndCloseFile(handle);
-        return nullptr;
-    }
-
-    Vector<char> buffer(bytesToRead);
-    size_t totalBytesRead = readFromFile(handle, buffer.data(), buffer.size());
-
-    unlockAndCloseFile(handle);
-
-    if (totalBytesRead != bytesToRead)
-        return nullptr;
-
-    return KeyedDecoder::decoder(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size());
-}
-
-ResourceLoadStatisticsPersistentStorage::ResourceLoadStatisticsPersistentStorage(WebResourceLoadStatisticsStore& store, const String& storageDirectoryPath)
-    : m_memoryStore(store)
-    , m_storageDirectoryPath(storageDirectoryPath)
-{
-    ASSERT(RunLoop::isMain());
-    m_memoryStore.statisticsQueue().dispatch([this] {
-        populateMemoryStoreFromDisk();
-        startMonitoringDisk();
-        m_memoryStore.includeTodayAsOperatingDateIfNecessary();
-    });
-}
-
-ResourceLoadStatisticsPersistentStorage::~ResourceLoadStatisticsPersistentStorage()
-{
-    finishAllPendingWorkSynchronously();
-    ASSERT(!m_hasPendingWrite);
-}
-
-String ResourceLoadStatisticsPersistentStorage::storageDirectoryPath() const
-{
-    return m_storageDirectoryPath.isolatedCopy();
-}
-
-String ResourceLoadStatisticsPersistentStorage::resourceLogFilePath() const
-{
-    String storagePath = this->storageDirectoryPath();
-    if (storagePath.isEmpty())
-        return emptyString();
-
-    return pathByAppendingComponent(storagePath, "full_browsing_session_resourceLog.plist");
-}
-
-void ResourceLoadStatisticsPersistentStorage::startMonitoringDisk()
-{
-    ASSERT(!RunLoop::isMain());
-    if (m_fileMonitor)
-        return;
-
-    String resourceLogPath = resourceLogFilePath();
-    if (resourceLogPath.isEmpty())
-        return;
-
-    m_fileMonitor = std::make_unique<FileMonitor>(resourceLogPath, m_memoryStore.statisticsQueue(), [this] (FileMonitor::FileChangeType type) {
-        ASSERT(!RunLoop::isMain());
-        switch (type) {
-        case FileMonitor::FileChangeType::Modification:
-            refreshMemoryStoreFromDisk();
-            break;
-        case FileMonitor::FileChangeType::Removal:
-            m_memoryStore.clearInMemory();
-            m_fileMonitor = nullptr;
-            break;
-        }
-    });
-}
-
-void ResourceLoadStatisticsPersistentStorage::stopMonitoringDisk()
-{
-    ASSERT(!RunLoop::isMain());
-    m_fileMonitor = nullptr;
-}
-
-// This is called when the file changes on disk.
-void ResourceLoadStatisticsPersistentStorage::refreshMemoryStoreFromDisk()
-{
-    ASSERT(!RunLoop::isMain());
-
-    String filePath = resourceLogFilePath();
-    if (filePath.isEmpty())
-        return;
-
-    // We sometimes see file changed events from before our load completed (we start
-    // reading at the first change event, but we might receive a series of events related
-    // to the same file operation). Catch this case to avoid reading overly often.
-    if (!hasFileChangedSince(filePath, m_lastStatisticsFileSyncTime))
-        return;
-
-    WallTime readTime = WallTime::now();
-
-    auto decoder = createDecoderForFile(filePath);
-    if (!decoder)
-        return;
-
-    m_memoryStore.resetDataFromDecoder(*decoder);
-    m_lastStatisticsFileSyncTime = readTime;
-}
-
-void ResourceLoadStatisticsPersistentStorage::populateMemoryStoreFromDisk()
-{
-    ASSERT(!RunLoop::isMain());
-
-    String filePath = resourceLogFilePath();
-    if (filePath.isEmpty() || !fileExists(filePath)) {
-        m_memoryStore.grandfatherExistingWebsiteData();
-        return;
-    }
-
-    if (!hasFileChangedSince(filePath, m_lastStatisticsFileSyncTime)) {
-        // No need to grandfather in this case.
-        return;
-    }
-
-    WallTime readTime = WallTime::now();
-
-    auto decoder = createDecoderForFile(filePath);
-    if (!decoder) {
-        m_memoryStore.grandfatherExistingWebsiteData();
-        return;
-    }
-
-    m_memoryStore.resetDataFromDecoder(*decoder);
-
-    m_lastStatisticsFileSyncTime = readTime;
-
-    if (m_memoryStore.isEmpty())
-        m_memoryStore.grandfatherExistingWebsiteData();
-}
-
-void ResourceLoadStatisticsPersistentStorage::writeMemoryStoreToDisk()
-{
-    ASSERT(!RunLoop::isMain());
-
-    m_hasPendingWrite = false;
-    stopMonitoringDisk();
-
-    auto encoder = m_memoryStore.createEncoderFromData();
-    auto rawData = encoder->finishEncoding();
-    if (!rawData)
-        return;
-
-    auto storagePath = this->storageDirectoryPath();
-    if (!storagePath.isEmpty()) {
-        makeAllDirectories(storagePath);
-        excludeFromBackup();
-    }
-
-    auto handle = openAndLockFile(resourceLogFilePath(), OpenForWrite);
-    if (handle == invalidPlatformFileHandle)
-        return;
-
-    int64_t writtenBytes = writeToFile(handle, rawData->data(), rawData->size());
-    unlockAndCloseFile(handle);
-
-    if (writtenBytes != static_cast<int64_t>(rawData->size()))
-        RELEASE_LOG_ERROR(ResourceLoadStatistics, "WebResourceLoadStatisticsStore: We only wrote %d out of %zu bytes to disk", static_cast<unsigned>(writtenBytes), rawData->size());
-
-    m_lastStatisticsFileSyncTime = WallTime::now();
-    m_lastStatisticsWriteTime = MonotonicTime::now();
-
-    startMonitoringDisk();
-}
-
-void ResourceLoadStatisticsPersistentStorage::scheduleOrWriteMemoryStore()
-{
-    ASSERT(!RunLoop::isMain());
-
-    auto timeSinceLastWrite = MonotonicTime::now() - m_lastStatisticsWriteTime;
-    if (timeSinceLastWrite < minimumWriteInterval) {
-        if (!m_hasPendingWrite) {
-            m_hasPendingWrite = true;
-            Seconds delay = minimumWriteInterval - timeSinceLastWrite + 1_s;
-            m_memoryStore.statisticsQueue().dispatchAfter(delay, [this] () mutable {
-                writeMemoryStoreToDisk();
-            });
-        }
-        return;
-    }
-
-    writeMemoryStoreToDisk();
-}
-
-void ResourceLoadStatisticsPersistentStorage::clear()
-{
-    ASSERT(!RunLoop::isMain());
-    String filePath = resourceLogFilePath();
-    if (filePath.isEmpty())
-        return;
-
-    stopMonitoringDisk();
-
-    if (!deleteFile(filePath))
-        RELEASE_LOG_ERROR(ResourceLoadStatistics, "Unable to delete statistics file: %s", filePath.utf8().data());
-}
-
-void ResourceLoadStatisticsPersistentStorage::finishAllPendingWorkSynchronously()
-{
-    BinarySemaphore semaphore;
-    // Make sure any pending work in our queue is finished before we terminate.
-    m_memoryStore.statisticsQueue().dispatch([&semaphore, this] {
-        // Write final file state to disk.
-        if (m_hasPendingWrite)
-            writeMemoryStoreToDisk();
-        semaphore.signal();
-    });
-    semaphore.wait(WallTime::infinity());
-}
-
-#if !PLATFORM(IOS)
-void ResourceLoadStatisticsPersistentStorage::excludeFromBackup() const
-{
-}
-#endif
-
-} // namespace WebKit
diff --git a/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.h b/Source/WebKit2/UIProcess/Storage/ResourceLoadStatisticsPersistentStorage.h
deleted file mode 100644 (file)
index 18285f8..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#pragma once
-
-#include <wtf/Forward.h>
-#include <wtf/MonotonicTime.h>
-#include <wtf/WallTime.h>
-#include <wtf/text/WTFString.h>
-
-namespace WebCore {
-class FileMonitor;
-}
-
-namespace WebKit {
-
-class WebResourceLoadStatisticsStore;
-
-class ResourceLoadStatisticsPersistentStorage {
-public:
-    ResourceLoadStatisticsPersistentStorage(WebResourceLoadStatisticsStore&, const String& storageDirectoryPath);
-    ~ResourceLoadStatisticsPersistentStorage();
-
-    void scheduleOrWriteMemoryStore();
-    void clear();
-
-    void finishAllPendingWorkSynchronously();
-
-private:
-    String storageDirectoryPath() const;
-    String resourceLogFilePath() const;
-
-    void startMonitoringDisk();
-    void stopMonitoringDisk();
-
-    void writeMemoryStoreToDisk();
-    void populateMemoryStoreFromDisk();
-    void excludeFromBackup() const;
-    void refreshMemoryStoreFromDisk();
-
-    WebResourceLoadStatisticsStore& m_memoryStore;
-    const String m_storageDirectoryPath;
-    std::unique_ptr<WebCore::FileMonitor> m_fileMonitor;
-    WallTime m_lastStatisticsFileSyncTime;
-    MonotonicTime m_lastStatisticsWriteTime;
-    bool m_hasPendingWrite { false };
-};
-
-}
diff --git a/Source/WebKit2/UIProcess/Storage/ios/ResourceLoadStatisticsPersistentStorageIOS.mm b/Source/WebKit2/UIProcess/Storage/ios/ResourceLoadStatisticsPersistentStorageIOS.mm
deleted file mode 100644 (file)
index 5b5cbd2..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2017 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.
- */
-
-#import "config.h"
-#import "ResourceLoadStatisticsPersistentStorage.h"
-
-#if PLATFORM(IOS)
-
-namespace WebKit {
-
-void ResourceLoadStatisticsPersistentStorage::excludeFromBackup() const
-{
-    [[NSURL fileURLWithPath:(NSString *)m_storageDirectoryPath] setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
-}
-
-}
-
-#endif
index 80b8abb..185a18b 100644 (file)
 #include "WebsiteDataFetchOption.h"
 #include "WebsiteDataStore.h"
 #include "WebsiteDataType.h"
+#include <WebCore/FileMonitor.h>
+#include <WebCore/FileSystem.h>
 #include <WebCore/KeyedCoding.h>
 #include <WebCore/ResourceLoadStatistics.h>
+#include <WebCore/SharedBuffer.h>
 #include <wtf/CrossThreadCopier.h>
 #include <wtf/MathExtras.h>
 #include <wtf/NeverDestroyed.h>
+#include <wtf/threads/BinarySemaphore.h>
 
 using namespace WebCore;
 
 namespace WebKit {
 
+constexpr Seconds minimumStatisticsFileWriteInterval { 5_min };
 constexpr unsigned operatingDatesWindow { 30 };
 constexpr unsigned statisticsModelVersion { 7 };
 constexpr unsigned maxImportance { 3 };
@@ -79,8 +84,8 @@ static const OptionSet<WebsiteDataType>& dataTypesToRemove()
 
 WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& resourceLoadStatisticsDirectory, UpdateCookiePartitioningForDomainsHandler&& updateCookiePartitioningForDomainsHandler)
     : m_statisticsQueue(WorkQueue::create("WebResourceLoadStatisticsStore Process Data Queue", WorkQueue::Type::Serial, WorkQueue::QOS::Utility))
-    , m_persistentStorage(*this, resourceLoadStatisticsDirectory)
     , m_updateCookiePartitioningForDomainsHandler(WTFMove(updateCookiePartitioningForDomainsHandler))
+    , m_statisticsStoragePath(resourceLoadStatisticsDirectory)
     , m_dailyTasksTimer(RunLoop::main(), this, &WebResourceLoadStatisticsStore::performDailyTasks)
 {
     ASSERT(RunLoop::isMain());
@@ -89,6 +94,10 @@ WebResourceLoadStatisticsStore::WebResourceLoadStatisticsStore(const String& res
     registerUserDefaultsIfNeeded();
 #endif
 
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this)] {
+        readDataFromDiskIfNeeded();
+        startMonitoringStatisticsStorage();
+    });
     m_statisticsQueue->dispatchAfter(5_s, [this, protectedThis = makeRef(*this)] {
         if (m_parameters.shouldSubmitTelemetry)
             WebResourceLoadStatisticsTelemetry::calculateAndSubmit(*this);
@@ -146,7 +155,7 @@ void WebResourceLoadStatisticsStore::processStatisticsAndDataRecords()
             });
         }
 
-        m_persistentStorage.scheduleOrWriteMemoryStore();
+        scheduleOrWriteStoreToDisk();
     });
 }
 
@@ -176,6 +185,79 @@ void WebResourceLoadStatisticsStore::grandfatherExistingWebsiteData()
         });
     });
 }
+
+WallTime WebResourceLoadStatisticsStore::statisticsFileModificationTime(const String& path) const
+{
+    ASSERT(!RunLoop::isMain());
+    time_t modificationTime;
+    if (!getFileModificationTime(path, modificationTime))
+        return { };
+
+    return WallTime::fromRawSeconds(modificationTime);
+}
+
+bool WebResourceLoadStatisticsStore::hasStatisticsFileChangedSinceLastSync(const String& path) const
+{
+    return statisticsFileModificationTime(path) > m_lastStatisticsFileSyncTime;
+}
+
+void WebResourceLoadStatisticsStore::readDataFromDiskIfNeeded()
+{
+    ASSERT(!RunLoop::isMain());
+
+    String resourceLog = resourceLogFilePath();
+    if (resourceLog.isEmpty() || !fileExists(resourceLog)) {
+        grandfatherExistingWebsiteData();
+        return;
+    }
+
+    if (!hasStatisticsFileChangedSinceLastSync(resourceLog)) {
+        // No need to grandfather in this case.
+        return;
+    }
+
+    WallTime readTime = WallTime::now();
+
+    auto decoder = createDecoderFromDisk(resourceLog);
+    if (!decoder) {
+        grandfatherExistingWebsiteData();
+        return;
+    }
+
+    clearInMemory();
+    populateFromDecoder(*decoder);
+
+    m_lastStatisticsFileSyncTime = readTime;
+
+    if (m_resourceStatisticsMap.isEmpty())
+        grandfatherExistingWebsiteData();
+
+    includeTodayAsOperatingDateIfNecessary();
+}
+    
+void WebResourceLoadStatisticsStore::refreshFromDisk()
+{
+    ASSERT(!RunLoop::isMain());
+
+    String resourceLog = resourceLogFilePath();
+    if (resourceLog.isEmpty())
+        return;
+
+    // We sometimes see file changed events from before our load completed (we start
+    // reading at the first change event, but we might receive a series of events related
+    // to the same file operation). Catch this case to avoid reading overly often.
+    if (!hasStatisticsFileChangedSinceLastSync(resourceLog))
+        return;
+
+    WallTime readTime = WallTime::now();
+
+    auto decoder = createDecoderFromDisk(resourceLog);
+    if (!decoder)
+        return;
+
+    populateFromDecoder(*decoder);
+    m_lastStatisticsFileSyncTime = readTime;
+}
     
 void WebResourceLoadStatisticsStore::processWillOpenConnection(WebProcessProxy&, IPC::Connection& connection)
 {
@@ -189,7 +271,177 @@ void WebResourceLoadStatisticsStore::processDidCloseConnection(WebProcessProxy&,
 
 void WebResourceLoadStatisticsStore::applicationWillTerminate()
 {
-    m_persistentStorage.finishAllPendingWorkSynchronously();
+    BinarySemaphore semaphore;
+    // Make sure any pending work in our queue is finished before we terminate.
+    m_statisticsQueue->dispatch([&semaphore, this, protectedThis = makeRef(*this)] {
+        // Write final file state to disk.
+        if (m_didScheduleWrite)
+            writeStoreToDisk();
+
+        semaphore.signal();
+    });
+    semaphore.wait(WallTime::infinity());
+}
+
+String WebResourceLoadStatisticsStore::statisticsStoragePath() const
+{
+    return m_statisticsStoragePath.isolatedCopy();
+}
+
+String WebResourceLoadStatisticsStore::resourceLogFilePath() const
+{
+    String statisticsStoragePath = this->statisticsStoragePath();
+    if (statisticsStoragePath.isEmpty())
+        return emptyString();
+
+    return pathByAppendingComponent(statisticsStoragePath, "full_browsing_session_resourceLog.plist");
+}
+
+void WebResourceLoadStatisticsStore::writeStoreToDisk()
+{
+    ASSERT(!RunLoop::isMain());
+    
+    stopMonitoringStatisticsStorage();
+
+    syncWithExistingStatisticsStorageIfNeeded();
+
+    auto encoder = createEncoderFromData();
+    RefPtr<SharedBuffer> rawData = encoder->finishEncoding();
+    if (!rawData)
+        return;
+
+    auto statisticsStoragePath = this->statisticsStoragePath();
+    if (!statisticsStoragePath.isEmpty()) {
+        makeAllDirectories(statisticsStoragePath);
+        platformExcludeFromBackup();
+    }
+
+    auto handle = openAndLockFile(resourceLogFilePath(), OpenForWrite);
+    if (handle == invalidPlatformFileHandle)
+        return;
+
+    int64_t writtenBytes = writeToFile(handle, rawData->data(), rawData->size());
+    unlockAndCloseFile(handle);
+
+    if (writtenBytes != static_cast<int64_t>(rawData->size()))
+        RELEASE_LOG_ERROR(ResourceLoadStatistics, "WebResourceLoadStatisticsStore: We only wrote %d out of %zu bytes to disk", static_cast<unsigned>(writtenBytes), rawData->size());
+
+    m_lastStatisticsFileSyncTime = WallTime::now();
+    m_lastStatisticsWriteTime = MonotonicTime::now();
+
+    startMonitoringStatisticsStorage();
+    m_didScheduleWrite = false;
+}
+
+void WebResourceLoadStatisticsStore::scheduleOrWriteStoreToDisk()
+{
+    ASSERT(!RunLoop::isMain());
+
+    auto timeSinceLastWrite = MonotonicTime::now() - m_lastStatisticsWriteTime;
+    if (timeSinceLastWrite < minimumStatisticsFileWriteInterval) {
+        if (!m_didScheduleWrite) {
+            m_didScheduleWrite = true;
+            Seconds delay = minimumStatisticsFileWriteInterval - timeSinceLastWrite + 1_s;
+            m_statisticsQueue->dispatchAfter(delay, [this, protectedThis = makeRef(*this)] {
+                writeStoreToDisk();
+            });
+        }
+        return;
+    }
+
+    writeStoreToDisk();
+}
+
+void WebResourceLoadStatisticsStore::deleteStoreFromDisk()
+{
+    ASSERT(!RunLoop::isMain());
+    String resourceLogPath = resourceLogFilePath();
+    if (resourceLogPath.isEmpty())
+        return;
+
+    stopMonitoringStatisticsStorage();
+
+    if (!deleteFile(resourceLogPath))
+        RELEASE_LOG_ERROR(ResourceLoadStatistics, "Unable to delete statistics file: %s", resourceLogPath.utf8().data());
+}
+
+void WebResourceLoadStatisticsStore::startMonitoringStatisticsStorage()
+{
+    ASSERT(!RunLoop::isMain());
+    if (m_statisticsStorageMonitor)
+        return;
+    
+    String resourceLogPath = resourceLogFilePath();
+    if (resourceLogPath.isEmpty())
+        return;
+    
+    m_statisticsStorageMonitor = std::make_unique<FileMonitor>(resourceLogPath, m_statisticsQueue.copyRef(), [this] (FileMonitor::FileChangeType type) {
+        ASSERT(!RunLoop::isMain());
+        switch (type) {
+        case FileMonitor::FileChangeType::Modification:
+            refreshFromDisk();
+            break;
+        case FileMonitor::FileChangeType::Removal:
+            clearInMemory();
+            m_statisticsStorageMonitor = nullptr;
+            break;
+        }
+    });
+}
+
+void WebResourceLoadStatisticsStore::stopMonitoringStatisticsStorage()
+{
+    ASSERT(!RunLoop::isMain());
+    m_statisticsStorageMonitor = nullptr;
+}
+
+void WebResourceLoadStatisticsStore::syncWithExistingStatisticsStorageIfNeeded()
+{
+    ASSERT(!RunLoop::isMain());
+    if (m_statisticsStorageMonitor)
+        return;
+
+    String resourceLog = resourceLogFilePath();
+    if (resourceLog.isEmpty() || !fileExists(resourceLog))
+        return;
+
+    refreshFromDisk();
+}
+
+#if !PLATFORM(COCOA)
+void WebResourceLoadStatisticsStore::platformExcludeFromBackup() const
+{
+}
+#endif
+
+std::unique_ptr<KeyedDecoder> WebResourceLoadStatisticsStore::createDecoderFromDisk(const String& path) const
+{
+    ASSERT(!RunLoop::isMain());
+    auto handle = openAndLockFile(path, OpenForRead);
+    if (handle == invalidPlatformFileHandle)
+        return nullptr;
+    
+    long long fileSize = 0;
+    if (!getFileSize(handle, fileSize)) {
+        unlockAndCloseFile(handle);
+        return nullptr;
+    }
+    
+    size_t bytesToRead;
+    if (!WTF::convertSafely(fileSize, bytesToRead)) {
+        unlockAndCloseFile(handle);
+        return nullptr;
+    }
+
+    Vector<char> buffer(bytesToRead);
+    size_t totalBytesRead = readFromFile(handle, buffer.data(), buffer.size());
+
+    unlockAndCloseFile(handle);
+
+    if (totalBytesRead != bytesToRead)
+        return nullptr;
+
+    return KeyedDecoder::decoder(reinterpret_cast<const uint8_t*>(buffer.data()), buffer.size());
 }
 
 void WebResourceLoadStatisticsStore::performDailyTasks()
@@ -401,7 +653,7 @@ void WebResourceLoadStatisticsStore::scheduleClearInMemoryAndPersistent()
     ASSERT(RunLoop::isMain());
     m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this)] {
         clearInMemory();
-        m_persistentStorage.clear();
+        deleteStoreFromDisk();
         grandfatherExistingWebsiteData();
     });
 }
@@ -480,11 +732,11 @@ std::unique_ptr<KeyedEncoder> WebResourceLoadStatisticsStore::createEncoderFromD
     return encoder;
 }
 
-void WebResourceLoadStatisticsStore::resetDataFromDecoder(KeyedDecoder& decoder)
+void WebResourceLoadStatisticsStore::populateFromDecoder(KeyedDecoder& decoder)
 {
     ASSERT(!RunLoop::isMain());
-
-    clearInMemory();
+    if (!m_resourceStatisticsMap.isEmpty())
+        return;
 
     unsigned versionOnDisk;
     if (!decoder.decodeUInt32("version", versionOnDisk))
index e4c62ae..aad9e6e 100644 (file)
@@ -27,7 +27,6 @@
 
 #include "Connection.h"
 #include "ResourceLoadStatisticsClassifier.h"
-#include "ResourceLoadStatisticsPersistentStorage.h"
 #include <wtf/MonotonicTime.h>
 #include <wtf/RunLoop.h>
 #include <wtf/Vector.h>
@@ -43,6 +42,7 @@ class WorkQueue;
 }
 
 namespace WebCore {
+class FileMonitor;
 class KeyedDecoder;
 class KeyedEncoder;
 class URL;
@@ -55,6 +55,7 @@ class WebProcessProxy;
 
 enum class ShouldClearFirst;
 
+// FIXME: We should consider moving FileSystem I/O to a separate class.
 class WebResourceLoadStatisticsStore final : public IPC::Connection::WorkQueueMessageReceiver {
 public:
     using UpdateCookiePartitioningForDomainsHandler = WTF::Function<void(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst)>;
@@ -65,9 +66,6 @@ public:
 
     ~WebResourceLoadStatisticsStore();
 
-    bool isEmpty() const { return m_resourceStatisticsMap.isEmpty(); }
-    WorkQueue& statisticsQueue() { return m_statisticsQueue.get(); }
-
     void setNotifyPagesWhenDataRecordsWereScanned(bool value) { m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned = value; }
     void setShouldClassifyResourcesBeforeDataRecordsRemoval(bool value) { m_parameters.shouldClassifyResourcesBeforeDataRecordsRemoval = value; }
     void setShouldSubmitTelemetry(bool value) { m_parameters.shouldSubmitTelemetry = value; }
@@ -111,21 +109,33 @@ public:
     void pruneStatisticsIfNeeded();
 
     void resetParametersToDefaultValues();
-
-    std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData() const;
-    void resetDataFromDecoder(WebCore::KeyedDecoder&);
-    void clearInMemory();
-    void grandfatherExistingWebsiteData();
-    void includeTodayAsOperatingDateIfNecessary();
     
 private:
     WebResourceLoadStatisticsStore(const String&, UpdateCookiePartitioningForDomainsHandler&&);
 
+    void readDataFromDiskIfNeeded();
+
     void removeDataRecords();
+    void startMonitoringStatisticsStorage();
+    void stopMonitoringStatisticsStorage();
+
+    String statisticsStoragePath() const;
+    String resourceLogFilePath() const;
 
     // IPC::MessageReceiver
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&) override;
 
+    void grandfatherExistingWebsiteData();
+
+    void writeStoreToDisk();
+    void scheduleOrWriteStoreToDisk();
+    std::unique_ptr<WebCore::KeyedDecoder> createDecoderFromDisk(const String& path) const;
+    WallTime statisticsFileModificationTime(const String& label) const;
+    void platformExcludeFromBackup() const;
+    void deleteStoreFromDisk();
+    void syncWithExistingStatisticsStorageIfNeeded();
+    void refreshFromDisk();
+    bool hasStatisticsFileChangedSinceLastSync(const String& path) const;
     void performDailyTasks();
     bool shouldRemoveDataRecords() const;
     void setDataRecordsBeingRemoved(bool);
@@ -133,11 +143,15 @@ private:
     bool shouldPartitionCookies(const WebCore::ResourceLoadStatistics&) const;
     bool hasStatisticsExpired(const WebCore::ResourceLoadStatistics&) const;
     bool hasHadUnexpiredRecentUserInteraction(WebCore::ResourceLoadStatistics&) const;
+    void includeTodayAsOperatingDateIfNecessary();
     Vector<String> topPrivatelyControlledDomainsToRemoveWebsiteDataFor();
     void updateCookiePartitioning();
     void updateCookiePartitioningForDomains(const Vector<String>& domainsToRemove, const Vector<String>& domainsToAdd, ShouldClearFirst);
     void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
     WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
+    std::unique_ptr<WebCore::KeyedEncoder> createEncoderFromData() const;
+    void populateFromDecoder(WebCore::KeyedDecoder&);
+    void clearInMemory();
 
     void resetCookiePartitioningState();
 
@@ -164,18 +178,22 @@ private:
     ResourceLoadStatisticsClassifier m_resourceLoadStatisticsClassifier;
 #endif
     Ref<WTF::WorkQueue> m_statisticsQueue;
-    ResourceLoadStatisticsPersistentStorage m_persistentStorage;
+    std::unique_ptr<WebCore::FileMonitor> m_statisticsStorageMonitor;
     Deque<WTF::WallTime> m_operatingDates;
 
     UpdateCookiePartitioningForDomainsHandler m_updateCookiePartitioningForDomainsHandler;
 
     WallTime m_endOfGrandfatheringTimestamp;
+    const String m_statisticsStoragePath;
+    WallTime m_lastStatisticsFileSyncTime;
+    MonotonicTime m_lastStatisticsWriteTime;
     RunLoop::Timer<WebResourceLoadStatisticsStore> m_dailyTasksTimer;
     MonotonicTime m_lastTimeDataRecordsWereRemoved;
 
     Parameters m_parameters;
 
     bool m_dataRecordsBeingRemoved { false };
+    bool m_didScheduleWrite { false };
 };
 
 } // namespace WebKit
index 4eaf46f..b06fe37 100644 (file)
                8310428C1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */; };
                831EEBBD1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.h in Headers */ = {isa = PBXBuildFile; fileRef = 831EEBBB1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.h */; };
                831EEBBE1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */; };
-               8324355C1F1714670035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 8324355B1F1714610035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm */; };
                832AE2521BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */; };
                832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */; };
                832ED18B1E2FE157006BA64A /* PerActivityStateCPUUsageSampler.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */; };
                8372DB281A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8372DB261A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp */; };
                8372DB291A67562800C697C5 /* WebPageDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB271A67562800C697C5 /* WebPageDiagnosticLoggingClient.h */; };
                8372DB2F1A677D4A00C697C5 /* WKDiagnosticLoggingResultType.h in Headers */ = {isa = PBXBuildFile; fileRef = 8372DB2E1A677D4A00C697C5 /* WKDiagnosticLoggingResultType.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               83850C0C1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 83850C0A1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp */; };
-               83850C0D1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.h in Headers */ = {isa = PBXBuildFile; fileRef = 83850C0B1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.h */; };
                83891B631A68B3420030F386 /* APIDiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B621A68B3420030F386 /* APIDiagnosticLoggingClient.h */; };
                83891B691A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B681A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
                83891B6C1A68C30B0030F386 /* DiagnosticLoggingClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 83891B6A1A68C30B0030F386 /* DiagnosticLoggingClient.h */; };
                8310428A1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSubresourcesEntry.cpp; sourceTree = "<group>"; };
                831EEBBB1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoad.h; sourceTree = "<group>"; };
                831EEBBC1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoad.cpp; sourceTree = "<group>"; };
-               8324355B1F1714610035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceLoadStatisticsPersistentStorageIOS.mm; sourceTree = "<group>"; };
                832AE2501BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NetworkCacheSpeculativeLoadManager.h; sourceTree = "<group>"; };
                832AE2511BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NetworkCacheSpeculativeLoadManager.cpp; sourceTree = "<group>"; };
                832ED1891E2FE13B006BA64A /* PerActivityStateCPUUsageSampler.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerActivityStateCPUUsageSampler.cpp; sourceTree = "<group>"; };
                8372DB261A67562800C697C5 /* WebPageDiagnosticLoggingClient.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebPageDiagnosticLoggingClient.cpp; sourceTree = "<group>"; };
                8372DB271A67562800C697C5 /* WebPageDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebPageDiagnosticLoggingClient.h; sourceTree = "<group>"; };
                8372DB2E1A677D4A00C697C5 /* WKDiagnosticLoggingResultType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKDiagnosticLoggingResultType.h; sourceTree = "<group>"; };
-               83850C0A1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadStatisticsPersistentStorage.cpp; sourceTree = "<group>"; };
-               83850C0B1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ResourceLoadStatisticsPersistentStorage.h; sourceTree = "<group>"; };
                83891B621A68B3420030F386 /* APIDiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APIDiagnosticLoggingClient.h; sourceTree = "<group>"; };
                83891B681A68BEBC0030F386 /* _WKDiagnosticLoggingDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _WKDiagnosticLoggingDelegate.h; sourceTree = "<group>"; };
                83891B6A1A68C30B0030F386 /* DiagnosticLoggingClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DiagnosticLoggingClient.h; sourceTree = "<group>"; };
                                1A1D8BA01731A36300141DA4 /* LocalStorageDatabase.h */,
                                1A8C728A1738477C000A6554 /* LocalStorageDatabaseTracker.cpp */,
                                1A8C728B1738477C000A6554 /* LocalStorageDatabaseTracker.h */,
-                               83850C0A1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp */,
-                               83850C0B1F16BA6C00C15E52 /* ResourceLoadStatisticsPersistentStorage.h */,
                                1A44B95916B73F9F00B7BBD8 /* StorageManager.cpp */,
                                1A44B95A16B73F9F00B7BBD8 /* StorageManager.h */,
                                1AB31A9316BC65AB00F6DBC9 /* StorageManager.messages.in */,
                        isa = PBXGroup;
                        children = (
                                5120C8301E54E2650025B250 /* LocalStorageDatabaseTrackerIOS.mm */,
-                               8324355B1F1714610035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm */,
                        );
                        path = ios;
                        sourceTree = "<group>";
                                1AD4C1931B39F33200ABC28E /* ApplicationStateTracker.h in Headers */,
                                1AEFD27911D16C81008219D3 /* ArgumentCoder.h in Headers */,
                                1AEFD2F711D1807B008219D3 /* ArgumentCoders.h in Headers */,
-                               83850C0D1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.h in Headers */,
                                1AAF0C4A12B16334008E49E2 /* ArgumentCodersCF.h in Headers */,
                                E179FD9C134D38060015B883 /* ArgumentCodersMac.h in Headers */,
                                CE1A0BD21A48E6C60054EF74 /* AssertionServicesSPI.h in Headers */,
                                E4436ECD1A0D040B00EAD204 /* NetworkCacheKey.cpp in Sources */,
                                831EEBBE1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.cpp in Sources */,
                                832AE2531BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.cpp in Sources */,
-                               83850C0C1F16BA9000C15E52 /* ResourceLoadStatisticsPersistentStorage.cpp in Sources */,
                                83BDCCB91AC5FDB6003F6441 /* NetworkCacheStatistics.cpp in Sources */,
                                E4436ED01A0D040B00EAD204 /* NetworkCacheStorage.cpp in Sources */,
                                8310428C1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.cpp in Sources */,
                                1ACC50F11CBC381D003C7D03 /* WKOpenPanelParameters.mm in Sources */,
                                BC85806312B8505700EDEB2E /* WKOpenPanelParametersRef.cpp in Sources */,
                                BC85806212B8505700EDEB2E /* WKOpenPanelResultListener.cpp in Sources */,
-                               8324355C1F1714670035AA3A /* ResourceLoadStatisticsPersistentStorageIOS.mm in Sources */,
                                BCD597D6112B56DC00EC8C23 /* WKPage.cpp in Sources */,
                                7C89D29B1A67837B003A5FDE /* WKPageConfigurationRef.cpp in Sources */,
                                BC7B633812A45ABA00D174A4 /* WKPageGroup.cpp in Sources */,