summaryrefslogtreecommitdiffstats
path: root/WebCore/loader/CachedResource.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/loader/CachedResource.cpp')
-rw-r--r--WebCore/loader/CachedResource.cpp98
1 files changed, 89 insertions, 9 deletions
diff --git a/WebCore/loader/CachedResource.cpp b/WebCore/loader/CachedResource.cpp
index 6d0af9b..f5ce737 100644
--- a/WebCore/loader/CachedResource.cpp
+++ b/WebCore/loader/CachedResource.cpp
@@ -3,7 +3,7 @@
Copyright (C) 2001 Dirk Mueller (mueller@kde.org)
Copyright (C) 2002 Waldo Bastian (bastian@kde.org)
Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
- Copyright (C) 2004, 2005, 2006, 2007 Apple Inc. All rights reserved.
+ Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
@@ -30,8 +30,8 @@
#include "Frame.h"
#include "FrameLoader.h"
#include "KURL.h"
+#include "PurgeableBuffer.h"
#include "Request.h"
-#include "SystemTime.h"
#include <wtf/RefCountedLeakCounter.h>
#include <wtf/Vector.h>
@@ -120,13 +120,13 @@ bool CachedResource::isExpired() const
time_t now = time(0);
return difftime(now, m_expirationDate) >= 0;
}
-
+
void CachedResource::setResponse(const ResourceResponse& response)
{
m_response = response;
m_expirationDate = response.expirationDate();
}
-
+
void CachedResource::setRequest(Request* request)
{
if (request && !m_request)
@@ -138,6 +138,8 @@ void CachedResource::setRequest(Request* request)
void CachedResource::addClient(CachedResourceClient *c)
{
+ ASSERT(!isPurgeable());
+
if (m_preloadResult == PreloadNotReferenced) {
if (isLoaded())
m_preloadResult = PreloadReferencedWhileComplete;
@@ -305,12 +307,90 @@ bool CachedResource::canUseCacheValidator() const
bool CachedResource::mustRevalidate(CachePolicy cachePolicy) const
{
if (m_loading)
- return false;
- String cacheControl = m_response.httpHeaderField("Cache-Control");
- // FIXME: It would be better to tokenize the field.
+ return false;
+
+ // FIXME: Also look at max-age, min-fresh, max-stale in Cache-Control
if (cachePolicy == CachePolicyCache)
- return !cacheControl.isEmpty() && (cacheControl.contains("no-cache", false) || (isExpired() && cacheControl.contains("must-revalidate", false)));
- return isExpired() || cacheControl.contains("no-cache", false);
+ return m_response.cacheControlContainsNoCache() || (isExpired() && m_response.cacheControlContainsMustRevalidate());
+ return isExpired() || m_response.cacheControlContainsNoCache();
+}
+
+bool CachedResource::isSafeToMakePurgeable() const
+{
+ return !hasClients() && !m_isBeingRevalidated && !m_resourceToRevalidate;
+}
+
+bool CachedResource::makePurgeable(bool purgeable)
+{
+ if (purgeable) {
+ ASSERT(isSafeToMakePurgeable());
+
+ if (m_purgeableData) {
+ ASSERT(!m_data);
+ return true;
+ }
+ if (!m_data)
+ return false;
+
+ // Should not make buffer purgeable if it has refs othen than this since we don't want two copies.
+ if (!m_data->hasOneRef())
+ return false;
+
+ // Purgeable buffers are allocated in multiples of the page size (4KB in common CPUs) so it does not make sense for very small buffers.
+ const size_t purgeableThreshold = 4 * 4096;
+ if (m_data->size() < purgeableThreshold)
+ return false;
+
+ if (m_data->hasPurgeableBuffer()) {
+ m_purgeableData.set(m_data->releasePurgeableBuffer());
+ } else {
+ m_purgeableData.set(PurgeableBuffer::create(m_data->data(), m_data->size()));
+ if (!m_purgeableData)
+ return false;
+ }
+
+ m_purgeableData->makePurgeable(true);
+ m_data.clear();
+ return true;
+ }
+
+ if (!m_purgeableData)
+ return true;
+ ASSERT(!m_data);
+ ASSERT(!hasClients());
+
+ if (!m_purgeableData->makePurgeable(false))
+ return false;
+
+ m_data = SharedBuffer::adoptPurgeableBuffer(m_purgeableData.release());
+ return true;
+}
+
+bool CachedResource::isPurgeable() const
+{
+ return m_purgeableData && m_purgeableData->isPurgeable();
+}
+
+bool CachedResource::wasPurged() const
+{
+ return m_purgeableData && m_purgeableData->wasPurged();
+}
+
+unsigned CachedResource::overheadSize() const
+{
+
+ // FIXME: Find some programmatic lighweight way to calculate response size, and size of the different CachedResource classes.
+ // This is a rough estimate of resource overhead based on stats collected from the stress test.
+ return sizeof(CachedResource) + 3648;
+
+ /* sizeof(CachedResource) +
+ 192 + // average size of m_url.
+ 384 + // average size of m_clients hash map.
+ 1280 * 2 + // average size of ResourceResponse. Doubled to account for the WebCore copy and the CF copy.
+ // Mostly due to the size of the hash maps, the Header Map strings and the URL.
+ 256 * 2 // Overhead from ResourceRequest, doubled to account for WebCore copy and CF copy.
+ // Mostly due to the URL and Header Map.
+ */
}
}