<!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>[234733] 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/234733">234733</a></dd>
<dt>Author</dt> <dd>sbarati@apple.com</dd>
<dt>Date</dt> <dd>2018-08-09 13:13:27 -0700 (Thu, 09 Aug 2018)</dd>
</dl>

<h3>Log Message</h3>
<pre>memoryFootprint should return size_t not optional<size_t>
https://bugs.webkit.org/show_bug.cgi?id=188444

Reviewed by Simon Fraser.

Source/WebCore:

* page/cocoa/ResourceUsageOverlayCocoa.mm:
(WebCore::ResourceUsageOverlay::platformDraw):

Source/WTF:

We're now going to return zero instead of returning nullopt on failure.
There was a lot of code dancing around memoryFootprint failing for no
good reason.

Users of this API were previously doing this on failure:
- Treating it as zero (this was the most common user).
- Crashing.
- Bailing out early and not changing our memory pressure state. This change
has the effect that instead of not changing our memory pressure state on
failure, we will go back to thinking we're not under memory pressure. Since
we relied on this API not failing to do anything useful (like kill the process
or release memory), this won't change our behavior here in a meaningful way.

* wtf/MemoryFootprint.h:
* wtf/MemoryPressureHandler.cpp:
(WTF::MemoryPressureHandler::currentMemoryUsagePolicy):
(WTF::MemoryPressureHandler::shrinkOrDie):
(WTF::MemoryPressureHandler::measurementTimerFired):
* wtf/cocoa/MemoryFootprintCocoa.cpp:
(WTF::memoryFootprint):
* wtf/linux/MemoryFootprintLinux.cpp:
(WTF::memoryFootprint):
* wtf/linux/MemoryPressureHandlerLinux.cpp:
(WTF::MemoryPressureHandler::ReliefLogger::platformMemoryUsage):
* wtf/win/MemoryFootprintWin.cpp:
(WTF::memoryFootprint):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWTFChangeLog">trunk/Source/WTF/ChangeLog</a></li>
<li><a href="#trunkSourceWTFwtfMemoryFootprinth">trunk/Source/WTF/wtf/MemoryFootprint.h</a></li>
<li><a href="#trunkSourceWTFwtfMemoryPressureHandlercpp">trunk/Source/WTF/wtf/MemoryPressureHandler.cpp</a></li>
<li><a href="#trunkSourceWTFwtfcocoaMemoryFootprintCocoacpp">trunk/Source/WTF/wtf/cocoa/MemoryFootprintCocoa.cpp</a></li>
<li><a href="#trunkSourceWTFwtflinuxMemoryFootprintLinuxcpp">trunk/Source/WTF/wtf/linux/MemoryFootprintLinux.cpp</a></li>
<li><a href="#trunkSourceWTFwtflinuxMemoryPressureHandlerLinuxcpp">trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp</a></li>
<li><a href="#trunkSourceWTFwtfwinMemoryFootprintWincpp">trunk/Source/WTF/wtf/win/MemoryFootprintWin.cpp</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepagecocoaResourceUsageOverlayCocoamm">trunk/Source/WebCore/page/cocoa/ResourceUsageOverlayCocoa.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWTFChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/ChangeLog (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/ChangeLog       2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WTF/ChangeLog  2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -1,3 +1,37 @@
</span><ins>+2018-08-09  Saam Barati  <sbarati@apple.com>
+
+        memoryFootprint should return size_t not optional<size_t>
+        https://bugs.webkit.org/show_bug.cgi?id=188444
+
+        Reviewed by Simon Fraser.
+
+        We're now going to return zero instead of returning nullopt on failure.
+        There was a lot of code dancing around memoryFootprint failing for no
+        good reason.
+        
+        Users of this API were previously doing this on failure:
+        - Treating it as zero (this was the most common user).
+        - Crashing.
+        - Bailing out early and not changing our memory pressure state. This change
+        has the effect that instead of not changing our memory pressure state on
+        failure, we will go back to thinking we're not under memory pressure. Since
+        we relied on this API not failing to do anything useful (like kill the process
+        or release memory), this won't change our behavior here in a meaningful way.
+
+        * wtf/MemoryFootprint.h:
+        * wtf/MemoryPressureHandler.cpp:
+        (WTF::MemoryPressureHandler::currentMemoryUsagePolicy):
+        (WTF::MemoryPressureHandler::shrinkOrDie):
+        (WTF::MemoryPressureHandler::measurementTimerFired):
+        * wtf/cocoa/MemoryFootprintCocoa.cpp:
+        (WTF::memoryFootprint):
+        * wtf/linux/MemoryFootprintLinux.cpp:
+        (WTF::memoryFootprint):
+        * wtf/linux/MemoryPressureHandlerLinux.cpp:
+        (WTF::MemoryPressureHandler::ReliefLogger::platformMemoryUsage):
+        * wtf/win/MemoryFootprintWin.cpp:
+        (WTF::memoryFootprint):
+
</ins><span class="cx"> 2018-08-05  Darin Adler  <darin@apple.com>
</span><span class="cx"> 
</span><span class="cx">         [Cocoa] More tweaks and refactoring to prepare for ARC
</span></span></pre></div>
<a id="trunkSourceWTFwtfMemoryFootprinth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MemoryFootprint.h (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MemoryFootprint.h   2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WTF/wtf/MemoryFootprint.h      2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -29,7 +29,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-WTF_EXPORT_PRIVATE std::optional<size_t> memoryFootprint();
</del><ins>+WTF_EXPORT_PRIVATE size_t memoryFootprint();
</ins><span class="cx"> 
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfMemoryPressureHandlercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/MemoryPressureHandler.cpp (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/MemoryPressureHandler.cpp   2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WTF/wtf/MemoryPressureHandler.cpp      2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -146,7 +146,7 @@
</span><span class="cx"> 
</span><span class="cx"> MemoryUsagePolicy MemoryPressureHandler::currentMemoryUsagePolicy()
</span><span class="cx"> {
</span><del>-    return policyForFootprint(memoryFootprint().value_or(0));
</del><ins>+    return policyForFootprint(memoryFootprint());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void MemoryPressureHandler::shrinkOrDie()
</span><span class="lines">@@ -154,17 +154,16 @@
</span><span class="cx">     RELEASE_LOG(MemoryPressure, "Process is above the memory kill threshold. Trying to shrink down.");
</span><span class="cx">     releaseMemory(Critical::Yes, Synchronous::Yes);
</span><span class="cx"> 
</span><del>-    auto footprint = memoryFootprint();
-    RELEASE_ASSERT(footprint);
-    RELEASE_LOG(MemoryPressure, "New memory footprint: %zu MB", footprint.value() / MB);
</del><ins>+    size_t footprint = memoryFootprint();
+    RELEASE_LOG(MemoryPressure, "New memory footprint: %zu MB", footprint / MB);
</ins><span class="cx"> 
</span><del>-    if (footprint.value() < thresholdForMemoryKill()) {
</del><ins>+    if (footprint < thresholdForMemoryKill()) {
</ins><span class="cx">         RELEASE_LOG(MemoryPressure, "Shrank below memory kill threshold. Process gets to live.");
</span><del>-        setMemoryUsagePolicyBasedOnFootprint(footprint.value());
</del><ins>+        setMemoryUsagePolicyBasedOnFootprint(footprint);
</ins><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    WTFLogAlways("Unable to shrink memory footprint of process (%zu MB) below the kill thresold (%zu MB). Killed\n", footprint.value() / MB, thresholdForMemoryKill() / MB);
</del><ins>+    WTFLogAlways("Unable to shrink memory footprint of process (%zu MB) below the kill thresold (%zu MB). Killed\n", footprint / MB, thresholdForMemoryKill() / MB);
</ins><span class="cx">     RELEASE_ASSERT(m_memoryKillCallback);
</span><span class="cx">     m_memoryKillCallback();
</span><span class="cx"> }
</span><span class="lines">@@ -182,17 +181,14 @@
</span><span class="cx"> 
</span><span class="cx"> void MemoryPressureHandler::measurementTimerFired()
</span><span class="cx"> {
</span><del>-    auto footprint = memoryFootprint();
-    if (!footprint)
-        return;
-
-    RELEASE_LOG(MemoryPressure, "Current memory footprint: %zu MB", footprint.value() / MB);
-    if (footprint.value() >= thresholdForMemoryKill()) {
</del><ins>+    size_t footprint = memoryFootprint();
+    RELEASE_LOG(MemoryPressure, "Current memory footprint: %zu MB", footprint / MB);
+    if (footprint >= thresholdForMemoryKill()) {
</ins><span class="cx">         shrinkOrDie();
</span><span class="cx">         return;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    setMemoryUsagePolicyBasedOnFootprint(footprint.value());
</del><ins>+    setMemoryUsagePolicyBasedOnFootprint(footprint);
</ins><span class="cx"> 
</span><span class="cx">     switch (m_memoryUsagePolicy) {
</span><span class="cx">     case MemoryUsagePolicy::Unrestricted:
</span><span class="lines">@@ -205,7 +201,7 @@
</span><span class="cx">         break;
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (processState() == WebsamProcessState::Active && footprint.value() > thresholdForMemoryKillWithProcessState(WebsamProcessState::Inactive, m_pageCount))
</del><ins>+    if (processState() == WebsamProcessState::Active && footprint > thresholdForMemoryKillWithProcessState(WebsamProcessState::Inactive, m_pageCount))
</ins><span class="cx">         doesExceedInactiveLimitWhileActive();
</span><span class="cx">     else
</span><span class="cx">         doesNotExceedInactiveLimitWhileActive();
</span></span></pre></div>
<a id="trunkSourceWTFwtfcocoaMemoryFootprintCocoacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/cocoa/MemoryFootprintCocoa.cpp (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/cocoa/MemoryFootprintCocoa.cpp      2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WTF/wtf/cocoa/MemoryFootprintCocoa.cpp 2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -31,13 +31,13 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-std::optional<size_t> memoryFootprint()
</del><ins>+size_t memoryFootprint()
</ins><span class="cx"> {
</span><span class="cx">     task_vm_info_data_t vmInfo;
</span><span class="cx">     mach_msg_type_number_t count = TASK_VM_INFO_COUNT;
</span><span class="cx">     kern_return_t result = task_info(mach_task_self(), TASK_VM_INFO, (task_info_t) &vmInfo, &count);
</span><span class="cx">     if (result != KERN_SUCCESS)
</span><del>-        return std::nullopt;
</del><ins>+        return 0;
</ins><span class="cx">     return static_cast<size_t>(vmInfo.phys_footprint);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtflinuxMemoryFootprintLinuxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/linux/MemoryFootprintLinux.cpp (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/linux/MemoryFootprintLinux.cpp      2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WTF/wtf/linux/MemoryFootprintLinux.cpp 2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -47,12 +47,12 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-std::optional<size_t> memoryFootprint()
</del><ins>+size_t memoryFootprint()
</ins><span class="cx"> {
</span><span class="cx"> #if OS(LINUX)
</span><span class="cx">     FILE* file = fopen("/proc/self/smaps", "r");
</span><span class="cx">     if (!file)
</span><del>-        return std::nullopt;
</del><ins>+        return 0;
</ins><span class="cx"> 
</span><span class="cx">     unsigned long totalPrivateDirtyInKB = 0;
</span><span class="cx">     bool isAnonymous = false;
</span><span class="lines">@@ -87,7 +87,7 @@
</span><span class="cx">     fclose(file);
</span><span class="cx">     return totalPrivateDirtyInKB * KB;
</span><span class="cx"> #endif
</span><del>-    return std::nullopt;
</del><ins>+    return 0;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWTFwtflinuxMemoryPressureHandlerLinuxcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp        2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WTF/wtf/linux/MemoryPressureHandlerLinux.cpp   2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -135,11 +135,7 @@
</span><span class="cx"> 
</span><span class="cx"> std::optional<MemoryPressureHandler::ReliefLogger::MemoryUsage> MemoryPressureHandler::ReliefLogger::platformMemoryUsage()
</span><span class="cx"> {
</span><del>-    size_t physical = 0;
-    auto footprint = memoryFootprint();
-    if (footprint)
-        physical = footprint.value();
-    return MemoryUsage {processMemoryUsage(), physical};
</del><ins>+    return MemoryUsage {processMemoryUsage(), memoryFootprint()};
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWTFwtfwinMemoryFootprintWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WTF/wtf/win/MemoryFootprintWin.cpp (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WTF/wtf/win/MemoryFootprintWin.cpp  2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WTF/wtf/win/MemoryFootprintWin.cpp     2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -35,7 +35,7 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="cx"> 
</span><del>-std::optional<size_t> memoryFootprint()
</del><ins>+size_t memoryFootprint()
</ins><span class="cx"> {
</span><span class="cx">     // We would like to calculate size of private working set.
</span><span class="cx">     // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684891(v=vs.85).aspx
</span><span class="lines">@@ -46,7 +46,7 @@
</span><span class="cx">     // > memory demand increases.
</span><span class="cx">     Win32Handle process(OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, GetCurrentProcessId()));
</span><span class="cx">     if (!process.isValid())
</span><del>-        return std::nullopt;
</del><ins>+        return 0;
</ins><span class="cx"> 
</span><span class="cx">     auto countSizeOfPrivateWorkingSet = [] (const PSAPI_WORKING_SET_INFORMATION& workingSets) {
</span><span class="cx">         constexpr const size_t pageSize = 4 * KB;
</span><span class="lines">@@ -81,7 +81,7 @@
</span><span class="cx">             return countSizeOfPrivateWorkingSet(*workingSets);
</span><span class="cx"> 
</span><span class="cx">         if (GetLastError() != ERROR_BAD_LENGTH)
</span><del>-            return std::nullopt;
</del><ins>+            return 0;
</ins><span class="cx">         numberOfEntries = updateNumberOfEntries(workingSets->NumberOfEntries);
</span><span class="cx">     }
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog   2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WebCore/ChangeLog      2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2018-08-09  Saam Barati  <sbarati@apple.com>
+
+        memoryFootprint should return size_t not optional<size_t>
+        https://bugs.webkit.org/show_bug.cgi?id=188444
+
+        Reviewed by Simon Fraser.
+
+        * page/cocoa/ResourceUsageOverlayCocoa.mm:
+        (WebCore::ResourceUsageOverlay::platformDraw):
+
</ins><span class="cx"> 2018-08-09  Ali Juma  <ajuma@chromium.org>
</span><span class="cx"> 
</span><span class="cx">         Update IDL for IntersectionObserverEntry and IntersectionObserverEntryInit
</span></span></pre></div>
<a id="trunkSourceWebCorepagecocoaResourceUsageOverlayCocoamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/cocoa/ResourceUsageOverlayCocoa.mm (234732 => 234733)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/cocoa/ResourceUsageOverlayCocoa.mm     2018-08-09 19:36:38 UTC (rev 234732)
+++ trunk/Source/WebCore/page/cocoa/ResourceUsageOverlayCocoa.mm        2018-08-09 20:13:27 UTC (rev 234733)
</span><span class="lines">@@ -458,10 +458,7 @@
</span><span class="cx"> 
</span><span class="cx">     static CGColorRef colorForLabels = createColor(0.9, 0.9, 0.9, 1);
</span><span class="cx">     showText(context, 10, 20, colorForLabels, String::format("        CPU: %g", data.cpu.last()));
</span><del>-    if (auto footprint = memoryFootprint())
-        showText(context, 10, 30, colorForLabels, "  Footprint: " + formatByteNumber(*footprint));
-    else
-        showText(context, 10, 30, colorForLabels, "  Footprint: " + formatByteNumber(data.totalDirtySize.last()));
</del><ins>+    showText(context, 10, 30, colorForLabels, "  Footprint: " + formatByteNumber(memoryFootprint()));
</ins><span class="cx">     showText(context, 10, 40, colorForLabels, "   External: " + formatByteNumber(data.totalExternalSize.last()));
</span><span class="cx"> 
</span><span class="cx">     float y = 55;
</span></span></pre>
</div>
</div>

</body>
</html>