<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[172744] trunk/Source</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/172744">172744</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2014-08-18 22:10:23 -0700 (Mon, 18 Aug 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Unreviewed, rolling out <a href="http://trac.webkit.org/projects/webkit/changeset/172736">r172736</a>.
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</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfPlatformh">trunk/Source/WTF/wtf/Platform.h</a></li>
<li><a href="#trunkSourceWTFwtfVMTagsh">trunk/Source/WTF/wtf/VMTags.h</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCorexcodeprojprojectpbxproj">trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj</a></li>
<li><a href="#trunkSourceWebCoreinspectorInspectorPageAgentcpp">trunk/Source/WebCore/inspector/InspectorPageAgent.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderDocumentLoadercpp">trunk/Source/WebCore/loader/DocumentLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceBuffercpp">trunk/Source/WebCore/loader/ResourceBuffer.cpp</a></li>
<li><a href="#trunkSourceWebCoreloaderResourceBufferh">trunk/Source/WebCore/loader/ResourceBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreloaderSubresourceLoadercpp">trunk/Source/WebCore/loader/SubresourceLoader.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedCSSStyleSheetcpp">trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedCSSStyleSheeth">trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImagecpp">trunk/Source/WebCore/loader/cache/CachedImage.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedImageh">trunk/Source/WebCore/loader/cache/CachedImage.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourcecpp">trunk/Source/WebCore/loader/cache/CachedResource.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedResourceh">trunk/Source/WebCore/loader/cache/CachedResource.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedScriptcpp">trunk/Source/WebCore/loader/cache/CachedScript.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheCachedScripth">trunk/Source/WebCore/loader/cache/CachedScript.h</a></li>
<li><a href="#trunkSourceWebCoreloadercacheMemoryCachecpp">trunk/Source/WebCore/loader/cache/MemoryCache.cpp</a></li>
<li><a href="#trunkSourceWebCoreloadercacheMemoryCacheh">trunk/Source/WebCore/loader/cache/MemoryCache.h</a></li>
<li><a href="#trunkSourceWebCoreplatformSharedBuffercpp">trunk/Source/WebCore/platform/SharedBuffer.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformSharedBufferh">trunk/Source/WebCore/platform/SharedBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformcfSharedBufferCFcpp">trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformmacSharedBufferMacmm">trunk/Source/WebCore/platform/mac/SharedBufferMac.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformsoupSharedBufferSoupcpp">trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp</a></li>
<li><a href="#trunkSourceWebKitmacChangeLog">trunk/Source/WebKit/mac/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitmacMiscWebCachemm">trunk/Source/WebKit/mac/Misc/WebCache.mm</a></li>
<li><a href="#trunkSourceWebKitwinChangeLog">trunk/Source/WebKit/win/ChangeLog</a></li>
<li><a href="#trunkSourceWebKitwinWebCachecpp">trunk/Source/WebKit/win/WebCache.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebProcesscpp">trunk/Source/WebKit2/WebProcess/WebProcess.cpp</a></li>
</ul>
<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformPurgePriorityh">trunk/Source/WebCore/platform/PurgePriority.h</a></li>
<li><a href="#trunkSourceWebCoreplatformPurgeableBufferh">trunk/Source/WebCore/platform/PurgeableBuffer.h</a></li>
<li><a href="#trunkSourceWebCoreplatformmacPurgeableBufferMaccpp">trunk/Source/WebCore/platform/mac/PurgeableBufferMac.cpp</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-08-18 Commit Queue <commit-queue@webkit.org>
+
+ 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
+
</ins><span class="cx"> 2014-08-18 Pratik Solanki <psolanki@apple.com>
</span><span class="cx">
</span><span class="cx"> Remove PurgeableBuffer since it is not very useful any more
</span></span></pre></div>
<a id="trunkSourceWTFwtfPlatformh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/Platform.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -490,6 +490,10 @@
</span><span class="cx">
</span><span class="cx"> #endif /* PLATFORM(MAC) */
</span><span class="cx">
</span><ins>+#if OS(DARWIN) && !PLATFORM(GTK)
+#define ENABLE_PURGEABLE_MEMORY 1
+#endif
+
</ins><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">
</span><span class="cx"> #define DONT_FINALIZE_ON_MAIN_THREAD 1
</span></span></pre></div>
<a id="trunkSourceWTFwtfVMTagsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/VMTags.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -56,12 +56,19 @@
</span><span class="cx"> #define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(63)
</span><span class="cx"> #endif // defined(VM_MEMORY_JAVASCRIPT_CORE)
</span><span class="cx">
</span><ins>+#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)
+
</ins><span class="cx"> #else // OS(DARWIN)
</span><span class="cx">
</span><span class="cx"> #define VM_TAG_FOR_TCMALLOC_MEMORY -1
</span><span class="cx"> #define VM_TAG_FOR_COLLECTOR_MEMORY -1
</span><span class="cx"> #define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1
</span><span class="cx"> #define VM_TAG_FOR_REGISTERFILE_MEMORY -1
</span><ins>+#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY -1
</ins><span class="cx">
</span><span class="cx"> #endif // OS(DARWIN)
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-08-18 Commit Queue <commit-queue@webkit.org>
+
+ 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
+
</ins><span class="cx"> 2014-08-18 Simon Fraser <simon.fraser@apple.com>
</span><span class="cx">
</span><span class="cx"> Provide default implementations of all GraphicsLayerClient methods
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCorexcodeprojprojectpbxproj"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -2430,6 +2430,7 @@
</span><span class="cx">                 7CE6CBFB187F370700D46BF5 /* FormatConverter.h in Headers */ = {isa = PBXBuildFile; fileRef = 7CE6CBFA187F370700D46BF5 /* FormatConverter.h */; };
</span><span class="cx">                 7CE6CBFD187F394900D46BF5 /* FormatConverter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */; };
</span><span class="cx">                 7D741BDA177226AA00859170 /* CSSValueKeywords.h in Copy Generated Headers */ = {isa = PBXBuildFile; fileRef = 6565814809D13043000E61D7 /* CSSValueKeywords.h */; };
</span><ins>+                7E33CD01127F340D00BE8F17 /* PurgePriority.h in Headers */ = {isa = PBXBuildFile; fileRef = 7E33CD00127F340D00BE8F17 /* PurgePriority.h */; settings = {ATTRIBUTES = (Private, ); }; };
</ins><span class="cx">                 7E37EF2E1339208800B29250 /* SubresourceLoaderCF.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E37EF2D1339208800B29250 /* SubresourceLoaderCF.cpp */; };
</span><span class="cx">                 7E428CE513E3407F003B661C /* ResourceHandleIOS.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7E428CE413E3407F003B661C /* ResourceHandleIOS.mm */; };
</span><span class="cx">                 7E46F6FA1627A2CA00062223 /* JSOESElementIndexUint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 7E46F6F81627A2C900062223 /* JSOESElementIndexUint.cpp */; };
</span><span class="lines">@@ -6187,6 +6188,8 @@
</span><span class="cx">                 E4D58EB817B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */; };
</span><span class="cx">                 E4D58EB917B4ED8900CBDCA8 /* StyleFontSizeFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */; };
</span><span class="cx">                 E4D58EBB17B8F12800CBDCA8 /* ElementTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */; settings = {ATTRIBUTES = (Private, ); }; };
</span><ins>+                E4D687770ED7AE3D006EA978 /* PurgeableBufferMac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */; };
+                E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */; };
</ins><span class="cx">                 E4D988B417BFD1F60084FB88 /* TextNodeTraversal.h in Headers */ = {isa = PBXBuildFile; fileRef = E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */; };
</span><span class="cx">                 E4D988B617BFEB210084FB88 /* TextNodeTraversal.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4D988B517BFEB210084FB88 /* TextNodeTraversal.cpp */; };
</span><span class="cx">                 E4DEAA1717A93DC3000E0430 /* StyleResolveTree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */; };
</span><span class="lines">@@ -9583,6 +9586,7 @@
</span><span class="cx">                 7CE683461921821500F4D928 /* UserMessageHandlerDescriptorTypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UserMessageHandlerDescriptorTypes.h; sourceTree = "<group>"; };
</span><span class="cx">                 7CE6CBFA187F370700D46BF5 /* FormatConverter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FormatConverter.h; sourceTree = "<group>"; };
</span><span class="cx">                 7CE6CBFC187F394900D46BF5 /* FormatConverter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FormatConverter.cpp; sourceTree = "<group>"; };
</span><ins>+                7E33CD00127F340D00BE8F17 /* PurgePriority.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PurgePriority.h; sourceTree = "<group>"; };
</ins><span class="cx">                 7E37EF2D1339208800B29250 /* SubresourceLoaderCF.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SubresourceLoaderCF.cpp; path = cf/SubresourceLoaderCF.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 7E428CE413E3407F003B661C /* ResourceHandleIOS.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ResourceHandleIOS.mm; sourceTree = "<group>"; };
</span><span class="cx">                 7E46F6F81627A2C900062223 /* JSOESElementIndexUint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSOESElementIndexUint.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -13704,6 +13708,8 @@
</span><span class="cx">                 E4D58EB617B4ED8900CBDCA8 /* StyleFontSizeFunctions.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleFontSizeFunctions.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 E4D58EB717B4ED8900CBDCA8 /* StyleFontSizeFunctions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StyleFontSizeFunctions.h; sourceTree = "<group>"; };
</span><span class="cx">                 E4D58EBA17B8F12800CBDCA8 /* ElementTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ElementTraversal.h; sourceTree = "<group>"; };
</span><ins>+                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>"; };
</ins><span class="cx">                 E4D988B317BFD1F60084FB88 /* TextNodeTraversal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextNodeTraversal.h; sourceTree = "<group>"; };
</span><span class="cx">                 E4D988B517BFEB210084FB88 /* TextNodeTraversal.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TextNodeTraversal.cpp; sourceTree = "<group>"; };
</span><span class="cx">                 E4DEAA1517A93DC3000E0430 /* StyleResolveTree.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StyleResolveTree.cpp; sourceTree = "<group>"; };
</span><span class="lines">@@ -16446,6 +16452,7 @@
</span><span class="cx">                                 BC94D1070C274F88006BC617 /* PlatformScreenMac.mm */,
</span><span class="cx">                                 29E4D8E016B0959800C84704 /* PlatformSpeechSynthesizerMac.mm */,
</span><span class="cx">                                 0081FEFE16B0A2B6008AAA7A /* PublicSuffixMac.mm */,
</span><ins>+                                E4D687760ED7AE3D006EA978 /* PurgeableBufferMac.cpp */,
</ins><span class="cx">                                 BCAE1FA512939DB7004CB026 /* ScrollAnimatorMac.h */,
</span><span class="cx">                                 BC51156D12B1749C00C96754 /* ScrollAnimatorMac.mm */,
</span><span class="cx">                                 BC8B853C0E7C7F1100AB6984 /* ScrollbarThemeMac.h */,
</span><span class="lines">@@ -21392,6 +21399,8 @@
</span><span class="cx">                                 ABC128760B33AA6D00C693D5 /* PopupMenuClient.h */,
</span><span class="cx">                                 BC3BE12A0E98092F00835588 /* PopupMenuStyle.h */,
</span><span class="cx">                                 0081FEFD16B0A244008AAA7A /* PublicSuffix.h */,
</span><ins>+                                E4D687780ED7AE4F006EA978 /* PurgeableBuffer.h */,
+                                7E33CD00127F340D00BE8F17 /* PurgePriority.h */,
</ins><span class="cx">                                 A72EA3BA1585CF55004FAA26 /* RefCountedSupplement.h */,
</span><span class="cx">                                 9831AE49154225A200FE2644 /* ReferrerPolicy.h */,
</span><span class="cx">                                 293EAE201356B32E0067ACF9 /* RuntimeApplicationChecks.cpp */,
</span><span class="lines">@@ -25572,6 +25581,8 @@
</span><span class="cx">                                 FF945ECC161F7F3600971BC8 /* PseudoElement.h in Headers */,
</span><span class="cx">                                 0081FF0016B0A2D3008AAA7A /* PublicSuffix.h in Headers */,
</span><span class="cx">                                 10FB084B14E15C7E00A3DB98 /* PublicURLManager.h in Headers */,
</span><ins>+                                E4D687790ED7AE4F006EA978 /* PurgeableBuffer.h in Headers */,
+                                7E33CD01127F340D00BE8F17 /* PurgePriority.h in Headers */,
</ins><span class="cx">                                 550A0BCA085F6039007353D6 /* QualifiedName.h in Headers */,
</span><span class="cx">                                 442AF7A9102CDDEA008FD4D3 /* QuickLook.h in Headers */,
</span><span class="cx">                                 072AE1E8183C0741000A5988 /* QuickTimePluginReplacement.h in Headers */,
</span><span class="lines">@@ -29072,6 +29083,7 @@
</span><span class="cx">                                 FF945ECB161F7F3600971BC8 /* PseudoElement.cpp in Sources */,
</span><span class="cx">                                 0081FEFF16B0A2B6008AAA7A /* PublicSuffixMac.mm in Sources */,
</span><span class="cx">                                 CDEE393717974259001D7580 /* PublicURLManager.cpp in Sources */,
</span><ins>+                                E4D687770ED7AE3D006EA978 /* PurgeableBufferMac.cpp in Sources */,
</ins><span class="cx">                                 550A0BC9085F6039007353D6 /* QualifiedName.cpp in Sources */,
</span><span class="cx">                                 442AF7AA102CDDEA008FD4D3 /* QuickLook.mm in Sources */,
</span><span class="cx">                                 072AE1E6183C0741000A5988 /* QuickTimePluginReplacement.mm in Sources */,
</span></span></pre></div>
<a id="trunkSourceWebCoreinspectorInspectorPageAgentcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/inspector/InspectorPageAgent.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -112,6 +112,17 @@
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+ 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;
+ }
+
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderDocumentLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/DocumentLoader.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1093,6 +1093,11 @@
</span><span class="cx"> if (resource->type() == CachedResource::MainResource)
</span><span class="cx"> return 0;
</span><span class="cx">
</span><ins>+ // 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;
+
</ins><span class="cx"> ResourceBuffer* data = resource->resourceBuffer();
</span><span class="cx"> if (!data)
</span><span class="cx"> return 0;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceBuffer.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "ResourceBuffer.h"
</span><span class="cx">
</span><ins>+#include "PurgeableBuffer.h"
</ins><span class="cx"> #include "SharedBuffer.h"
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="lines">@@ -112,6 +113,30 @@
</span><span class="cx"> return ResourceBuffer::adoptSharedBuffer(m_sharedBuffer->copy());
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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();
+}
+
</ins><span class="cx"> #if USE(CF)
</span><span class="cx"> RetainPtr<CFDataRef> ResourceBuffer::createCFData()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderResourceBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/ResourceBuffer.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -38,6 +38,7 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><ins>+class PurgeableBuffer;
</ins><span class="cx"> class SharedBuffer;
</span><span class="cx">
</span><span class="cx"> class ResourceBuffer : public RefCounted<ResourceBuffer> {
</span><span class="lines">@@ -68,6 +69,17 @@
</span><span class="cx"> #endif
</span><span class="cx"> PassRefPtr<ResourceBuffer> copy() const;
</span><span class="cx">
</span><ins>+ 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();
+
</ins><span class="cx"> #if USE(FOUNDATION)
</span><span class="cx"> RetainPtr<NSData> createNSData();
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderSubresourceLoadercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/SubresourceLoader.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -299,8 +299,12 @@
</span><span class="cx"> LOG(ResourceLoading, "Received '%s'.", m_resource->url().string().latin1().data());
</span><span class="cx">
</span><span class="cx"> Ref<SubresourceLoader> protect(*this);
</span><ins>+
+#if PLATFORM(IOS)
+ if (resourceData())
+ resourceData()->setShouldUsePurgeableMemory(true);
+#endif
</ins><span class="cx"> CachedResourceHandle<CachedResource> protectResource(m_resource);
</span><del>-
</del><span class="cx"> m_state = Finishing;
</span><span class="cx"> m_resource->setLoadFinishTime(finishTime);
</span><span class="cx"> m_resource->finishLoading(resourceData());
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedCSSStyleSheetcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -80,6 +80,8 @@
</span><span class="cx">
</span><span class="cx"> const String CachedCSSStyleSheet::sheetText(bool enforceMIMEType, bool* hasValidMIMEType) const
</span><span class="cx"> {
</span><ins>+ ASSERT(!isPurgeable());
+
</ins><span class="cx"> if (!m_data || m_data->isEmpty() || !canUseSheet(enforceMIMEType, hasValidMIMEType))
</span><span class="cx"> return String();
</span><span class="cx">
</span><span class="lines">@@ -146,6 +148,9 @@
</span><span class="cx"> m_parsedStyleSheetCache.clear();
</span><span class="cx">
</span><span class="cx"> setDecodedSize(0);
</span><ins>+
+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
+ makePurgeable(true);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> PassRefPtr<StyleSheetContents> CachedCSSStyleSheet::restoreParsedStyleSheet(const CSSParserContext& context)
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedCSSStyleSheeth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedCSSStyleSheet.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -48,6 +48,7 @@
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="cx"> bool canUseSheet(bool enforceMIMEType, bool* hasValidMIMEType) const;
</span><ins>+ virtual PurgePriority purgePriority() const override { return PurgeLast; }
</ins><span class="cx"> virtual bool mayTryReplaceEncodedData() const override { return true; }
</span><span class="cx">
</span><span class="cx"> virtual void didAddClient(CachedResourceClient*) override;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -192,6 +192,8 @@
</span><span class="cx">
</span><span class="cx"> Image* CachedImage::image()
</span><span class="cx"> {
</span><ins>+ ASSERT(!isPurgeable());
+
</ins><span class="cx"> if (errorOccurred() && m_shouldPaintBrokenImage) {
</span><span class="cx"> // Returning the 1x broken image is non-ideal, but we cannot reliably access the appropriate
</span><span class="cx"> // deviceScaleFactor from here. It is critical that callers use CachedImage::brokenImage()
</span><span class="lines">@@ -207,6 +209,8 @@
</span><span class="cx">
</span><span class="cx"> Image* CachedImage::imageForRenderer(const RenderObject* renderer)
</span><span class="cx"> {
</span><ins>+ ASSERT(!isPurgeable());
+
</ins><span class="cx"> if (errorOccurred() && m_shouldPaintBrokenImage) {
</span><span class="cx"> // Returning the 1x broken image is non-ideal, but we cannot reliably access the appropriate
</span><span class="cx"> // deviceScaleFactor from here. It is critical that callers use CachedImage::brokenImage()
</span><span class="lines">@@ -270,6 +274,8 @@
</span><span class="cx">
</span><span class="cx"> LayoutSize CachedImage::imageSizeForRenderer(const RenderObject* renderer, float multiplier, SizeType sizeType)
</span><span class="cx"> {
</span><ins>+ ASSERT(!isPurgeable());
+
</ins><span class="cx"> if (!m_image)
</span><span class="cx"> return LayoutSize();
</span><span class="cx">
</span><span class="lines">@@ -456,9 +462,13 @@
</span><span class="cx"> void CachedImage::destroyDecodedData()
</span><span class="cx"> {
</span><span class="cx"> bool canDeleteImage = !m_image || (m_image->hasOneRef() && m_image->isBitmapImage());
</span><del>- if (canDeleteImage && !isLoading()) {
</del><ins>+ 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.
</ins><span class="cx"> m_image = 0;
</span><span class="cx"> setDecodedSize(0);
</span><ins>+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction())
+ makePurgeable(true);
</ins><span class="cx"> } else if (m_image && !errorOccurred())
</span><span class="cx"> m_image->destroyDecodedData();
</span><span class="cx"> }
</span><span class="lines">@@ -514,6 +524,9 @@
</span><span class="cx"> if (!m_data)
</span><span class="cx"> return false;
</span><span class="cx">
</span><ins>+ if (isPurgeable())
+ return false;
+
</ins><span class="cx"> if (m_data->size() < diskImageCache().minimumImageSize())
</span><span class="cx"> return false;
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedImageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedImage.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -101,6 +101,7 @@
</span><span class="cx"> void clearImage();
</span><span class="cx"> // If not null, changeRect is the changed part of the image.
</span><span class="cx"> void notifyObservers(const IntRect* changeRect = 0);
</span><ins>+ virtual PurgePriority purgePriority() const override { return PurgeFirst; }
</ins><span class="cx"> void checkShouldPaintBrokenImage();
</span><span class="cx">
</span><span class="cx"> virtual void switchClientsToRevalidatedResource() override;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourcecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -40,6 +40,7 @@
</span><span class="cx"> #include "Logging.h"
</span><span class="cx"> #include "MemoryCache.h"
</span><span class="cx"> #include "PlatformStrategies.h"
</span><ins>+#include "PurgeableBuffer.h"
</ins><span class="cx"> #include "ResourceBuffer.h"
</span><span class="cx"> #include "ResourceHandle.h"
</span><span class="cx"> #include "ResourceLoadScheduler.h"
</span><span class="lines">@@ -465,6 +466,8 @@
</span><span class="cx">
</span><span class="cx"> bool CachedResource::addClientToSet(CachedResourceClient* client)
</span><span class="cx"> {
</span><ins>+ ASSERT(!isPurgeable());
+
</ins><span class="cx"> if (m_preloadResult == PreloadNotReferenced) {
</span><span class="cx"> if (isLoaded())
</span><span class="cx"> m_preloadResult = PreloadReferencedWhileComplete;
</span><span class="lines">@@ -783,6 +786,64 @@
</span><span class="cx"> return false;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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();
+}
+
</ins><span class="cx"> unsigned CachedResource::overheadSize() const
</span><span class="cx"> {
</span><span class="cx"> static const int kAverageClientsHashMapSize = 384;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedResourceh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedResource.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx">
</span><span class="cx"> #include "CachePolicy.h"
</span><span class="cx"> #include "FrameLoaderTypes.h"
</span><ins>+#include "PurgePriority.h"
</ins><span class="cx"> #include "ResourceError.h"
</span><span class="cx"> #include "ResourceLoadPriority.h"
</span><span class="cx"> #include "ResourceLoaderOptions.h"
</span><span class="lines">@@ -46,6 +47,7 @@
</span><span class="cx"> class CachedResourceHandleBase;
</span><span class="cx"> class CachedResourceLoader;
</span><span class="cx"> class InspectorResource;
</span><ins>+class PurgeableBuffer;
</ins><span class="cx"> class ResourceBuffer;
</span><span class="cx"> class SecurityOrigin;
</span><span class="cx"> class SharedBuffer;
</span><span class="lines">@@ -186,7 +188,7 @@
</span><span class="cx">
</span><span class="cx"> void clearLoader();
</span><span class="cx">
</span><del>- ResourceBuffer* resourceBuffer() const { return m_data.get(); }
</del><ins>+ ResourceBuffer* resourceBuffer() const { ASSERT(!m_purgeableData); return m_data.get(); }
</ins><span class="cx">
</span><span class="cx"> virtual void willSendRequest(ResourceRequest&, const ResourceResponse&) { m_requestedFromNetworkingLayer = true; }
</span><span class="cx"> virtual void responseReceived(const ResourceResponse&);
</span><span class="lines">@@ -229,6 +231,14 @@
</span><span class="cx"> bool isCacheValidator() const { return m_resourceToRevalidate; }
</span><span class="cx"> CachedResource* resourceToRevalidate() const { return m_resourceToRevalidate; }
</span><span class="cx">
</span><ins>+ 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);
+
</ins><span class="cx"> // HTTP revalidation support methods for CachedResourceLoader.
</span><span class="cx"> void setResourceToRevalidate(CachedResource*);
</span><span class="cx"> virtual void switchClientsToRevalidatedResource();
</span><span class="lines">@@ -263,6 +273,8 @@
</span><span class="cx"> void setDecodedSize(unsigned);
</span><span class="cx"> void didAccessDecodedData(double timeStamp);
</span><span class="cx">
</span><ins>+ bool isSafeToMakePurgeable() const;
+
</ins><span class="cx"> HashCountedSet<CachedResourceClient*> m_clients;
</span><span class="cx">
</span><span class="cx"> class CachedResourceCallback {
</span><span class="lines">@@ -290,6 +302,7 @@
</span><span class="cx"> double m_responseTimestamp;
</span><span class="cx">
</span><span class="cx"> RefPtr<ResourceBuffer> m_data;
</span><ins>+ OwnPtr<PurgeableBuffer> m_purgeableData;
</ins><span class="cx"> DeferrableOneShotTimer m_decodedDataDeletionTimer;
</span><span class="cx">
</span><span class="cx"> private:
</span><span class="lines">@@ -297,6 +310,7 @@
</span><span class="cx">
</span><span class="cx"> void decodedDataDeletionTimerFired();
</span><span class="cx">
</span><ins>+ virtual PurgePriority purgePriority() const { return PurgeDefault; }
</ins><span class="cx"> virtual bool mayTryReplaceEncodedData() const { return false; }
</span><span class="cx">
</span><span class="cx"> double currentAge() const;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedScriptcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedScript.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -71,6 +71,8 @@
</span><span class="cx">
</span><span class="cx"> const String& CachedScript::script()
</span><span class="cx"> {
</span><ins>+ ASSERT(!isPurgeable());
+
</ins><span class="cx"> if (!m_script && m_data) {
</span><span class="cx"> m_script = m_decoder->decodeAndFlush(m_data->data(), encodedSize());
</span><span class="cx"> setDecodedSize(m_script.sizeInBytes());
</span><span class="lines">@@ -91,6 +93,8 @@
</span><span class="cx"> {
</span><span class="cx"> m_script = String();
</span><span class="cx"> setDecodedSize(0);
</span><ins>+ if (!MemoryCache::shouldMakeResourcePurgeableOnEviction() && isSafeToMakePurgeable())
+ makePurgeable(true);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> #if ENABLE(NOSNIFF)
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheCachedScripth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/CachedScript.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -47,6 +47,7 @@
</span><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> private:
</span><ins>+ virtual PurgePriority purgePriority() const override { return PurgeLast; }
</ins><span class="cx"> virtual bool mayTryReplaceEncodedData() const override { return true; }
</span><span class="cx">
</span><span class="cx"> virtual bool shouldIgnoreHTTPStatusCodeErrors() const override;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheMemoryCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/MemoryCache.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -212,6 +212,15 @@
</span><span class="cx"> #else
</span><span class="cx"> CachedResource* resource = resources.get(url);
</span><span class="cx"> #endif
</span><ins>+ 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());
</ins><span class="cx"> return resource;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -395,6 +404,19 @@
</span><span class="cx">
</span><span class="cx"> int size = m_allResources.size();
</span><span class="cx">
</span><ins>+ // 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;
+ }
+ }
</ins><span class="cx"> if (targetSize && m_deadSize <= targetSize)
</span><span class="cx"> return;
</span><span class="cx">
</span><span class="lines">@@ -430,7 +452,9 @@
</span><span class="cx"> CachedResourceHandle<CachedResource> previous = current->m_prevInAllResourcesList;
</span><span class="cx"> ASSERT(!previous || previous->inCache());
</span><span class="cx"> if (!current->hasClients() && !current->isPreloaded() && !current->isCacheValidator()) {
</span><del>- evict(current);
</del><ins>+ if (!makeResourcePurgeable(current))
+ evict(current);
+
</ins><span class="cx"> if (targetSize && m_deadSize <= targetSize)
</span><span class="cx"> return;
</span><span class="cx"> }
</span><span class="lines">@@ -497,6 +521,28 @@
</span><span class="cx"> prune();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+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;
+}
+
</ins><span class="cx"> void MemoryCache::evict(CachedResource* resource)
</span><span class="cx"> {
</span><span class="cx"> ASSERT(WTF::isMainThread());
</span><span class="lines">@@ -521,6 +567,12 @@
</span><span class="cx"> // Remove from the appropriate LRU list.
</span><span class="cx"> removeFromLRUList(resource);
</span><span class="cx"> removeFromLiveDecodedResourcesList(resource);
</span><ins>+
+ // 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()));
</ins><span class="cx"> } else
</span><span class="cx"> #if ENABLE(CACHE_PARTITIONING)
</span><span class="cx"> ASSERT(!resources.get(resource->url()) || resources.get(resource->url())->get(resource->cachePartition()) != resource);
</span><span class="lines">@@ -840,10 +892,15 @@
</span><span class="cx">
</span><span class="cx"> void MemoryCache::TypeStatistic::addResource(CachedResource* o)
</span><span class="cx"> {
</span><ins>+ bool purged = o->wasPurged();
+ bool purgeable = o->isPurgeable() && !purged;
+ int pageSize = (o->encodedSize() + o->overheadSize() + 4095) & ~4095;
</ins><span class="cx"> count++;
</span><del>- size += o->size();
</del><ins>+ size += purged ? 0 : o->size();
</ins><span class="cx"> liveSize += o->hasClients() ? o->size() : 0;
</span><span class="cx"> decodedSize += o->decodedSize();
</span><ins>+ purgeableSize += purgeable ? pageSize : 0;
+ purgedSize += purged ? pageSize : 0;
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> // Only the data inside the resource was mapped, not the entire resource.
</span><span class="cx"> mappedSize += o->isUsingDiskImageCache() ? o->resourceBuffer()->sharedBuffer()->size() : 0;
</span><span class="lines">@@ -944,29 +1001,29 @@
</span><span class="cx"> {
</span><span class="cx"> Statistics s = getStatistics();
</span><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><del>- printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "", "Count", "Size", "LiveSize", "DecodedSize", "Mapped", "\"Real\"");
</del><ins>+ 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");
</ins><span class="cx"> printf("%-13s %-13s %-13s %-13s %-13s %-13s %-13s\n", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------");
</span><del>- 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);
</del><ins>+ 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);
</ins><span class="cx"> #endif
</span><del>- printf("%-13s %13d %13d %13d %13d\n", "CSS", s.cssStyleSheets.count, s.cssStyleSheets.size, s.cssStyleSheets.liveSize, s.cssStyleSheets.decodedSize);
</del><ins>+ 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);
</ins><span class="cx"> #if ENABLE(XSLT)
</span><del>- printf("%-13s %13d %13d %13d %13d\n", "XSL", s.xslStyleSheets.count, s.xslStyleSheets.size, s.xslStyleSheets.liveSize, s.xslStyleSheets.decodedSize);
</del><ins>+ 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);
</ins><span class="cx"> #endif
</span><del>- 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", "-------------", "-------------", "-------------", "-------------", "-------------");
</del><ins>+ 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", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------", "-------------");
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void MemoryCache::dumpLRULists(bool includeLive) const
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><del>- printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isMemoryMapped):\n");
</del><ins>+ printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isPurgeable, wasPurged, isMemoryMapped):\n");
</ins><span class="cx"> #else
</span><del>- printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced):\n");
</del><ins>+ printf("LRU-SP lists in eviction order (Kilobytes decoded, Kilobytes encoded, Access count, Referenced, isPurgeable, wasPurged):\n");
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> int size = m_allResources.size();
</span><span class="lines">@@ -977,9 +1034,9 @@
</span><span class="cx"> CachedResource* prev = current->m_prevInAllResourcesList;
</span><span class="cx"> if (includeLive || !current->hasClients())
</span><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><del>- printf("(%.1fK, %.1fK, %uA, %dR, %d); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients(), current->isUsingDiskImageCache());
</del><ins>+ 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());
</ins><span class="cx"> #else
</span><del>- printf("(%.1fK, %.1fK, %uA, %dR); ", current->decodedSize() / 1024.0f, (current->encodedSize() + current->overheadSize()) / 1024.0f, current->accessCount(), current->hasClients());
</del><ins>+ 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());
</ins><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> current = prev;
</span></span></pre></div>
<a id="trunkSourceWebCoreloadercacheMemoryCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/cache/MemoryCache.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -61,6 +61,22 @@
</span><span class="cx"> // -------|-----+++++++++++++++|
</span><span class="cx"> // -------|-----+++++++++++++++|+++++
</span><span class="cx">
</span><ins>+// 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.
+
</ins><span class="cx"> class MemoryCache {
</span><span class="cx"> WTF_MAKE_NONCOPYABLE(MemoryCache); WTF_MAKE_FAST_ALLOCATED;
</span><span class="cx"> public:
</span><span class="lines">@@ -85,21 +101,14 @@
</span><span class="cx"> int size;
</span><span class="cx"> int liveSize;
</span><span class="cx"> int decodedSize;
</span><ins>+ int purgeableSize;
+ int purgedSize;
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> int mappedSize;
</span><ins>+ 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) { }
</ins><span class="cx"> #endif
</span><del>-
- TypeStatistic()
- : count(0)
- , size(0)
- , liveSize(0)
- , decodedSize(0)
-#if ENABLE(DISK_IMAGE_CACHE)
- , mappedSize(0)
-#endif
- {
- }
-
</del><span class="cx"> void addResource(CachedResource*);
</span><span class="cx"> };
</span><span class="cx">
</span><span class="lines">@@ -158,6 +167,8 @@
</span><span class="cx"> void addToLiveResourcesSize(CachedResource*);
</span><span class="cx"> void removeFromLiveResourcesSize(CachedResource*);
</span><span class="cx">
</span><ins>+ static bool shouldMakeResourcePurgeableOnEviction();
+
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> void flushCachedImagesToDisk(); // Flush encoded data from resources still referenced by web pages.
</span><span class="cx"> #endif
</span><span class="lines">@@ -211,6 +222,7 @@
</span><span class="cx"> unsigned liveCapacity() const;
</span><span class="cx"> unsigned deadCapacity() const;
</span><span class="cx">
</span><ins>+ bool makeResourcePurgeable(CachedResource*);
</ins><span class="cx"> void evict(CachedResource*);
</span><span class="cx">
</span><span class="cx"> CachedResource* resourceForRequestImpl(const ResourceRequest&, CachedResourceMap&);
</span><span class="lines">@@ -246,6 +258,15 @@
</span><span class="cx"> SessionCachedResourceMap m_sessionResources;
</span><span class="cx"> };
</span><span class="cx">
</span><ins>+inline bool MemoryCache::shouldMakeResourcePurgeableOnEviction()
+{
+#if PLATFORM(IOS)
+ return true;
+#else
+ return false;
+#endif
+}
+
</ins><span class="cx"> // Function to obtain the global cache.
</span><span class="cx"> MemoryCache* memoryCache();
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformPurgePriorityh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/PurgePriority.h (0 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/PurgePriority.h         (rev 0)
+++ trunk/Source/WebCore/platform/PurgePriority.h        2014-08-19 05:10:23 UTC (rev 172744)
</span><span class="lines">@@ -0,0 +1,39 @@
</span><ins>+/*
+ * 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
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformPurgeableBufferh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/PurgeableBuffer.h (0 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/PurgeableBuffer.h         (rev 0)
+++ trunk/Source/WebCore/platform/PurgeableBuffer.h        2014-08-19 05:10:23 UTC (rev 172744)
</span><span class="lines">@@ -0,0 +1,77 @@
</span><ins>+/*
+ * 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
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformSharedBuffercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/SharedBuffer.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "SharedBuffer.h"
</span><span class="cx">
</span><ins>+#include "PurgeableBuffer.h"
</ins><span class="cx"> #include <wtf/PassOwnPtr.h>
</span><span class="cx"> #include <wtf/unicode/UTF8.h>
</span><span class="cx">
</span><span class="lines">@@ -65,6 +66,7 @@
</span><span class="cx"> SharedBuffer::SharedBuffer()
</span><span class="cx"> : m_size(0)
</span><span class="cx"> , m_buffer(adoptRef(new DataBuffer))
</span><ins>+ , m_shouldUsePurgeableMemory(false)
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> , m_isMemoryMapped(false)
</span><span class="cx"> , m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
</span><span class="lines">@@ -77,6 +79,7 @@
</span><span class="cx"> SharedBuffer::SharedBuffer(unsigned size)
</span><span class="cx"> : m_size(size)
</span><span class="cx"> , m_buffer(adoptRef(new DataBuffer))
</span><ins>+ , m_shouldUsePurgeableMemory(false)
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> , m_isMemoryMapped(false)
</span><span class="cx"> , m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
</span><span class="lines">@@ -89,6 +92,7 @@
</span><span class="cx"> SharedBuffer::SharedBuffer(const char* data, unsigned size)
</span><span class="cx"> : m_size(0)
</span><span class="cx"> , m_buffer(adoptRef(new DataBuffer))
</span><ins>+ , m_shouldUsePurgeableMemory(false)
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> , m_isMemoryMapped(false)
</span><span class="cx"> , m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
</span><span class="lines">@@ -102,6 +106,7 @@
</span><span class="cx"> SharedBuffer::SharedBuffer(const unsigned char* data, unsigned size)
</span><span class="cx"> : m_size(0)
</span><span class="cx"> , m_buffer(adoptRef(new DataBuffer))
</span><ins>+ , m_shouldUsePurgeableMemory(false)
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> , m_isMemoryMapped(false)
</span><span class="cx"> , m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
</span><span class="lines">@@ -132,11 +137,22 @@
</span><span class="cx"> return buffer.release();
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+PassRefPtr<SharedBuffer> SharedBuffer::adoptPurgeableBuffer(PassOwnPtr<PurgeableBuffer> purgeableBuffer)
+{
+ ASSERT(!purgeableBuffer->isPurgeable());
+ RefPtr<SharedBuffer> buffer = create();
+ buffer->m_purgeableBuffer = purgeableBuffer;
+ return buffer.release();
+}
+
</ins><span class="cx"> unsigned SharedBuffer::size() const
</span><span class="cx"> {
</span><span class="cx"> if (hasPlatformData())
</span><span class="cx"> return platformDataSize();
</span><span class="cx">
</span><ins>+ if (m_purgeableBuffer)
+ return m_purgeableBuffer->size();
+
</ins><span class="cx"> return m_size;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -200,6 +216,44 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+// 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);
+}
+
</ins><span class="cx"> const char* SharedBuffer::data() const
</span><span class="cx"> {
</span><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="lines">@@ -215,6 +269,11 @@
</span><span class="cx"> return buffer;
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+ createPurgeableBuffer();
+
+ if (m_purgeableBuffer)
+ return m_purgeableBuffer->data();
+
</ins><span class="cx"> return this->buffer().data();
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -257,6 +316,7 @@
</span><span class="cx">
</span><span class="cx"> void SharedBuffer::append(const char* data, unsigned length)
</span><span class="cx"> {
</span><ins>+ ASSERT(!m_purgeableBuffer);
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> ASSERT(!isMemoryMapped());
</span><span class="cx"> #endif
</span><span class="lines">@@ -326,12 +386,13 @@
</span><span class="cx">
</span><span class="cx"> m_size = 0;
</span><span class="cx"> clearDataBuffer();
</span><ins>+ m_purgeableBuffer.clear();
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> PassRefPtr<SharedBuffer> SharedBuffer::copy() const
</span><span class="cx"> {
</span><span class="cx"> RefPtr<SharedBuffer> clone(adoptRef(new SharedBuffer));
</span><del>- if (hasPlatformData()) {
</del><ins>+ if (m_purgeableBuffer || hasPlatformData()) {
</ins><span class="cx"> clone->append(data(), size());
</span><span class="cx"> return clone;
</span><span class="cx"> }
</span><span class="lines">@@ -349,6 +410,12 @@
</span><span class="cx"> return clone;
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+PassOwnPtr<PurgeableBuffer> SharedBuffer::releasePurgeableBuffer()
+{
+ ASSERT(hasOneRef());
+ return m_purgeableBuffer.release();
+}
+
</ins><span class="cx"> void SharedBuffer::duplicateDataBufferIfNecessary() const
</span><span class="cx"> {
</span><span class="cx"> if (m_buffer->hasOneRef() || m_size <= m_buffer->data.capacity())
</span><span class="lines">@@ -419,7 +486,7 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx">
</span><del>- if (hasPlatformData()) {
</del><ins>+ if (hasPlatformData() || m_purgeableBuffer) {
</ins><span class="cx"> ASSERT_WITH_SECURITY_IMPLICATION(position < size());
</span><span class="cx"> someData = data() + position;
</span><span class="cx"> return totalSize - position;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformSharedBufferh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/SharedBuffer.h (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -49,6 +49,8 @@
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span><span class="cx">
</span><ins>+class PurgeableBuffer;
+
</ins><span class="cx"> class SharedBuffer : public RefCounted<SharedBuffer> {
</span><span class="cx"> public:
</span><span class="cx"> static PassRefPtr<SharedBuffer> create() { return adoptRef(new SharedBuffer); }
</span><span class="lines">@@ -60,6 +62,10 @@
</span><span class="cx">
</span><span class="cx"> static PassRefPtr<SharedBuffer> adoptVector(Vector<char>& vector);
</span><span class="cx">
</span><ins>+ // 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>);
+
</ins><span class="cx"> ~SharedBuffer();
</span><span class="cx">
</span><span class="cx"> #if USE(FOUNDATION)
</span><span class="lines">@@ -104,6 +110,11 @@
</span><span class="cx">
</span><span class="cx"> PassRefPtr<SharedBuffer> copy() const;
</span><span class="cx">
</span><ins>+ bool hasPurgeableBuffer() const { return m_purgeableBuffer.get(); }
+
+ // Ensure this buffer has no other clients before calling this.
+ PassOwnPtr<PurgeableBuffer> releasePurgeableBuffer();
+
</ins><span class="cx"> // Return the number of consecutive bytes after "position". "data"
</span><span class="cx"> // points to the first byte.
</span><span class="cx"> // Return 0 when no more data left.
</span><span class="lines">@@ -118,6 +129,8 @@
</span><span class="cx"> // }
</span><span class="cx"> unsigned getSomeData(const char*& data, unsigned position = 0) const;
</span><span class="cx">
</span><ins>+ void shouldUsePurgeableMemory(bool use) { m_shouldUsePurgeableMemory = use; }
+
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> enum MemoryMappingState { QueuedForMapping, PreviouslyQueuedForMapping, SuccessAlreadyMapped, FailureCacheFull };
</span><span class="cx">
</span><span class="lines">@@ -142,6 +155,8 @@
</span><span class="cx"> void setMemoryMappedNotificationCallback(MemoryMappedNotifyCallback, MemoryMappedNotifyCallbackData);
</span><span class="cx"> #endif
</span><span class="cx">
</span><ins>+ void createPurgeableBuffer() const;
+
</ins><span class="cx"> void tryReplaceContentsWithPlatformBuffer(SharedBuffer*);
</span><span class="cx"> bool hasPlatformData() const;
</span><span class="cx">
</span><span class="lines">@@ -158,6 +173,8 @@
</span><span class="cx"> // Calling this function will force internal segmented buffers
</span><span class="cx"> // to be merged into a flat buffer. Use getSomeData() whenever possible
</span><span class="cx"> // for better performance.
</span><ins>+ // As well, be aware that this method does *not* return any purgeable
+ // memory, which can be a source of bugs.
</ins><span class="cx"> const Vector<char>& buffer() const;
</span><span class="cx">
</span><span class="cx"> void clearPlatformData();
</span><span class="lines">@@ -173,6 +190,8 @@
</span><span class="cx"> unsigned m_size;
</span><span class="cx"> mutable RefPtr<DataBuffer> m_buffer;
</span><span class="cx">
</span><ins>+ bool m_shouldUsePurgeableMemory;
+ mutable OwnPtr<PurgeableBuffer> m_purgeableBuffer;
</ins><span class="cx"> #if USE(NETWORK_CFDATA_ARRAY_CALLBACK)
</span><span class="cx"> explicit SharedBuffer(CFArrayRef);
</span><span class="cx"> mutable Vector<RetainPtr<CFDataRef>> m_dataArray;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformcfSharedBufferCFcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/cf/SharedBufferCF.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -28,6 +28,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "SharedBuffer.h"
</span><span class="cx">
</span><ins>+#include "PurgeableBuffer.h"
</ins><span class="cx"> #include <wtf/cf/TypeCasts.h>
</span><span class="cx">
</span><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="lines">@@ -39,6 +40,7 @@
</span><span class="cx"> SharedBuffer::SharedBuffer(CFDataRef cfData)
</span><span class="cx"> : m_size(0)
</span><span class="cx"> , m_buffer(adoptRef(new DataBuffer))
</span><ins>+ , m_shouldUsePurgeableMemory(false)
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> , m_isMemoryMapped(false)
</span><span class="cx"> , m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
</span><span class="lines">@@ -128,6 +130,7 @@
</span><span class="cx"> SharedBuffer::SharedBuffer(CFArrayRef cfDataArray)
</span><span class="cx"> : m_size(0)
</span><span class="cx"> , m_buffer(adoptRef(new DataBuffer))
</span><ins>+ , m_shouldUsePurgeableMemory(false)
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE)
</span><span class="cx"> , m_isMemoryMapped(false)
</span><span class="cx"> , m_diskImageCacheId(DiskImageCache::invalidDiskCacheId)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformmacPurgeableBufferMaccpp"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/mac/PurgeableBufferMac.cpp (0 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -0,0 +1,159 @@
</span><ins>+/*
+ * 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 = reinterpret_cast<char*>(buffer);
+ 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
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformmacSharedBufferMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/mac/SharedBufferMac.mm (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -152,6 +152,12 @@
</span><span class="cx"> #endif
</span><span class="cx">
</span><span class="cx"> data(); // Force data into m_buffer from segments or data array.
</span><ins>+ if (hasPurgeableBuffer()) {
+ RefPtr<SharedBuffer::DataBuffer> copiedBuffer = adoptRef(new DataBuffer);
+ copiedBuffer->data.append(data(), size());
+ return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:copiedBuffer.get()]).leakRef());
+ }
+
</ins><span class="cx"> return adoptCF((CFDataRef)adoptNS([[WebCoreSharedBufferData alloc] initWithSharedBufferDataBuffer:m_buffer.get()]).leakRef());
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformsoupSharedBufferSoupcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/soup/SharedBufferSoup.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx">
</span><span class="cx"> #include "SharedBuffer.h"
</span><span class="cx">
</span><ins>+#include "PurgeableBuffer.h"
</ins><span class="cx"> #include <libsoup/soup.h>
</span><span class="cx">
</span><span class="cx"> namespace WebCore {
</span></span></pre></div>
<a id="trunkSourceWebKitmacChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/ChangeLog (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-08-18 Commit Queue <commit-queue@webkit.org>
+
+ 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
+
</ins><span class="cx"> 2014-08-18 Pratik Solanki <psolanki@apple.com>
</span><span class="cx">
</span><span class="cx"> Remove PurgeableBuffer since it is not very useful any more
</span></span></pre></div>
<a id="trunkSourceWebKitmacMiscWebCachemm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/mac/Misc/WebCache.mm (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -108,6 +108,26 @@
</span><span class="cx"> #endif
</span><span class="cx"> [NSNumber numberWithInt:s.scripts.decodedSize], @"JavaScript",
</span><span class="cx"> nil],
</span><ins>+ [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],
</ins><span class="cx"> #if ENABLE(DISK_IMAGE_CACHE) && PLATFORM(IOS)
</span><span class="cx"> [NSDictionary dictionaryWithObjectsAndKeys:
</span><span class="cx"> [NSNumber numberWithInt:s.images.mappedSize], @"Images",
</span></span></pre></div>
<a id="trunkSourceWebKitwinChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/ChangeLog (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-08-18 Commit Queue <commit-queue@webkit.org>
+
+ 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
+
</ins><span class="cx"> 2014-08-18 Pratik Solanki <psolanki@apple.com>
</span><span class="cx">
</span><span class="cx"> Remove PurgeableBuffer since it is not very useful any more
</span></span></pre></div>
<a id="trunkSourceWebKitwinWebCachecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit/win/WebCache.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -202,6 +202,52 @@
</span><span class="cx"> propBag->setDictionary(dictionary.get());
</span><span class="cx"> s[3] = propBag.leakRef();
</span><span class="cx">
</span><ins>+ // 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();
+
</ins><span class="cx"> return S_OK;
</span><span class="cx"> }
</span><span class="cx">
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -1,3 +1,16 @@
</span><ins>+2014-08-18 Commit Queue <commit-queue@webkit.org>
+
+ 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
+
</ins><span class="cx"> 2014-08-18 Simon Fraser <simon.fraser@apple.com>
</span><span class="cx">
</span><span class="cx"> Provide default implementations of all GraphicsLayerClient methods
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebProcesscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebProcess.cpp (172743 => 172744)</h4>
<pre class="diff"><span>
<span class="info">--- 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)
</span><span class="lines">@@ -885,6 +885,20 @@
</span><span class="cx"> decodedSizes.set(xslString, memoryCacheStatistics.xslStyleSheets.decodedSize);
</span><span class="cx"> decodedSizes.set(javaScriptString, memoryCacheStatistics.scripts.decodedSize);
</span><span class="cx"> result.append(decodedSizes);
</span><ins>+
+ 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(javaScriptString, 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(javaScriptString, memoryCacheStatistics.scripts.purgedSize);
+ result.append(purgedSizes);
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> void WebProcess::getWebCoreStatistics(uint64_t callbackID)
</span></span></pre>
</div>
</div>
</body>
</html>