Clean up / modernize PageCache class
authorcdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Jan 2015 18:38:51 +0000 (18:38 +0000)
committercdumez@apple.com <cdumez@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 29 Jan 2015 18:38:51 +0000 (18:38 +0000)
https://bugs.webkit.org/show_bug.cgi?id=141009

Reviewed by Darin Adler.

Source/WebCore:

Clean up / modernize PageCache class:
- Use more references instead of pointers
- Use a ListHashSet<Ref<HistoryItem>> internally instead of a linked
  list of HistoryItem*. This avoids having the ref/unref HistoryItems
  manually and maintaining the list size separately. It also simplifies
  the code dealing with the container and makes looking up HistoryItems
  faster as a bonus. Similarly to the previous implementation, we are
  adding elements to one end and removing from the opposite end when
  pruning to drop old history items first. Note that even though the
  previous implementation was called LRUList, it did not move items to
  the front when accessed. The new implementation doesn't either.
 - Rename "capacity" to "maxSize" to avoid confusing with containers'
   capacity (which doesn't limit the size of the container).
 - Use unsigned instead of int for all values that are supposed to be
   positive.
 - Do not explicitely define the default constructor and let the
   compiler generate it for us (and use in-class initialization for
   members)
 - Fix indentation in the header.

Source/WebKit/mac:

Clean up / modernize PageCache class.

* History/WebBackForwardList.mm:
(-[WebBackForwardList pageCacheSize]):
* WebView/WebView.mm:
(-[WebView _loadBackForwardListFromOtherView:]):
(-[WebView goToBackForwardItem:]):
(+[WebView _setCacheModel:]):

Source/WebKit/win:

Clean up / modernize PageCache class.

* WebView.cpp:
(WebView::setCacheModel):

Source/WebKit2:

Clean up / modernize PageCache class.

* WebProcess/WebPage/WebBackForwardListProxy.cpp:
(WebKit::WebBackForwardListProxy::removeItem):
(WebKit::WebBackForwardListProxy::close):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::goForward):
(WebKit::WebPage::goBack):
(WebKit::WebPage::goToBackForwardItem):
* WebProcess/WebProcess.cpp:
(WebKit::WebProcess::releasePageCache):
* WebProcess/cocoa/WebProcessCocoa.mm:
(WebKit::WebProcess::platformSetCacheModel):
* WebProcess/soup/WebProcessSoup.cpp:
(WebKit::WebProcess::platformSetCacheModel):

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

29 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/history/BackForwardController.cpp
Source/WebCore/history/BackForwardList.cpp
Source/WebCore/history/HistoryItem.cpp
Source/WebCore/history/PageCache.cpp
Source/WebCore/history/PageCache.h
Source/WebCore/loader/FrameLoader.cpp
Source/WebCore/loader/FrameLoader.h
Source/WebCore/loader/HistoryController.cpp
Source/WebCore/loader/HistoryController.h
Source/WebCore/page/DiagnosticLoggingKeys.cpp
Source/WebCore/page/DiagnosticLoggingKeys.h
Source/WebCore/page/Frame.cpp
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h
Source/WebCore/page/Settings.cpp
Source/WebCore/platform/MemoryPressureHandler.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/History/WebBackForwardList.mm
Source/WebKit/mac/WebView/WebView.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/WebView.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/WebProcess/WebPage/WebBackForwardListProxy.cpp
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Source/WebKit2/WebProcess/WebProcess.cpp
Source/WebKit2/WebProcess/cocoa/WebProcessCocoa.mm
Source/WebKit2/WebProcess/soup/WebProcessSoup.cpp

index 03034f9..487f301 100644 (file)
@@ -1,3 +1,30 @@
+2015-01-29  Chris Dumez  <cdumez@apple.com>
+
+        Clean up / modernize PageCache class
+        https://bugs.webkit.org/show_bug.cgi?id=141009
+
+        Reviewed by Darin Adler.
+
+        Clean up / modernize PageCache class:
+        - Use more references instead of pointers
+        - Use a ListHashSet<Ref<HistoryItem>> internally instead of a linked
+          list of HistoryItem*. This avoids having the ref/unref HistoryItems
+          manually and maintaining the list size separately. It also simplifies
+          the code dealing with the container and makes looking up HistoryItems
+          faster as a bonus. Similarly to the previous implementation, we are
+          adding elements to one end and removing from the opposite end when
+          pruning to drop old history items first. Note that even though the
+          previous implementation was called LRUList, it did not move items to
+          the front when accessed. The new implementation doesn't either.
+         - Rename "capacity" to "maxSize" to avoid confusing with containers'
+           capacity (which doesn't limit the size of the container).
+         - Use unsigned instead of int for all values that are supposed to be
+           positive.
+         - Do not explicitely define the default constructor and let the
+           compiler generate it for us (and use in-class initialization for
+           members)
+         - Fix indentation in the header.
+
 2015-01-29  Julien Isorce  <j.isorce@samsung.com>
 
         HTMLImageLoader: fix build failure on assert condition after r179340
index 80ae281..ad5e640 100644 (file)
@@ -1239,7 +1239,7 @@ __ZN7WebCore4Page35resumeActiveDOMObjectsAndAnimationsEv
 __ZN7WebCore4Page36setShouldSuppressScrollbarAnimationsEb
 __ZN7WebCore4Page36suspendActiveDOMObjectsAndAnimationsEv
 __ZN7WebCore4Page37setInLowQualityImageInterpolationModeEb
-__ZN7WebCore4Page8goToItemEPNS_11HistoryItemENS_13FrameLoadTypeE
+__ZN7WebCore4Page8goToItemERNS_11HistoryItemENS_13FrameLoadTypeE
 __ZN7WebCore4Page8setMutedEb
 __ZN7WebCore4Page9initGroupEv
 __ZN7WebCore4PageC1ERNS_17PageConfigurationE
@@ -1606,10 +1606,10 @@ __ZN7WebCore9JSElement6s_infoE
 __ZN7WebCore9JSElement9toWrappedEN3JSC7JSValueE
 __ZN7WebCore9LayerPoolC1Ev
 __ZN7WebCore9LayerPoolD1Ev
-__ZN7WebCore9PageCache11setCapacityEi
-__ZN7WebCore9PageCache18pruneToCapacityNowEiNS_13PruningReasonE
+__ZN7WebCore9PageCache10setMaxSizeEj
+__ZN7WebCore9PageCache14pruneToSizeNowEjNS_13PruningReasonE
 __ZN7WebCore9PageCache34markPagesForVisitedLinkStyleRecalcEv
-__ZN7WebCore9PageCache6removeEPNS_11HistoryItemE
+__ZN7WebCore9PageCache6removeERNS_11HistoryItemE
 __ZN7WebCore9PageCache6sharedEv
 __ZN7WebCore9PageGroup9pageGroupERKN3WTF6StringE
 __ZN7WebCore9Scrollbar11mouseExitedEv
index 9c16722..55caf1c 100644 (file)
@@ -74,7 +74,7 @@ void BackForwardController::goBackOrForward(int distance)
     if (!item)
         return;
 
-    m_page.goToItem(item, FrameLoadType::IndexedBackForward);
+    m_page.goToItem(*item, FrameLoadType::IndexedBackForward);
 }
 
 bool BackForwardController::goBack()
@@ -83,7 +83,7 @@ bool BackForwardController::goBack()
     if (!item)
         return false;
 
-    m_page.goToItem(item, FrameLoadType::Back);
+    m_page.goToItem(*item, FrameLoadType::Back);
     return true;
 }
 
@@ -93,7 +93,7 @@ bool BackForwardController::goForward()
     if (!item)
         return false;
 
-    m_page.goToItem(item, FrameLoadType::Forward);
+    m_page.goToItem(*item, FrameLoadType::Forward);
     return true;
 }
 
index cce07f4..b3ad619 100644 (file)
@@ -68,7 +68,7 @@ void BackForwardList::addItem(PassRefPtr<HistoryItem> prpItem)
             RefPtr<HistoryItem> item = m_entries.last();
             m_entries.removeLast();
             m_entryHash.remove(item);
-            PageCache::shared().remove(item.get());
+            PageCache::shared().remove(*item);
         }
     }
 
@@ -78,7 +78,7 @@ void BackForwardList::addItem(PassRefPtr<HistoryItem> prpItem)
         RefPtr<HistoryItem> item = m_entries[0];
         m_entries.remove(0);
         m_entryHash.remove(item);
-        PageCache::shared().remove(item.get());
+        PageCache::shared().remove(*item);
         m_current--;
     }
 
@@ -175,7 +175,7 @@ void BackForwardList::setCapacity(int size)
         RefPtr<HistoryItem> item = m_entries.last();
         m_entries.removeLast();
         m_entryHash.remove(item);
-        PageCache::shared().remove(item.get());
+        PageCache::shared().remove(*item);
     }
 
     if (!size)
@@ -242,12 +242,10 @@ void BackForwardList::setCurrent(unsigned newCurrent)
 bool BackForwardList::clearAllPageCaches()
 {
     bool didRemoveAtLeastOneItem = false;
-    unsigned length = m_entries.size();
-    for (unsigned i = 0; i < length; ++i) {
-        HistoryItem* item = m_entries[i].get();
+    for (auto& item : m_entries) {
         if (item->isInPageCache()) {
             didRemoveAtLeastOneItem = true;
-            PageCache::shared().remove(item);
+            PageCache::shared().remove(*item);
         }
     }
     return didRemoveAtLeastOneItem;
@@ -256,12 +254,11 @@ bool BackForwardList::clearAllPageCaches()
 
 void BackForwardList::close()
 {
-    int size = m_entries.size();
-    for (int i = 0; i < size; ++i)
-        PageCache::shared().remove(m_entries[i].get());
+    for (auto& item : m_entries)
+        PageCache::shared().remove(*item);
     m_entries.clear();
     m_entryHash.clear();
-    m_page = 0;
+    m_page = nullptr;
     m_closed = true;
 }
 
index 0c473c0..1b525df 100644 (file)
@@ -286,7 +286,7 @@ void HistoryItem::setURLString(const String& urlString)
 
 void HistoryItem::setURL(const URL& url)
 {
-    PageCache::shared().remove(this);
+    PageCache::shared().remove(*this);
     setURLString(url.string());
     clearDocumentState();
 }
index 9f53a6b..22d6802 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007, 2014 Apple Inc.  All rights reserved.
+ * Copyright (C) 2007, 2014, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -43,7 +43,6 @@
 #include "FrameLoaderStateMachine.h"
 #include "FrameView.h"
 #include "HistoryController.h"
-#include "HistoryItem.h"
 #include "Logging.h"
 #include "MainFrame.h"
 #include "MemoryPressureHandler.h"
@@ -110,7 +109,7 @@ static inline void logPageCacheFailureDiagnosticMessage(Page* page, const String
     logPageCacheFailureDiagnosticMessage(page->mainFrame().diagnosticLoggingClient(), reason);
 }
 
-static unsigned logCanCacheFrameDecision(Frame& frame, DiagnosticLoggingClient& diagnosticLoggingClient, int indentLevel)
+static unsigned logCanCacheFrameDecision(Frame& frame, DiagnosticLoggingClient& diagnosticLoggingClient, unsigned indentLevel)
 {
     PCLOG("+---");
     if (!frame.loader().documentLoader()) {
@@ -234,7 +233,7 @@ static void logCanCachePageDecision(Page& page)
     if (currentURL.isEmpty())
         return;
     
-    int indentLevel = 0;    
+    unsigned indentLevel = 0;
     PCLOG("--------\n Determining if page can be cached:");
     
     unsigned rejectReasons = 0;
@@ -297,26 +296,17 @@ PageCache& PageCache::shared()
     static NeverDestroyed<PageCache> globalPageCache;
     return globalPageCache;
 }
-
-PageCache::PageCache()
-    : m_capacity(0)
-    , m_size(0)
-    , m_head(0)
-    , m_tail(0)
-    , m_shouldClearBackingStores(false)
-{
-}
     
-bool PageCache::canCachePageContainingThisFrame(Frame* frame)
+bool PageCache::canCachePageContainingThisFrame(Frame& frame)
 {
-    for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
-        if (!canCachePageContainingThisFrame(child))
+    for (Frame* child = frame.tree().firstChild(); child; child = child->tree().nextSibling()) {
+        if (!canCachePageContainingThisFrame(*child))
             return false;
     }
     
-    FrameLoader& frameLoader = frame->loader();
+    FrameLoader& frameLoader = frame.loader();
     DocumentLoader* documentLoader = frameLoader.documentLoader();
-    Document* document = frame->document();
+    Document* document = frame.document();
     
     return documentLoader
 #if !PLATFORM(IOS)
@@ -326,8 +316,8 @@ bool PageCache::canCachePageContainingThisFrame(Frame* frame)
 #endif
         // Do not cache error pages (these can be recognized as pages with substitute data or unreachable URLs).
         && !(documentLoader->substituteData().isValid() && !documentLoader->substituteData().failingURL().isEmpty())
-        && (!frameLoader.subframeLoader().containsPlugins() || frame->page()->settings().pageCacheSupportsPlugins())
-        && !(frame->isMainFrame() && document->url().protocolIs("https") && documentLoader->response().cacheControlContainsNoStore())
+        && (!frameLoader.subframeLoader().containsPlugins() || frame.page()->settings().pageCacheSupportsPlugins())
+        && !(frame.isMainFrame() && document->url().protocolIs("https") && documentLoader->response().cacheControlContainsNoStore())
         && !DatabaseManager::manager().hasOpenDatabases(document)
         && frameLoader.history().currentItem()
         && !frameLoader.quickRedirectComing()
@@ -357,8 +347,8 @@ bool PageCache::canCache(Page* page) const
     // over it again when we leave that page.
     FrameLoadType loadType = page->mainFrame().loader().loadType();
     
-    return m_capacity > 0
-        && canCachePageContainingThisFrame(&page->mainFrame())
+    return m_maxSize > 0
+        && canCachePageContainingThisFrame(page->mainFrame())
         && page->settings().usesPageCache()
 #if ENABLE(DEVICE_ORIENTATION) && !PLATFORM(IOS)
         && !DeviceMotionController::isActiveAt(page)
@@ -373,27 +363,24 @@ bool PageCache::canCache(Page* page) const
             || loadType == FrameLoadType::IndexedBackForward);
 }
 
-void PageCache::pruneToCapacityNow(int capacity, PruningReason pruningReason)
+void PageCache::pruneToSizeNow(unsigned size, PruningReason pruningReason)
 {
-    TemporaryChange<int>(m_capacity, std::max(capacity, 0));
+    TemporaryChange<unsigned>(m_maxSize, size);
     prune(pruningReason);
 }
 
-void PageCache::setCapacity(int capacity)
+void PageCache::setMaxSize(unsigned maxSize)
 {
-    ASSERT(capacity >= 0);
-    m_capacity = std::max(capacity, 0);
-
+    m_maxSize = maxSize;
     prune(PruningReason::None);
 }
 
-int PageCache::frameCount() const
+unsigned PageCache::frameCount() const
 {
-    int frameCount = 0;
-    for (HistoryItem* current = m_head; current; current = current->m_next) {
-        ++frameCount;
-        ASSERT(current->m_cachedPage);
-        frameCount += current->m_cachedPage->cachedMainFrame()->descendantFrameCount();
+    unsigned frameCount = m_items.size();
+    for (auto& item : m_items) {
+        ASSERT(item->m_cachedPage);
+        frameCount += item->m_cachedPage->cachedMainFrame()->descendantFrameCount();
     }
     
     return frameCount;
@@ -401,26 +388,26 @@ int PageCache::frameCount() const
 
 void PageCache::markPagesForVisitedLinkStyleRecalc()
 {
-    for (HistoryItem* current = m_head; current; current = current->m_next) {
-        ASSERT(current->m_cachedPage);
-        current->m_cachedPage->markForVisitedLinkStyleRecalc();
+    for (auto& item : m_items) {
+        ASSERT(item->m_cachedPage);
+        item->m_cachedPage->markForVisitedLinkStyleRecalc();
     }
 }
 
-void PageCache::markPagesForFullStyleRecalc(Page* page)
+void PageCache::markPagesForFullStyleRecalc(Page& page)
 {
-    for (HistoryItem* current = m_head; current; current = current->m_next) {
-        CachedPage& cachedPage = *current->m_cachedPage;
-        if (&page->mainFrame() == &cachedPage.cachedMainFrame()->view()->frame())
+    for (auto& item : m_items) {
+        CachedPage& cachedPage = *item->m_cachedPage;
+        if (&page.mainFrame() == &cachedPage.cachedMainFrame()->view()->frame())
             cachedPage.markForFullStyleRecalc();
     }
 }
 
-void PageCache::markPagesForDeviceScaleChanged(Page* page)
+void PageCache::markPagesForDeviceScaleChanged(Page& page)
 {
-    for (HistoryItem* current = m_head; current; current = current->m_next) {
-        CachedPage& cachedPage = *current->m_cachedPage;
-        if (&page->mainFrame() == &cachedPage.cachedMainFrame()->view()->frame())
+    for (auto& item : m_items) {
+        CachedPage& cachedPage = *item->m_cachedPage;
+        if (&page.mainFrame() == &cachedPage.cachedMainFrame()->view()->frame())
             cachedPage.markForDeviceScaleChanged();
     }
 }
@@ -428,9 +415,9 @@ void PageCache::markPagesForDeviceScaleChanged(Page* page)
 #if ENABLE(VIDEO_TRACK)
 void PageCache::markPagesForCaptionPreferencesChanged()
 {
-    for (HistoryItem* current = m_head; current; current = current->m_next) {
-        ASSERT(current->m_cachedPage);
-        current->m_cachedPage->markForCaptionPreferencesChanged();
+    for (auto& item : m_items) {
+        ASSERT(item->m_cachedPage);
+        item->m_cachedPage->markForCaptionPreferencesChanged();
     }
 }
 #endif
@@ -442,8 +429,8 @@ static String pruningReasonToDiagnosticLoggingKey(PruningReason pruningReason)
         return DiagnosticLoggingKeys::prunedDueToMemoryPressureKey();
     case PruningReason::ProcessSuspended:
         return DiagnosticLoggingKeys::prunedDueToProcessSuspended();
-    case PruningReason::ReachedCapacity:
-        return DiagnosticLoggingKeys::prunedDueToCapacityReached();
+    case PruningReason::ReachedMaxSize:
+        return DiagnosticLoggingKeys::prunedDueToMaxSizeReached();
     case PruningReason::None:
         break;
     }
@@ -451,45 +438,33 @@ static String pruningReasonToDiagnosticLoggingKey(PruningReason pruningReason)
     return emptyString();
 }
 
-void PageCache::add(PassRefPtr<HistoryItem> prpItem, Page& page)
+void PageCache::add(HistoryItem& item, Page& page)
 {
-    ASSERT(prpItem);
     ASSERT(canCache(&page));
-    
-    HistoryItem* item = prpItem.leakRef(); // Balanced in remove().
 
     // Remove stale cache entry if necessary.
-    if (item->m_cachedPage)
-        remove(item);
+    remove(item);
 
-    item->m_cachedPage = std::make_unique<CachedPage>(page);
-    item->m_pruningReason = PruningReason::None;
-    addToLRUList(item);
-    ++m_size;
+    item.m_cachedPage = std::make_unique<CachedPage>(page);
+    item.m_pruningReason = PruningReason::None;
+    m_items.add(&item);
     
-    prune(PruningReason::ReachedCapacity);
+    prune(PruningReason::ReachedMaxSize);
 }
 
-std::unique_ptr<CachedPage> PageCache::take(HistoryItem* item, Page* page)
+std::unique_ptr<CachedPage> PageCache::take(HistoryItem& item, Page* page)
 {
-    if (!item)
-        return nullptr;
-
-    std::unique_ptr<CachedPage> cachedPage = WTF::move(item->m_cachedPage);
-
-    removeFromLRUList(item);
-    --m_size;
-
-    item->deref(); // Balanced in add().
-
-    if (!cachedPage) {
-        if (item->m_pruningReason != PruningReason::None)
-            logPageCacheFailureDiagnosticMessage(page, pruningReasonToDiagnosticLoggingKey(item->m_pruningReason));
+    if (!item.m_cachedPage) {
+        if (item.m_pruningReason != PruningReason::None)
+            logPageCacheFailureDiagnosticMessage(page, pruningReasonToDiagnosticLoggingKey(item.m_pruningReason));
         return nullptr;
     }
 
+    std::unique_ptr<CachedPage> cachedPage = WTF::move(item.m_cachedPage);
+    m_items.remove(&item);
+
     if (cachedPage->hasExpired()) {
-        LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", item->url().string().ascii().data());
+        LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", item.url().string().ascii().data());
         logPageCacheFailureDiagnosticMessage(page, DiagnosticLoggingKeys::expiredKey());
         return nullptr;
     }
@@ -497,78 +472,41 @@ std::unique_ptr<CachedPage> PageCache::take(HistoryItem* item, Page* page)
     return cachedPage;
 }
 
-CachedPage* PageCache::get(HistoryItem* item, Page* page)
+CachedPage* PageCache::get(HistoryItem& item, Page* page) const
 {
-    if (!item)
+    CachedPage* cachedPage = item.m_cachedPage.get();
+    if (!cachedPage) {
+        if (item.m_pruningReason != PruningReason::None)
+            logPageCacheFailureDiagnosticMessage(page, pruningReasonToDiagnosticLoggingKey(item.m_pruningReason));
         return nullptr;
+    }
 
-    if (CachedPage* cachedPage = item->m_cachedPage.get()) {
-        if (!cachedPage->hasExpired())
-            return cachedPage;
-        
-        LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", item->url().string().ascii().data());
+    if (cachedPage->hasExpired()) {
+        LOG(PageCache, "Not restoring page for %s from back/forward cache because cache entry has expired", item.url().string().ascii().data());
         logPageCacheFailureDiagnosticMessage(page, DiagnosticLoggingKeys::expiredKey());
         PageCache::shared().remove(item);
-    } else if (item->m_pruningReason != PruningReason::None)
-        logPageCacheFailureDiagnosticMessage(page, pruningReasonToDiagnosticLoggingKey(item->m_pruningReason));
-
-    return nullptr;
+        return nullptr;
+    }
+    return cachedPage;
 }
 
-void PageCache::remove(HistoryItem* item)
+void PageCache::remove(HistoryItem& item)
 {
     // Safely ignore attempts to remove items not in the cache.
-    if (!item || !item->m_cachedPage)
+    if (!item.m_cachedPage)
         return;
 
-    item->m_cachedPage = nullptr;
-    removeFromLRUList(item);
-    --m_size;
-
-    item->deref(); // Balanced in add().
+    item.m_cachedPage = nullptr;
+    m_items.remove(&item);
 }
 
 void PageCache::prune(PruningReason pruningReason)
 {
-    while (m_size > m_capacity) {
-        ASSERT(m_tail && m_tail->m_cachedPage);
-        m_tail->m_pruningReason = pruningReason;
-        remove(m_tail);
-    }
-}
-
-void PageCache::addToLRUList(HistoryItem* item)
-{
-    item->m_next = m_head;
-    item->m_prev = 0;
-
-    if (m_head) {
-        ASSERT(m_tail);
-        m_head->m_prev = item;
-    } else {
-        ASSERT(!m_tail);
-        m_tail = item;
-    }
-
-    m_head = item;
-}
-
-void PageCache::removeFromLRUList(HistoryItem* item)
-{
-    if (!item->m_next) {
-        ASSERT(item == m_tail);
-        m_tail = item->m_prev;
-    } else {
-        ASSERT(item != m_tail);
-        item->m_next->m_prev = item->m_prev;
-    }
-
-    if (!item->m_prev) {
-        ASSERT(item == m_head);
-        m_head = item->m_next;
-    } else {
-        ASSERT(item != m_head);
-        item->m_prev->m_next = item->m_next;
+    while (pageCount() > maxSize()) {
+        auto& oldestItem = m_items.first();
+        oldestItem->m_cachedPage = nullptr;
+        oldestItem->m_pruningReason = pruningReason;
+        m_items.removeFirst();
     }
 }
 
index c310d4e..9536a9f 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ * Copyright (C) 2007, 2015 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
 #ifndef PageCache_h
 #define PageCache_h
 
+#include "HistoryItem.h"
 #include "Timer.h"
 #include <wtf/Forward.h>
-#include <wtf/HashSet.h>
+#include <wtf/ListHashSet.h>
 #include <wtf/Noncopyable.h>
 
 namespace WebCore {
 
-    class CachedPage;
-    class Frame;
-    class HistoryItem;
-    class Page;
+class CachedPage;
+class Frame;
+class Page;
 
-    enum class PruningReason { None, ProcessSuspended, MemoryPressure, ReachedCapacity };
-    
-    class PageCache {
-        WTF_MAKE_NONCOPYABLE(PageCache); WTF_MAKE_FAST_ALLOCATED;
-    public:
-        // Function to obtain the global page cache.
-        WEBCORE_EXPORT static PageCache& shared();
-        
-        bool canCache(Page*) const;
+enum class PruningReason { None, ProcessSuspended, MemoryPressure, ReachedMaxSize };
 
-        WEBCORE_EXPORT void setCapacity(int); // number of pages to cache
-        int capacity() { return m_capacity; }
-        
-        void add(PassRefPtr<HistoryItem>, Page&); // Prunes if capacity() is exceeded.
-        WEBCORE_EXPORT void remove(HistoryItem*);
-        CachedPage* get(HistoryItem*, Page*);
-        std::unique_ptr<CachedPage> take(HistoryItem*, Page*);
+class PageCache {
+    WTF_MAKE_NONCOPYABLE(PageCache); WTF_MAKE_FAST_ALLOCATED;
+public:
+    // Function to obtain the global page cache.
+    WEBCORE_EXPORT static PageCache& shared();
 
-        int pageCount() const { return m_size; }
-        WEBCORE_EXPORT int frameCount() const;
+    bool canCache(Page*) const;
 
-        WEBCORE_EXPORT void markPagesForVisitedLinkStyleRecalc();
+    // Used when memory is low to prune some cached pages.
+    WEBCORE_EXPORT void pruneToSizeNow(unsigned maxSize, PruningReason);
+    WEBCORE_EXPORT void setMaxSize(unsigned); // number of pages to cache.
+    unsigned maxSize() const { return m_maxSize; }
 
-        // Will mark all cached pages associated with the given page as needing style recalc.
-        void markPagesForFullStyleRecalc(Page*);
+    void add(HistoryItem&, Page&); // Prunes if maxSize() is exceeded.
+    WEBCORE_EXPORT void remove(HistoryItem&);
+    CachedPage* get(HistoryItem&, Page*) const;
+    std::unique_ptr<CachedPage> take(HistoryItem&, Page*);
 
-        // Used when memory is low to prune some cached pages.
-        WEBCORE_EXPORT void pruneToCapacityNow(int capacity, PruningReason);
+    unsigned pageCount() const { return m_items.size(); }
+    WEBCORE_EXPORT unsigned frameCount() const;
 
+    WEBCORE_EXPORT void markPagesForVisitedLinkStyleRecalc();
+    // Will mark all cached pages associated with the given page as needing style recalc.
+    void markPagesForFullStyleRecalc(Page&);
+    void markPagesForDeviceScaleChanged(Page&);
 #if ENABLE(VIDEO_TRACK)
-        void markPagesForCaptionPreferencesChanged();
+    void markPagesForCaptionPreferencesChanged();
 #endif
 
-        bool shouldClearBackingStores() const { return m_shouldClearBackingStores; }
-        void setShouldClearBackingStores(bool flag) { m_shouldClearBackingStores = flag; }
-        void markPagesForDeviceScaleChanged(Page*);
+    bool shouldClearBackingStores() const { return m_shouldClearBackingStores; }
+    void setShouldClearBackingStores(bool flag) { m_shouldClearBackingStores = flag; }
 
-    private:
-        PageCache(); // Use shared() instead.
-        ~PageCache(); // Not implemented to make sure nobody accidentally calls delete -- WebCore does not delete singletons.
-        
-        static bool canCachePageContainingThisFrame(Frame*);
+private:
+    PageCache() = default; // Use shared() instead.
+    ~PageCache() = delete; // Make sure nobody accidentally calls delete -- WebCore does not delete singletons.
 
-        void addToLRUList(HistoryItem*); // Adds to the head of the list.
-        void removeFromLRUList(HistoryItem*);
+    static bool canCachePageContainingThisFrame(Frame&);
 
-        void prune(PruningReason);
+    void prune(PruningReason);
 
-        int m_capacity;
-        int m_size;
+    ListHashSet<RefPtr<HistoryItem>> m_items;
+    unsigned m_maxSize {0};
+    bool m_shouldClearBackingStores {false};
 
-        // LRU List
-        HistoryItem* m_head;
-        HistoryItem* m_tail;
-        
-        bool m_shouldClearBackingStores;
-
-        friend class WTF::NeverDestroyed<PageCache>;
-    };
+    friend class WTF::NeverDestroyed<PageCache>;
+};
 
 } // namespace WebCore
 
index 90b5a0a..95fef61 100644 (file)
@@ -921,7 +921,7 @@ void FrameLoader::loadURLIntoChildFrame(const URL& url, const String& referer, F
         HistoryItem* childItem = parentItem->childItemWithTarget(childFrame->tree().uniqueName());
         if (childItem) {
             childFrame->loader().m_requestedHistoryItem = childItem;
-            childFrame->loader().loadDifferentDocumentItem(childItem, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem);
+            childFrame->loader().loadDifferentDocumentItem(*childItem, loadType(), MayAttemptCacheOnlyLoadForFormSubmissionItem);
             return;
         }
     }
@@ -1740,8 +1740,8 @@ void FrameLoader::commitProvisionalLoad()
     Ref<Frame> protect(m_frame);
 
     std::unique_ptr<CachedPage> cachedPage;
-    if (m_loadingFromCachedPage)
-        cachedPage = PageCache::shared().take(history().provisionalItem(), m_frame.page());
+    if (m_loadingFromCachedPage && history().provisionalItem())
+        cachedPage = PageCache::shared().take(*history().provisionalItem(), m_frame.page());
 
     LOG(PageCache, "WebCoreLoading %s: About to commit provisional load from previous URL '%s' to new URL '%s'", m_frame.tree().uniqueName().string().utf8().data(),
         m_frame.document() ? m_frame.document()->url().stringCenterEllipsizedToLength().utf8().data() : "",
@@ -1758,11 +1758,11 @@ void FrameLoader::commitProvisionalLoad()
             LOG(MemoryPressure, "Pruning page cache because under memory pressure at: %s", __PRETTY_FUNCTION__);
             LOG(PageCache, "Pruning page cache to 0 due to memory pressure");
             // Don't cache any page if we are under memory pressure.
-            PageCache::shared().pruneToCapacityNow(0, PruningReason::MemoryPressure);
+            PageCache::shared().pruneToSizeNow(0, PruningReason::MemoryPressure);
         } else if (systemMemoryLevel() <= memoryLevelThresholdToPrunePageCache) {
             LOG(MemoryPressure, "Pruning page cache because system memory level is %d at: %s", systemMemoryLevel(), __PRETTY_FUNCTION__);
             LOG(PageCache, "Pruning page cache to %d due to low memory (level %d less or equal to %d threshold)", PageCache::shared().capacity() / 2, systemMemoryLevel(), memoryLevelThresholdToPrunePageCache);
-            PageCache::shared().pruneToCapacityNow(PageCache::shared().capacity() / 2, PruningReason::MemoryPressure);
+            PageCache::shared().pruneToSizeNow(PageCache::shared().maxSize() / 2, PruningReason::MemoryPressure);
         }
     }
 #endif
@@ -1771,8 +1771,8 @@ void FrameLoader::commitProvisionalLoad()
 
     // Check to see if we need to cache the page we are navigating away from into the back/forward cache.
     // We are doing this here because we know for sure that a new page is about to be loaded.
-    HistoryItem* item = history().currentItem();
-    if (!m_frame.tree().parent() && PageCache::shared().canCache(m_frame.page()) && !item->isInPageCache())
+    HistoryItem& item = *history().currentItem();
+    if (!m_frame.tree().parent() && PageCache::shared().canCache(m_frame.page()) && !item.isInPageCache())
         PageCache::shared().add(item, *m_frame.page());
 
     if (m_loadType != FrameLoadType::Replace)
@@ -3127,14 +3127,14 @@ Frame* FrameLoader::findFrameForNavigation(const AtomicString& name, Document* a
         activeDocument = m_frame.document();
 
     if (!activeDocument->canNavigate(frame))
-        return 0;
+        return nullptr;
 
     return frame;
 }
 
-void FrameLoader::loadSameDocumentItem(HistoryItem* item)
+void FrameLoader::loadSameDocumentItem(HistoryItem& item)
 {
-    ASSERT(item->documentSequenceNumber() == history().currentItem()->documentSequenceNumber());
+    ASSERT(item.documentSequenceNumber() == history().currentItem()->documentSequenceNumber());
 
     // Save user view state to the current history item here since we don't do a normal load.
     // FIXME: Does form state need to be saved here too?
@@ -3142,10 +3142,10 @@ void FrameLoader::loadSameDocumentItem(HistoryItem* item)
     if (FrameView* view = m_frame.view())
         view->setWasScrolledByUser(false);
 
-    history().setCurrentItem(item);
+    history().setCurrentItem(&item);
         
     // loadInSameDocument() actually changes the URL and notifies load delegates of a "fake" load
-    loadInSameDocument(item->url(), item->stateObject(), false);
+    loadInSameDocument(item.url(), item.stateObject(), false);
 
     // Restore user view state from the current history item here since we don't do a normal load.
     history().restoreScrollPositionAndViewState();
@@ -3154,10 +3154,10 @@ void FrameLoader::loadSameDocumentItem(HistoryItem* item)
 // FIXME: This function should really be split into a couple pieces, some of
 // which should be methods of HistoryController and some of which should be
 // methods of FrameLoader.
-void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loadType, FormSubmissionCacheLoadPolicy cacheLoadPolicy)
+void FrameLoader::loadDifferentDocumentItem(HistoryItem& item, FrameLoadType loadType, FormSubmissionCacheLoadPolicy cacheLoadPolicy)
 {
     // Remember this item so we can traverse any child items as child frames load
-    history().setProvisionalItem(item);
+    history().setProvisionalItem(&item);
 
     if (CachedPage* cachedPage = PageCache::shared().get(item, m_frame.page())) {
         auto documentLoader = cachedPage->documentLoader();
@@ -3167,17 +3167,17 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loa
         return;
     }
 
-    URL itemURL = item->url();
-    URL itemOriginalURL = item->originalURL();
+    URL itemURL = item.url();
+    URL itemOriginalURL = item.originalURL();
     URL currentURL;
     if (documentLoader())
         currentURL = documentLoader()->url();
-    RefPtr<FormData> formData = item->formData();
+    RefPtr<FormData> formData = item.formData();
 
     ResourceRequest request(itemURL);
 
-    if (!item->referrer().isNull())
-        request.setHTTPReferrer(item->referrer());
+    if (!item.referrer().isNull())
+        request.setHTTPReferrer(item.referrer());
     
     // If this was a repost that failed the page cache, we might try to repost the form.
     NavigationAction action;
@@ -3186,8 +3186,8 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loa
 
         request.setHTTPMethod("POST");
         request.setHTTPBody(formData);
-        request.setHTTPContentType(item->formContentType());
-        RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item->referrer());
+        request.setHTTPContentType(item.formContentType());
+        RefPtr<SecurityOrigin> securityOrigin = SecurityOrigin::createFromString(item.referrer());
         addHTTPOriginIfNeeded(request, securityOrigin->toString());
 
         // Make sure to add extra fields to the request after the Origin header is added for the FormData case.
@@ -3242,11 +3242,11 @@ void FrameLoader::loadDifferentDocumentItem(HistoryItem* item, FrameLoadType loa
 }
 
 // Loads content into this frame, as specified by history item
-void FrameLoader::loadItem(HistoryItem* item, FrameLoadType loadType)
+void FrameLoader::loadItem(HistoryItem& item, FrameLoadType loadType)
 {
-    m_requestedHistoryItem = item;
+    m_requestedHistoryItem = &item;
     HistoryItem* currentItem = history().currentItem();
-    bool sameDocumentNavigation = currentItem && item->shouldDoSameDocumentNavigationTo(currentItem);
+    bool sameDocumentNavigation = currentItem && item.shouldDoSameDocumentNavigationTo(currentItem);
 
     if (sameDocumentNavigation)
         loadSameDocumentItem(item);
@@ -3260,11 +3260,12 @@ void FrameLoader::retryAfterFailedCacheOnlyMainResourceLoad()
     ASSERT(!m_loadingFromCachedPage);
     // We only use cache-only loads to avoid resubmitting forms.
     ASSERT(isBackForwardLoadType(m_loadType));
+    ASSERT(history().provisionalItem());
     ASSERT(history().provisionalItem()->formData());
     ASSERT(history().provisionalItem() == m_requestedHistoryItem.get());
 
     FrameLoadType loadType = m_loadType;
-    HistoryItem* item = history().provisionalItem();
+    HistoryItem& item = *history().provisionalItem();
 
     stopAllLoaders(ShouldNotClearProvisionalItem);
     loadDifferentDocumentItem(item, loadType, MayNotAttemptCacheOnlyLoadForFormSubmissionItem);
index 6d55806..06fa8f0 100644 (file)
@@ -125,7 +125,7 @@ public:
     WEBCORE_EXPORT void reloadWithOverrideEncoding(const String& overrideEncoding);
 
     void open(CachedFrameBase&);
-    void loadItem(HistoryItem*, FrameLoadType);
+    void loadItem(HistoryItem&, FrameLoadType);
     HistoryItem* requestedHistoryItem() const { return m_requestedHistoryItem.get(); }
 
     void retryAfterFailedCacheOnlyMainResourceLoad();
@@ -299,8 +299,8 @@ private:
 
     void checkTimerFired();
     
-    void loadSameDocumentItem(HistoryItem*);
-    void loadDifferentDocumentItem(HistoryItem*, FrameLoadType, FormSubmissionCacheLoadPolicy);
+    void loadSameDocumentItem(HistoryItem&);
+    void loadDifferentDocumentItem(HistoryItem&, FrameLoadType, FormSubmissionCacheLoadPolicy);
     
     void loadProvisionalItemFromCachedPage();
 
index 9b83a84..833e588 100644 (file)
@@ -234,11 +234,13 @@ void HistoryController::restoreDocumentState()
 
 void HistoryController::invalidateCurrentItemCachedPage()
 {
-    // When we are pre-commit, the currentItem is where any page cache data resides.
-    if (!PageCache::shared().get(currentItem(), m_frame.page()))
+    if (!currentItem())
         return;
 
-    std::unique_ptr<CachedPage> cachedPage = PageCache::shared().take(currentItem(), m_frame.page());
+    // When we are pre-commit, the currentItem is where any page cache data resides.
+    std::unique_ptr<CachedPage> cachedPage = PageCache::shared().take(*currentItem(), m_frame.page());
+    if (!cachedPage)
+        return;
 
     // FIXME: This is a grotesque hack to fix <rdar://problem/4059059> Crash in RenderFlow::detach
     // Somehow the PageState object is not properly updated, and is holding onto a stale document.
@@ -265,7 +267,7 @@ bool HistoryController::shouldStopLoadingForHistoryItem(HistoryItem* targetItem)
 
 // Main funnel for navigating to a previous location (back/forward, non-search snap-back)
 // This includes recursion to handle loading into framesets properly
-void HistoryController::goToItem(HistoryItem* targetItem, FrameLoadType type)
+void HistoryController::goToItem(HistoryItem& targetItem, FrameLoadType type)
 {
     ASSERT(!m_frame.tree().parent());
     
@@ -276,10 +278,10 @@ void HistoryController::goToItem(HistoryItem* targetItem, FrameLoadType type)
     Page* page = m_frame.page();
     if (!page)
         return;
-    if (!m_frame.loader().client().shouldGoToHistoryItem(targetItem))
+    if (!m_frame.loader().client().shouldGoToHistoryItem(&targetItem))
         return;
     if (m_defersLoading) {
-        m_deferredItem = targetItem;
+        m_deferredItem = &targetItem;
         m_deferredFrameLoadType = type;
         return;
     }
@@ -288,7 +290,7 @@ void HistoryController::goToItem(HistoryItem* targetItem, FrameLoadType type)
     // - plus, it only makes sense for the top level of the operation through the frame tree,
     // as opposed to happening for some/one of the page commits that might happen soon
     RefPtr<HistoryItem> currentItem = page->backForward().currentItem();
-    page->backForward().setCurrentItem(targetItem);
+    page->backForward().setCurrentItem(&targetItem);
     m_frame.loader().client().updateGlobalHistoryItemForPage();
 
     // First set the provisional item of any frames that are not actually navigating.
@@ -305,8 +307,8 @@ void HistoryController::setDefersLoading(bool defer)
 {
     m_defersLoading = defer;
     if (!defer && m_deferredItem) {
-        goToItem(m_deferredItem.get(), m_deferredFrameLoadType);
-        m_deferredItem = 0;
+        goToItem(*m_deferredItem, m_deferredFrameLoadType);
+        m_deferredItem = nullptr;
     }
 }
 
@@ -334,7 +336,7 @@ void HistoryController::updateForReload()
 #endif
 
     if (m_currentItem) {
-        PageCache::shared().remove(m_currentItem.get());
+        PageCache::shared().remove(*m_currentItem);
     
         if (m_frame.loader().loadType() == FrameLoadType::Reload || m_frame.loader().loadType() == FrameLoadType::ReloadFromOrigin)
             saveScrollPositionAndViewStateToItem(m_currentItem.get());
@@ -499,7 +501,7 @@ void HistoryController::recursiveUpdateForCommit()
     // For each frame that already had the content the item requested (based on
     // (a matching URL and frame tree snapshot), just restore the scroll position.
     // Save form state (works from currentItem, since m_frameLoadComplete is true)
-    if (m_currentItem && itemsAreClones(m_currentItem.get(), m_provisionalItem.get())) {
+    if (m_currentItem && itemsAreClones(*m_currentItem, m_provisionalItem.get())) {
         ASSERT(m_frameLoadComplete);
         saveDocumentState();
         saveScrollPositionAndViewStateToItem(m_currentItem.get());
@@ -707,17 +709,15 @@ PassRefPtr<HistoryItem> HistoryController::createItemTree(Frame& targetFrame, bo
 // tracking whether each frame already has the content the item requests.  If there is
 // a match, we set the provisional item and recurse.  Otherwise we will reload that
 // frame and all its kids in recursiveGoToItem.
-void HistoryController::recursiveSetProvisionalItem(HistoryItem* item, HistoryItem* fromItem)
+void HistoryController::recursiveSetProvisionalItem(HistoryItem& item, HistoryItem* fromItem)
 {
-    ASSERT(item);
-
     if (!itemsAreClones(item, fromItem))
         return;
 
     // Set provisional item, which will be committed in recursiveUpdateForCommit.
-    m_provisionalItem = item;
+    m_provisionalItem = &item;
 
-    for (const auto& childItem : item->children()) {
+    for (const auto& childItem : item.children()) {
         const String& childFrameName = childItem->target();
 
         HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
@@ -725,34 +725,32 @@ void HistoryController::recursiveSetProvisionalItem(HistoryItem* item, HistoryIt
         Frame* childFrame = m_frame.tree().child(childFrameName);
         ASSERT(childFrame);
 
-        childFrame->loader().history().recursiveSetProvisionalItem(childItem.get(), fromChildItem);
+        childFrame->loader().history().recursiveSetProvisionalItem(*childItem, fromChildItem);
     }
 }
 
 // We now traverse the frame tree and item tree a second time, loading frames that
 // do have the content the item requests.
-void HistoryController::recursiveGoToItem(HistoryItem* item, HistoryItem* fromItem, FrameLoadType type)
+void HistoryController::recursiveGoToItem(HistoryItem& item, HistoryItem* fromItem, FrameLoadType type)
 {
-    ASSERT(item);
-
     if (!itemsAreClones(item, fromItem)) {
         m_frame.loader().loadItem(item, type);
         return;
     }
 
     // Just iterate over the rest, looking for frames to navigate.
-    for (const auto& childItem : item->children()) {
+    for (const auto& childItem : item.children()) {
         const String& childFrameName = childItem->target();
 
         HistoryItem* fromChildItem = fromItem->childItemWithTarget(childFrameName);
         ASSERT(fromChildItem);
         Frame* childFrame = m_frame.tree().child(childFrameName);
         ASSERT(childFrame);
-        childFrame->loader().history().recursiveGoToItem(childItem.get(), fromChildItem, type);
+        childFrame->loader().history().recursiveGoToItem(*childItem, fromChildItem, type);
     }
 }
 
-bool HistoryController::itemsAreClones(HistoryItem* item1, HistoryItem* item2) const
+bool HistoryController::itemsAreClones(HistoryItem& item1, HistoryItem* item2) const
 {
     // If the item we're going to is a clone of the item we're at, then we do
     // not need to load it again.  The current frame tree and the frame tree
@@ -761,12 +759,11 @@ bool HistoryController::itemsAreClones(HistoryItem* item1, HistoryItem* item2) c
     // a reload.  Thus, if item1 and item2 are the same, we need to create a
     // new document and should not consider them clones.
     // (See http://webkit.org/b/35532 for details.)
-    return item1
-        && item2
-        && item1 != item2
-        && item1->itemSequenceNumber() == item2->itemSequenceNumber()
-        && currentFramesMatchItem(item1)
-        && item2->hasSameFrames(item1);
+    return item2
+        && &item1 != item2
+        && item1.itemSequenceNumber() == item2->itemSequenceNumber()
+        && currentFramesMatchItem(&item1)
+        && item2->hasSameFrames(&item1);
 }
 
 // Helper method that determines whether the current frame tree matches given history item's.
index 431f30e..1b40a80 100644 (file)
@@ -93,19 +93,19 @@ public:
 private:
     friend class Page;
     bool shouldStopLoadingForHistoryItem(HistoryItem*) const;
-    void goToItem(HistoryItem*, FrameLoadType);
+    void goToItem(HistoryItem&, FrameLoadType);
 
     void initializeItem(HistoryItem*);
     PassRefPtr<HistoryItem> createItem();
     PassRefPtr<HistoryItem> createItemTree(Frame& targetFrame, bool clipAtTarget);
 
-    void recursiveSetProvisionalItem(HistoryItem*, HistoryItem*);
-    void recursiveGoToItem(HistoryItem*, HistoryItem*, FrameLoadType);
+    void recursiveSetProvisionalItem(HistoryItem&, HistoryItem*);
+    void recursiveGoToItem(HistoryItem&, HistoryItem*, FrameLoadType);
     bool isReplaceLoadTypeWithProvisionalItem(FrameLoadType);
     bool isReloadTypeWithProvisionalItem(FrameLoadType);
     void recursiveUpdateForCommit();
     void recursiveUpdateForSameDocumentNavigation();
-    bool itemsAreClones(HistoryItem*, HistoryItem*) const;
+    bool itemsAreClones(HistoryItem&, HistoryItem*) const;
     bool currentFramesMatchItem(HistoryItem*) const;
     void updateBackForwardListClippedAtTarget(bool doClip);
     void updateCurrentItem();
index 959c415..1d2df78 100644 (file)
@@ -388,7 +388,7 @@ String DiagnosticLoggingKeys::prunedDueToMemoryPressureKey()
     return ASCIILiteral("pruned.memoryPressure");
 }
 
-String DiagnosticLoggingKeys::prunedDueToCapacityReached()
+String DiagnosticLoggingKeys::prunedDueToMaxSizeReached()
 {
     return ASCIILiteral("pruned.capacityReached");
 }
index 6df524d..5e54aff 100644 (file)
@@ -76,7 +76,7 @@ public:
     static String playedKey();
     static String pluginLoadedKey();
     static String pluginLoadingFailedKey();
-    static String prunedDueToCapacityReached();
+    static String prunedDueToMaxSizeReached();
     static String prunedDueToMemoryPressureKey();
     static String prunedDueToProcessSuspended();
     static String quirkRedirectComingKey();
index 8314c9a..78cb193 100644 (file)
@@ -989,7 +989,7 @@ void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor
     }
 
     if (isMainFrame())
-        PageCache::shared().markPagesForFullStyleRecalc(page);
+        PageCache::shared().markPagesForFullStyleRecalc(*page);
 }
 
 float Frame::frameScaleFactor() const
index 7c535d0..7d97aef 100644 (file)
@@ -430,13 +430,13 @@ void Page::setOpenedByDOM()
     m_openedByDOM = true;
 }
 
-void Page::goToItem(HistoryItem* item, FrameLoadType type)
+void Page::goToItem(HistoryItem& item, FrameLoadType type)
 {
     // stopAllLoaders may end up running onload handlers, which could cause further history traversals that may lead to the passed in HistoryItem
     // being deref()-ed. Make sure we can still use it with HistoryController::goToItem later.
-    RefPtr<HistoryItem> protector(item);
+    Ref<HistoryItem> protector(item);
 
-    if (m_mainFrame->loader().history().shouldStopLoadingForHistoryItem(item))
+    if (m_mainFrame->loader().history().shouldStopLoadingForHistoryItem(&item))
         m_mainFrame->loader().stopAllLoaders();
 
     m_mainFrame->loader().history().goToItem(item, type);
@@ -839,9 +839,9 @@ void Page::setDeviceScaleFactor(float scaleFactor)
     setNeedsRecalcStyleInAllFrames();
 
     mainFrame().deviceOrPageScaleFactorChanged();
-    PageCache::shared().markPagesForDeviceScaleChanged(this);
+    PageCache::shared().markPagesForDeviceScaleChanged(*this);
 
-    PageCache::shared().markPagesForFullStyleRecalc(this);
+    PageCache::shared().markPagesForFullStyleRecalc(*this);
     GraphicsContext::updateDocumentMarkerResources();
 
     mainFrame().pageOverlayController().didChangeDeviceScaleFactor();
@@ -921,7 +921,7 @@ void Page::setPagination(const Pagination& pagination)
     m_pagination = pagination;
 
     setNeedsRecalcStyleInAllFrames();
-    PageCache::shared().markPagesForFullStyleRecalc(this);
+    PageCache::shared().markPagesForFullStyleRecalc(*this);
 }
 
 unsigned Page::pageCount() const
@@ -1661,7 +1661,7 @@ void Page::setVisitedLinkStore(Ref<VisitedLinkStore>&& visitedLinkStore)
     m_visitedLinkStore->addPage(*this);
 
     invalidateStylesForAllLinks();
-    PageCache::shared().markPagesForFullStyleRecalc(this);
+    PageCache::shared().markPagesForFullStyleRecalc(*this);
 }
 
 SessionID Page::sessionID() const
index 28c04d8..7fcf7ab 100644 (file)
@@ -150,7 +150,7 @@ public:
     bool openedByDOM() const;
     void setOpenedByDOM();
 
-    WEBCORE_EXPORT void goToItem(HistoryItem*, FrameLoadType);
+    WEBCORE_EXPORT void goToItem(HistoryItem&, FrameLoadType);
 
     WEBCORE_EXPORT void setGroupName(const String&);
     WEBCORE_EXPORT const String& groupName() const;
index d7739d1..956b44c 100644 (file)
@@ -519,12 +519,8 @@ void Settings::setUsesPageCache(bool usesPageCache)
     if (!m_page)
         return;
 
-    if (!m_usesPageCache) {
-        int first = -m_page->backForward().backCount();
-        int last = m_page->backForward().forwardCount();
-        for (int i = first; i <= last; i++)
-            PageCache::shared().remove(m_page->backForward().itemAtIndex(i));
-    }
+    if (!m_usesPageCache)
+        PageCache::shared().pruneToSizeNow(0, PruningReason::None);
 }
 
 void Settings::setScreenFontSubstitutionEnabled(bool enabled)
index 9378ab6..b502deb 100644 (file)
@@ -102,7 +102,7 @@ void MemoryPressureHandler::releaseCriticalMemory()
         ReliefLogger log("Empty the PageCache");
         // Right now, the only reason we call release critical memory while not under memory pressure is if the process is about to be suspended.
         PruningReason pruningReason = memoryPressureHandler().isUnderMemoryPressure() ? PruningReason::MemoryPressure : PruningReason::ProcessSuspended;
-        PageCache::shared().pruneToCapacityNow(0, pruningReason);
+        PageCache::shared().pruneToSizeNow(0, pruningReason);
     }
 
     {
index 6597163..32995da 100644 (file)
@@ -1,3 +1,19 @@
+2015-01-29  Chris Dumez  <cdumez@apple.com>
+
+        Clean up / modernize PageCache class
+        https://bugs.webkit.org/show_bug.cgi?id=141009
+
+        Reviewed by Darin Adler.
+
+        Clean up / modernize PageCache class.
+
+        * History/WebBackForwardList.mm:
+        (-[WebBackForwardList pageCacheSize]):
+        * WebView/WebView.mm:
+        (-[WebView _loadBackForwardListFromOtherView:]):
+        (-[WebView goToBackForwardItem:]):
+        (+[WebView _setCacheModel:]):
+
 2015-01-28  Beth Dakin  <bdakin@apple.com>
 
         Remove Mountain Lion code from WebKit and WebKit2
index 8757c8c..6b45002 100644 (file)
@@ -355,7 +355,7 @@ static bool bumperCarBackForwardHackNeeded()
 
 - (NSUInteger)pageCacheSize
 {
-    return [kit(core(self)->page()) usesPageCache] ? PageCache::shared().capacity() : 0;
+    return [kit(core(self)->page()) usesPageCache] ? PageCache::shared().maxSize() : 0;
 }
 
 - (int)backListCount
index 90bf06e..7952f7a 100644 (file)
@@ -1997,7 +1997,7 @@ static bool fastDocumentTeardownEnabled()
     if (!otherBackForwardClient->currentItem())
         return; // empty back forward list, bail
     
-    HistoryItem* newItemToGoTo = 0;
+    HistoryItem* newItemToGoTo = nullptr;
 
     int lastItemIndex = otherBackForwardClient->forwardListCount();
     for (int i = -otherBackForwardClient->backListCount(); i <= lastItemIndex; ++i) {
@@ -2014,7 +2014,7 @@ static bool fastDocumentTeardownEnabled()
     }
     
     ASSERT(newItemToGoTo);
-    _private->page->goToItem(newItemToGoTo, FrameLoadType::IndexedBackForward);
+    _private->page->goToItem(*newItemToGoTo, FrameLoadType::IndexedBackForward);
 }
 
 - (void)_setFormDelegate: (id<WebFormDelegate>)delegate
@@ -5647,7 +5647,8 @@ static NSString * const backingPropertyOldScaleFactorKey = @"NSBackingPropertyOl
     if (!_private->page)
         return NO;
 
-    _private->page->goToItem(core(item), FrameLoadType::IndexedBackForward);
+    ASSERT(item);
+    _private->page->goToItem(*core(item), FrameLoadType::IndexedBackForward);
     return YES;
 }
 
@@ -7742,7 +7743,7 @@ static inline uint64_t roundUpToPowerOf2(uint64_t num)
     unsigned cacheMaxDeadCapacity = 0;
     auto deadDecodedDataDeletionInterval = std::chrono::seconds { 0 };
 
-    unsigned pageCacheCapacity = 0;
+    unsigned pageCacheSize = 0;
 
     NSUInteger nsurlCacheMemoryCapacity = 0;
     NSUInteger nsurlCacheDiskCapacity = 0;
@@ -7753,7 +7754,7 @@ static inline uint64_t roundUpToPowerOf2(uint64_t num)
     switch (cacheModel) {
     case WebCacheModelDocumentViewer: {
         // Page cache capacity (in pages)
-        pageCacheCapacity = 0;
+        pageCacheSize = 0;
 
         // Object cache capacities (in bytes)
         if (memSize >= 4096)
@@ -7790,13 +7791,13 @@ static inline uint64_t roundUpToPowerOf2(uint64_t num)
     case WebCacheModelDocumentBrowser: {
         // Page cache capacity (in pages)
         if (memSize >= 1024)
-            pageCacheCapacity = 3;
+            pageCacheSize = 3;
         else if (memSize >= 512)
-            pageCacheCapacity = 2;
+            pageCacheSize = 2;
         else if (memSize >= 256)
-            pageCacheCapacity = 1;
+            pageCacheSize = 1;
         else
-            pageCacheCapacity = 0;
+            pageCacheSize = 0;
 
         // Object cache capacities (in bytes)
         if (memSize >= 4096)
@@ -7844,22 +7845,22 @@ static inline uint64_t roundUpToPowerOf2(uint64_t num)
         // Page cache capacity (in pages)
         // (Research indicates that value / page drops substantially after 3 pages.)
         if (memSize >= 2048)
-            pageCacheCapacity = 5;
+            pageCacheSize = 5;
         else if (memSize >= 1024)
-            pageCacheCapacity = 4;
+            pageCacheSize = 4;
         else if (memSize >= 512)
-            pageCacheCapacity = 3;
+            pageCacheSize = 3;
         else if (memSize >= 256)
-            pageCacheCapacity = 2;
+            pageCacheSize = 2;
         else
-            pageCacheCapacity = 1;
+            pageCacheSize = 1;
 
 #if PLATFORM(IOS)
         // Cache page less aggressively in iOS to reduce the chance of being jettisoned.
         // FIXME (<rdar://problem/11779846>): Avoiding jettisoning should not have to require reducing the page cache capacity.
         // Reducing the capacity by 1 reduces overall back-forward performance.
-        if (pageCacheCapacity > 0)
-            pageCacheCapacity -= 1;
+        if (pageCacheSize > 0)
+            pageCacheSize -= 1;
 #endif
 
         // Object cache capacities (in bytes)
@@ -7935,7 +7936,7 @@ static inline uint64_t roundUpToPowerOf2(uint64_t num)
 
     memoryCache().setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
     memoryCache().setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
-    PageCache::shared().setCapacity(pageCacheCapacity);
+    PageCache::shared().setMaxSize(pageCacheSize);
 #if PLATFORM(IOS)
     PageCache::shared().setShouldClearBackingStores(true);
     nsurlCacheMemoryCapacity = std::max(nsurlCacheMemoryCapacity, [nsurlCache memoryCapacity]);
index 3556d70..7d6e9b5 100644 (file)
@@ -1,3 +1,15 @@
+2015-01-29  Chris Dumez  <cdumez@apple.com>
+
+        Clean up / modernize PageCache class
+        https://bugs.webkit.org/show_bug.cgi?id=141009
+
+        Reviewed by Darin Adler.
+
+        Clean up / modernize PageCache class.
+
+        * WebView.cpp:
+        (WebView::setCacheModel):
+
 2015-01-28  peavo@outlook.com  <peavo@outlook.com>
 
         [WinCairo] Message loop is flooded with timer messages when animating in accelerated compositing mode.
index 0f17eda..eabf1c0 100644 (file)
@@ -530,13 +530,13 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
     unsigned cacheMaxDeadCapacity = 0;
     auto deadDecodedDataDeletionInterval = std::chrono::seconds { 0 };
 
-    unsigned pageCacheCapacity = 0;
+    unsigned pageCacheSize = 0;
 
 
     switch (cacheModel) {
     case WebCacheModelDocumentViewer: {
         // Page cache capacity (in pages)
-        pageCacheCapacity = 0;
+        pageCacheSize = 0;
 
         // Object cache capacities (in bytes)
         if (memSize >= 2048)
@@ -563,13 +563,13 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
     case WebCacheModelDocumentBrowser: {
         // Page cache capacity (in pages)
         if (memSize >= 1024)
-            pageCacheCapacity = 3;
+            pageCacheSize = 3;
         else if (memSize >= 512)
-            pageCacheCapacity = 2;
+            pageCacheSize = 2;
         else if (memSize >= 256)
-            pageCacheCapacity = 1;
+            pageCacheSize = 1;
         else
-            pageCacheCapacity = 0;
+            pageCacheSize = 0;
 
         // Object cache capacities (in bytes)
         if (memSize >= 2048)
@@ -610,15 +610,15 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
         // Page cache capacity (in pages)
         // (Research indicates that value / page drops substantially after 3 pages.)
         if (memSize >= 2048)
-            pageCacheCapacity = 5;
+            pageCacheSize = 5;
         else if (memSize >= 1024)
-            pageCacheCapacity = 4;
+            pageCacheSize = 4;
         else if (memSize >= 512)
-            pageCacheCapacity = 3;
+            pageCacheSize = 3;
         else if (memSize >= 256)
-            pageCacheCapacity = 2;
+            pageCacheSize = 2;
         else
-            pageCacheCapacity = 1;
+            pageCacheSize = 1;
 
         // Object cache capacities (in bytes)
         // (Testing indicates that value / MB depends heavily on content and
@@ -675,7 +675,7 @@ void WebView::setCacheModel(WebCacheModel cacheModel)
 
     memoryCache().setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
     memoryCache().setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
-    PageCache::shared().setCapacity(pageCacheCapacity);
+    PageCache::shared().setMaxSize(pageCacheSize);
 
 #if USE(CFNETWORK)
     // Don't shrink a big disk cache, since that would cause churn.
@@ -3154,7 +3154,7 @@ HRESULT STDMETHODCALLTYPE WebView::goToBackForwardItem(
     if (FAILED(hr))
         return hr;
 
-    m_page->goToItem(webHistoryItem->historyItem(), FrameLoadType::IndexedBackForward);
+    m_page->goToItem(*webHistoryItem->historyItem(), FrameLoadType::IndexedBackForward);
     *succeeded = TRUE;
 
     return S_OK;
@@ -5501,7 +5501,7 @@ HRESULT STDMETHODCALLTYPE WebView::loadBackForwardListFromOtherView(
     }
     
     ASSERT(newItemToGoTo);
-    m_page->goToItem(newItemToGoTo, FrameLoadType::IndexedBackForward);
+    m_page->goToItem(*newItemToGoTo, FrameLoadType::IndexedBackForward);
     return S_OK;
 }
 
index 45c7211..2328e45 100644 (file)
@@ -1,3 +1,26 @@
+2015-01-29  Chris Dumez  <cdumez@apple.com>
+
+        Clean up / modernize PageCache class
+        https://bugs.webkit.org/show_bug.cgi?id=141009
+
+        Reviewed by Darin Adler.
+
+        Clean up / modernize PageCache class.
+
+        * WebProcess/WebPage/WebBackForwardListProxy.cpp:
+        (WebKit::WebBackForwardListProxy::removeItem):
+        (WebKit::WebBackForwardListProxy::close):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::goForward):
+        (WebKit::WebPage::goBack):
+        (WebKit::WebPage::goToBackForwardItem):
+        * WebProcess/WebProcess.cpp:
+        (WebKit::WebProcess::releasePageCache):
+        * WebProcess/cocoa/WebProcessCocoa.mm:
+        (WebKit::WebProcess::platformSetCacheModel):
+        * WebProcess/soup/WebProcessSoup.cpp:
+        (WebKit::WebProcess::platformSetCacheModel):
+
 2015-01-29  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         [EFL][GTK] Fix the build after r179326
index a17613b..75e27ba 100644 (file)
@@ -132,7 +132,7 @@ void WebBackForwardListProxy::removeItem(uint64_t itemID)
     if (!item)
         return;
         
-    PageCache::shared().remove(item.get());
+    PageCache::shared().remove(*item);
     WebCore::Page::clearPreviousItemFromAllPages(item.get());
     historyItemToIDMap().remove(item);
 }
@@ -216,12 +216,12 @@ int WebBackForwardListProxy::forwardListCount()
 
 void WebBackForwardListProxy::close()
 {
-    HashSet<uint64_t>::iterator end = m_associatedItemIDs.end();
-    for (HashSet<uint64_t>::iterator i = m_associatedItemIDs.begin(); i != end; ++i)
-        WebCore::PageCache::shared().remove(itemForID(*i));
+    for (auto& itemID : m_associatedItemIDs) {
+        if (HistoryItem* item = itemForID(itemID))
+            WebCore::PageCache::shared().remove(*item);
+    }
 
     m_associatedItemIDs.clear();
-
     m_page = nullptr;
 }
 
index 9f89fc1..5810aba 100644 (file)
@@ -1210,7 +1210,7 @@ void WebPage::goForward(uint64_t navigationID, uint64_t backForwardItemID)
     if (!item->isInPageCache())
         m_pendingNavigationID = navigationID;
 
-    m_page->goToItem(item, FrameLoadType::Forward);
+    m_page->goToItem(*item, FrameLoadType::Forward);
 }
 
 void WebPage::goBack(uint64_t navigationID, uint64_t backForwardItemID)
@@ -1226,7 +1226,7 @@ void WebPage::goBack(uint64_t navigationID, uint64_t backForwardItemID)
     if (!item->isInPageCache())
         m_pendingNavigationID = navigationID;
 
-    m_page->goToItem(item, FrameLoadType::Back);
+    m_page->goToItem(*item, FrameLoadType::Back);
 }
 
 void WebPage::goToBackForwardItem(uint64_t navigationID, uint64_t backForwardItemID)
@@ -1242,7 +1242,7 @@ void WebPage::goToBackForwardItem(uint64_t navigationID, uint64_t backForwardIte
     if (!item->isInPageCache())
         m_pendingNavigationID = navigationID;
 
-    m_page->goToItem(item, FrameLoadType::IndexedBackForward);
+    m_page->goToItem(*item, FrameLoadType::IndexedBackForward);
 }
 
 void WebPage::tryRestoreScrollPosition()
index 8b8b884..9616b00 100644 (file)
@@ -1116,7 +1116,7 @@ void WebProcess::setTextCheckerState(const TextCheckerState& textCheckerState)
 
 void WebProcess::releasePageCache()
 {
-    PageCache::shared().pruneToCapacityNow(0, PruningReason::MemoryPressure);
+    PageCache::shared().pruneToSizeNow(0, PruningReason::MemoryPressure);
 }
 
 #if !PLATFORM(COCOA)
index 88e4d98..45adc09 100644 (file)
@@ -104,18 +104,18 @@ void WebProcess::platformSetCacheModel(CacheModel cacheModel)
     unsigned cacheMinDeadCapacity = 0;
     unsigned cacheMaxDeadCapacity = 0;
     auto deadDecodedDataDeletionInterval = std::chrono::seconds { 0 };
-    unsigned pageCacheCapacity = 0;
+    unsigned pageCacheSize = 0;
     unsigned long urlCacheMemoryCapacity = 0;
     unsigned long urlCacheDiskCapacity = 0;
 
     calculateCacheSizes(cacheModel, memSize, diskFreeSize,
         cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval,
-        pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity);
+        pageCacheSize, urlCacheMemoryCapacity, urlCacheDiskCapacity);
 
 
     memoryCache().setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
     memoryCache().setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
-    PageCache::shared().setCapacity(pageCacheCapacity);
+    PageCache::shared().setMaxSize(pageCacheSize);
 
     NSURLCache *nsurlCache = [NSURLCache sharedURLCache];
 
index bcc7ad6..118c722 100644 (file)
@@ -83,7 +83,7 @@ void WebProcess::platformSetCacheModel(CacheModel cacheModel)
     unsigned cacheMinDeadCapacity = 0;
     unsigned cacheMaxDeadCapacity = 0;
     auto deadDecodedDataDeletionInterval = std::chrono::seconds { 0 };
-    unsigned pageCacheCapacity = 0;
+    unsigned pageCacheSize = 0;
 
     unsigned long urlCacheMemoryCapacity = 0;
     unsigned long urlCacheDiskCapacity = 0;
@@ -99,12 +99,12 @@ void WebProcess::platformSetCacheModel(CacheModel cacheModel)
     uint64_t memSize = getMemorySize();
     calculateCacheSizes(cacheModel, memSize, diskFreeSize,
                         cacheTotalCapacity, cacheMinDeadCapacity, cacheMaxDeadCapacity, deadDecodedDataDeletionInterval,
-                        pageCacheCapacity, urlCacheMemoryCapacity, urlCacheDiskCapacity);
+                        pageCacheSize, urlCacheMemoryCapacity, urlCacheDiskCapacity);
 
     WebCore::memoryCache().setDisabled(cacheModel == CacheModelDocumentViewer);
     WebCore::memoryCache().setCapacities(cacheMinDeadCapacity, cacheMaxDeadCapacity, cacheTotalCapacity);
     WebCore::memoryCache().setDeadDecodedDataDeletionInterval(deadDecodedDataDeletionInterval);
-    WebCore::PageCache::shared().setCapacity(pageCacheCapacity);
+    WebCore::PageCache::shared().setMaxSize(pageCacheSize);
 
 #if PLATFORM(GTK)
     WebCore::PageCache::shared().setShouldClearBackingStores(true);