JSHeap and FastMallocStatistics based memory measurement for performance-tests
authorzoltan@webkit.org <zoltan@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Aug 2012 16:21:09 +0000 (16:21 +0000)
committerzoltan@webkit.org <zoltan@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 9 Aug 2012 16:21:09 +0000 (16:21 +0000)
https://bugs.webkit.org/show_bug.cgi?id=90858

PerformanceTests:

Reviewed Ryosuke Niwa.

Measure the memory usage of the performancetests with the help of the windows.memory.usedJSHeapSize
object and the window.internals.fastMallocStatistics() function call.

* resources/runner.js:
(PerfTestRunner.logStatistics):
(PerfTestRunner.printStatistics):
(PerfTestRunner.storeHeapResults):
(PerfTestRunner.getUsedFastMallocHeap):
(PerfTestRunner.getUsedJSHeap):
(PerfTestRunner.getAndPrintMemoryStatistics):
(PerfTestRunner.ignoreWarmUpAndLog):
(PerfTestRunner.initAndStartLoop):

Tools:

Reviewed by Ryosuke Niwa.

Measure the memory usage of the performancetests with the help of the windows.memory.usedJSHeapSize
object and the window.internals.fastMallocStatistics() function call.

* Scripts/webkitpy/performance_tests/perftest.py:
(PerfTest):
(PerfTest.parse_output):
(PerfTest.output_statistics):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@125178 268f45cc-cd09-0410-ab3c-d52691b4dbfc

PerformanceTests/ChangeLog
PerformanceTests/resources/runner.js
Tools/ChangeLog
Tools/Scripts/webkitpy/performance_tests/perftest.py

index 58fbfd1..6ae65ee 100644 (file)
@@ -1,3 +1,23 @@
+2012-08-09  Zoltan Horvath  <zoltan@webkit.org>
+
+        JSHeap and FastMallocStatistics based memory measurement for performance-tests
+        https://bugs.webkit.org/show_bug.cgi?id=90858
+
+        Reviewed Ryosuke Niwa.
+
+        Measure the memory usage of the performancetests with the help of the windows.memory.usedJSHeapSize
+        object and the window.internals.fastMallocStatistics() function call.
+
+        * resources/runner.js:
+        (PerfTestRunner.logStatistics):
+        (PerfTestRunner.printStatistics):
+        (PerfTestRunner.storeHeapResults):
+        (PerfTestRunner.getUsedFastMallocHeap):
+        (PerfTestRunner.getUsedJSHeap):
+        (PerfTestRunner.getAndPrintMemoryStatistics):
+        (PerfTestRunner.ignoreWarmUpAndLog):
+        (PerfTestRunner.initAndStartLoop):
+
 2012-08-08  Benjamin Poulain  <benjamin@webkit.org>
 
         Calling internals from the performance test runner prevents manual running
index d7dcfa0..94242e8 100755 (executable)
@@ -89,14 +89,14 @@ PerfTestRunner.computeStatistics = function (times, unit) {
     return result;
 }
 
-PerfTestRunner.logStatistics = function (times) {
-    this.log("");
-    var statistics = this.computeStatistics(times, this.unit);
-    this.printStatistics(statistics);
+PerfTestRunner.logStatistics = function (values, unit, title) {
+    var statistics = this.computeStatistics(values, unit);
+    this.printStatistics(statistics, title);
 }
 
-PerfTestRunner.printStatistics = function (statistics) {
+PerfTestRunner.printStatistics = function (statistics, title) {
     this.log("");
+    this.log(title);
     this.log("avg " + statistics.mean + " " + statistics.unit);
     this.log("median " + statistics.median + " " + statistics.unit);
     this.log("stdev " + statistics.stdev + " " + statistics.unit);
@@ -127,7 +127,11 @@ PerfTestRunner._runLoop = function () {
     } else {
         if (this._description)
             this.log("Description: " + this._description);
-        this.logStatistics(this._results);
+        this.logStatistics(this._results, this.unit, "Time:");
+        if (window.internals) {
+            this.logStatistics(this._jsHeapResults, "bytes", "JS Heap:");
+            this.logStatistics(this._fastMallocHeapResults, "bytes", "FastMalloc:");
+        }
         if (this._logLines) {
             var logLines = this._logLines;
             this._logLines = null;
@@ -160,6 +164,32 @@ PerfTestRunner._runner = function () {
     this._runLoop();
 }
 
+PerfTestRunner.storeHeapResults = function() {
+    if (!window.internals)
+        return;
+    this._jsHeapResults.push(this.getUsedJSHeap());
+    this._fastMallocHeapResults.push(this.getUsedFastMallocHeap());
+}
+
+PerfTestRunner.getUsedFastMallocHeap = function() {
+    var stats = window.internals.fastMallocStatistics();
+    return stats.committedVMBytes - stats.freeListBytes;
+}
+
+PerfTestRunner.getUsedJSHeap = function() {
+    return console.memory.usedJSHeapSize;
+}
+
+PerfTestRunner.getAndPrintMemoryStatistics = function() {
+    if (!window.internals)
+        return;
+    var jsMemoryStats = PerfTestRunner.computeStatistics([PerfTestRunner.getUsedJSHeap()], "bytes");
+    PerfTestRunner.printStatistics(jsMemoryStats, "JS Heap:");
+
+    var fastMallocMemoryStats = PerfTestRunner.computeStatistics([PerfTestRunner.getUsedFastMallocHeap()], "bytes");
+    PerfTestRunner.printStatistics(fastMallocMemoryStats, "FastMalloc:");
+}
+
 PerfTestRunner.ignoreWarmUpAndLog = function (result) {
     this._completedRuns++;
 
@@ -168,6 +198,7 @@ PerfTestRunner.ignoreWarmUpAndLog = function (result) {
         this.log("Ignoring warm-up run (" + labeledResult + ")");
     else {
         this._results.push(result);
+        this.storeHeapResults();
         this.log(labeledResult);
     }
 }
@@ -176,6 +207,8 @@ PerfTestRunner.initAndStartLoop = function() {
     this._completedRuns = -1;
     this.customRunFunction = null;
     this._results = [];
+    this._jsHeapResults = [];
+    this._fastMallocHeapResults = [];
     this._logLines = window.testRunner ? [] : null;
     this.log("Running " + this._runCount + " times");
     this._runLoop();
index ef9efc8..8cceb8c 100644 (file)
@@ -1,3 +1,18 @@
+2012-08-09  Zoltan Horvath  <zoltan@webkit.org>
+
+        JSHeap and FastMallocStatistics based memory measurement for performance-tests
+        https://bugs.webkit.org/show_bug.cgi?id=90858
+
+        Reviewed by Ryosuke Niwa.
+
+        Measure the memory usage of the performancetests with the help of the windows.memory.usedJSHeapSize
+        object and the window.internals.fastMallocStatistics() function call.
+
+        * Scripts/webkitpy/performance_tests/perftest.py:
+        (PerfTest):
+        (PerfTest.parse_output):
+        (PerfTest.output_statistics):
+
 2012-08-09  Csaba Osztrogon√°c  <ossy@webkit.org>
 
         [Qt][Win] Build system bug revealed by r124835
index 8aac78f..ff7e291 100644 (file)
@@ -103,8 +103,6 @@ class PerfTest(object):
         # Following is for html5.html
         re.compile(re.escape("""Blocked access to external URL http://www.whatwg.org/specs/web-apps/current-work/"""))]
 
-    _statistics_keys = ['avg', 'median', 'stdev', 'min', 'max']
-
     def _should_ignore_line_in_parser_test_result(self, line):
         if not line:
             return True
@@ -113,48 +111,59 @@ class PerfTest(object):
                 return True
         return False
 
+    _statistics_keys = ['avg', 'median', 'stdev', 'min', 'max', 'unit']
+    _result_classes = ['Time:', 'JS Heap:', 'FastMalloc:']
+
     def parse_output(self, output):
         got_a_result = False
         test_failed = False
-        results = {}
+        results = dict([(name, dict()) for name in self._result_classes])
         score_regex = re.compile(r'^(?P<key>' + r'|'.join(self._statistics_keys) + r')\s+(?P<value>[0-9\.]+)\s*(?P<unit>.*)')
         description_regex = re.compile(r'^Description: (?P<description>.*)$', re.IGNORECASE)
         description_string = ""
-        unit = "ms"
+        result_class_regex = re.compile(r'^(?P<resultclass>' + r'|'.join(self._result_classes) + ')')
 
+        result_class = ""
         for line in re.split('\n', output.text):
             description = description_regex.match(line)
             if description:
                 description_string = description.group('description')
                 continue
 
+            result_class_match = result_class_regex.match(line)
+            if result_class_match:
+                result_class = result_class_match.group('resultclass')
+                continue
+
             score = score_regex.match(line)
             if score:
-                results[score.group('key')] = float(score.group('value'))
-                if score.group('unit'):
-                    unit = score.group('unit')
+                key = score.group('key')
+                value = float(score.group('value'))
+                unit = score.group('unit')
+                results[result_class]['unit'] = unit
+                results[result_class][key] = value
                 continue
 
             if not self._should_ignore_line_in_parser_test_result(line):
                 test_failed = True
                 _log.error(line)
 
-        if test_failed or set(self._statistics_keys) != set(results.keys()):
+        if test_failed or set(self._statistics_keys) != set(results[self._result_classes[0]].keys()):
             return None
 
-        results['unit'] = unit
-
         test_name = re.sub(r'\.\w+$', '', self._test_name)
-        self.output_statistics(test_name, results, description_string)
-
+        self.output_statistics(test_name, results[self._result_classes[0]], description_string)
+        if results[self._result_classes[1]] and results[self._result_classes[2]]:
+            self.output_statistics(test_name + "/JSHeap", results[self._result_classes[1]])
+            self.output_statistics(test_name + "/FastMalloc", results[self._result_classes[2]])
         return {test_name: results}
 
-    def output_statistics(self, test_name, results, description_string):
+    def output_statistics(self, test_name, results, description_string=None):
         unit = results['unit']
         if description_string:
             _log.info('DESCRIPTION: %s' % description_string)
         _log.info('RESULT %s= %s %s' % (test_name.replace('/', ': '), results['avg'], unit))
-        _log.info(', '.join(['%s= %s %s' % (key, results[key], unit) for key in self._statistics_keys[1:]]))
+        _log.info(', '.join(['%s= %s %s' % (key, results[key], unit) for key in self._statistics_keys[1:5]]))
 
 
 class ChromiumStylePerfTest(PerfTest):