Title: [123856] trunk/Source
Revision
123856
Author
[email protected]
Date
2012-07-27 02:37:51 -0700 (Fri, 27 Jul 2012)

Log Message

Add a Setting to expose quantized, rate-limited MemoryInfo values
https://bugs.webkit.org/show_bug.cgi?id=80444

Reviewed by Eric Seidel.

We do not currently expose real MemoryInfo objects to the web unless
the user opts in because we're worried that this memory information
could be used in side-channel attacks.

We've gotten feedback from a number of web app developers that this
information is very useful in tracking the performance of their
applications.  These developers use the setting in their testing labs
and regression harnesses to catch memory leaks and regressiosn early in
their development cycle.

Some of these developers have experimented with enabling this feature
within their enterprise and have found the memory data from the field
extremely useful in tracking down memory issues that slip through their
testing.

Based on this experience, they've asked whether we can enable this
functionality on a wider scale so they catch even more problems
including problems that don't manifest within their enterprise.
Because we're still worried about side-channel attacks, we don't want
to expose the raw data, so we've talked with these folks in more detail
to understand what information they find most valuable.

This patch is the result of those discussions.  In particular, this
patch adds an option to expose quantized and rate-limited memory
information to web pages.  Web pages can only learn new data every 20
minutes, which helps mitigate attacks where the attacker compares two
or readings to extract side-channel information.  The patch also only
reports 100 distinct memory values, which (combined with the rate
limts) makes it difficult for attackers to learn about small changes in
memory use.

* page/MemoryInfo.cpp:
(WebCore):
(HeapSizeCache):
(WebCore::HeapSizeCache::HeapSizeCache):
(WebCore::HeapSizeCache::getCachedHeapSize):
(WebCore::HeapSizeCache::maybeUpdate):
(WebCore::HeapSizeCache::update):
(WebCore::HeapSizeCache::quantize):
(WebCore::MemoryInfo::MemoryInfo):
* page/Settings.cpp:
(WebCore::Settings::Settings):
* page/Settings.h:
(WebCore::Settings::setQuantizedMemoryInfoEnabled):
(WebCore::Settings::quantizedMemoryInfoEnabled):
(Settings):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (123855 => 123856)


--- trunk/Source/WebCore/ChangeLog	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/ChangeLog	2012-07-27 09:37:51 UTC (rev 123856)
@@ -1,3 +1,57 @@
+2012-07-27  Adam Barth  <[email protected]>
+
+        Add a Setting to expose quantized, rate-limited MemoryInfo values
+        https://bugs.webkit.org/show_bug.cgi?id=80444
+
+        Reviewed by Eric Seidel.
+
+        We do not currently expose real MemoryInfo objects to the web unless
+        the user opts in because we're worried that this memory information
+        could be used in side-channel attacks.
+
+        We've gotten feedback from a number of web app developers that this
+        information is very useful in tracking the performance of their
+        applications.  These developers use the setting in their testing labs
+        and regression harnesses to catch memory leaks and regressiosn early in
+        their development cycle.
+
+        Some of these developers have experimented with enabling this feature
+        within their enterprise and have found the memory data from the field
+        extremely useful in tracking down memory issues that slip through their
+        testing.
+
+        Based on this experience, they've asked whether we can enable this
+        functionality on a wider scale so they catch even more problems
+        including problems that don't manifest within their enterprise.
+        Because we're still worried about side-channel attacks, we don't want
+        to expose the raw data, so we've talked with these folks in more detail
+        to understand what information they find most valuable.
+
+        This patch is the result of those discussions.  In particular, this
+        patch adds an option to expose quantized and rate-limited memory
+        information to web pages.  Web pages can only learn new data every 20
+        minutes, which helps mitigate attacks where the attacker compares two
+        or readings to extract side-channel information.  The patch also only
+        reports 100 distinct memory values, which (combined with the rate
+        limts) makes it difficult for attackers to learn about small changes in
+        memory use.
+
+        * page/MemoryInfo.cpp:
+        (WebCore):
+        (HeapSizeCache):
+        (WebCore::HeapSizeCache::HeapSizeCache):
+        (WebCore::HeapSizeCache::getCachedHeapSize):
+        (WebCore::HeapSizeCache::maybeUpdate):
+        (WebCore::HeapSizeCache::update):
+        (WebCore::HeapSizeCache::quantize):
+        (WebCore::MemoryInfo::MemoryInfo):
+        * page/Settings.cpp:
+        (WebCore::Settings::Settings):
+        * page/Settings.h:
+        (WebCore::Settings::setQuantizedMemoryInfoEnabled):
+        (WebCore::Settings::quantizedMemoryInfoEnabled):
+        (Settings):
+
 2012-07-27  Vsevolod Vlasov  <[email protected]>
 
         Web Inspector: Move formatting support from _javascript_Source to UISourceCode.

Modified: trunk/Source/WebCore/bindings/js/ScriptGCEvent.cpp (123855 => 123856)


--- trunk/Source/WebCore/bindings/js/ScriptGCEvent.cpp	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/bindings/js/ScriptGCEvent.cpp	2012-07-27 09:37:51 UTC (rev 123856)
@@ -43,12 +43,12 @@
 
 using namespace JSC;
 
-void ScriptGCEvent::getHeapSize(size_t& usedHeapSize, size_t& totalHeapSize, size_t& heapSizeLimit)
+void ScriptGCEvent::getHeapSize(HeapInfo& info)
 {
     JSGlobalData* globalData = JSDOMWindow::commonJSGlobalData();
-    totalHeapSize = globalData->heap.capacity();
-    usedHeapSize = globalData->heap.size();
-    heapSizeLimit = 0;
+    info.totalJSHeapSize = globalData->heap.capacity();
+    info.usedJSHeapSize = globalData->heap.size();
+    info.jsHeapSizeLimit = 0;
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/js/ScriptGCEvent.h (123855 => 123856)


--- trunk/Source/WebCore/bindings/js/ScriptGCEvent.h	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/bindings/js/ScriptGCEvent.h	2012-07-27 09:37:51 UTC (rev 123856)
@@ -37,12 +37,25 @@
 
 class ScriptGCEventListener;
 
+struct HeapInfo {
+    HeapInfo()
+        : usedJSHeapSize(0)
+        , totalJSHeapSize(0)
+        , jsHeapSizeLimit(0)
+    {
+    }
+
+    size_t usedJSHeapSize;
+    size_t totalJSHeapSize;
+    size_t jsHeapSizeLimit;
+};
+
 class ScriptGCEvent
 {
 public:
     static void addEventListener(ScriptGCEventListener*) { }
     static void removeEventListener(ScriptGCEventListener*) { }
-    static void getHeapSize(size_t& usedHeapSize, size_t& totalHeapSize, size_t& heapSizeLimit);
+    static void getHeapSize(HeapInfo&);
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/bindings/v8/ScriptGCEvent.cpp (123855 => 123856)


--- trunk/Source/WebCore/bindings/v8/ScriptGCEvent.cpp	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/bindings/v8/ScriptGCEvent.cpp	2012-07-27 09:37:51 UTC (rev 123856)
@@ -71,13 +71,13 @@
     }
 }
 
-void ScriptGCEvent::getHeapSize(size_t& usedHeapSize, size_t& totalHeapSize, size_t& heapSizeLimit)
+void ScriptGCEvent::getHeapSize(HeapInfo& info)
 {
     v8::HeapStatistics heapStatistics;
     v8::V8::GetHeapStatistics(&heapStatistics);
-    usedHeapSize = heapStatistics.used_heap_size();
-    totalHeapSize = heapStatistics.total_heap_size();
-    heapSizeLimit = heapStatistics.heap_size_limit();
+    info.usedJSHeapSize = heapStatistics.used_heap_size();
+    info.totalJSHeapSize = heapStatistics.total_heap_size();
+    info.jsHeapSizeLimit = heapStatistics.heap_size_limit();
 }
 
 size_t ScriptGCEvent::getUsedHeapSize()

Modified: trunk/Source/WebCore/bindings/v8/ScriptGCEvent.h (123855 => 123856)


--- trunk/Source/WebCore/bindings/v8/ScriptGCEvent.h	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/bindings/v8/ScriptGCEvent.h	2012-07-27 09:37:51 UTC (rev 123856)
@@ -40,12 +40,26 @@
 
 class ScriptGCEventListener;
 
+struct HeapInfo {
+    HeapInfo()
+        : usedJSHeapSize(0)
+        , totalJSHeapSize(0)
+        , jsHeapSizeLimit(0)
+    {
+    }
+
+    size_t usedJSHeapSize;
+    size_t totalJSHeapSize;
+    size_t jsHeapSizeLimit;
+};
+
 class ScriptGCEvent
 {
 public:
     static void addEventListener(ScriptGCEventListener*);
     static void removeEventListener(ScriptGCEventListener*);
-    static void getHeapSize(size_t&, size_t&, size_t&);
+    static void getHeapSize(HeapInfo&);
+
 private:
     static void gcEpilogueCallback(v8::GCType type, v8::GCCallbackFlags flags);
     static void gcPrologueCallback(v8::GCType type, v8::GCCallbackFlags flags);

Modified: trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp (123855 => 123856)


--- trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/inspector/InspectorMemoryAgent.cpp	2012-07-27 09:37:51 UTC (rev 123856)
@@ -417,17 +417,15 @@
 
 static PassRefPtr<InspectorMemoryBlock> jsHeapInfo()
 {
-    size_t usedJSHeapSize;
-    size_t totalJSHeapSize;
-    size_t jsHeapSizeLimit;
-    ScriptGCEvent::getHeapSize(usedJSHeapSize, totalJSHeapSize, jsHeapSizeLimit);
+    HeapInfo info;
+    ScriptGCEvent::getHeapSize(info);
 
     RefPtr<InspectorMemoryBlock> jsHeapAllocated = InspectorMemoryBlock::create().setName(MemoryBlockName::jsHeapAllocated);
-    jsHeapAllocated->setSize(totalJSHeapSize);
+    jsHeapAllocated->setSize(static_cast<int>(info.totalJSHeapSize));
 
     RefPtr<TypeBuilder::Array<InspectorMemoryBlock> > children = TypeBuilder::Array<InspectorMemoryBlock>::create();
     RefPtr<InspectorMemoryBlock> jsHeapUsed = InspectorMemoryBlock::create().setName(MemoryBlockName::jsHeapUsed);
-    jsHeapUsed->setSize(usedJSHeapSize);
+    jsHeapUsed->setSize(static_cast<int>(info.usedJSHeapSize));
     children->addItem(jsHeapUsed);
 
     jsHeapAllocated->setChildren(children);

Modified: trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp (123855 => 123856)


--- trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/inspector/InspectorTimelineAgent.cpp	2012-07-27 09:37:51 UTC (rev 123856)
@@ -467,12 +467,10 @@
 
 void InspectorTimelineAgent::setHeapSizeStatistics(InspectorObject* record)
 {
-    size_t usedHeapSize = 0;
-    size_t totalHeapSize = 0;
-    size_t heapSizeLimit = 0;
-    ScriptGCEvent::getHeapSize(usedHeapSize, totalHeapSize, heapSizeLimit);
-    record->setNumber("usedHeapSize", usedHeapSize);
-    record->setNumber("totalHeapSize", totalHeapSize);
+    HeapInfo info;
+    ScriptGCEvent::getHeapSize(info);
+    record->setNumber("usedHeapSize", info.usedJSHeapSize);
+    record->setNumber("totalHeapSize", info.totalJSHeapSize);
 
     if (m_state->getBoolean(TimelineAgentState::includeMemoryDetails)) {
         RefPtr<InspectorObject> counters = InspectorObject::create();

Modified: trunk/Source/WebCore/page/MemoryInfo.cpp (123855 => 123856)


--- trunk/Source/WebCore/page/MemoryInfo.cpp	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/page/MemoryInfo.cpp	2012-07-27 09:37:51 UTC (rev 123856)
@@ -34,19 +34,119 @@
 #include "Frame.h"
 #include "ScriptGCEvent.h"
 #include "Settings.h"
+#include <limits>
+#include <wtf/CurrentTime.h>
+#include <wtf/MainThread.h>
 
 namespace WebCore {
 
+#if ENABLE(INSPECTOR)
+
+class HeapSizeCache {
+    WTF_MAKE_NONCOPYABLE(HeapSizeCache);
+public:
+    HeapSizeCache()
+        : m_lastUpdateTime(0)
+    {
+    }
+
+    void getCachedHeapSize(HeapInfo& info)
+    {
+        maybeUpdate();
+        info = m_info;
+    }
+
+private:
+    void maybeUpdate()
+    {
+        // We rate-limit queries to once every twenty minutes to make it more difficult
+        // for attackers to compare memory usage before and after some event.
+        const double TwentyMinutesInSeconds = 20 * 60;
+
+        double now = monotonicallyIncreasingTime();
+        if (now - m_lastUpdateTime >= TwentyMinutesInSeconds) {
+            update();
+            m_lastUpdateTime = now;
+        }
+    }
+
+    void update()
+    {
+        ScriptGCEvent::getHeapSize(m_info);
+        m_info.usedJSHeapSize = quantizeMemorySize(m_info.usedJSHeapSize);
+        m_info.totalJSHeapSize = quantizeMemorySize(m_info.totalJSHeapSize);
+        m_info.jsHeapSizeLimit = quantizeMemorySize(m_info.jsHeapSizeLimit);
+    }
+
+    double m_lastUpdateTime;
+
+    HeapInfo m_info;
+};
+
+// We quantize the sizes to make it more difficult for an attacker to see precise
+// impact of operations on memory. The values are used for performance tuning,
+// and hence don't need to be as refined when the value is large, so we threshold
+// at a list of exponentially separated buckets.
+size_t quantizeMemorySize(size_t size)
+{
+    const int numberOfBuckets = 100;
+    DEFINE_STATIC_LOCAL(Vector<size_t>, bucketSizeList, ());
+
+    ASSERT(isMainThread());
+    if (bucketSizeList.isEmpty()) {
+        bucketSizeList.resize(numberOfBuckets);
+
+        float sizeOfNextBucket = 10000000.0; // First bucket size is roughly 10M.
+        const float largestBucketSize = 4000000000.0; // Roughly 4GB.
+        // We scale with the Nth root of the ratio, so that we use all the bucktes.
+        const float scalingFactor = exp(log(largestBucketSize / sizeOfNextBucket) / numberOfBuckets);
+
+        size_t nextPowerOfTen = static_cast<size_t>(pow(10, floor(log10(sizeOfNextBucket)) + 1) + 0.5);
+        size_t granularity = nextPowerOfTen / 1000; // We want 3 signficant digits.
+
+        for (int i = 0; i < numberOfBuckets; ++i) {
+            size_t currentBucketSize = static_cast<size_t>(sizeOfNextBucket);
+            bucketSizeList[i] = currentBucketSize - (currentBucketSize % granularity);
+
+            sizeOfNextBucket *= scalingFactor;
+            if (sizeOfNextBucket >= nextPowerOfTen) {
+                if (std::numeric_limits<size_t>::max() / 10 <= nextPowerOfTen)
+                    nextPowerOfTen = std::numeric_limits<size_t>::max();                       
+                else {
+                    nextPowerOfTen *= 10;
+                    granularity *= 10;
+                }
+            }
+
+            // Watch out for overflow, if the range is too large for size_t.
+            if (i > 0 && bucketSizeList[i] < bucketSizeList[i - 1])
+                bucketSizeList[i] = std::numeric_limits<size_t>::max();
+        }
+    }
+
+    for (int i = 0; i < numberOfBuckets; ++i) {
+        if (size <= bucketSizeList[i])
+            return bucketSizeList[i];
+    }
+
+    return bucketSizeList[numberOfBuckets - 1];
+}
+
+#endif
+
 MemoryInfo::MemoryInfo(Frame* frame)
-        : m_totalJSHeapSize(0),
-          m_usedJSHeapSize(0),
-          m_jsHeapSizeLimit(0)
 {
-    if (frame && frame->settings() && frame->settings()->memoryInfoEnabled()) {
+    if (!frame || !frame->settings())
+        return;
+
 #if ENABLE(INSPECTOR)
-        ScriptGCEvent::getHeapSize(m_usedJSHeapSize, m_totalJSHeapSize, m_jsHeapSizeLimit);
+    if (frame->settings()->memoryInfoEnabled())
+        ScriptGCEvent::getHeapSize(m_info);
+    else if (true || frame->settings()->quantizedMemoryInfoEnabled()) {
+        DEFINE_STATIC_LOCAL(HeapSizeCache, heapSizeCache, ());
+        heapSizeCache.getCachedHeapSize(m_info);
+    }
 #endif
-    }
 }
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/page/MemoryInfo.h (123855 => 123856)


--- trunk/Source/WebCore/page/MemoryInfo.h	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/page/MemoryInfo.h	2012-07-27 09:37:51 UTC (rev 123856)
@@ -31,6 +31,7 @@
 #ifndef MemoryInfo_h
 #define MemoryInfo_h
 
+#include "ScriptGCEvent.h"
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
 
@@ -42,18 +43,18 @@
 public:
     static PassRefPtr<MemoryInfo> create(Frame* frame) { return adoptRef(new MemoryInfo(frame)); }
 
-    size_t totalJSHeapSize() const { return m_totalJSHeapSize; }
-    size_t usedJSHeapSize() const { return m_usedJSHeapSize; }
-    size_t jsHeapSizeLimit() const { return m_jsHeapSizeLimit; }
+    size_t totalJSHeapSize() const { return m_info.totalJSHeapSize; }
+    size_t usedJSHeapSize() const { return m_info.usedJSHeapSize; }
+    size_t jsHeapSizeLimit() const { return m_info.jsHeapSizeLimit; }
 
 private:
     explicit MemoryInfo(Frame*);
 
-    size_t m_totalJSHeapSize;
-    size_t m_usedJSHeapSize;
-    size_t m_jsHeapSizeLimit;
+    HeapInfo m_info;
 };
 
+size_t quantizeMemorySize(size_t);
+
 } // namespace WebCore
 
 #endif // MemoryInfo_h

Modified: trunk/Source/WebCore/page/Settings.cpp (123855 => 123856)


--- trunk/Source/WebCore/page/Settings.cpp	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/page/Settings.cpp	2012-07-27 09:37:51 UTC (rev 123856)
@@ -242,6 +242,7 @@
     , m_unifiedTextCheckerEnabled(false)
 #endif
     , m_memoryInfoEnabled(false)
+    , m_quantizedMemoryInfoEnabled(false)
     , m_interactiveFormValidation(false)
     , m_usePreHTML5ParserQuirks(false)
     , m_hyperlinkAuditingEnabled(false)

Modified: trunk/Source/WebCore/page/Settings.h (123855 => 123856)


--- trunk/Source/WebCore/page/Settings.h	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebCore/page/Settings.h	2012-07-27 09:37:51 UTC (rev 123856)
@@ -453,6 +453,9 @@
         void setMemoryInfoEnabled(bool flag) { m_memoryInfoEnabled = flag; }
         bool memoryInfoEnabled() const { return m_memoryInfoEnabled; }
 
+        void setQuantizedMemoryInfoEnabled(bool flag) { m_quantizedMemoryInfoEnabled = flag; }
+        bool quantizedMemoryInfoEnabled() const { return m_quantizedMemoryInfoEnabled; }
+
         // This setting will be removed when an HTML5 compatibility issue is
         // resolved and WebKit implementation of interactive validation is
         // completed. See http://webkit.org/b/40520, http://webkit.org/b/40747,
@@ -731,11 +734,12 @@
 #if ENABLE(FULLSCREEN_API)
         bool m_fullScreenAPIEnabled : 1;
 #endif
-        bool m_asynchronousSpellCheckingEnabled: 1;
-        bool m_unifiedTextCheckerEnabled: 1;
-        bool m_memoryInfoEnabled: 1;
-        bool m_interactiveFormValidation: 1;
-        bool m_usePreHTML5ParserQuirks: 1;
+        bool m_asynchronousSpellCheckingEnabled : 1;
+        bool m_unifiedTextCheckerEnabled : 1;
+        bool m_memoryInfoEnabled : 1;
+        bool m_quantizedMemoryInfoEnabled : 1;
+        bool m_interactiveFormValidation : 1;
+        bool m_usePreHTML5ParserQuirks : 1;
         bool m_hyperlinkAuditingEnabled : 1;
         bool m_crossOriginCheckInGetMatchedCSSRulesDisabled : 1;
         bool m_forceCompositingMode : 1;

Modified: trunk/Source/WebKit/chromium/WebKit.gypi (123855 => 123856)


--- trunk/Source/WebKit/chromium/WebKit.gypi	2012-07-27 09:36:18 UTC (rev 123855)
+++ trunk/Source/WebKit/chromium/WebKit.gypi	2012-07-27 09:37:51 UTC (rev 123856)
@@ -125,6 +125,7 @@
             'tests/ListenerLeakTest.cpp',
             'tests/LocalizedDateICUTest.cpp',
             'tests/LocalizedNumberICUTest.cpp',
+            'tests/MemoryInfo.cpp',
             'tests/MockCCQuadCuller.h',
             'tests/OpaqueRectTrackingContentLayerDelegateTest.cpp',
             'tests/OpenTypeVerticalDataTest.cpp',

Copied: trunk/Source/WebKit/chromium/tests/MemoryInfo.cpp (from rev 123854, trunk/Source/WebCore/page/MemoryInfo.cpp) (0 => 123856)


--- trunk/Source/WebKit/chromium/tests/MemoryInfo.cpp	                        (rev 0)
+++ trunk/Source/WebKit/chromium/tests/MemoryInfo.cpp	2012-07-27 09:37:51 UTC (rev 123856)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 Google 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:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * 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.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
+ * OWNER 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"
+
+#include "MemoryInfo.h"
+
+#include <gtest/gtest.h>
+
+using namespace WebCore;
+
+namespace {
+
+TEST(MemoryInfo, quantizeMemorySize)
+{
+    EXPECT_EQ(10000000u, quantizeMemorySize(1024));
+    EXPECT_EQ(10000000u, quantizeMemorySize(1024 * 1024));
+    EXPECT_EQ(410000000u, quantizeMemorySize(389472983));
+    EXPECT_EQ(39600000u, quantizeMemorySize(38947298));
+    EXPECT_EQ(29400000u, quantizeMemorySize(28947298));
+    EXPECT_EQ(19300000u, quantizeMemorySize(18947298));
+    EXPECT_EQ(14300000u, quantizeMemorySize(13947298));
+    EXPECT_EQ(10000000u, quantizeMemorySize(3894729));
+    EXPECT_EQ(10000000u, quantizeMemorySize(389472));
+    EXPECT_EQ(10000000u, quantizeMemorySize(38947));
+    EXPECT_EQ(10000000u, quantizeMemorySize(3894));
+    EXPECT_EQ(10000000u, quantizeMemorySize(389));
+    EXPECT_EQ(10000000u, quantizeMemorySize(38));
+    EXPECT_EQ(10000000u, quantizeMemorySize(3));
+    EXPECT_EQ(10000000u, quantizeMemorySize(1));
+    EXPECT_EQ(10000000u, quantizeMemorySize(0));
+}
+
+} // namespace
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to