Title: [146544] trunk/Source
Revision
146544
Author
beid...@apple.com
Date
2013-03-21 17:14:03 -0700 (Thu, 21 Mar 2013)

Log Message

If a previously loaded resource is later stored to the disk cache, replace the buffer with MMAP'ed memory.
<rdar://problem/13414154> and https://bugs.webkit.org/show_bug.cgi?id=112943

Reviewed by Geoff Garen.

Source/WebCore:

No new tests (No change in behavior.)

Give SharedBuffer the ability to replace its contents from another SharedBuffer:
* platform/SharedBuffer.h:
* platform/cf/SharedBufferCF.cpp:
(WebCore::SharedBuffer:: tryReplaceContentsWithPlatformBuffer):

Forward along SharedBuffer's new ability to ResourceBuffer:
* loader/mac/ResourceBuffer.mm:
(WebCore::ResourceBuffer:: tryReplaceSharedBufferContents):
* loader/ResourceBuffer.h:

Give CachedResource the ability to replace its encoded data buffer if appropriate:
* loader/cache/CachedResource.cpp:
(WebCore::CachedResource:: tryReplaceEncodedData):
* loader/cache/CachedResource.h:

* WebCore.exp.in:

Source/WebKit2:

Add a timer that will try to look up the disk cached buffer for the resource a few seconds after the load
completes and - if the resource is disk backed - send it to the WebProcess for sharing:
* NetworkProcess/NetworkResourceLoader.cpp:
(WebKit::NetworkResourceLoader::NetworkResourceLoader):
(WebKit::NetworkResourceLoader::diskCacheTimerFired):
(WebKit::NetworkResourceLoader::didReceiveResponse):
(WebKit::NetworkResourceLoader::didReceiveData):
(WebKit::NetworkResourceLoader::didFinishLoading):
* NetworkProcess/NetworkResourceLoader.h:

* NetworkProcess/mac/NetworkResourceLoaderMac.mm:
(WebKit::NetworkResourceLoader::tryGetShareableHandleForResource):

Refactor SharedMemory to remove the unnecessary vm_copy and only vm_allocate when an appropriate buffer
doesn't already exist:
* Platform/SharedMemory.h:
* Platform/mac/SharedMemoryMac.cpp:
(WebKit::SharedMemory::create):
(WebKit::SharedMemory::createFromVMBuffer):
(WebKit::SharedMemory::~SharedMemory):

Give ShareableResource the ability to create a CFDataRef that wraps "this", and return it in a SharedBuffer:
* Shared/ShareableResource.cpp:
(WebKit::shareableResourceDeallocate):
(WebKit::createShareableResourceDeallocator):
(WebKit::ShareableResource::Handle::tryWrapInSharedBuffer):
* Shared/ShareableResource.h:

* Shared/WebCoreArgumentCoders.cpp: Encode/decode the cache partition for ResourceRequest.

* WebProcess/Network/NetworkProcessConnection.cpp:
(WebKit::NetworkProcessConnection::didReceiveMessage):
(WebKit::NetworkProcessConnection::didCacheResource): Lookup the CachedResource in the WebCore memory cache
  and try to replace its encoded data with the shared mmap'ed buffer.
* WebProcess/Network/NetworkProcessConnection.h:
* WebProcess/Network/NetworkProcessConnection.messages.in:

* WebProcess/Network/WebResourceLoader.cpp:
(WebKit::WebResourceLoader::didReceiveResource):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (146543 => 146544)


--- trunk/Source/WebCore/ChangeLog	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/ChangeLog	2013-03-22 00:14:03 UTC (rev 146544)
@@ -1,3 +1,29 @@
+2013-03-21  Brady Eidson  <beid...@apple.com>
+
+        If a previously loaded resource is later stored to the disk cache, replace the buffer with MMAP'ed memory.
+        <rdar://problem/13414154> and https://bugs.webkit.org/show_bug.cgi?id=112943
+
+        Reviewed by Geoff Garen.
+
+        No new tests (No change in behavior.)
+
+        Give SharedBuffer the ability to replace its contents from another SharedBuffer:
+        * platform/SharedBuffer.h:
+        * platform/cf/SharedBufferCF.cpp:
+        (WebCore::SharedBuffer:: tryReplaceContentsWithPlatformBuffer):
+
+        Forward along SharedBuffer's new ability to ResourceBuffer:
+        * loader/mac/ResourceBuffer.mm:
+        (WebCore::ResourceBuffer:: tryReplaceSharedBufferContents):
+        * loader/ResourceBuffer.h:
+
+        Give CachedResource the ability to replace its encoded data buffer if appropriate:
+        * loader/cache/CachedResource.cpp:
+        (WebCore::CachedResource:: tryReplaceEncodedData):
+        * loader/cache/CachedResource.h:
+
+        * WebCore.exp.in:
+
 2013-03-21  Joshua Bell  <jsb...@chromium.org>
 
         IndexedDB: Ensure script wrappers can be collected after context is stopped

Modified: trunk/Source/WebCore/WebCore.exp.in (146543 => 146544)


--- trunk/Source/WebCore/WebCore.exp.in	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/WebCore.exp.in	2013-03-22 00:14:03 UTC (rev 146544)
@@ -170,6 +170,7 @@
 __ZN7WebCore11MemoryCache13setCapacitiesEjjj
 __ZN7WebCore11MemoryCache14evictResourcesEv
 __ZN7WebCore11MemoryCache14resourceForURLERKNS_4KURLE
+__ZN7WebCore11MemoryCache18resourceForRequestERKNS_15ResourceRequestE
 __ZN7WebCore11MemoryCache19getOriginsWithCacheERN3WTF7HashSetINS1_6RefPtrINS_14SecurityOriginEEENS_18SecurityOriginHashENS1_10HashTraitsIS5_EEEE
 __ZN7WebCore11MemoryCache25removeResourcesWithOriginEPNS_14SecurityOriginE
 __ZN7WebCore11URLWithDataEP6NSDataP5NSURL
@@ -273,6 +274,7 @@
 __ZN7WebCore13toJSDOMWindowEN3JSC7JSValueE
 __ZN7WebCore14CachedResource12removeClientEPNS_20CachedResourceClientE
 __ZN7WebCore14CachedResource16unregisterHandleEPNS_24CachedResourceHandleBaseE
+__ZN7WebCore14CachedResource21tryReplaceEncodedDataEN3WTF10PassRefPtrINS_12SharedBufferEEE
 __ZN7WebCore14CachedResource9addClientEPNS_20CachedResourceClientE
 __ZN7WebCore14ClientRectListC1ERKN3WTF6VectorINS_9FloatQuadELm0EEE
 __ZN7WebCore14ClientRectListC1Ev
@@ -1597,6 +1599,7 @@
 _stringIsCaseInsensitiveEqualToString
 _suggestedFilenameWithMIMEType
 #if ENABLE(CACHE_PARTITIONING)
+__ZN7WebCore15ResourceRequest13partitionNameERKN3WTF6StringE
 _wkCachePartitionKey
 #endif
 _wkCGContextGetShouldSmoothFonts

Modified: trunk/Source/WebCore/loader/ResourceBuffer.h (146543 => 146544)


--- trunk/Source/WebCore/loader/ResourceBuffer.h	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/loader/ResourceBuffer.h	2013-03-22 00:14:03 UTC (rev 146544)
@@ -64,6 +64,9 @@
     unsigned getSomeData(const char*& data, unsigned position = 0) const;
     
     SharedBuffer* sharedBuffer() const;
+#if PLATFORM(MAC)
+    void tryReplaceSharedBufferContents(SharedBuffer*);
+#endif
     PassRefPtr<ResourceBuffer> copy() const;
 
     bool hasPurgeableBuffer() const;

Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (146543 => 146544)


--- trunk/Source/WebCore/loader/cache/CachedResource.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -969,4 +969,19 @@
         info.addRawBuffer(m_purgeableData.get(), m_purgeableData->size(), "PurgeableData", "purgeableData");
 }
 
+#if PLATFORM(MAC)
+void CachedResource::tryReplaceEncodedData(PassRefPtr<SharedBuffer> newBuffer)
+{
+    if (!m_data)
+        return;
+    
+    // Because the disk cache is asynchronous and racey with regards to the data we might be asked to replace,
+    // we need to verify that the new buffer has the same contents as our old buffer.
+    if (m_data->size() != newBuffer->size() || memcmp(m_data->data(), newBuffer->data(), m_data->size()))
+        return;
+
+    m_data->tryReplaceSharedBufferContents(newBuffer.get());
 }
+#endif
+
+}

Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (146543 => 146544)


--- trunk/Source/WebCore/loader/cache/CachedResource.h	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/loader/cache/CachedResource.h	2013-03-22 00:14:03 UTC (rev 146544)
@@ -50,6 +50,7 @@
 class PurgeableBuffer;
 class ResourceBuffer;
 class SecurityOrigin;
+class SharedBuffer;
 class SubresourceLoader;
 
 // A resource that is held in the cache. Classes who want to use this object should derive
@@ -263,6 +264,10 @@
 
     virtual bool canReuse(const ResourceRequest&) const { return true; }
 
+#if PLATFORM(MAC)
+    void tryReplaceEncodedData(PassRefPtr<SharedBuffer>);
+#endif
+
 protected:
     virtual void checkNotify();
 

Modified: trunk/Source/WebCore/loader/mac/ResourceBuffer.mm (146543 => 146544)


--- trunk/Source/WebCore/loader/mac/ResourceBuffer.mm	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/loader/mac/ResourceBuffer.mm	2013-03-22 00:14:03 UTC (rev 146544)
@@ -33,4 +33,12 @@
     return m_sharedBuffer->createNSData();
 }
 
+void ResourceBuffer::tryReplaceSharedBufferContents(SharedBuffer* newContents)
+{
+    if (!m_sharedBuffer)
+        m_sharedBuffer = newContents;
+    else
+        m_sharedBuffer->tryReplaceContentsWithPlatformBuffer(newContents);
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/SharedBuffer.h (146543 => 146544)


--- trunk/Source/WebCore/platform/SharedBuffer.h	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/platform/SharedBuffer.h	2013-03-22 00:14:03 UTC (rev 146544)
@@ -118,6 +118,8 @@
 
     void createPurgeableBuffer() const;
 
+    void tryReplaceContentsWithPlatformBuffer(SharedBuffer*);
+
 private:
     SharedBuffer();
     explicit SharedBuffer(size_t);

Modified: trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp (146543 => 146544)


--- trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -93,6 +93,15 @@
     m_cfData = 0;
 }
 
+void SharedBuffer::tryReplaceContentsWithPlatformBuffer(SharedBuffer* newContents)
+{
+    if (!newContents->m_cfData)
+        return;
+
+    clear();
+    m_cfData = newContents->m_cfData;
+}
+
 #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
 void SharedBuffer::append(CFDataRef data)
 {

Modified: trunk/Source/WebKit2/ChangeLog (146543 => 146544)


--- trunk/Source/WebKit2/ChangeLog	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/ChangeLog	2013-03-22 00:14:03 UTC (rev 146544)
@@ -1,3 +1,50 @@
+2013-03-21  Brady Eidson  <beid...@apple.com>
+
+        If a previously loaded resource is later stored to the disk cache, replace the buffer with MMAP'ed memory.
+        <rdar://problem/13414154> and https://bugs.webkit.org/show_bug.cgi?id=112943
+
+        Reviewed by Geoff Garen.
+
+        Add a timer that will try to look up the disk cached buffer for the resource a few seconds after the load
+        completes and - if the resource is disk backed - send it to the WebProcess for sharing:
+        * NetworkProcess/NetworkResourceLoader.cpp:
+        (WebKit::NetworkResourceLoader::NetworkResourceLoader):
+        (WebKit::NetworkResourceLoader::diskCacheTimerFired):
+        (WebKit::NetworkResourceLoader::didReceiveResponse):
+        (WebKit::NetworkResourceLoader::didReceiveData):
+        (WebKit::NetworkResourceLoader::didFinishLoading):
+        * NetworkProcess/NetworkResourceLoader.h:
+
+        * NetworkProcess/mac/NetworkResourceLoaderMac.mm:
+        (WebKit::NetworkResourceLoader::tryGetShareableHandleForResource):
+
+        Refactor SharedMemory to remove the unnecessary vm_copy and only vm_allocate when an appropriate buffer
+        doesn't already exist:
+        * Platform/SharedMemory.h:
+        * Platform/mac/SharedMemoryMac.cpp:
+        (WebKit::SharedMemory::create):
+        (WebKit::SharedMemory::createFromVMBuffer):
+        (WebKit::SharedMemory::~SharedMemory):
+
+        Give ShareableResource the ability to create a CFDataRef that wraps "this", and return it in a SharedBuffer:
+        * Shared/ShareableResource.cpp:
+        (WebKit::shareableResourceDeallocate):
+        (WebKit::createShareableResourceDeallocator):
+        (WebKit::ShareableResource::Handle::tryWrapInSharedBuffer):
+        * Shared/ShareableResource.h:
+
+        * Shared/WebCoreArgumentCoders.cpp: Encode/decode the cache partition for ResourceRequest.
+
+        * WebProcess/Network/NetworkProcessConnection.cpp:
+        (WebKit::NetworkProcessConnection::didReceiveMessage):
+        (WebKit::NetworkProcessConnection::didCacheResource): Lookup the CachedResource in the WebCore memory cache
+          and try to replace its encoded data with the shared mmap'ed buffer.
+        * WebProcess/Network/NetworkProcessConnection.h:
+        * WebProcess/Network/NetworkProcessConnection.messages.in:
+
+        * WebProcess/Network/WebResourceLoader.cpp:
+        (WebKit::WebResourceLoader::didReceiveResource):
+
 2013-03-21  Tim Horton  <timothy_hor...@apple.com>
 
         Unreviewed build fix, forgot to stage one file.

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp (146543 => 146544)


--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -33,6 +33,7 @@
 #include "Logging.h"
 #include "NetworkConnectionToWebProcess.h"
 #include "NetworkProcess.h"
+#include "NetworkProcessConnectionMessages.h"
 #include "NetworkResourceLoadParameters.h"
 #include "PlatformCertificateInfo.h"
 #include "RemoteNetworkingContext.h"
@@ -43,6 +44,7 @@
 #include <WebCore/NotImplemented.h>
 #include <WebCore/ResourceBuffer.h>
 #include <WebCore/ResourceHandle.h>
+#include <wtf/CurrentTime.h>
 #include <wtf/MainThread.h>
 
 using namespace WebCore;
@@ -51,6 +53,10 @@
 
 NetworkResourceLoader::NetworkResourceLoader(const NetworkResourceLoadParameters& loadParameters, NetworkConnectionToWebProcess* connection)
     : SchedulableLoader(loadParameters, connection)
+    , m_bytesReceived(0)
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    , m_diskCacheTimer(RunLoop::main(), this, &NetworkResourceLoader::diskCacheTimerFired)
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 {
     ASSERT(isMainThread());
 }
@@ -168,6 +174,21 @@
     cleanup();
 }
 
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+void NetworkResourceLoader::diskCacheTimerFired()
+{
+    ASSERT(isMainThread());
+    RefPtr<NetworkResourceLoader> adoptedRef = adoptRef(this); // Balance out the ref() when setting the timer.
+
+    ShareableResource::Handle handle;
+    tryGetShareableHandleForResource(handle);
+    if (handle.isNull())
+        return;
+
+    send(Messages::NetworkProcessConnection::DidCacheResource(request(), handle));
+}
+#endif // #if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+
 template<typename U> bool NetworkResourceLoader::sendAbortingOnFailure(const U& message)
 {
     bool result = send(message);
@@ -203,7 +224,17 @@
     if (!sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveResponseWithCertificateInfo(response, PlatformCertificateInfo(response))))
         return;
 
-    platformDidReceiveResponse(response);
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    ShareableResource::Handle handle;
+    tryGetShareableHandleForResource(handle);
+    if (handle.isNull())
+        return;
+
+    // Since we're delivering this resource by ourselves all at once, we'll abort the resource handle since we don't need anymore callbacks from ResourceHandle.
+    abortInProgressLoad();
+    
+    send(Messages::WebResourceLoader::DidReceiveResource(handle, currentTime()));
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
 }
 
 void NetworkResourceLoader::didReceiveData(ResourceHandle*, const char* data, int length, int encodedDataLength)
@@ -211,6 +242,8 @@
     // FIXME (NetworkProcess): For the memory cache we'll also need to cache the response data here.
     // Such buffering will need to be thread safe, as this callback is happening on a background thread.
     
+    m_bytesReceived += length;
+
     CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(data), length);
     sendAbortingOnFailure(Messages::WebResourceLoader::DidReceiveData(dataReference, encodedDataLength));
 }
@@ -221,6 +254,17 @@
     // Such bookkeeping will need to be thread safe, as this callback is happening on a background thread.
     invalidateSandboxExtensions();
     send(Messages::WebResourceLoader::DidFinishResourceLoad(finishTime));
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    // If this resource was large enough that it should be cached to disk as a separate file,
+    // then we should try to re-deliver the resource to the WebProcess once it *is* saved as a separate file.    
+    if (m_bytesReceived >= fileBackedResourceMinimumSize()) {
+        // FIXME: Once a notification API exists that obliviates this timer, use that instead.
+        ref(); // Balanced by an adoptRef() in diskCacheTimerFired().
+        m_diskCacheTimer.startOneShot(10);
+    }
+#endif // __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    
     scheduleCleanupOnMainThread();
 }
 

Modified: trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h (146543 => 146544)


--- trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/NetworkProcess/NetworkResourceLoader.h	2013-03-22 00:14:03 UTC (rev 146544)
@@ -30,8 +30,10 @@
 
 #include "MessageSender.h"
 #include "SchedulableLoader.h"
+#include "ShareableResource.h"
 #include <WebCore/ResourceHandleClient.h>
 #include <WebCore/ResourceLoaderOptions.h>
+#include <WebCore/RunLoop.h>
 
 namespace WebCore {
 class ResourceBuffer;
@@ -107,8 +109,17 @@
     template<typename U> bool sendSyncAbortingOnFailure(const U& message, const typename U::Reply& reply);
     void abortInProgressLoad();
 
+    void tryGetShareableHandleForResource(ShareableResource::Handle&);
+
     RefPtr<RemoteNetworkingContext> m_networkingContext;
     RefPtr<WebCore::ResourceHandle> m_handle;
+
+    uint64_t m_bytesReceived;
+
+#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
+    void diskCacheTimerFired();
+    WebCore::RunLoop::Timer<NetworkResourceLoader> m_diskCacheTimer;
+#endif
 };
 
 } // namespace WebKit

Modified: trunk/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoaderMac.mm (146543 => 146544)


--- trunk/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoaderMac.mm	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/NetworkProcess/mac/NetworkResourceLoaderMac.mm	2013-03-22 00:14:03 UTC (rev 146544)
@@ -29,7 +29,7 @@
 #include "ShareableResource.h"
 #include "SharedMemory.h"
 #include "WebResourceLoaderMessages.h"
-#include <wtf/CurrentTime.h>
+#include <WebCore/SoftLinking.h>
 
 using namespace WebCore;
 
@@ -39,11 +39,21 @@
 extern "C" CFURLCacheRef CFURLCacheCopySharedURLCache();
 extern "C" CFCachedURLResponseRef CFURLCacheCopyResponseForRequest(CFURLCacheRef, CFURLRequestRef);
 extern "C" CFArrayRef CFCachedURLResponseCopyReceiverDataArray(CFCachedURLResponseRef);
+
+SOFT_LINK_FRAMEWORK(CFNetwork)
+static bool CFURLCacheIsMemMappedData(CFURLCacheRef cache, CFDataRef data)
+{
+    static CFBooleanRef (*softLinkIsCacheMMAPedData)(CFURLCacheRef cache, CFDataRef data) = (CFBooleanRef (*)(CFURLCacheRef cache, CFDataRef data)) dlsym(CFNetworkLibrary(), "_CFURLCacheIsResponseDataMemMapped");
+    
+    if (softLinkIsCacheMMAPedData)
+        return softLinkIsCacheMMAPedData(cache, data) == kCFBooleanTrue;
+    return false;
+}
 #endif
 
 namespace WebKit {
 
-void NetworkResourceLoader::platformDidReceiveResponse(const WebCore::ResourceResponse&)
+void NetworkResourceLoader::tryGetShareableHandleForResource(ShareableResource::Handle& handle)
 {
 #if __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
     return;
@@ -73,24 +83,18 @@
     if (CFDataGetLength(data) < (CFIndex)fileBackedResourceMinimumSize())
         return;
     
-    RefPtr<SharedMemory> sharedMemory = SharedMemory::createWithVMCopy((void*)CFDataGetBytePtr(data), CFDataGetLength(data));
+    if (!CFURLCacheIsMemMappedData(cache.get(), data))
+        return;
+
+    RefPtr<SharedMemory> sharedMemory = SharedMemory::createFromVMBuffer((void*)CFDataGetBytePtr(data), CFDataGetLength(data));
     if (!sharedMemory) {
-        LOG_ERROR("Failed to create VMCopied shared memory for cached resource.  We'll let it load normally.");
+        LOG_ERROR("Failed to create VMCopied shared memory for cached resource.");
         return;
     }
- 
+
     size_t size = sharedMemory->size();
     RefPtr<ShareableResource> resource = ShareableResource::create(sharedMemory.release(), 0, size);
-    ShareableResource::Handle handle;
-    if (!resource->createHandle(handle)) {
-        LOG_ERROR("Failed to create ShareableResource handle to send to the WebProcess for resource.  We'll let it load normally.");
-        return;
-    }
-
-    // Since we're delivering this resource by ourselves all at once, we'll abort the resource handle since we don't need anymore callbacks from CFNetwork.
-    abortInProgressLoad();
-    
-    send(Messages::WebResourceLoader::DidReceiveResource(handle, currentTime()));
+    resource->createHandle(handle);
 #endif // __MAC_OS_X_VERSION_MIN_REQUIRED < 1090
 }
 

Modified: trunk/Source/WebKit2/Platform/SharedMemory.h (146543 => 146544)


--- trunk/Source/WebKit2/Platform/SharedMemory.h	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/Platform/SharedMemory.h	2013-03-22 00:14:03 UTC (rev 146544)
@@ -84,7 +84,7 @@
 
     // Create a shared memory object with the given size by vm_copy'ing the given buffer.
     // Will return 0 on failure.
-    static PassRefPtr<SharedMemory> createWithVMCopy(void*, size_t);
+    static PassRefPtr<SharedMemory> createFromVMBuffer(void*, size_t);
 
 #if OS(WINDOWS)
     static PassRefPtr<SharedMemory> adopt(HANDLE, size_t, Protection);
@@ -109,6 +109,8 @@
 private:
     size_t m_size;
     void* m_data;
+    bool m_shouldVMDeallocateData;
+
 #if OS(DARWIN)
     mach_port_t m_port;
 #elif OS(WINDOWS)

Modified: trunk/Source/WebKit2/Platform/mac/SharedMemoryMac.cpp (146543 => 146544)


--- trunk/Source/WebKit2/Platform/mac/SharedMemoryMac.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/Platform/mac/SharedMemoryMac.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -92,37 +92,36 @@
     
 PassRefPtr<SharedMemory> SharedMemory::create(size_t size)
 {
-    return SharedMemory::createWithVMCopy(0, size);
-}
-
-PassRefPtr<SharedMemory> SharedMemory::createWithVMCopy(void* data, size_t size)
-{
     ASSERT(size);
 
     mach_vm_address_t address;
     kern_return_t kr = mach_vm_allocate(mach_task_self(), &address, round_page(size), VM_FLAGS_ANYWHERE);
     if (kr != KERN_SUCCESS) {
-        LOG_ERROR("Failed to allocate mach_vm_allocate shared memory (%zu bytes). %s (%x)", size, mach_error_string(kr), kr); 
+        LOG_ERROR("Failed to allocate mach_vm_allocate shared memory (%zu bytes). %s (%x)", size, mach_error_string(kr), kr);
         return 0;
     }
+
+    RefPtr<SharedMemory> sharedMemory = createFromVMBuffer(toPointer(address), size);
+    if (!sharedMemory) {
+        mach_vm_deallocate(mach_task_self(), address, round_page(size));
+        return 0;
+    }
     
-    if (data) {
-        kr = mach_vm_copy(mach_task_self(), toVMAddress(data), round_page(size), address);
-        if (kr != KERN_SUCCESS) {
-            LOG_ERROR("Failed to vm_copy in to shared memory (%zu bytes). %s (%x)", size, mach_error_string(kr), kr); 
-            mach_vm_deallocate(mach_task_self(), address, round_page(size));
-            return 0;
-        }
-    }
+    sharedMemory->m_shouldVMDeallocateData = true;
+    return sharedMemory.release();
+}
 
+PassRefPtr<SharedMemory> SharedMemory::createFromVMBuffer(void* data, size_t size)  
+{
+    ASSERT(size);
+    
     // Create a Mach port that represents the shared memory.
     mach_port_t port;
     memory_object_size_t memoryObjectSize = round_page(size);
-    kr = mach_make_memory_entry_64(mach_task_self(), &memoryObjectSize, address, VM_PROT_DEFAULT, &port, MACH_PORT_NULL);
-
+    kern_return_t kr = mach_make_memory_entry_64(mach_task_self(), &memoryObjectSize, toVMAddress(data), VM_PROT_DEFAULT | VM_PROT_IS_MASK, &port, MACH_PORT_NULL);
+    
     if (kr != KERN_SUCCESS) {
         LOG_ERROR("Failed to create a mach port for shared memory. %s (%x)", mach_error_string(kr), kr);
-        mach_vm_deallocate(mach_task_self(), address, round_page(size));
         return 0;
     }
 
@@ -130,7 +129,8 @@
 
     RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory));
     sharedMemory->m_size = size;
-    sharedMemory->m_data = toPointer(address);
+    sharedMemory->m_data = data;
+    sharedMemory->m_shouldVMDeallocateData = false;
     sharedMemory->m_port = port;
 
     return sharedMemory.release();
@@ -164,6 +164,7 @@
     RefPtr<SharedMemory> sharedMemory(adoptRef(new SharedMemory));
     sharedMemory->m_size = handle.m_size;
     sharedMemory->m_data = toPointer(mappedAddress);
+    sharedMemory->m_shouldVMDeallocateData = true;
     sharedMemory->m_port = MACH_PORT_NULL;
 
     return sharedMemory.release();
@@ -171,7 +172,7 @@
 
 SharedMemory::~SharedMemory()
 {
-    if (m_data) {
+    if (m_data && m_shouldVMDeallocateData) {
         kern_return_t kr = mach_vm_deallocate(mach_task_self(), toVMAddress(m_data), round_page(m_size));
         ASSERT_UNUSED(kr, kr == KERN_SUCCESS);
     }

Modified: trunk/Source/WebKit2/Shared/ShareableResource.cpp (146543 => 146544)


--- trunk/Source/WebKit2/Shared/ShareableResource.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/Shared/ShareableResource.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -27,7 +27,10 @@
 #include "ShareableResource.h"
 
 #include "ArgumentCoders.h"
+#include <WebCore/SharedBuffer.h>
 
+using namespace WebCore;
+
 namespace WebKit {
 
 ShareableResource::Handle::Handle()
@@ -51,7 +54,44 @@
         return false;
     return true;
 }
+
+static void shareableResourceDeallocate(void *ptr, void *info)
+{
+    (static_cast<ShareableResource*>(info))->deref(); // Balanced by ref() in createShareableResourceDeallocator()
+}
     
+static CFAllocatorRef createShareableResourceDeallocator(ShareableResource* resource)
+{
+    resource->ref(); // Balanced by deref in shareableResourceDeallocate()
+
+    CFAllocatorContext context = { 0,
+        resource,
+        NULL, // retain
+        NULL, // release
+        NULL, // copyDescription
+        NULL, // allocate
+        NULL, // reallocate
+        shareableResourceDeallocate,
+        NULL, // preferredSize
+    };
+
+    return CFAllocatorCreate(kCFAllocatorDefault, &context);
+}
+
+PassRefPtr<SharedBuffer> ShareableResource::Handle::tryWrapInSharedBuffer() const
+{
+    RefPtr<ShareableResource> resource = ShareableResource::create(*this);
+    if (!resource) {
+        LOG_ERROR("Failed to recreate ShareableResource from handle.");
+        return 0;
+    }
+
+    RetainPtr<CFAllocatorRef> deallocator(AdoptCF, createShareableResourceDeallocator(resource.get()));
+    RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(resource->data()), static_cast<CFIndex>(resource->size()), deallocator.get()));
+
+    return SharedBuffer::wrapCFData(data.get());
+}
+    
 PassRefPtr<ShareableResource> ShareableResource::create(PassRefPtr<SharedMemory> sharedMemory, unsigned offset, unsigned size)
 {
     return adoptRef(new ShareableResource(sharedMemory, offset, size));

Modified: trunk/Source/WebKit2/Shared/ShareableResource.h (146543 => 146544)


--- trunk/Source/WebKit2/Shared/ShareableResource.h	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/Shared/ShareableResource.h	2013-03-22 00:14:03 UTC (rev 146544)
@@ -32,6 +32,10 @@
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
 
+namespace WebCore {
+class SharedBuffer;
+}
+
 namespace WebKit {
     
 class ShareableResource : public RefCounted<ShareableResource> {
@@ -48,6 +52,8 @@
         void encode(CoreIPC::ArgumentEncoder&) const;
         static bool decode(CoreIPC::ArgumentDecoder&, Handle&);
 
+        PassRefPtr<WebCore::SharedBuffer> tryWrapInSharedBuffer() const;
+
     private:
         friend class ShareableResource;
 

Modified: trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp (146543 => 146544)


--- trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/Shared/WebCoreArgumentCoders.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -387,6 +387,10 @@
         encoder << resourceRequest.firstPartyForCookies().string();
     }
 
+#if ENABLE(CACHE_PARTITIONING)
+    encoder << resourceRequest.cachePartition();
+#endif
+
     encodePlatformData(encoder, resourceRequest);
 }
 
@@ -428,6 +432,13 @@
         resourceRequest = request;
     }
 
+#if ENABLE(CACHE_PARTITIONING)
+    String cachePartition;
+    if (!decoder.decode(cachePartition))
+        return false;
+    resourceRequest.setCachePartition(cachePartition);
+#endif
+
     return decodePlatformData(decoder, resourceRequest);
 }
 

Modified: trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp (146543 => 146544)


--- trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -33,6 +33,7 @@
 #include "WebResourceBuffer.h"
 #include "WebResourceLoadScheduler.h"
 #include "WebResourceLoaderMessages.h"
+#include <WebCore/MemoryCache.h>
 #include <WebCore/ResourceBuffer.h>
 
 #if ENABLE(NETWORK_PROCESS)
@@ -60,7 +61,7 @@
         return;
     }
 
-    ASSERT_NOT_REACHED();
+    didReceiveNetworkProcessConnectionMessage(connection, decoder);
 }
 
 void NetworkProcessConnection::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr<CoreIPC::MessageEncoder>& replyEncoder)
@@ -85,6 +86,21 @@
 {
 }
 
+void NetworkProcessConnection::didCacheResource(const ResourceRequest& request, const ShareableResource::Handle& handle)
+{
+    CachedResource* resource = memoryCache()->resourceForRequest(request);
+    if (!resource)
+        return;
+    
+    RefPtr<SharedBuffer> buffer = handle.tryWrapInSharedBuffer();
+    if (!buffer) {
+        LOG_ERROR("Unabled to create SharedBuffer from ShareableResource handle for resource url %s", request.url().string().utf8().data());
+        return;
+    }
+
+    resource->tryReplaceEncodedData(buffer.release());
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(NETWORK_PROCESS)

Modified: trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h (146543 => 146544)


--- trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.h	2013-03-22 00:14:03 UTC (rev 146544)
@@ -27,6 +27,7 @@
 #define NetworkProcessConnection_h
 
 #include "Connection.h"
+#include "ShareableResource.h"
 #include <wtf/RefCounted.h>
 #include <wtf/text/WTFString.h>
 
@@ -56,15 +57,20 @@
     
     CoreIPC::Connection* connection() const { return m_connection.get(); }
 
+    void didReceiveNetworkProcessConnectionMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
+
 private:
     NetworkProcessConnection(CoreIPC::Connection::Identifier);
 
     // CoreIPC::Connection::Client
-    virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&);
-    virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&);
-    virtual void didClose(CoreIPC::Connection*);
+    virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&) OVERRIDE;
+    virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageDecoder&, OwnPtr<CoreIPC::MessageEncoder>&) OVERRIDE;
+    virtual void didClose(CoreIPC::Connection*) OVERRIDE;
     virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference messageReceiverName, CoreIPC::StringReference messageName) OVERRIDE;
 
+    // Message handlers.
+    void didCacheResource(const WebCore::ResourceRequest&, const ShareableResource::Handle&);
+
     // The connection from the web process to the network process.
     RefPtr<CoreIPC::Connection> m_connection;
 };

Modified: trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in (146543 => 146544)


--- trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/WebProcess/Network/NetworkProcessConnection.messages.in	2013-03-22 00:14:03 UTC (rev 146544)
@@ -24,6 +24,8 @@
 
 messages -> NetworkProcessConnection LegacyReceiver {
 
+    DidCacheResource(WebCore::ResourceRequest request, WebKit::ShareableResource::Handle resource)
+
 }
 
 #endif // ENABLE(NETWORK_PROCESS)

Modified: trunk/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp (146543 => 146544)


--- trunk/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp	2013-03-22 00:08:00 UTC (rev 146543)
+++ trunk/Source/WebKit2/WebProcess/Network/WebResourceLoader.cpp	2013-03-22 00:14:03 UTC (rev 146544)
@@ -107,47 +107,20 @@
     m_coreLoader->didFail(error);
 }
 
-static void shareableResourceDeallocate(void *ptr, void *info)
-{
-    ShareableResource* resource = static_cast<ShareableResource*>(info);
-    resource->deref();
-}
-    
-static CFAllocatorRef createShareableResourceDeallocator(PassRefPtr<ShareableResource> resource)
-{
-    CFAllocatorContext context = { 0,
-        resource.leakRef(),
-        NULL, // retain
-        NULL, // release
-        NULL, // copyDescription
-        NULL, // allocate
-        NULL, // reallocate
-        shareableResourceDeallocate,
-        NULL,
-    };
-
-    return CFAllocatorCreate(kCFAllocatorDefault, &context);
-}
-
 void WebResourceLoader::didReceiveResource(const ShareableResource::Handle& handle, double finishTime)
 {
     LOG(Network, "(WebProcess) WebResourceLoader::didReceiveResource for '%s'", m_coreLoader->url().string().utf8().data());
 
-    RefPtr<ShareableResource> resource = ShareableResource::create(handle);
-    if (!resource) {
-        LOG_ERROR("Unabled to recreate the ShareableResource sent from the network process.");
+    RefPtr<SharedBuffer> buffer = handle.tryWrapInSharedBuffer();
+    if (!buffer) {
+        LOG_ERROR("Unable to create buffer from ShareableResource sent from the network process.");
         m_coreLoader->didFail(internalError(m_coreLoader->request().url()));
         return;
     }
 
     // Only send data to the didReceiveData callback if it exists.
-    if (resource->size()) {
-        RetainPtr<CFAllocatorRef> deallocator(AdoptCF, createShareableResourceDeallocator(resource));
-        RetainPtr<CFDataRef> data(AdoptCF, CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, reinterpret_cast<const UInt8*>(resource->data()), static_cast<CFIndex>(resource->size()), deallocator.get()));
-
-        RefPtr<SharedBuffer> buffer = SharedBuffer::wrapCFData(data.get());
+    if (buffer->size())
         m_coreLoader->didReceiveBuffer(buffer.get(), buffer->size(), DataPayloadWholeResource);
-    }
 
     m_coreLoader->didFinishLoading(finishTime);
 }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to