WebCore:
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Jan 2009 15:40:24 +0000 (15:40 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Jan 2009 15:40:24 +0000 (15:40 +0000)
2009-01-07  Darin Adler  <darin@apple.com>

        Reviewed by Oliver Hunt.

        Bug 23160: add setMemoryCacheClientCallsEnabled SPI so Safari can be faster with activity window closed
        https://bugs.webkit.org/show_bug.cgi?id=23160

        * WebCore.base.exp: Added Page::setMemoryCacheClientCallsEnabled.

        * inspector/InspectorController.cpp:
        (WebCore::InspectorController::didLoadResourceFromMemoryCache): Updated to take a CachedResource
        so that there's no extra work the caller has to do when the inspector is disabled.
        * inspector/InspectorController.h: Ditto.

        * loader/DocumentLoader.h: Added recordMemoryCacheLoadForFutureClientNotification,
        takeMemoryCacheLoadsForClientNotification, and m_resourcesLoadedFromMemoryCacheForClientNotification.

        * loader/FrameLoader.cpp:
        (WebCore::FrameLoader::loadedResourceFromMemoryCache): Streamlined code so less work is done when
        there's no inspector or client call needed. Added code to check areMemoryCacheClientCallsEnabled
        and if it's false, use recordMemoryCacheLoadForFutureClientNotification.
        (WebCore::FrameLoader::tellClientAboutPastMemoryCacheLoads): Added.
        * loader/FrameLoader.h: Ditto.

        * page/Page.cpp:
        (WebCore::Page::Page): Initialize m_areMemoryCacheClientCallsEnabled to be compatible with old behavior.
        (WebCore::Page::setMemoryCacheClientCallsEnabled): Added.
        * page/Page.h: Added setMemoryCacheClientCallsEnabled, areMemoryCacheClientCallsEnabled,
        and m_areMemoryCacheClientCallsEnabled.

WebKit/mac:

2009-01-07  Darin Adler  <darin@apple.com>

        Reviewed by Oliver Hunt.

        Bug 23160: add setMemoryCacheClientCallsEnabled SPI so Safari can be faster with activity window closed
        https://bugs.webkit.org/show_bug.cgi?id=23160

        * WebView/WebView.mm:
        (-[WebView setMemoryCacheDelegateCallsEnabled:]): Added.
        (-[WebView areMemoryCacheDelegateCallsEnabled]): Added
        * WebView/WebViewPrivate.h: Ditto.

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

12 files changed:
WebCore/ChangeLog
WebCore/WebCore.base.exp
WebCore/inspector/InspectorController.cpp
WebCore/inspector/InspectorController.h
WebCore/loader/DocumentLoader.h
WebCore/loader/FrameLoader.cpp
WebCore/loader/FrameLoader.h
WebCore/page/Page.cpp
WebCore/page/Page.h
WebKit/mac/ChangeLog
WebKit/mac/WebView/WebView.mm
WebKit/mac/WebView/WebViewPrivate.h

index 0f2f2f5..29d10c5 100644 (file)
@@ -1,3 +1,33 @@
+2009-01-07  Darin Adler  <darin@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Bug 23160: add setMemoryCacheClientCallsEnabled SPI so Safari can be faster with activity window closed
+        https://bugs.webkit.org/show_bug.cgi?id=23160
+
+        * WebCore.base.exp: Added Page::setMemoryCacheClientCallsEnabled.
+
+        * inspector/InspectorController.cpp:
+        (WebCore::InspectorController::didLoadResourceFromMemoryCache): Updated to take a CachedResource
+        so that there's no extra work the caller has to do when the inspector is disabled.
+        * inspector/InspectorController.h: Ditto.
+
+        * loader/DocumentLoader.h: Added recordMemoryCacheLoadForFutureClientNotification,
+        takeMemoryCacheLoadsForClientNotification, and m_resourcesLoadedFromMemoryCacheForClientNotification.
+
+        * loader/FrameLoader.cpp:
+        (WebCore::FrameLoader::loadedResourceFromMemoryCache): Streamlined code so less work is done when
+        there's no inspector or client call needed. Added code to check areMemoryCacheClientCallsEnabled
+        and if it's false, use recordMemoryCacheLoadForFutureClientNotification.
+        (WebCore::FrameLoader::tellClientAboutPastMemoryCacheLoads): Added.
+        * loader/FrameLoader.h: Ditto.
+
+        * page/Page.cpp:
+        (WebCore::Page::Page): Initialize m_areMemoryCacheClientCallsEnabled to be compatible with old behavior.
+        (WebCore::Page::setMemoryCacheClientCallsEnabled): Added.
+        * page/Page.h: Added setMemoryCacheClientCallsEnabled, areMemoryCacheClientCallsEnabled,
+        and m_areMemoryCacheClientCallsEnabled.
+
 2009-01-07  Ariya Hidayat  <ariya.hidayat@trolltech.com>
 
         Rubber-stamped by Simon Hausmann.
index 679f8cf..42514a0 100644 (file)
@@ -459,6 +459,7 @@ __ZN7WebCore4Page23clearUndoRedoOperationsEv
 __ZN7WebCore4Page23pendingUnloadEventCountEv
 __ZN7WebCore4Page31setCustomHTMLTokenizerChunkSizeEi
 __ZN7WebCore4Page31setCustomHTMLTokenizerTimeDelayEd
+__ZN7WebCore4Page32setMemoryCacheClientCallsEnabledEb
 __ZN7WebCore4Page37setInLowQualityImageInterpolationModeEb
 __ZN7WebCore4Page6goBackEv
 __ZN7WebCore4Page8goToItemEPNS_11HistoryItemENS_13FrameLoadTypeE
index 37ed7bb..9d42964 100644 (file)
@@ -2379,22 +2379,22 @@ void InspectorController::removeResource(InspectorResource* resource)
     }
 }
 
-void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, const ResourceRequest& request, const ResourceResponse& response, int length)
+void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader, const CachedResource* cachedResource)
 {
     if (!enabled())
         return;
 
     // If the resource URL is already known, we don't need to add it again since this is just a cached load.
-    if (m_knownResources.contains(request.url().string()))
+    if (m_knownResources.contains(cachedResource->url()))
         return;
 
     RefPtr<InspectorResource> resource = InspectorResource::create(m_nextIdentifier--, loader, loader->frame());
     resource->finished = true;
 
-    updateResourceRequest(resource.get(), request);
-    updateResourceResponse(resource.get(), response);
+    resource->requestURL = KURL(cachedResource->url());
+    updateResourceResponse(resource.get(), cachedResource->response());
 
-    resource->length = length;
+    resource->length = cachedResource->encodedSize();
     resource->cached = true;
     resource->startTime = currentTime();
     resource->responseReceivedTime = resource->startTime;
@@ -2402,7 +2402,7 @@ void InspectorController::didLoadResourceFromMemoryCache(DocumentLoader* loader,
 
     ASSERT(m_inspectedPage);
 
-    if (loader->frame() == m_inspectedPage->mainFrame() && request.url() == loader->requestURL())
+    if (loader->frame() == m_inspectedPage->mainFrame() && cachedResource->url() == loader->requestURL())
         m_mainResource = resource;
 
     addResource(resource.get());
index 056ae91..e52bee9 100644 (file)
 #ifndef InspectorController_h
 #define InspectorController_h
 
-#if ENABLE(JAVASCRIPT_DEBUGGER)
-#include "JavaScriptDebugListener.h"
-#endif
-
 #include "Console.h"
 #include "PlatformString.h"
 #include "StringHash.h"
 #include "Timer.h"
-
 #include <JavaScriptCore/JSContextRef.h>
-
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
 #include <wtf/Vector.h>
 
+#if ENABLE(JAVASCRIPT_DEBUGGER)
+#include "JavaScriptDebugListener.h"
+#endif
+
+
 namespace JSC {
     class Profile;
     class UString;
@@ -51,6 +50,7 @@ namespace JSC {
 
 namespace WebCore {
 
+class CachedResource;
 class Database;
 class DocumentLoader;
 class GraphicsContext;
@@ -59,6 +59,7 @@ class InspectorClient;
 class JavaScriptCallFrame;
 class Node;
 class Page;
+class ResourceRequest;
 class ResourceResponse;
 class ResourceError;
 class ScriptCallStack;
@@ -67,7 +68,6 @@ class SharedBuffer;
 struct ConsoleMessage;
 struct InspectorDatabaseResource;
 struct InspectorResource;
-class ResourceRequest;
 
 class InspectorController
 #if ENABLE(JAVASCRIPT_DEBUGGER)
@@ -196,7 +196,7 @@ public:
     void didCommitLoad(DocumentLoader*);
     void frameDetachedFromParent(Frame*);
 
-    void didLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length);
+    void didLoadResourceFromMemoryCache(DocumentLoader*, const CachedResource*);
 
     void identifierForInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest&);
     void willSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest&, const ResourceResponse& redirectResponse);
index 2b80295..691a7e2 100644 (file)
@@ -188,6 +188,8 @@ namespace WebCore {
         
         void didTellClientAboutLoad(const String& url) { m_resourcesClientKnowsAbout.add(url); }
         bool haveToldClientAboutLoad(const String& url) { return m_resourcesClientKnowsAbout.contains(url); }
+        void recordMemoryCacheLoadForFutureClientNotification(const String& url);
+        void takeMemoryCacheLoadsForClientNotification(Vector<String>& loads);
 
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)
         bool scheduleApplicationCacheLoad(ResourceLoader*, const ResourceRequest&, const KURL& originalURL);
@@ -284,6 +286,7 @@ namespace WebCore {
         RefPtr<SharedBuffer> m_parsedArchiveData;
 
         HashSet<String> m_resourcesClientKnowsAbout;
+        Vector<String> m_resourcesLoadedFromMemoryCacheForClientNotification;
 
 #if ENABLE(OFFLINE_WEB_APPLICATIONS)  
         // The application cache that the document loader is associated with (if any).
@@ -298,6 +301,17 @@ namespace WebCore {
 #endif
     };
 
+    inline void DocumentLoader::recordMemoryCacheLoadForFutureClientNotification(const String& url)
+    {
+        m_resourcesLoadedFromMemoryCacheForClientNotification.append(url);
+    }
+
+    inline void DocumentLoader::takeMemoryCacheLoadsForClientNotification(Vector<String>& loadsSet)
+    {
+        loadsSet.swap(m_resourcesLoadedFromMemoryCacheForClientNotification);
+        m_resourcesLoadedFromMemoryCacheForClientNotification.clear();
+    }
+
 }
 
 #endif // DocumentLoader_h
index 6023f14..1a9f4a4 100644 (file)
@@ -4024,27 +4024,31 @@ void FrameLoader::requestFromDelegate(ResourceRequest& request, unsigned long& i
 
 void FrameLoader::loadedResourceFromMemoryCache(const CachedResource* resource)
 {
-    ResourceRequest request(resource->url());
-    const ResourceResponse& response = resource->response();
-    SharedBuffer* data = resource->data();
-    int length = data ? data->size() : 0;
+    Page* page = m_frame->page();
+    if (!page)
+        return;
 
-    if (Page* page = m_frame->page())
-        page->inspectorController()->didLoadResourceFromMemoryCache(m_documentLoader.get(), request, response, length);
+    page->inspectorController()->didLoadResourceFromMemoryCache(m_documentLoader.get(), resource);
 
-    if (!resource->sendResourceLoadCallbacks() || m_documentLoader->haveToldClientAboutLoad(request.url()))
+    if (!resource->sendResourceLoadCallbacks() || m_documentLoader->haveToldClientAboutLoad(resource->url()))
         return;
 
-    if (m_client->dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), request, response, length)) {
-        m_documentLoader->didTellClientAboutLoad(request.url());
+    if (!page->areMemoryCacheClientCallsEnabled()) {
+        m_documentLoader->recordMemoryCacheLoadForFutureClientNotification(resource->url());
+        m_documentLoader->didTellClientAboutLoad(resource->url());
+        return;
+    }
+
+    ResourceRequest request(resource->url());
+    if (m_client->dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), request, resource->response(), resource->encodedSize())) {
+        m_documentLoader->didTellClientAboutLoad(resource->url());
         return;
     }
 
     unsigned long identifier;
     ResourceError error;
-    ResourceRequest r(request);
-    requestFromDelegate(r, identifier, error);
-    sendRemainingDelegateMessages(identifier, response, length, error);
+    requestFromDelegate(request, identifier, error);
+    sendRemainingDelegateMessages(identifier, resource->response(), resource->encodedSize(), error);
 }
 
 void FrameLoader::applyUserAgent(ResourceRequest& request)
@@ -5155,6 +5159,33 @@ void FrameLoader::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long
         page->inspectorController()->didFinishLoading(loader, identifier);
 }
 
+void FrameLoader::tellClientAboutPastMemoryCacheLoads()
+{
+    ASSERT(m_frame->page());
+    ASSERT(m_frame->page()->areMemoryCacheClientCallsEnabled());
+
+    if (!m_documentLoader)
+        return;
+
+    Vector<String> pastLoads;
+    m_documentLoader->takeMemoryCacheLoadsForClientNotification(pastLoads);
+
+    size_t size = pastLoads.size();
+    for (size_t i = 0; i < size; ++i) {
+        CachedResource* resource = cache()->resourceForURL(pastLoads[i]);
+
+        // FIXME: These loads, loaded from cache, but now gone from the cache by the time
+        // Page::setMemoryCacheClientCallsEnabled(true) is called, will not be seen by the client.
+        // Consider if there's some efficient way of remembering enough to deliver this client call.
+        // We have the URL, but not the rest of the response or the length.
+        if (!resource)
+            continue;
+
+        ResourceRequest request(resource->url());
+        m_client->dispatchDidLoadResourceFromMemoryCache(m_documentLoader.get(), request, resource->response(), resource->encodedSize());
+    }
+}
+
 #if USE(LOW_BANDWIDTH_DISPLAY)
 
 bool FrameLoader::addLowBandwidthDisplayRequest(CachedResource* cache)
index a02012c..dd55552 100644 (file)
@@ -264,6 +264,7 @@ namespace WebCore {
         void sendRemainingDelegateMessages(unsigned long identifier, const ResourceResponse&, int length, const ResourceError&);
         void requestFromDelegate(ResourceRequest&, unsigned long& identifier, ResourceError&);
         void loadedResourceFromMemoryCache(const CachedResource*);
+        void tellClientAboutPastMemoryCacheLoads();
 
         void recursiveCheckLoadComplete();
         void checkLoadComplete();
index 48d63d9..67f1266 100644 (file)
@@ -121,6 +121,7 @@ Page::Page(ChromeClient* chromeClient, ContextMenuClient* contextMenuClient, Edi
     , m_defersLoading(false)
     , m_inLowQualityInterpolationMode(false)
     , m_cookieEnabled(true)
+    , m_areMemoryCacheClientCallsEnabled(true)
     , m_mediaVolume(1)
     , m_parentInspectorController(0)
     , m_didLoadUserStyleSheet(false)
@@ -613,4 +614,17 @@ void Page::setCustomHTMLTokenizerChunkSize(int customHTMLTokenizerChunkSize)
     m_customHTMLTokenizerChunkSize = customHTMLTokenizerChunkSize;
 }
 
+void Page::setMemoryCacheClientCallsEnabled(bool enabled)
+{
+    if (m_areMemoryCacheClientCallsEnabled == enabled)
+        return;
+
+    m_areMemoryCacheClientCallsEnabled = enabled;
+    if (!enabled)
+        return;
+
+    for (RefPtr<Frame> frame = mainFrame(); frame; frame = frame->tree()->traverseNext())
+        frame->loader()->tellClientAboutPastMemoryCacheLoads();
+}
+
 } // namespace WebCore
index 7a1b6da..de2b3f6 100644 (file)
 #include "FrameLoaderTypes.h"
 #include "LinkHash.h"
 #include "PlatformString.h"
+#include <wtf/HashSet.h>
+#include <wtf/OwnPtr.h>
+
 #if PLATFORM(MAC)
 #include "SchedulePair.h"
 #endif
-#include <wtf/HashSet.h>
-#include <wtf/OwnPtr.h>
 
 #if PLATFORM(WIN) || (PLATFORM(WX) && PLATFORM(WIN_OS)) || (PLATFORM(QT) && defined(Q_WS_WIN))
 typedef struct HINSTANCE__* HINSTANCE;
@@ -193,6 +194,9 @@ namespace WebCore {
         bool hasCustomHTMLTokenizerChunkSize() const { return m_customHTMLTokenizerChunkSize != -1; }
         int customHTMLTokenizerChunkSize() const { ASSERT(m_customHTMLTokenizerChunkSize != -1); return m_customHTMLTokenizerChunkSize; }
 
+        void setMemoryCacheClientCallsEnabled(bool);
+        bool areMemoryCacheClientCallsEnabled() const { return m_areMemoryCacheClientCallsEnabled; }
+
     private:
         void initGroup();
 
@@ -222,6 +226,7 @@ namespace WebCore {
 
         bool m_inLowQualityInterpolationMode;
         bool m_cookieEnabled;
+        bool m_areMemoryCacheClientCallsEnabled;
         float m_mediaVolume;
     
         InspectorController* m_parentInspectorController;
@@ -245,6 +250,7 @@ namespace WebCore {
 #if ENABLE(DOM_STORAGE)
         RefPtr<SessionStorage> m_sessionStorage;
 #endif
+
 #if PLATFORM(WIN) || (PLATFORM(WX) && defined(__WXMSW__)) || (PLATFORM(QT) && defined(Q_WS_WIN))
         static HINSTANCE s_instanceHandle;
 #endif
index 2c50e3e..ddc2503 100644 (file)
@@ -1,3 +1,15 @@
+2009-01-07  Darin Adler  <darin@apple.com>
+
+        Reviewed by Oliver Hunt.
+
+        Bug 23160: add setMemoryCacheClientCallsEnabled SPI so Safari can be faster with activity window closed
+        https://bugs.webkit.org/show_bug.cgi?id=23160
+
+        * WebView/WebView.mm:
+        (-[WebView setMemoryCacheDelegateCallsEnabled:]): Added.
+        (-[WebView areMemoryCacheDelegateCallsEnabled]): Added
+        * WebView/WebViewPrivate.h: Ditto.
+
 2009-01-05  Gavin Barraclough  <baraclough@apple.com>
 
         Rubber Stamped by Oliver Hunt.
index 7719fb0..0418b10 100644 (file)
@@ -2046,6 +2046,16 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati
     return _private->selectTrailingWhitespaceEnabled;
 }
 
+- (void)setMemoryCacheDelegateCallsEnabled:(BOOL)enabled
+{
+    _private->page->setMemoryCacheClientCallsEnabled(enabled);
+}
+
+- (BOOL)areMemoryCacheDelegateCallsEnabled
+{
+    return _private->page->areMemoryCacheClientCallsEnabled();
+}
+
 @end
 
 @implementation _WebSafeForwarder
index 54dd144..95e1249 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005 Apple Computer, Inc.  All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -403,6 +403,9 @@ Could be worth adding to the API.
 - (void)setSelectTrailingWhitespaceEnabled:(BOOL)flag;
 - (BOOL)isSelectTrailingWhitespaceEnabled;
 
+- (void)setMemoryCacheDelegateCallsEnabled:(BOOL)suspend;
+- (BOOL)areMemoryCacheDelegateCallsEnabled;
+
 @end
 
 @interface WebView (WebViewPrintingPrivate)