src/cm/media/js/lib/yui/yui3.0.0/build/profiler/profiler-debug.js
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 /*
       
     2 Copyright (c) 2009, Yahoo! Inc. All rights reserved.
       
     3 Code licensed under the BSD License:
       
     4 http://developer.yahoo.net/yui/license.txt
       
     5 version: 3.0.0
       
     6 build: 1549
       
     7 */
       
     8 YUI.add('profiler', function(Y) {
       
     9 
       
    10     /**
       
    11      * The YUI JavaScript profiler.
       
    12      * @module profiler
       
    13      * @requires yui
       
    14      */
       
    15      
       
    16     //-------------------------------------------------------------------------
       
    17     // Private Variables and Functions
       
    18     //-------------------------------------------------------------------------
       
    19     
       
    20     var container   = {},   //Container object on which to put the original unprofiled methods.
       
    21         report      = {},   //Profiling information for functions
       
    22         stopwatches = {},   //Additional stopwatch information
       
    23         
       
    24         WATCH_STARTED   = 0,
       
    25         WATCH_STOPPED   = 1,
       
    26         WATCH_PAUSED    = 2,    
       
    27         
       
    28         //shortcuts
       
    29         L   = Y.Lang;
       
    30 
       
    31     /* (intentionally not documented)
       
    32      * Creates a report object with the given name.
       
    33      * @param {String} name The name to store for the report object.
       
    34      * @return {Void}
       
    35      * @method createReport
       
    36      * @private
       
    37      */
       
    38     function createReport(name){
       
    39         report[name] = {
       
    40             calls: 0,
       
    41             max: 0,
       
    42             min: 0,
       
    43             avg: 0,
       
    44             points: []
       
    45         };
       
    46         return report[name];
       
    47     }
       
    48     
       
    49     /* (intentionally not documented)
       
    50      * Called when a method ends execution. Marks the start and end time of the 
       
    51      * method so it can calculate how long the function took to execute. Also 
       
    52      * updates min/max/avg calculations for the function.
       
    53      * @param {String} name The name of the function to mark as stopped.
       
    54      * @param {int} duration The number of milliseconds it took the function to
       
    55      *      execute.
       
    56      * @return {Void}
       
    57      * @method saveDataPoint
       
    58      * @private
       
    59      * @static
       
    60      */
       
    61     function saveDataPoint(name, duration){
       
    62 
       
    63         //get the function data
       
    64         var functionData /*:Object*/ = report[name];
       
    65         
       
    66         //just in case clear() was called
       
    67         if (!functionData){
       
    68             functionData = createReport(name);
       
    69         }
       
    70     
       
    71         //increment the calls
       
    72         functionData.calls++;
       
    73         functionData.points.push(duration);
       
    74 
       
    75         //if it's already been called at least once, do more complex calculations
       
    76         if (functionData.calls > 1) {
       
    77             functionData.avg = ((functionData.avg*(functionData.calls-1))+duration)/functionData.calls;
       
    78             functionData.min = Math.min(functionData.min, duration);
       
    79             functionData.max = Math.max(functionData.max, duration);
       
    80         } else {
       
    81             functionData.avg = duration;
       
    82             functionData.min = duration;
       
    83             functionData.max = duration;
       
    84         }                             
       
    85     
       
    86     }
       
    87     
       
    88     //-------------------------------------------------------------------------
       
    89     // Public Interface
       
    90     //-------------------------------------------------------------------------
       
    91     
       
    92     /**
       
    93      * Profiles functions in JavaScript.
       
    94      * @class Profiler
       
    95      * @static
       
    96      */
       
    97     Y.Profiler = {
       
    98     
       
    99         //-------------------------------------------------------------------------
       
   100         // Utility Methods
       
   101         //-------------------------------------------------------------------------        
       
   102         
       
   103         /**
       
   104          * Removes all report data from the profiler.
       
   105          * @param {String} name (Optional) The name of the report to clear. If
       
   106          *      omitted, then all report data is cleared.
       
   107          * @return {Void}
       
   108          * @method clear
       
   109          * @static
       
   110          */
       
   111         clear: function(name){
       
   112             if (L.isString(name)){
       
   113                 delete report[name];
       
   114                 delete stopwatches[name];
       
   115             } else {
       
   116                 report = {};
       
   117                 stopwatches = {};
       
   118             }
       
   119         },
       
   120 
       
   121         /**
       
   122          * Returns the uninstrumented version of a function/object.
       
   123          * @param {String} name The name of the function/object to retrieve.
       
   124          * @return {Function|Object} The uninstrumented version of a function/object.
       
   125          * @method getOriginal
       
   126          * @static
       
   127          */    
       
   128         getOriginal: function(name){
       
   129             return container[name];
       
   130         },
       
   131     
       
   132         /**
       
   133          * Instruments a method to have profiling calls.
       
   134          * @param {String} name The name of the report for the function.
       
   135          * @param {Function} method The function to instrument.
       
   136          * @return {Function} An instrumented version of the function.
       
   137          * @method instrument
       
   138          * @static
       
   139          */
       
   140         instrument: function(name, method){
       
   141         
       
   142             //create instrumented version of function
       
   143             var newMethod = function () {
       
   144     
       
   145                 var start = new Date(),
       
   146                     retval = method.apply(this, arguments),
       
   147                     stop = new Date();
       
   148                 
       
   149                 saveDataPoint(name, stop-start);
       
   150                 
       
   151                 return retval;                
       
   152             
       
   153             };     
       
   154 
       
   155             //copy the function properties over
       
   156             Y.mix(newMethod, method);
       
   157             
       
   158             //assign prototype and flag as being profiled
       
   159             newMethod.__yuiProfiled = true;
       
   160             newMethod.prototype = method.prototype;
       
   161             
       
   162             //store original method
       
   163             container[name] = method;
       
   164             container[name].__yuiFuncName = name;
       
   165             
       
   166             //create the report
       
   167             createReport(name);
       
   168 
       
   169             //return the new method
       
   170             return newMethod;
       
   171         },    
       
   172         
       
   173         //-------------------------------------------------------------------------
       
   174         // Stopwatch Methods
       
   175         //-------------------------------------------------------------------------        
       
   176         
       
   177         /**
       
   178          * Pauses profiling information for a given name.
       
   179          * @param {String} name The name of the data point.
       
   180          * @return {Void}
       
   181          * @method pause
       
   182          * @static
       
   183          */        
       
   184         pause: function(name){
       
   185             var now = new Date(),
       
   186                 stopwatch = stopwatches[name];
       
   187                 
       
   188             if (stopwatch && stopwatch.state == WATCH_STARTED){
       
   189                 stopwatch.total += (now - stopwatch.start);
       
   190                 stopwatch.start = 0;
       
   191                 stopwatch.state = WATCH_PAUSED;
       
   192             }
       
   193         
       
   194         },
       
   195         
       
   196         /**
       
   197          * Start profiling information for a given name. The name cannot be the name
       
   198          * of a registered function or object. This is used to start timing for a
       
   199          * particular block of code rather than instrumenting the entire function.
       
   200          * @param {String} name The name of the data point.
       
   201          * @return {Void}
       
   202          * @method start
       
   203          * @static
       
   204          */
       
   205         start: function(name){
       
   206             if(container[name]){
       
   207                 throw new Error("Cannot use '" + name + "' for profiling through start(), name is already in use.");
       
   208             } else {
       
   209             
       
   210                 //create report if necessary
       
   211                 if (!report[name]){
       
   212                     createReport(name);
       
   213                 }
       
   214                 
       
   215                 //create stopwatch object if necessary
       
   216                 if (!stopwatches[name]){             
       
   217                     stopwatches[name] = {
       
   218                         state: WATCH_STOPPED,
       
   219                         start: 0,
       
   220                         total: 0
       
   221                     };
       
   222                 }
       
   223                 
       
   224                 if (stopwatches[name].state == WATCH_STOPPED){
       
   225                     stopwatches[name].state = WATCH_STARTED;
       
   226                     stopwatches[name].start = new Date();                    
       
   227                 }
       
   228 
       
   229             }
       
   230         },
       
   231         
       
   232         /**
       
   233          * Stops profiling information for a given name.
       
   234          * @param {String} name The name of the data point.
       
   235          * @return {Void}
       
   236          * @method stop
       
   237          * @static
       
   238          */
       
   239         stop: function(name){
       
   240             var now = new Date(),
       
   241                 stopwatch = stopwatches[name];
       
   242                 
       
   243             if (stopwatch){
       
   244                 if (stopwatch.state == WATCH_STARTED){
       
   245                     saveDataPoint(name, stopwatch.total + (now - stopwatch.start));                    
       
   246                 } else if (stopwatch.state == WATCH_PAUSED){
       
   247                     saveDataPoint(name, stopwatch.total);
       
   248                 }
       
   249                 
       
   250                 //reset stopwatch information
       
   251                 stopwatch.start = 0;
       
   252                 stopwatch.total = 0;
       
   253                 stopwatch.state = WATCH_STOPPED;                
       
   254             }
       
   255         },
       
   256     
       
   257         //-------------------------------------------------------------------------
       
   258         // Reporting Methods
       
   259         //-------------------------------------------------------------------------    
       
   260         
       
   261         /**
       
   262          * Returns the average amount of time (in milliseconds) that the function
       
   263          * with the given name takes to execute.
       
   264          * @param {String} name The name of the function whose data should be returned.
       
   265          *      If an object type method, it should be 'constructor.prototype.methodName';
       
   266          *      a normal object method would just be 'object.methodName'.
       
   267          * @return {float} The average time it takes the function to execute.
       
   268          * @method getAverage
       
   269          * @static
       
   270          */
       
   271         getAverage : function (name /*:String*/) /*:float*/ {
       
   272             return report[name].avg;
       
   273         },
       
   274     
       
   275         /**
       
   276          * Returns the number of times that the given function has been called.
       
   277          * @param {String} name The name of the function whose data should be returned.
       
   278          * @return {int} The number of times the function was called.
       
   279          * @method getCallCount
       
   280          * @static
       
   281          */
       
   282         getCallCount : function (name /*:String*/) /*:int*/ {
       
   283             return report[name].calls;    
       
   284         },
       
   285         
       
   286         /**
       
   287          * Returns the maximum amount of time (in milliseconds) that the function
       
   288          * with the given name takes to execute.
       
   289          * @param {String} name The name of the function whose data should be returned.
       
   290          *      If an object type method, it should be 'constructor.prototype.methodName';
       
   291          *      a normal object method would just be 'object.methodName'.
       
   292          * @return {float} The maximum time it takes the function to execute.
       
   293          * @method getMax
       
   294          * @static
       
   295          */
       
   296         getMax : function (name /*:String*/) /*:int*/ {
       
   297             return report[name].max;
       
   298         },
       
   299         
       
   300         /**
       
   301          * Returns the minimum amount of time (in milliseconds) that the function
       
   302          * with the given name takes to execute.
       
   303          * @param {String} name The name of the function whose data should be returned.
       
   304          *      If an object type method, it should be 'constructor.prototype.methodName';
       
   305          *      a normal object method would just be 'object.methodName'.
       
   306          * @return {float} The minimum time it takes the function to execute.
       
   307          * @method getMin
       
   308          * @static
       
   309          */
       
   310         getMin : function (name /*:String*/) /*:int*/ {
       
   311             return report[name].min;
       
   312         },
       
   313     
       
   314         /**
       
   315          * Returns an object containing profiling data for a single function.
       
   316          * The object has an entry for min, max, avg, calls, and points).
       
   317          * @return {Object} An object containing profile data for a given function.
       
   318          * @method getFunctionReport
       
   319          * @static
       
   320          * @deprecated Use getReport() instead.
       
   321          */
       
   322         getFunctionReport : function (name /*:String*/) /*:Object*/ {
       
   323             return report[name];
       
   324         },
       
   325     
       
   326         /**
       
   327          * Returns an object containing profiling data for a single function.
       
   328          * The object has an entry for min, max, avg, calls, and points).
       
   329          * @return {Object} An object containing profile data for a given function.
       
   330          * @method getReport
       
   331          * @static
       
   332          */
       
   333         getReport : function (name /*:String*/) /*:Object*/ {
       
   334             return report[name];
       
   335         },
       
   336     
       
   337         /**
       
   338          * Returns an object containing profiling data for all of the functions 
       
   339          * that were profiled. The object has an entry for each function and 
       
   340          * returns all information (min, max, average, calls, etc.) for each
       
   341          * function.
       
   342          * @return {Object} An object containing all profile data.
       
   343          * @static
       
   344          */
       
   345         getFullReport : function (filter /*:Function*/) /*:Object*/ {
       
   346             filter = filter || function(){return true;};
       
   347         
       
   348             if (L.isFunction(filter)) {
       
   349                 var fullReport = {};
       
   350                 
       
   351                 for (var name in report){
       
   352                     if (filter(report[name])){
       
   353                         fullReport[name] = report[name];    
       
   354                     }
       
   355                 }
       
   356                 
       
   357                 return fullReport;
       
   358             }
       
   359         },
       
   360     
       
   361         //-------------------------------------------------------------------------
       
   362         // Profiling Methods
       
   363         //-------------------------------------------------------------------------   
       
   364         
       
   365         /**
       
   366          * Sets up a constructor for profiling, including all properties and methods on the prototype.
       
   367          * @param {string} name The fully-qualified name of the function including namespace information.
       
   368          * @param {Object} owner (Optional) The object that owns the function (namespace or containing object).
       
   369          * @return {Void}
       
   370          * @method registerConstructor
       
   371          * @static
       
   372          */
       
   373         registerConstructor : function (name /*:String*/, owner /*:Object*/) /*:Void*/ {    
       
   374             this.registerFunction(name, owner, true);
       
   375         },
       
   376     
       
   377         /**
       
   378          * Sets up a function for profiling. It essentially overwrites the function with one
       
   379          * that has instrumentation data. This method also creates an entry for the function
       
   380          * in the profile report. The original function is stored on the container object.
       
   381          * @param {String} name The full name of the function including namespacing. This
       
   382          *      is the name of the function that is stored in the report.
       
   383          * @param {Object} owner (Optional) The object that owns the function. If the function
       
   384          *      isn't global then this argument is required. This could be the namespace that
       
   385          *      the function belongs to or the object on which it's
       
   386          *      a method.
       
   387          * @param {Boolean} registerPrototype (Optional) Indicates that the prototype should
       
   388          *      also be instrumented. Setting to true has the same effect as calling
       
   389          *      registerConstructor().
       
   390          * @return {Void}
       
   391          * @method registerFunction
       
   392          * @static
       
   393          */     
       
   394         registerFunction : function(name /*:String*/, owner /*:Object*/, registerPrototype /*:Boolean*/) /*:Void*/{
       
   395         
       
   396             //figure out the function name without namespacing
       
   397             var funcName = (name.indexOf(".") > -1 ? 
       
   398                     name.substring(name.lastIndexOf(".")+1) : name),
       
   399                 method,
       
   400                 prototype;
       
   401                 
       
   402             //if owner isn't an object, try to find it from the name
       
   403             if (!L.isObject(owner)){
       
   404                 owner = eval(name.substring(0, name.lastIndexOf(".")));
       
   405             }
       
   406             
       
   407             //get the method and prototype
       
   408             method = owner[funcName];
       
   409             prototype = method.prototype;
       
   410             
       
   411             //see if the method has already been registered
       
   412             if (L.isFunction(method) && !method.__yuiProfiled){
       
   413                 
       
   414                 //replace the function with the profiling one
       
   415                 owner[funcName] = this.instrument(name, method);
       
   416                         
       
   417                 /*
       
   418                  * Store original function information. We store the actual
       
   419                  * function as well as the owner and the name used to identify
       
   420                  * the function so it can be restored later.
       
   421                  */
       
   422                 container[name].__yuiOwner = owner;
       
   423                 container[name].__yuiFuncName = funcName;  //overwrite with less-specific name
       
   424                  
       
   425                 //register prototype if necessary
       
   426                 if (registerPrototype) {            
       
   427                     this.registerObject(name + ".prototype", prototype);          
       
   428                 }
       
   429     
       
   430             }
       
   431         
       
   432         },
       
   433             
       
   434         
       
   435         /**
       
   436          * Sets up an object for profiling. It takes the object and looks for functions.
       
   437          * When a function is found, registerMethod() is called on it. If set to recrusive
       
   438          * mode, it will also setup objects found inside of this object for profiling, 
       
   439          * using the same methodology.
       
   440          * @param {String} name The name of the object to profile (shows up in report).
       
   441          * @param {Object} owner (Optional) The object represented by the name.
       
   442          * @param {Boolean} recurse (Optional) Determines if subobject methods are also profiled.
       
   443          * @return {Void}
       
   444          * @method registerObject
       
   445          * @static
       
   446          */
       
   447         registerObject : function (name /*:String*/, object /*:Object*/, recurse /*:Boolean*/) /*:Void*/{
       
   448         
       
   449             //get the object
       
   450             object = (L.isObject(object) ? object : eval(name));
       
   451         
       
   452             //save the object
       
   453             container[name] = object;
       
   454         
       
   455             for (var prop in object) {
       
   456                 if (typeof object[prop] == "function"){
       
   457                     if (prop != "constructor" && prop != "superclass"){ //don't do constructor or superclass, it's recursive
       
   458                         this.registerFunction(name + "." + prop, object);
       
   459                     }
       
   460                 } else if (typeof object[prop] == "object" && recurse){
       
   461                     this.registerObject(name + "." + prop, object[prop], recurse);
       
   462                 }
       
   463             }
       
   464         
       
   465         },    
       
   466         
       
   467         /**
       
   468          * Removes a constructor function from profiling. Reverses the registerConstructor() method.
       
   469          * @param {String} name The full name of the function including namespacing. This
       
   470          *      is the name of the function that is stored in the report.
       
   471          * @return {Void}
       
   472          * @method unregisterFunction
       
   473          * @static
       
   474          */     
       
   475         unregisterConstructor : function(name /*:String*/) /*:Void*/{
       
   476                 
       
   477             //see if the method has been registered
       
   478             if (L.isFunction(container[name])){
       
   479                 this.unregisterFunction(name, true);
       
   480             }    
       
   481         },
       
   482         
       
   483         /**
       
   484          * Removes function from profiling. Reverses the registerFunction() method.
       
   485          * @param {String} name The full name of the function including namespacing. This
       
   486          *      is the name of the function that is stored in the report.
       
   487          * @return {Void}
       
   488          * @method unregisterFunction
       
   489          * @static
       
   490          */     
       
   491         unregisterFunction : function(name /*:String*/, unregisterPrototype /*:Boolean*/) /*:Void*/{
       
   492                 
       
   493             //see if the method has been registered
       
   494             if (L.isFunction(container[name])){
       
   495             
       
   496                 //check to see if you should unregister the prototype
       
   497                 if (unregisterPrototype){
       
   498                     this.unregisterObject(name + ".prototype", container[name].prototype);
       
   499                 }
       
   500                     
       
   501                 //get original data
       
   502                 var owner /*:Object*/ = container[name].__yuiOwner,
       
   503                     funcName /*:String*/ = container[name].__yuiFuncName;
       
   504                     
       
   505                 //delete extra information
       
   506                 delete container[name].__yuiOwner;
       
   507                 delete container[name].__yuiFuncName;
       
   508                 
       
   509                 //replace instrumented function
       
   510                 owner[funcName] = container[name];
       
   511                 
       
   512                 //delete supporting information
       
   513                 delete container[name];          
       
   514             }
       
   515                 
       
   516         
       
   517         },
       
   518         
       
   519         /**
       
   520          * Unregisters an object for profiling. It takes the object and looks for functions.
       
   521          * When a function is found, unregisterMethod() is called on it. If set to recrusive
       
   522          * mode, it will also unregister objects found inside of this object, 
       
   523          * using the same methodology.
       
   524          * @param {String} name The name of the object to unregister.
       
   525          * @param {Boolean} recurse (Optional) Determines if subobject methods should also be
       
   526          *      unregistered.
       
   527          * @return {Void}
       
   528          * @method unregisterObject
       
   529          * @static
       
   530          */
       
   531         unregisterObject : function (name /*:String*/, recurse /*:Boolean*/) /*:Void*/{
       
   532         
       
   533             //get the object
       
   534             if (L.isObject(container[name])){            
       
   535                 var object = container[name];    
       
   536             
       
   537                 for (var prop in object) {
       
   538                     if (typeof object[prop] == "function"){
       
   539                         this.unregisterFunction(name + "." + prop);
       
   540                     } else if (typeof object[prop] == "object" && recurse){
       
   541                         this.unregisterObject(name + "." + prop, recurse);
       
   542                     }
       
   543                 }
       
   544                 
       
   545                 delete container[name];
       
   546             }
       
   547         
       
   548         }
       
   549              
       
   550     
       
   551     };
       
   552 
       
   553 
       
   554 
       
   555 }, '3.0.0' ,{requires:['oop']});