Diff
Modified: trunk/Source/WTF/ChangeLog (172743 => 172744)
--- trunk/Source/WTF/ChangeLog 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WTF/ChangeLog 2014-08-19 05:10:23 UTC (rev 172744)
@@ -1,3 +1,16 @@
+2014-08-18 Commit Queue <[email protected]>
+
+ Unreviewed, rolling out r172736.
+ https://bugs.webkit.org/show_bug.cgi?id=136060
+
+ Caused 14% PLT regressions (Requested by rniwa on #webkit).
+
+ Reverted changeset:
+
+ "Remove PurgeableBuffer since it is not very useful any more"
+ https://bugs.webkit.org/show_bug.cgi?id=135939
+ http://trac.webkit.org/changeset/172736
+
2014-08-18 Pratik Solanki <[email protected]>
Remove PurgeableBuffer since it is not very useful any more
Modified: trunk/Source/WTF/wtf/Platform.h (172743 => 172744)
--- trunk/Source/WTF/wtf/Platform.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WTF/wtf/Platform.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -490,6 +490,10 @@
#endif /* PLATFORM(MAC) */
+#if OS(DARWIN) && !PLATFORM(GTK)
+#define ENABLE_PURGEABLE_MEMORY 1
+#endif
+
#if PLATFORM(IOS)
#define DONT_FINALIZE_ON_MAIN_THREAD 1
Modified: trunk/Source/WTF/wtf/VMTags.h (172743 => 172744)
--- trunk/Source/WTF/wtf/VMTags.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WTF/wtf/VMTags.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -56,12 +56,19 @@
#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(63)
#endif // defined(VM_MEMORY_JAVASCRIPT_CORE)
+#if defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
+#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
+#else
+#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(69)
+#endif // defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS)
+
#else // OS(DARWIN)
#define VM_TAG_FOR_TCMALLOC_MEMORY -1
#define VM_TAG_FOR_COLLECTOR_MEMORY -1
#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1
#define VM_TAG_FOR_REGISTERFILE_MEMORY -1
+#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY -1
#endif // OS(DARWIN)
Modified: trunk/Source/WebCore/ChangeLog (172743 => 172744)
--- trunk/Source/WebCore/ChangeLog 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/ChangeLog 2014-08-19 05:10:23 UTC (rev 172744)
@@ -1,3 +1,16 @@
+2014-08-18 Commit Queue <[email protected]>
+
+ Unreviewed, rolling out r172736.
+ https://bugs.webkit.org/show_bug.cgi?id=136060
+
+ Caused 14% PLT regressions (Requested by rniwa on #webkit).
+
+ Reverted changeset:
+
+ "Remove PurgeableBuffer since it is not very useful any more"
+ https://bugs.webkit.org/show_bug.cgi?id=135939
+ http://trac.webkit.org/changeset/172736
+
2014-08-18 Simon Fraser <[email protected]>
Provide default implementations of all GraphicsLayerClient methods
Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (172743 => 172744)
--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj 2014-08-19 05:10:23 UTC (rev 172744)
@@ -2430,6 +2430,7 @@
7CE6CBFB187F370700D46BF5 /* FormatConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE6CBFA187F370700D46BF5 /* FormatConverter.h */; };
7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */; };
7D741BDA177226AA00859170 /* CSSValueKeywords.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 6565814809D13043000E61D7 /* CSSValueKeywords.h */; };
+ 7E33CD01127F340D00BE8F17 /* PurgePriority.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E33CD00127F340D00BE8F17 /* PurgePriority.h */; settings = {ATTRIBUTES = (Private, ); }; };
7E37EF2E1339208800B29250 /* SubresourceLoaderCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E37EF2D1339208800B29250 /* SubresourceLoaderCF.cpp */; };
7E428CE513E3407F003B661C /* ResourceHandleIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7E428CE413E3407F003B661C /* ResourceHandleIOS.mm */; };
7E46F6FA1627A2CA00062223 /* JSOESElementIndexUint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E46F6F81627A2C900062223 /* JSOESElementIndexUint.cpp */; };
@@ -6187,6 +6188,8 @@
E4D58EB817B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */; };
E4D58EB917B4ED8900CBDCA8 /* StyleFontSizeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */; };
E4D58EBB17B8F12800CBDCA8 /* ElementTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ E4D687770ED7AE3D006EA978 /* PurgeableBufferMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */; };
+ E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */; };
E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */; };
E4D988B617BFEB210084FB88 /* TextNodeTraversal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D988B517BFEB210084FB88 /* TextNodeTraversal.cpp */; };
E4DEAA1717A93DC3000E0430 /* StyleResolveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */; };
@@ -9583,6 +9586,7 @@
7CE683461921821500F4D928 /* UserMessageHandlerDescriptorTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMessageHandlerDescriptorTypes.h; sourceTree = "<group>"; };
7CE6CBFA187F370700D46BF5 /* FormatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatConverter.h; sourceTree = "<group>"; };
7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatConverter.cpp; sourceTree = "<group>"; };
+ 7E33CD00127F340D00BE8F17 /* PurgePriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PurgePriority.h; sourceTree = "<group>"; };
7E37EF2D1339208800B29250 /* SubresourceLoaderCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SubresourceLoaderCF.cpp; path = cf/SubresourceLoaderCF.cpp; sourceTree = "<group>"; };
7E428CE413E3407F003B661C /* ResourceHandleIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceHandleIOS.mm; sourceTree = "<group>"; };
7E46F6F81627A2C900062223 /* JSOESElementIndexUint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSOESElementIndexUint.cpp; sourceTree = "<group>"; };
@@ -13704,6 +13708,8 @@
E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleFontSizeFunctions.cpp; sourceTree = "<group>"; };
E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleFontSizeFunctions.h; sourceTree = "<group>"; };
E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementTraversal.h; sourceTree = "<group>"; };
+ E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PurgeableBufferMac.cpp; sourceTree = "<group>"; };
+ E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PurgeableBuffer.h; sourceTree = "<group>"; };
E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextNodeTraversal.h; sourceTree = "<group>"; };
E4D988B517BFEB210084FB88 /* TextNodeTraversal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextNodeTraversal.cpp; sourceTree = "<group>"; };
E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveTree.cpp; sourceTree = "<group>"; };
@@ -16446,6 +16452,7 @@
BC94D1070C274F88006BC617 /* PlatformScreenMac.mm */,
29E4D8E016B0959800C84704 /* PlatformSpeechSynthesizerMac.mm */,
0081FEFE16B0A2B6008AAA7A /* PublicSuffixMac.mm */,
+ E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */,
BCAE1FA512939DB7004CB026 /* ScrollAnimatorMac.h */,
BC51156D12B1749C00C96754 /* ScrollAnimatorMac.mm */,
BC8B853C0E7C7F1100AB6984 /* ScrollbarThemeMac.h */,
@@ -21392,6 +21399,8 @@
ABC128760B33AA6D00C693D5 /* PopupMenuClient.h */,
BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */,
0081FEFD16B0A244008AAA7A /* PublicSuffix.h */,
+ E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */,
+ 7E33CD00127F340D00BE8F17 /* PurgePriority.h */,
A72EA3BA1585CF55004FAA26 /* RefCountedSupplement.h */,
9831AE49154225A200FE2644 /* ReferrerPolicy.h */,
293EAE201356B32E0067ACF9 /* RuntimeApplicationChecks.cpp */,
@@ -25572,6 +25581,8 @@
FF945ECC161F7F3600971BC8 /* PseudoElement.h in Headers */,
0081FF0016B0A2D3008AAA7A /* PublicSuffix.h in Headers */,
10FB084B14E15C7E00A3DB98 /* PublicURLManager.h in Headers */,
+ E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */,
+ 7E33CD01127F340D00BE8F17 /* PurgePriority.h in Headers */,
550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */,
442AF7A9102CDDEA008FD4D3 /* QuickLook.h in Headers */,
072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */,
@@ -29072,6 +29083,7 @@
FF945ECB161F7F3600971BC8 /* PseudoElement.cpp in Sources */,
0081FEFF16B0A2B6008AAA7A /* PublicSuffixMac.mm in Sources */,
CDEE393717974259001D7580 /* PublicURLManager.cpp in Sources */,
+ E4D687770ED7AE3D006EA978 /* PurgeableBufferMac.cpp in Sources */,
550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */,
442AF7AA102CDDEA008FD4D3 /* QuickLook.mm in Sources */,
072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */,
Modified: trunk/Source/WebCore/inspector/InspectorPageAgent.cpp (172743 => 172744)
--- trunk/Source/WebCore/inspector/InspectorPageAgent.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/inspector/InspectorPageAgent.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -112,6 +112,17 @@
return true;
}
+ if (cachedResource->isPurgeable()) {
+ // If the resource is purgeable then make it unpurgeable to get
+ // get its data. This might fail, in which case we return an
+ // empty String.
+ // FIXME: should we do something else in the case of a purged
+ // resource that informs the user why there is no data in the
+ // inspector?
+ if (!cachedResource->makePurgeable(false))
+ return false;
+ }
+
return true;
}
Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/DocumentLoader.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/DocumentLoader.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -1093,6 +1093,11 @@
if (resource->type() == CachedResource::MainResource)
return 0;
+ // FIXME: This has the side effect of making the resource non-purgeable.
+ // It would be better if it didn't have this permanent effect.
+ if (!resource->makePurgeable(false))
+ return 0;
+
ResourceBuffer* data = ""
if (!data)
return 0;
Modified: trunk/Source/WebCore/loader/ResourceBuffer.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/ResourceBuffer.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/ResourceBuffer.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -26,6 +26,7 @@
#include "config.h"
#include "ResourceBuffer.h"
+#include "PurgeableBuffer.h"
#include "SharedBuffer.h"
namespace WebCore {
@@ -112,6 +113,30 @@
return ResourceBuffer::adoptSharedBuffer(m_sharedBuffer->copy());
}
+bool ResourceBuffer::hasPurgeableBuffer() const
+{
+ return m_sharedBuffer->hasPurgeableBuffer();
+}
+
+#if PLATFORM(IOS)
+void ResourceBuffer::setShouldUsePurgeableMemory(bool shouldUsePurgeableMemory)
+{
+ ASSERT(m_sharedBuffer);
+ sharedBuffer()->shouldUsePurgeableMemory(shouldUsePurgeableMemory);
+}
+#endif
+
+void ResourceBuffer::createPurgeableBuffer() const
+{
+ ASSERT(m_sharedBuffer);
+ sharedBuffer()->createPurgeableBuffer();
+}
+
+PassOwnPtr<PurgeableBuffer> ResourceBuffer::releasePurgeableBuffer()
+{
+ return m_sharedBuffer->releasePurgeableBuffer();
+}
+
#if USE(CF)
RetainPtr<CFDataRef> ResourceBuffer::createCFData()
{
Modified: trunk/Source/WebCore/loader/ResourceBuffer.h (172743 => 172744)
--- trunk/Source/WebCore/loader/ResourceBuffer.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/ResourceBuffer.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -38,6 +38,7 @@
namespace WebCore {
+class PurgeableBuffer;
class SharedBuffer;
class ResourceBuffer : public RefCounted<ResourceBuffer> {
@@ -68,6 +69,17 @@
#endif
PassRefPtr<ResourceBuffer> copy() const;
+ bool hasPurgeableBuffer() const;
+ void createPurgeableBuffer() const;
+
+#if PLATFORM(IOS)
+ // FIXME: Remove PLATFORM(IOS)-guard once we upstream the iOS changes to SharedBuffer.{cpp, h} and SharedBufferCF.cpp.
+ void setShouldUsePurgeableMemory(bool);
+#endif
+
+ // Ensure this buffer has no other clients before calling this.
+ PassOwnPtr<PurgeableBuffer> releasePurgeableBuffer();
+
#if USE(FOUNDATION)
RetainPtr<NSData> createNSData();
#endif
Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/SubresourceLoader.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/SubresourceLoader.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -299,8 +299,12 @@
LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());
Ref<SubresourceLoader> protect(*this);
+
+#if PLATFORM(IOS)
+ if (resourceData())
+ resourceData()->setShouldUsePurgeableMemory(true);
+#endif
CachedResourceHandle<CachedResource> protectResource(m_resource);
-
m_state = Finishing;
m_resource->setLoadFinishTime(finishTime);
m_resource->finishLoading(resourceData());
Modified: trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -80,6 +80,8 @@
const String CachedCSSStyleSheet::sheetText(bool enforceMIMEType, bool* hasValidMIMEType) const
{
+ ASSERT(!isPurgeable());
+
if (!m_data || m_data->isEmpty() || !canUseSheet(enforceMIMEType, hasValidMIMEType))
return String();
@@ -146,6 +148,9 @@
m_parsedStyleSheetCache.clear();
setDecodedSize(0);
+
+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
+ makePurgeable(true);
}
PassRefPtr<StyleSheetContents> CachedCSSStyleSheet::restoreParsedStyleSheet(const CSSParserContext& context)
Modified: trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.h (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -48,6 +48,7 @@
private:
bool canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const;
+ virtual PurgePriority purgePriority() const override { return PurgeLast; }
virtual bool mayTryReplaceEncodedData() const override { return true; }
virtual void didAddClient(CachedResourceClient*) override;
Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedImage.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedImage.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -192,6 +192,8 @@
Image* CachedImage::image()
{
+ ASSERT(!isPurgeable());
+
if (errorOccurred() && m_shouldPaintBrokenImage) {
// Returning the 1x broken image is non-ideal, but we cannot reliably access the appropriate
// deviceScaleFactor from here. It is critical that callers use CachedImage::brokenImage()
@@ -207,6 +209,8 @@
Image* CachedImage::imageForRenderer(const RenderObject* renderer)
{
+ ASSERT(!isPurgeable());
+
if (errorOccurred() && m_shouldPaintBrokenImage) {
// Returning the 1x broken image is non-ideal, but we cannot reliably access the appropriate
// deviceScaleFactor from here. It is critical that callers use CachedImage::brokenImage()
@@ -270,6 +274,8 @@
LayoutSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float multiplier, SizeType sizeType)
{
+ ASSERT(!isPurgeable());
+
if (!m_image)
return LayoutSize();
@@ -456,9 +462,13 @@
void CachedImage::destroyDecodedData()
{
bool canDeleteImage = !m_image || (m_image->hasOneRef() && m_image->isBitmapImage());
- if (canDeleteImage && !isLoading()) {
+ if (isSafeToMakePurgeable() && canDeleteImage && !isLoading()) {
+ // Image refs the data buffer so we should not make it purgeable while the image is alive.
+ // Invoking addClient() will reconstruct the image object.
m_image = 0;
setDecodedSize(0);
+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction())
+ makePurgeable(true);
} else if (m_image && !errorOccurred())
m_image->destroyDecodedData();
}
@@ -514,6 +524,9 @@
if (!m_data)
return false;
+ if (isPurgeable())
+ return false;
+
if (m_data->size() < diskImageCache().minimumImageSize())
return false;
Modified: trunk/Source/WebCore/loader/cache/CachedImage.h (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedImage.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedImage.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -101,6 +101,7 @@
void clearImage();
// If not null, changeRect is the changed part of the image.
void notifyObservers(const IntRect* changeRect = 0);
+ virtual PurgePriority purgePriority() const override { return PurgeFirst; }
void checkShouldPaintBrokenImage();
virtual void switchClientsToRevalidatedResource() override;
Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedResource.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedResource.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -40,6 +40,7 @@
#include "Logging.h"
#include "MemoryCache.h"
#include "PlatformStrategies.h"
+#include "PurgeableBuffer.h"
#include "ResourceBuffer.h"
#include "ResourceHandle.h"
#include "ResourceLoadScheduler.h"
@@ -465,6 +466,8 @@
bool CachedResource::addClientToSet(CachedResourceClient* client)
{
+ ASSERT(!isPurgeable());
+
if (m_preloadResult == PreloadNotReferenced) {
if (isLoaded())
m_preloadResult = PreloadReferencedWhileComplete;
@@ -783,6 +786,64 @@
return false;
}
+bool CachedResource::isSafeToMakePurgeable() const
+{
+#if ENABLE(DISK_IMAGE_CACHE)
+ // It does not make sense to have a resource in the disk image cache
+ // (memory mapped on disk) and purgeable (in memory). So do not allow
+ // disk image cached resources to be purgeable.
+ if (isUsingDiskImageCache())
+ return false;
+#endif
+
+ return !hasClients() && !m_proxyResource && !m_resourceToRevalidate;
+}
+
+bool CachedResource::makePurgeable(bool purgeable)
+{
+ if (purgeable) {
+ ASSERT(isSafeToMakePurgeable());
+
+ if (m_purgeableData) {
+ ASSERT(!m_data);
+ return true;
+ }
+ if (!m_data)
+ return false;
+
+ m_data->createPurgeableBuffer();
+ if (!m_data->hasPurgeableBuffer())
+ return false;
+
+ m_purgeableData = m_data->releasePurgeableBuffer();
+ m_purgeableData->setPurgePriority(purgePriority());
+ 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 = ResourceBuffer::adoptSharedBuffer(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
{
static const int kAverageClientsHashMapSize = 384;
Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedResource.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedResource.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -25,6 +25,7 @@
#include "CachePolicy.h"
#include "FrameLoaderTypes.h"
+#include "PurgePriority.h"
#include "ResourceError.h"
#include "ResourceLoadPriority.h"
#include "ResourceLoaderOptions.h"
@@ -46,6 +47,7 @@
class CachedResourceHandleBase;
class CachedResourceLoader;
class InspectorResource;
+class PurgeableBuffer;
class ResourceBuffer;
class SecurityOrigin;
class SharedBuffer;
@@ -186,7 +188,7 @@
void clearLoader();
- ResourceBuffer* resourceBuffer() const { return m_data.get(); }
+ ResourceBuffer* resourceBuffer() const { ASSERT(!m_purgeableData); return m_data.get(); }
virtual void willSendRequest(ResourceRequest&, const ResourceResponse&) { m_requestedFromNetworkingLayer = true; }
virtual void responseReceived(const ResourceResponse&);
@@ -229,6 +231,14 @@
bool isCacheValidator() const { return m_resourceToRevalidate; }
CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
+ bool isPurgeable() const;
+ bool wasPurged() const;
+
+ // This is used by the archive machinery to get at a purged resource without
+ // triggering a load. We should make it protected again if we can find a
+ // better way to handle the archive case.
+ bool makePurgeable(bool purgeable);
+
// HTTP revalidation support methods for CachedResourceLoader.
void setResourceToRevalidate(CachedResource*);
virtual void switchClientsToRevalidatedResource();
@@ -263,6 +273,8 @@
void setDecodedSize(unsigned);
void didAccessDecodedData(double timeStamp);
+ bool isSafeToMakePurgeable() const;
+
HashCountedSet<CachedResourceClient*> m_clients;
class CachedResourceCallback {
@@ -290,6 +302,7 @@
double m_responseTimestamp;
RefPtr<ResourceBuffer> m_data;
+ OwnPtr<PurgeableBuffer> m_purgeableData;
DeferrableOneShotTimer m_decodedDataDeletionTimer;
private:
@@ -297,6 +310,7 @@
void decodedDataDeletionTimerFired();
+ virtual PurgePriority purgePriority() const { return PurgeDefault; }
virtual bool mayTryReplaceEncodedData() const { return false; }
double currentAge() const;
Modified: trunk/Source/WebCore/loader/cache/CachedScript.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedScript.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedScript.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -71,6 +71,8 @@
const String& CachedScript::script()
{
+ ASSERT(!isPurgeable());
+
if (!m_script && m_data) {
m_script = m_decoder->decodeAndFlush(m_data->data(), encodedSize());
setDecodedSize(m_script.sizeInBytes());
@@ -91,6 +93,8 @@
{
m_script = String();
setDecodedSize(0);
+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
+ makePurgeable(true);
}
#if ENABLE(NOSNIFF)
Modified: trunk/Source/WebCore/loader/cache/CachedScript.h (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/CachedScript.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/CachedScript.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -47,6 +47,7 @@
#endif
private:
+ virtual PurgePriority purgePriority() const override { return PurgeLast; }
virtual bool mayTryReplaceEncodedData() const override { return true; }
virtual bool shouldIgnoreHTTPStatusCodeErrors() const override;
Modified: trunk/Source/WebCore/loader/cache/MemoryCache.cpp (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/MemoryCache.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/MemoryCache.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -212,6 +212,15 @@
#else
CachedResource* resource = resources.get(url);
#endif
+ bool wasPurgeable = MemoryCache::shouldMakeResourcePurgeableOnEviction() && resource && resource->isPurgeable();
+ if (resource && !resource->makePurgeable(false)) {
+ ASSERT(!resource->hasClients());
+ evict(resource);
+ return 0;
+ }
+ // Add the size back since we had subtracted it when we marked the memory as purgeable.
+ if (wasPurgeable)
+ adjustSize(resource->hasClients(), resource->size());
return resource;
}
@@ -395,6 +404,19 @@
int size = m_allResources.size();
+ // See if we have any purged resources we can evict.
+ for (int i = 0; i < size; i++) {
+ CachedResource* current = m_allResources[i].m_tail;
+ while (current) {
+ CachedResource* prev = current->m_prevInAllResourcesList;
+ if (current->wasPurged()) {
+ ASSERT(!current->hasClients());
+ ASSERT(!current->isPreloaded());
+ evict(current);
+ }
+ current = prev;
+ }
+ }
if (targetSize && m_deadSize <= targetSize)
return;
@@ -430,7 +452,9 @@
CachedResourceHandle<CachedResource> previous = current->m_prevInAllResourcesList;
ASSERT(!previous || previous->inCache());
if (!current->hasClients() && !current->isPreloaded() && !current->isCacheValidator()) {
- evict(current);
+ if (!makeResourcePurgeable(current))
+ evict(current);
+
if (targetSize && m_deadSize <= targetSize)
return;
}
@@ -497,6 +521,28 @@
prune();
}
+bool MemoryCache::makeResourcePurgeable(CachedResource* resource)
+{
+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction())
+ return false;
+
+ if (!resource->inCache())
+ return false;
+
+ if (resource->isPurgeable())
+ return true;
+
+ if (!resource->isSafeToMakePurgeable())
+ return false;
+
+ if (!resource->makePurgeable(true))
+ return false;
+
+ adjustSize(resource->hasClients(), -static_cast<int>(resource->size()));
+
+ return true;
+}
+
void MemoryCache::evict(CachedResource* resource)
{
ASSERT(WTF::isMainThread());
@@ -521,6 +567,12 @@
// Remove from the appropriate LRU list.
removeFromLRUList(resource);
removeFromLiveDecodedResourcesList(resource);
+
+ // If the resource was purged, it means we had already decremented the size when we made the
+ // resource purgeable in makeResourcePurgeable(). So adjust the size if we are evicting a
+ // resource that was not marked as purgeable.
+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() || !resource->isPurgeable())
+ adjustSize(resource->hasClients(), -static_cast<int>(resource->size()));
} else
#if ENABLE(CACHE_PARTITIONING)
ASSERT(!resources.get(resource->url()) || resources.get(resource->url())->get(resource->cachePartition()) != resource);
@@ -840,10 +892,15 @@
void MemoryCache::TypeStatistic::addResource(CachedResource* o)
{
+ bool purged = o->wasPurged();
+ bool purgeable = o->isPurgeable() && !purged;
+ int pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095;
count++;
- size += o->size();
+ size += purged ? 0 : o->size();
liveSize += o->hasClients() ? o->size() : 0;
decodedSize += o->decodedSize();
+ purgeableSize += purgeable ? pageSize : 0;
+ purgedSize += purged ? pageSize : 0;
#if ENABLE(DISK_IMAGE_CACHE)
// Only the data inside the resource was mapped, not the entire resource.
mappedSize += o->isUsingDiskImageCache() ? o->resourceBuffer()->sharedBuffer()->size() : 0;
@@ -944,29 +1001,29 @@
{
Statistics s = getStatistics();
#if ENABLE(DISK_IMAGE_CACHE)
- printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "LiveSize", "DecodedSize", "Mapped", "\"Real\"");
+ printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "LiveSize", "DecodedSize", "PurgeableSize", "PurgedSize", "Mapped", "\"Real\"");
+ printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------");
+ printf("%-13s %13d %13d %13d %13d %13d %13d %13d %13d\n", "Images", s.images.count, s.images.size, s.images.liveSize, s.images.decodedSize, s.images.purgeableSize, s.images.purgedSize, s.images.mappedSize, s.images.size - s.images.mappedSize);
+#else
+ printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "LiveSize", "DecodedSize", "PurgeableSize", "PurgedSize");
printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------");
- printf("%-13s %13d %13d %13d %13d %13d %13d\n", "Images", s.images.count, s.images.size, s.images.liveSize, s.images.decodedSize, s.images.mappedSize, s.images.size - s.images.mappedSize);
-#else
- printf("%-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "LiveSize", "DecodedSize");
- printf("%-13s %-13s %-13s %-13s %-13s\n", "-------------", "-------------", "-------------", "-------------", "-------------");
- printf("%-13s %13d %13d %13d %13d\n", "Images", s.images.count, s.images.size, s.images.liveSize, s.images.decodedSize);
+ printf("%-13s %13d %13d %13d %13d %13d %13d\n", "Images", s.images.count, s.images.size, s.images.liveSize, s.images.decodedSize, s.images.purgeableSize, s.images.purgedSize);
#endif
- printf("%-13s %13d %13d %13d %13d\n", "CSS", s.cssStyleSheets.count, s.cssStyleSheets.size, s.cssStyleSheets.liveSize, s.cssStyleSheets.decodedSize);
+ printf("%-13s %13d %13d %13d %13d %13d %13d\n", "CSS", s.cssStyleSheets.count, s.cssStyleSheets.size, s.cssStyleSheets.liveSize, s.cssStyleSheets.decodedSize, s.cssStyleSheets.purgeableSize, s.cssStyleSheets.purgedSize);
#if ENABLE(XSLT)
- printf("%-13s %13d %13d %13d %13d\n", "XSL", s.xslStyleSheets.count, s.xslStyleSheets.size, s.xslStyleSheets.liveSize, s.xslStyleSheets.decodedSize);
+ printf("%-13s %13d %13d %13d %13d %13d %13d\n", "XSL", s.xslStyleSheets.count, s.xslStyleSheets.size, s.xslStyleSheets.liveSize, s.xslStyleSheets.decodedSize, s.xslStyleSheets.purgeableSize, s.xslStyleSheets.purgedSize);
#endif
- printf("%-13s %13d %13d %13d %13d\n", "_javascript_", s.scripts.count, s.scripts.size, s.scripts.liveSize, s.scripts.decodedSize);
- printf("%-13s %13d %13d %13d %13d\n", "Fonts", s.fonts.count, s.fonts.size, s.fonts.liveSize, s.fonts.decodedSize);
- printf("%-13s %-13s %-13s %-13s %-13s\n\n", "-------------", "-------------", "-------------", "-------------", "-------------");
+ printf("%-13s %13d %13d %13d %13d %13d %13d\n", "_javascript_", s.scripts.count, s.scripts.size, s.scripts.liveSize, s.scripts.decodedSize, s.scripts.purgeableSize, s.scripts.purgedSize);
+ printf("%-13s %13d %13d %13d %13d %13d %13d\n", "Fonts", s.fonts.count, s.fonts.size, s.fonts.liveSize, s.fonts.decodedSize, s.fonts.purgeableSize, s.fonts.purgedSize);
+ printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n\n", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------");
}
void MemoryCache::dumpLRULists(bool includeLive) const
{
#if ENABLE(DISK_IMAGE_CACHE)
- printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isMemoryMapped):\n");
+ printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isPurgeable, wasPurged, isMemoryMapped):\n");
#else
- printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced):\n");
+ printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isPurgeable, wasPurged):\n");
#endif
int size = m_allResources.size();
@@ -977,9 +1034,9 @@
CachedResource* prev = current->m_prevInAllResourcesList;
if (includeLive || !current->hasClients())
#if ENABLE(DISK_IMAGE_CACHE)
- printf("(%.1fK, %.1fK, %uA, %dR, %d); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients(), current->isUsingDiskImageCache());
+ printf("(%.1fK, %.1fK, %uA, %dR, %d, %d, %d); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients(), current->isPurgeable(), current->wasPurged(), current->isUsingDiskImageCache());
#else
- printf("(%.1fK, %.1fK, %uA, %dR); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients());
+ printf("(%.1fK, %.1fK, %uA, %dR, %d, %d); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients(), current->isPurgeable(), current->wasPurged());
#endif
current = prev;
Modified: trunk/Source/WebCore/loader/cache/MemoryCache.h (172743 => 172744)
--- trunk/Source/WebCore/loader/cache/MemoryCache.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/loader/cache/MemoryCache.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -61,6 +61,22 @@
// -------|-----+++++++++++++++|
// -------|-----+++++++++++++++|+++++
+// The behavior of the cache changes in the following way if shouldMakeResourcePurgeableOnEviction
+// returns true.
+//
+// 1. Dead resources in the cache are kept in non-purgeable memory.
+// 2. When we prune dead resources, instead of freeing them, we mark their memory as purgeable and
+// keep the resources until the kernel reclaims the purgeable memory.
+//
+// By leaving the in-cache dead resources in dirty resident memory, we decrease the likelihood of
+// the kernel claiming that memory and forcing us to refetch the resource (for example when a user
+// presses back).
+//
+// And by having an unbounded number of resource objects using purgeable memory, we can use as much
+// memory as is available on the machine. The trade-off here is that the CachedResource object (and
+// its member variables) are allocated in non-purgeable TC-malloc'd memory so we would see slightly
+// more memory use due to this.
+
class MemoryCache {
WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED;
public:
@@ -85,21 +101,14 @@
int size;
int liveSize;
int decodedSize;
+ int purgeableSize;
+ int purgedSize;
#if ENABLE(DISK_IMAGE_CACHE)
int mappedSize;
+ TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0), mappedSize(0) { }
+#else
+ TypeStatistic() : count(0), size(0), liveSize(0), decodedSize(0), purgeableSize(0), purgedSize(0) { }
#endif
-
- TypeStatistic()
- : count(0)
- , size(0)
- , liveSize(0)
- , decodedSize(0)
-#if ENABLE(DISK_IMAGE_CACHE)
- , mappedSize(0)
-#endif
- {
- }
-
void addResource(CachedResource*);
};
@@ -158,6 +167,8 @@
void addToLiveResourcesSize(CachedResource*);
void removeFromLiveResourcesSize(CachedResource*);
+ static bool shouldMakeResourcePurgeableOnEviction();
+
#if ENABLE(DISK_IMAGE_CACHE)
void flushCachedImagesToDisk(); // Flush encoded data from resources still referenced by web pages.
#endif
@@ -211,6 +222,7 @@
unsigned liveCapacity() const;
unsigned deadCapacity() const;
+ bool makeResourcePurgeable(CachedResource*);
void evict(CachedResource*);
CachedResource* resourceForRequestImpl(const ResourceRequest&, CachedResourceMap&);
@@ -246,6 +258,15 @@
SessionCachedResourceMap m_sessionResources;
};
+inline bool MemoryCache::shouldMakeResourcePurgeableOnEviction()
+{
+#if PLATFORM(IOS)
+ return true;
+#else
+ return false;
+#endif
+}
+
// Function to obtain the global cache.
MemoryCache* memoryCache();
Added: trunk/Source/WebCore/platform/PurgePriority.h (0 => 172744)
--- trunk/Source/WebCore/platform/PurgePriority.h (rev 0)
+++ trunk/Source/WebCore/platform/PurgePriority.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2010 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PurgePriority_h
+#define PurgePriority_h
+
+namespace WebCore {
+
+enum PurgePriority {
+ PurgeLast,
+ PurgeMiddle,
+ PurgeFirst,
+ PurgeDefault = PurgeMiddle
+};
+
+}
+
+#endif // PurgePriority_h
Added: trunk/Source/WebCore/platform/PurgeableBuffer.h (0 => 172744)
--- trunk/Source/WebCore/platform/PurgeableBuffer.h (rev 0)
+++ trunk/Source/WebCore/platform/PurgeableBuffer.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef PurgeableBuffer_h
+#define PurgeableBuffer_h
+
+#include "PurgePriority.h"
+#include <wtf/PassOwnPtr.h>
+#include <wtf/Vector.h>
+
+namespace WebCore {
+
+ class PurgeableBuffer {
+ WTF_MAKE_NONCOPYABLE(PurgeableBuffer);
+ public:
+ static PassOwnPtr<PurgeableBuffer> createUninitialized(size_t, char*& data);
+ static PassOwnPtr<PurgeableBuffer> create(const char* data, size_t);
+
+ ~PurgeableBuffer();
+
+ // Call makePurgeable(false) and check the return value before accessing the data.
+ const char* data() const;
+ size_t size() const { return m_size; }
+
+ PurgePriority purgePriority() const { return m_purgePriority; }
+ void setPurgePriority(PurgePriority priority) { m_purgePriority = priority; }
+
+ bool isPurgeable() const { return m_state != NonVolatile; }
+ bool wasPurged() const;
+
+ bool makePurgeable(bool purgeable);
+
+ private:
+ PurgeableBuffer(char* data, size_t);
+
+ char* m_data;
+ size_t m_size;
+ PurgePriority m_purgePriority;
+
+ enum State { NonVolatile, Volatile, Purged };
+ mutable State m_state;
+ };
+
+#if !ENABLE(PURGEABLE_MEMORY)
+ inline PassOwnPtr<PurgeableBuffer> PurgeableBuffer::createUninitialized(size_t, char*&) { return nullptr; }
+ inline PassOwnPtr<PurgeableBuffer> PurgeableBuffer::create(const char*, size_t) { return nullptr; }
+ inline PurgeableBuffer::~PurgeableBuffer() { }
+ inline const char* PurgeableBuffer::data() const { return 0; }
+ inline bool PurgeableBuffer::wasPurged() const { return false; }
+ inline bool PurgeableBuffer::makePurgeable(bool) { return false; }
+#endif
+
+}
+
+#endif
Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (172743 => 172744)
--- trunk/Source/WebCore/platform/SharedBuffer.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/platform/SharedBuffer.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -27,6 +27,7 @@
#include "config.h"
#include "SharedBuffer.h"
+#include "PurgeableBuffer.h"
#include <wtf/PassOwnPtr.h>
#include <wtf/unicode/UTF8.h>
@@ -65,6 +66,7 @@
SharedBuffer::SharedBuffer()
: m_size(0)
, m_buffer(adoptRef(new DataBuffer))
+ , m_shouldUsePurgeableMemory(false)
#if ENABLE(DISK_IMAGE_CACHE)
, m_isMemoryMapped(false)
, m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
@@ -77,6 +79,7 @@
SharedBuffer::SharedBuffer(unsigned size)
: m_size(size)
, m_buffer(adoptRef(new DataBuffer))
+ , m_shouldUsePurgeableMemory(false)
#if ENABLE(DISK_IMAGE_CACHE)
, m_isMemoryMapped(false)
, m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
@@ -89,6 +92,7 @@
SharedBuffer::SharedBuffer(const char* data, unsigned size)
: m_size(0)
, m_buffer(adoptRef(new DataBuffer))
+ , m_shouldUsePurgeableMemory(false)
#if ENABLE(DISK_IMAGE_CACHE)
, m_isMemoryMapped(false)
, m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
@@ -102,6 +106,7 @@
SharedBuffer::SharedBuffer(const unsigned char* data, unsigned size)
: m_size(0)
, m_buffer(adoptRef(new DataBuffer))
+ , m_shouldUsePurgeableMemory(false)
#if ENABLE(DISK_IMAGE_CACHE)
, m_isMemoryMapped(false)
, m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
@@ -132,11 +137,22 @@
return buffer.release();
}
+PassRefPtr<SharedBuffer> SharedBuffer::adoptPurgeableBuffer(PassOwnPtr<PurgeableBuffer> purgeableBuffer)
+{
+ ASSERT(!purgeableBuffer->isPurgeable());
+ RefPtr<SharedBuffer> buffer = create();
+ buffer->m_purgeableBuffer = purgeableBuffer;
+ return buffer.release();
+}
+
unsigned SharedBuffer::size() const
{
if (hasPlatformData())
return platformDataSize();
+ if (m_purgeableBuffer)
+ return m_purgeableBuffer->size();
+
return m_size;
}
@@ -200,6 +216,44 @@
}
#endif
+// Try to create a PurgeableBuffer. We can fail to create one for any of the
+// following reasons:
+// - shouldUsePurgeableMemory is set to false.
+// - the size of the buffer is less than the minimum size required by
+// PurgeableBuffer (currently 16k).
+// - PurgeableBuffer::createUninitialized() call fails.
+void SharedBuffer::createPurgeableBuffer() const
+{
+ if (m_purgeableBuffer)
+ return;
+
+ if (hasPlatformData())
+ return;
+
+#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
+ if (singleDataArrayBuffer())
+ return;
+#endif
+
+ if (!m_buffer->hasOneRef())
+ return;
+
+ if (!m_shouldUsePurgeableMemory)
+ return;
+
+ char* destination = 0;
+ m_purgeableBuffer = PurgeableBuffer::createUninitialized(m_size, destination);
+ if (!m_purgeableBuffer)
+ return;
+ unsigned bufferSize = m_buffer->data.size();
+ if (bufferSize) {
+ memcpy(destination, m_buffer->data.data(), bufferSize);
+ destination += bufferSize;
+ (const_cast<SharedBuffer*>(this))->clearDataBuffer();
+ }
+ copyBufferAndClear(destination, m_size - bufferSize);
+}
+
const char* SharedBuffer::data() const
{
#if ENABLE(DISK_IMAGE_CACHE)
@@ -215,6 +269,11 @@
return buffer;
#endif
+ createPurgeableBuffer();
+
+ if (m_purgeableBuffer)
+ return m_purgeableBuffer->data();
+
return this->buffer().data();
}
@@ -257,6 +316,7 @@
void SharedBuffer::append(const char* data, unsigned length)
{
+ ASSERT(!m_purgeableBuffer);
#if ENABLE(DISK_IMAGE_CACHE)
ASSERT(!isMemoryMapped());
#endif
@@ -326,12 +386,13 @@
m_size = 0;
clearDataBuffer();
+ m_purgeableBuffer.clear();
}
PassRefPtr<SharedBuffer> SharedBuffer::copy() const
{
RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer));
- if (hasPlatformData()) {
+ if (m_purgeableBuffer || hasPlatformData()) {
clone->append(data(), size());
return clone;
}
@@ -349,6 +410,12 @@
return clone;
}
+PassOwnPtr<PurgeableBuffer> SharedBuffer::releasePurgeableBuffer()
+{
+ ASSERT(hasOneRef());
+ return m_purgeableBuffer.release();
+}
+
void SharedBuffer::duplicateDataBufferIfNecessary() const
{
if (m_buffer->hasOneRef() || m_size <= m_buffer->data.capacity())
@@ -419,7 +486,7 @@
}
#endif
- if (hasPlatformData()) {
+ if (hasPlatformData() || m_purgeableBuffer) {
ASSERT_WITH_SECURITY_IMPLICATION(position < size());
someData = data() + position;
return totalSize - position;
Modified: trunk/Source/WebCore/platform/SharedBuffer.h (172743 => 172744)
--- trunk/Source/WebCore/platform/SharedBuffer.h 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/platform/SharedBuffer.h 2014-08-19 05:10:23 UTC (rev 172744)
@@ -49,6 +49,8 @@
namespace WebCore {
+class PurgeableBuffer;
+
class SharedBuffer : public RefCounted<SharedBuffer> {
public:
static PassRefPtr<SharedBuffer> create() { return adoptRef(new SharedBuffer); }
@@ -60,6 +62,10 @@
static PassRefPtr<SharedBuffer> adoptVector(Vector<char>& vector);
+ // The buffer must be in non-purgeable state before adopted to a SharedBuffer.
+ // It will stay that way until released.
+ static PassRefPtr<SharedBuffer> adoptPurgeableBuffer(PassOwnPtr<PurgeableBuffer>);
+
~SharedBuffer();
#if USE(FOUNDATION)
@@ -104,6 +110,11 @@
PassRefPtr<SharedBuffer> copy() const;
+ bool hasPurgeableBuffer() const { return m_purgeableBuffer.get(); }
+
+ // Ensure this buffer has no other clients before calling this.
+ PassOwnPtr<PurgeableBuffer> releasePurgeableBuffer();
+
// Return the number of consecutive bytes after "position". "data"
// points to the first byte.
// Return 0 when no more data left.
@@ -118,6 +129,8 @@
// }
unsigned getSomeData(const char*& data, unsigned position = 0) const;
+ void shouldUsePurgeableMemory(bool use) { m_shouldUsePurgeableMemory = use; }
+
#if ENABLE(DISK_IMAGE_CACHE)
enum MemoryMappingState { QueuedForMapping, PreviouslyQueuedForMapping, SuccessAlreadyMapped, FailureCacheFull };
@@ -142,6 +155,8 @@
void setMemoryMappedNotificationCallback(MemoryMappedNotifyCallback, MemoryMappedNotifyCallbackData);
#endif
+ void createPurgeableBuffer() const;
+
void tryReplaceContentsWithPlatformBuffer(SharedBuffer*);
bool hasPlatformData() const;
@@ -158,6 +173,8 @@
// Calling this function will force internal segmented buffers
// to be merged into a flat buffer. Use getSomeData() whenever possible
// for better performance.
+ // As well, be aware that this method does *not* return any purgeable
+ // memory, which can be a source of bugs.
const Vector<char>& buffer() const;
void clearPlatformData();
@@ -173,6 +190,8 @@
unsigned m_size;
mutable RefPtr<DataBuffer> m_buffer;
+ bool m_shouldUsePurgeableMemory;
+ mutable OwnPtr<PurgeableBuffer> m_purgeableBuffer;
#if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
explicit SharedBuffer(CFArrayRef);
mutable Vector<RetainPtr<CFDataRef>> m_dataArray;
Modified: trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp (172743 => 172744)
--- trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -28,6 +28,7 @@
#include "config.h"
#include "SharedBuffer.h"
+#include "PurgeableBuffer.h"
#include <wtf/cf/TypeCasts.h>
#if ENABLE(DISK_IMAGE_CACHE)
@@ -39,6 +40,7 @@
SharedBuffer::SharedBuffer(CFDataRef cfData)
: m_size(0)
, m_buffer(adoptRef(new DataBuffer))
+ , m_shouldUsePurgeableMemory(false)
#if ENABLE(DISK_IMAGE_CACHE)
, m_isMemoryMapped(false)
, m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
@@ -128,6 +130,7 @@
SharedBuffer::SharedBuffer(CFArrayRef cfDataArray)
: m_size(0)
, m_buffer(adoptRef(new DataBuffer))
+ , m_shouldUsePurgeableMemory(false)
#if ENABLE(DISK_IMAGE_CACHE)
, m_isMemoryMapped(false)
, m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
Added: trunk/Source/WebCore/platform/mac/PurgeableBufferMac.cpp (0 => 172744)
--- trunk/Source/WebCore/platform/mac/PurgeableBufferMac.cpp (rev 0)
+++ trunk/Source/WebCore/platform/mac/PurgeableBufferMac.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+
+#if ENABLE(PURGEABLE_MEMORY)
+
+#include "PurgeableBuffer.h"
+
+#include <mach/mach.h>
+#include <wtf/Assertions.h>
+#include <wtf/VMTags.h>
+
+namespace WebCore {
+
+// Purgeable buffers are allocated in multiples of the page size (4KB in common CPUs) so
+// it does not make sense for very small buffers. Set our minimum size to 16KB.
+static const size_t minPurgeableBufferSize = 4 * 4096;
+
+PurgeableBuffer::PurgeableBuffer(char* data, size_t size)
+ : m_data(data)
+ , m_size(size)
+ , m_purgePriority(PurgeDefault)
+ , m_state(NonVolatile)
+{
+}
+
+PurgeableBuffer::~PurgeableBuffer()
+{
+ vm_deallocate(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), m_size);
+}
+
+PassOwnPtr<PurgeableBuffer> PurgeableBuffer::createUninitialized(size_t size, char*& data)
+{
+ if (size < minPurgeableBufferSize)
+ return nullptr;
+
+ vm_address_t buffer = 0;
+ kern_return_t ret = vm_allocate(mach_task_self(), &buffer, size, VM_FLAGS_PURGABLE | VM_FLAGS_ANYWHERE | VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY);
+
+ ASSERT(ret == KERN_SUCCESS);
+ if (ret != KERN_SUCCESS)
+ return nullptr;
+
+ data = ""
+ return adoptPtr(new PurgeableBuffer(data, size));
+}
+
+PassOwnPtr<PurgeableBuffer> PurgeableBuffer::create(const char* data, size_t size)
+{
+ char* destination;
+ OwnPtr<PurgeableBuffer> purgeableBuffer = PurgeableBuffer::createUninitialized(size, destination);
+ if (!purgeableBuffer)
+ return nullptr;
+ memcpy(destination, data, size);
+ return purgeableBuffer.release();
+}
+
+bool PurgeableBuffer::makePurgeable(bool purgeable)
+{
+ if (purgeable) {
+ if (m_state != NonVolatile)
+ return true;
+
+ int volatileGroup;
+ if (m_purgePriority == PurgeFirst)
+ volatileGroup = VM_VOLATILE_GROUP_0;
+ else if (m_purgePriority == PurgeMiddle)
+ volatileGroup = VM_VOLATILE_GROUP_4;
+ else
+ volatileGroup = VM_VOLATILE_GROUP_7;
+
+ int state = VM_PURGABLE_VOLATILE | volatileGroup;
+ // So apparently "purgeable" is the correct spelling and the API here is misspelled.
+ kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_SET_STATE, &state);
+
+ if (ret != KERN_SUCCESS) {
+ // If that failed we have no clue what state we are in so assume purged.
+ m_state = Purged;
+ return true;
+ }
+
+ m_state = Volatile;
+ return true;
+ }
+
+ if (m_state == NonVolatile)
+ return true;
+ if (m_state == Purged)
+ return false;
+
+ int state = VM_PURGABLE_NONVOLATILE;
+ kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_SET_STATE, &state);
+
+ if (ret != KERN_SUCCESS) {
+ // If that failed we have no clue what state we are in so assume purged.
+ m_state = Purged;
+ return false;
+ }
+
+ m_state = state & VM_PURGABLE_EMPTY ? Purged : NonVolatile;
+ return m_state == NonVolatile;
+}
+
+bool PurgeableBuffer::wasPurged() const
+{
+ if (m_state == NonVolatile)
+ return false;
+ if (m_state == Purged)
+ return true;
+
+ int state;
+ kern_return_t ret = vm_purgable_control(mach_task_self(), reinterpret_cast<vm_address_t>(m_data), VM_PURGABLE_GET_STATE, &state);
+
+ if (ret != KERN_SUCCESS) {
+ // If that failed we have no clue what state we are in so assume purged.
+ m_state = Purged;
+ return true;
+ }
+
+ if (state & VM_PURGABLE_EMPTY) {
+ m_state = Purged;
+ return true;
+ }
+
+ return false;
+}
+
+const char* PurgeableBuffer::data() const
+{
+ ASSERT(m_state == NonVolatile);
+ return m_data;
+}
+
+}
+
+#endif
Modified: trunk/Source/WebCore/platform/mac/SharedBufferMac.mm (172743 => 172744)
--- trunk/Source/WebCore/platform/mac/SharedBufferMac.mm 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/platform/mac/SharedBufferMac.mm 2014-08-19 05:10:23 UTC (rev 172744)
@@ -152,6 +152,12 @@
#endif
data(); // Force data into m_buffer from segments or data array.
+ if (hasPurgeableBuffer()) {
+ RefPtr<SharedBuffer::DataBuffer> copiedBuffer = adoptRef(new DataBuffer);
+ copiedBuffer->data.append(data(), size());
+ return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:copiedBuffer.get()]).leakRef());
+ }
+
return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.get()]).leakRef());
}
Modified: trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp (172743 => 172744)
--- trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -22,6 +22,7 @@
#include "SharedBuffer.h"
+#include "PurgeableBuffer.h"
#include <libsoup/soup.h>
namespace WebCore {
Modified: trunk/Source/WebKit/mac/ChangeLog (172743 => 172744)
--- trunk/Source/WebKit/mac/ChangeLog 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebKit/mac/ChangeLog 2014-08-19 05:10:23 UTC (rev 172744)
@@ -1,3 +1,16 @@
+2014-08-18 Commit Queue <[email protected]>
+
+ Unreviewed, rolling out r172736.
+ https://bugs.webkit.org/show_bug.cgi?id=136060
+
+ Caused 14% PLT regressions (Requested by rniwa on #webkit).
+
+ Reverted changeset:
+
+ "Remove PurgeableBuffer since it is not very useful any more"
+ https://bugs.webkit.org/show_bug.cgi?id=135939
+ http://trac.webkit.org/changeset/172736
+
2014-08-18 Pratik Solanki <[email protected]>
Remove PurgeableBuffer since it is not very useful any more
Modified: trunk/Source/WebKit/mac/Misc/WebCache.mm (172743 => 172744)
--- trunk/Source/WebKit/mac/Misc/WebCache.mm 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebKit/mac/Misc/WebCache.mm 2014-08-19 05:10:23 UTC (rev 172744)
@@ -108,6 +108,26 @@
#endif
[NSNumber numberWithInt:s.scripts.decodedSize], @"_javascript_",
nil],
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:s.images.purgeableSize], @"Images",
+ [NSNumber numberWithInt:s.cssStyleSheets.purgeableSize] ,@"CSS",
+#if ENABLE(XSLT)
+ [NSNumber numberWithInt:s.xslStyleSheets.purgeableSize], @"XSL",
+#else
+ [NSNumber numberWithInt:0], @"XSL",
+#endif
+ [NSNumber numberWithInt:s.scripts.purgeableSize], @"_javascript_",
+ nil],
+ [NSDictionary dictionaryWithObjectsAndKeys:
+ [NSNumber numberWithInt:s.images.purgedSize], @"Images",
+ [NSNumber numberWithInt:s.cssStyleSheets.purgedSize] ,@"CSS",
+#if ENABLE(XSLT)
+ [NSNumber numberWithInt:s.xslStyleSheets.purgedSize], @"XSL",
+#else
+ [NSNumber numberWithInt:0], @"XSL",
+#endif
+ [NSNumber numberWithInt:s.scripts.purgedSize], @"_javascript_",
+ nil],
#if ENABLE(DISK_IMAGE_CACHE) && PLATFORM(IOS)
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:s.images.mappedSize], @"Images",
Modified: trunk/Source/WebKit/win/ChangeLog (172743 => 172744)
--- trunk/Source/WebKit/win/ChangeLog 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebKit/win/ChangeLog 2014-08-19 05:10:23 UTC (rev 172744)
@@ -1,3 +1,16 @@
+2014-08-18 Commit Queue <[email protected]>
+
+ Unreviewed, rolling out r172736.
+ https://bugs.webkit.org/show_bug.cgi?id=136060
+
+ Caused 14% PLT regressions (Requested by rniwa on #webkit).
+
+ Reverted changeset:
+
+ "Remove PurgeableBuffer since it is not very useful any more"
+ https://bugs.webkit.org/show_bug.cgi?id=135939
+ http://trac.webkit.org/changeset/172736
+
2014-08-18 Pratik Solanki <[email protected]>
Remove PurgeableBuffer since it is not very useful any more
Modified: trunk/Source/WebKit/win/WebCache.cpp (172743 => 172744)
--- trunk/Source/WebKit/win/WebCache.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebKit/win/WebCache.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -202,6 +202,52 @@
propBag->setDictionary(dictionary.get());
s[3] = propBag.leakRef();
+ // Purgable Sizes.
+ dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.images.purgeableSize));
+ CFDictionaryAddValue(dictionary.get(), imagesKey, value.get());
+
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.cssStyleSheets.purgeableSize));
+ CFDictionaryAddValue(dictionary.get(), stylesheetsKey, value.get());
+
+#if ENABLE(XSLT)
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.xslStyleSheets.purgeableSize));
+#else
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &zero));
+#endif
+ CFDictionaryAddValue(dictionary.get(), xslKey, value.get());
+
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.scripts.purgeableSize));
+ CFDictionaryAddValue(dictionary.get(), scriptsKey, value.get());
+
+ propBag = CFDictionaryPropertyBag::createInstance();
+ propBag->setDictionary(dictionary.get());
+ s[4] = propBag.leakRef();
+
+ // Purged Sizes.
+ dictionary = adoptCF(CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.images.purgedSize));
+ CFDictionaryAddValue(dictionary.get(), imagesKey, value.get());
+
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.cssStyleSheets.purgedSize));
+ CFDictionaryAddValue(dictionary.get(), stylesheetsKey, value.get());
+
+#if ENABLE(XSLT)
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.xslStyleSheets.purgedSize));
+#else
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &zero));
+#endif
+ CFDictionaryAddValue(dictionary.get(), xslKey, value.get());
+
+ value = adoptCF(CFNumberCreate(0, kCFNumberIntType, &stat.scripts.purgedSize));
+ CFDictionaryAddValue(dictionary.get(), scriptsKey, value.get());
+
+ propBag = CFDictionaryPropertyBag::createInstance();
+ propBag->setDictionary(dictionary.get());
+ s[5] = propBag.leakRef();
+
return S_OK;
}
Modified: trunk/Source/WebKit2/ChangeLog (172743 => 172744)
--- trunk/Source/WebKit2/ChangeLog 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebKit2/ChangeLog 2014-08-19 05:10:23 UTC (rev 172744)
@@ -1,3 +1,16 @@
+2014-08-18 Commit Queue <[email protected]>
+
+ Unreviewed, rolling out r172736.
+ https://bugs.webkit.org/show_bug.cgi?id=136060
+
+ Caused 14% PLT regressions (Requested by rniwa on #webkit).
+
+ Reverted changeset:
+
+ "Remove PurgeableBuffer since it is not very useful any more"
+ https://bugs.webkit.org/show_bug.cgi?id=135939
+ http://trac.webkit.org/changeset/172736
+
2014-08-18 Simon Fraser <[email protected]>
Provide default implementations of all GraphicsLayerClient methods
Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (172743 => 172744)
--- trunk/Source/WebKit2/WebProcess/WebProcess.cpp 2014-08-19 05:04:07 UTC (rev 172743)
+++ trunk/Source/WebKit2/WebProcess/WebProcess.cpp 2014-08-19 05:10:23 UTC (rev 172744)
@@ -885,6 +885,20 @@
decodedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.decodedSize);
decodedSizes.set(_javascript_String, memoryCacheStatistics.scripts.decodedSize);
result.append(decodedSizes);
+
+ HashMap<String, uint64_t> purgeableSizes;
+ purgeableSizes.set(imagesString, memoryCacheStatistics.images.purgeableSize);
+ purgeableSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgeableSize);
+ purgeableSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgeableSize);
+ purgeableSizes.set(_javascript_String, memoryCacheStatistics.scripts.purgeableSize);
+ result.append(purgeableSizes);
+
+ HashMap<String, uint64_t> purgedSizes;
+ purgedSizes.set(imagesString, memoryCacheStatistics.images.purgedSize);
+ purgedSizes.set(cssString, memoryCacheStatistics.cssStyleSheets.purgedSize);
+ purgedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.purgedSize);
+ purgedSizes.set(_javascript_String, memoryCacheStatistics.scripts.purgedSize);
+ result.append(purgedSizes);
}
void WebProcess::getWebCoreStatistics(uint64_t callbackID)