Commit 21302485 authored by beidson@apple.com's avatar beidson@apple.com

If a previously loaded resource is later stored to the disk cache, replace the...

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):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@146544 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6e016da1
2013-03-21 Brady Eidson <beidson@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 <jsbell@chromium.org>
IndexedDB: Ensure script wrappers can be collected after context is stopped
......@@ -170,6 +170,7 @@ __ZN7WebCore11MemoryCache13getStatisticsEv
__ZN7WebCore11MemoryCache13setCapacitiesEjjj
__ZN7WebCore11MemoryCache14evictResourcesEv
__ZN7WebCore11MemoryCache14resourceForURLERKNS_4KURLE
__ZN7WebCore11MemoryCache18resourceForRequestERKNS_15ResourceRequestE
__ZN7WebCore11MemoryCache19getOriginsWithCacheERN3WTF7HashSetINS1_6RefPtrINS_14SecurityOriginEEENS_18SecurityOriginHashENS1_10HashTraitsIS5_EEEE
__ZN7WebCore11MemoryCache25removeResourcesWithOriginEPNS_14SecurityOriginE
__ZN7WebCore11URLWithDataEP6NSDataP5NSURL
......@@ -273,6 +274,7 @@ __ZN7WebCore13toHTMLElementEPNS_21FormAssociatedElementE
__ZN7WebCore13toJSDOMWindowEN3JSC7JSValueE
__ZN7WebCore14CachedResource12removeClientEPNS_20CachedResourceClientE
__ZN7WebCore14CachedResource16unregisterHandleEPNS_24CachedResourceHandleBaseE
__ZN7WebCore14CachedResource21tryReplaceEncodedDataEN3WTF10PassRefPtrINS_12SharedBufferEEE
__ZN7WebCore14CachedResource9addClientEPNS_20CachedResourceClientE
__ZN7WebCore14ClientRectListC1ERKN3WTF6VectorINS_9FloatQuadELm0EEE
__ZN7WebCore14ClientRectListC1Ev
......@@ -1597,6 +1599,7 @@ _hasCaseInsensitiveSuffix
_stringIsCaseInsensitiveEqualToString
_suggestedFilenameWithMIMEType
#if ENABLE(CACHE_PARTITIONING)
__ZN7WebCore15ResourceRequest13partitionNameERKN3WTF6StringE
_wkCachePartitionKey
#endif
_wkCGContextGetShouldSmoothFonts
......
......@@ -64,6 +64,9 @@ public:
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;
......
......@@ -969,4 +969,19 @@ void CachedResource::reportMemoryUsage(MemoryObjectInfo* memoryObjectInfo) const
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
}
......@@ -50,6 +50,7 @@ class InspectorResource;
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 @@ public:
virtual bool canReuse(const ResourceRequest&) const { return true; }
#if PLATFORM(MAC)
void tryReplaceEncodedData(PassRefPtr<SharedBuffer>);
#endif
protected:
virtual void checkNotify();
......
......@@ -33,4 +33,12 @@ NSData* ResourceBuffer::createNSData()
return m_sharedBuffer->createNSData();
}
void ResourceBuffer::tryReplaceSharedBufferContents(SharedBuffer* newContents)
{
if (!m_sharedBuffer)
m_sharedBuffer = newContents;
else
m_sharedBuffer->tryReplaceContentsWithPlatformBuffer(newContents);
}
} // namespace WebCore
......@@ -118,6 +118,8 @@ public:
void createPurgeableBuffer() const;
void tryReplaceContentsWithPlatformBuffer(SharedBuffer*);
private:
SharedBuffer();
explicit SharedBuffer(size_t);
......
......@@ -93,6 +93,15 @@ void SharedBuffer::clearPlatformData()
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)
{
......
2013-03-21 Brady Eidson <beidson@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_horton@apple.com>
Unreviewed build fix, forgot to stage one file.
......@@ -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 @@ namespace WebKit {
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 @@ void NetworkResourceLoader::connectionToWebProcessDidClose()
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 @@ void NetworkResourceLoader::didReceiveResponse(ResourceHandle*, const ResourceRe
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 @@ void NetworkResourceLoader::didReceiveData(ResourceHandle*, const char* data, in
// 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 @@ void NetworkResourceLoader::didFinishLoading(ResourceHandle*, double finishTime)
// 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();
}
......
......@@ -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 @@ private:
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
......
......@@ -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 @@ typedef struct _CFCachedURLResponse* CFCachedURLResponseRef;
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 @@ void NetworkResourceLoader::platformDidReceiveResponse(const WebCore::ResourceRe
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
}
......
......@@ -84,7 +84,7 @@ public:
// 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 @@ public:
private:
size_t m_size;
void* m_data;
bool m_shouldVMDeallocateData;
#if OS(DARWIN)
mach_port_t m_port;
#elif OS(WINDOWS)
......
......@@ -91,38 +91,37 @@ static inline mach_vm_address_t toVMAddress(void* pointer)
}
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;
}
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;
}
RefPtr<SharedMemory> sharedMemory = createFromVMBuffer(toPointer(address), size);
if (!sharedMemory) {
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 @@ PassRefPtr<SharedMemory> SharedMemory::createWithVMCopy(void* data, size_t size)
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 @@ PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection p
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 @@ PassRefPtr<SharedMemory> SharedMemory::create(const Handle& handle, Protection p
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);
}
......
......@@ -27,6 +27,9 @@
#include "ShareableResource.h"
#include "ArgumentCoders.h"
#include <WebCore/SharedBuffer.h>
using namespace WebCore;
namespace WebKit {
......@@ -51,6 +54,43 @@ bool ShareableResource::Handle::decode(CoreIPC::ArgumentDecoder& decoder, Handle
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)
{
......
......@@ -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 @@ public:
void encode(CoreIPC::ArgumentEncoder&) const;
static bool decode(CoreIPC::ArgumentDecoder&, Handle&);
PassRefPtr<WebCore::SharedBuffer> tryWrapInSharedBuffer() const;
private:
friend class ShareableResource;
......
......@@ -387,6 +387,10 @@ void ArgumentCoder<ResourceRequest>::encode(ArgumentEncoder& encoder, const Reso
encoder << resourceRequest.firstPartyForCookies().string();
}
#if ENABLE(CACHE_PARTITIONING)
encoder << resourceRequest.cachePartition();
#endif
encodePlatformData(encoder, resourceRequest);
}
......@@ -428,6 +432,13 @@ bool ArgumentCoder<ResourceRequest>::decode(ArgumentDecoder& decoder, ResourceRe
resourceRequest = request;
}
#if ENABLE(CACHE_PARTITIONING)
String cachePartition;
if (!decoder.decode(cachePartition))
return false;
resourceRequest.setCachePartition(cachePartition);
#endif
return decodePlatformData(decoder, resourceRequest);
}
......
......@@ -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 @@ void NetworkProcessConnection::didReceiveMessage(CoreIPC::Connection* connection
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::didReceiveInvalidMessage(CoreIPC::Connection*, Co
{
}
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)
......@@ -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 @@ public:
CoreIPC::Connection* connection() const { return m_connection.get(); }