]> git.donarmstrong.com Git - dactyl.git/blob - common/tests/functional/shared-modules/performance.js
Initial import of 1.0~b6
[dactyl.git] / common / tests / functional / shared-modules / performance.js
1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
3  *
4  * The contents of this file are subject to the Mozilla Public License Version
5  * 1.1 (the "License"); you may not use this file except in compliance with
6  * the License. You may obtain a copy of the License at
7  * http://www.mozilla.org/MPL/
8  *
9  * Software distributed under the License is distributed on an "AS IS" basis,
10  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11  * for the specific language governing rights and limitations under the
12  * License.
13  *
14  * The Original Code is MozMill Test code.
15  *
16  * The Initial Developer of the Original Code is the Mozilla Foundation.
17  * Portions created by the Initial Developer are Copyright (C) 2010
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  *   Geo Mealer <gmealer@mozilla.com>
22  *
23  * Alternatively, the contents of this file may be used under the terms of
24  * either the GNU General Public License Version 2 or later (the "GPL"), or
25  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26  * in which case the provisions of the GPL or the LGPL are applicable instead
27  * of those above. If you wish to allow use of your version of this file only
28  * under the terms of either the GPL or the LGPL, and not to allow others to
29  * use your version of this file under the terms of the MPL, indicate your
30  * decision by deleting the provisions above and replace them with the notice
31  * and other provisions required by the GPL or the LGPL. If you do not delete
32  * the provisions above, a recipient may use your version of this file under
33  * the terms of any one of the MPL, the GPL or the LGPL.
34  *
35  * ***** END LICENSE BLOCK ***** */
36
37 // Paths for mapped memory and allocated memory, respectively.  Use as
38 // keys to access the appropriate memory reporters.
39 const PATH_MAPPED = "malloc/mapped";
40 const PATH_ALLOCATED = "malloc/allocated";
41
42 // Returning this as a numeric constant to simplify memory calculations
43 // Neither allocated nor mapped should be 0 in real life.
44 const MEMORY_UNAVAILABLE = "0";
45
46 // INITIALIZE MEMORY REPORTERS
47
48 // gMemReporters will be a dictionary, key=path and val=reporter
49 // See initMemReporters() for how it's used.
50 var gMemReporters = {};
51
52 /**
53  * Initialize the static memory reporters
54  *
55  * Called during module initialization, below.
56  * See also aboutMemory.js in Firefox code
57  */
58 function initMemReporters() {
59   var memMgr = Cc["@mozilla.org/memory-reporter-manager;1"].
60                getService(Ci.nsIMemoryReporterManager);
61
62   // Grab all the memory reporters, load into gMemReporters as a dictionary
63   var e = memMgr.enumerateReporters();
64   while (e.hasMoreElements()) {
65     var memReporter = e.getNext().QueryInterface(Ci.nsIMemoryReporter);
66     gMemReporters[memReporter.path] = memReporter;
67   }
68 }
69
70 initMemReporters();
71
72 /**
73  * PERFORMANCE TRACER
74  *
75  * Keeps a trace log of both actions and performance statistics
76  * throughout a test run.
77  *
78  * Performance stats currently include mapped and allocated memory.
79  * More stats will be added as methods to read them are discovered.
80  *
81  * Usage:
82  *   Before test, create a new PerfTracer named after the test.
83  *     Ex: var perf = new performance.PerfTracer("MyTestFunc");
84  *
85  *   During test, after notable actions call PerfTracer.addCheckpoint(label)
86  *     Ex: perf.addCheckpoint("Opened preferences dialog");
87  *
88  *   After test, call PerfTracer.finish()
89  *     Ex: perf.finish();
90  */
91
92 /**
93  * PerfTracer constructor
94  *
95  * @param {string} name
96  *        Name of the tracer, currently used in the output title
97  */
98 function PerfTracer(name) {
99   if (!name) {
100     throw new Error(arguments.callee.name + ": name not supplied.");
101   }
102
103   this.clearLog();
104   this._name = name;
105 }
106
107 PerfTracer.prototype = {
108   // UTILITY METHODS
109
110   /**
111    * Format a single result for printing
112    *
113    * @param {object} result
114    *        Result as created by addCheckpoint()
115    *        Elements: timestamp {Date}   - date/time
116    *                  allocated {number} - allocated memory
117    *                  mapped {number}    - mapped memory
118    *                  label {string}     - label for result
119    *
120    * @returns Result string formatted for output
121    * @type {string}
122    */
123   _formatResult : function PerfTracer_formatResult(result) {
124     var resultString = result.timestamp.toUTCString() + " | " +
125                        result.allocated + " | " +
126                        result.mapped + " | " +
127                        result.label + "\n";
128
129     return resultString;
130   },
131
132   // PUBLIC INTERFACE
133
134   /**
135    * Get a memory value from a reporter
136    *
137    * @param {string} path
138    *        Path of memory reporter (e.g. PATH_MAPPED)
139    * @returns Memory value from requested reporter, MEMORY_UNAVAILABLE if
140    *          not found
141    * @type {number}
142    */
143   getMemory : function PerfTracer_getMemory(path) {
144     var val = MEMORY_UNAVAILABLE;
145     if (path in gMemReporters) {
146       val = gMemReporters[path].memoryUsed;
147     }
148
149     return val;
150   },
151
152   /**
153    * Clears the tracker log and starts over
154    */
155   clearLog : function PerfTracer_clearLog() {
156     this._log = new Array();
157   },
158
159   /**
160    * Adds a checkpoint to the tracker log, with time and performance info
161    *
162    * @param {string} aLabel
163    *        Label attached to performance results. Typically should be
164    *        whatever the test just did.
165    */
166   addCheckpoint : function PerfTracer_addCheckpoint(aLabel) {
167     var result = {
168       label:     aLabel,
169       timestamp: new Date(),
170       mapped:    this.getMemory(PATH_MAPPED),
171       allocated: this.getMemory(PATH_ALLOCATED)
172     };
173
174     this._log.push(result);
175   },
176
177   /**
178    * Prints all results to console.
179    * XXX: make this work with output files
180    */
181   finish : function PerfTracer_finish() {
182     // Title
183     var title = "Performance Trace (" + this._name + ")";
184
185     // Separator
186     var sep = "";
187     for(var i = 0; i < title.length; i++) {
188       sep += "=";
189     }
190
191     dump(sep + "\n");
192     dump(title + "\n");
193     dump(sep + "\n");
194
195     // Log
196     for(i = 0; i < this._log.length; i++) {
197       dump(this._formatResult(this._log[i]));
198     }
199   }
200 }
201
202 // Exported constants
203 exports.PATH_MAPPED = PATH_MAPPED;
204 exports.PATH_ALLOCATED = PATH_ALLOCATED;
205 exports.MEMORY_UNAVAILABLE = MEMORY_UNAVAILABLE;
206
207 // Exported class
208 exports.PerfTracer = PerfTracer;