[ReactNative] Optimize console.profile and add markers on JS entry points

Summary:
@public

Right now the profiler shows how long the executor took on JS but doesn't show
how long each of the batched calls took, this adds a *very* high level view of JS
execution (still doesn't show properly calls dispatched with setImmediate)

Also added a global property on JS to avoid trips to Native when profiling is
disabled.

Test Plan:
Run the Profiler on any app

{F22491690}
This commit is contained in:
Tadeu Zagallo
2015-06-02 06:15:53 -07:00
parent 2dfa3b34a1
commit 0f16d15d64
6 changed files with 101 additions and 5 deletions

View File

@@ -0,0 +1,37 @@
/**
* Copyright (c) 2015-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
* @providesModule BridgeProfiling
* @flow
*/
'use strict';
var GLOBAL = GLOBAL || this;
var BridgeProfiling = {
profile(profileName: String, args?: any) {
if (GLOBAL.__BridgeProfilingIsProfiling) {
if (args) {
try {
args = JSON.stringify(args);
} catch(err) {
args = err.message;
}
}
console.profile(profileName, args);
}
},
profileEnd() {
if (GLOBAL.__BridgeProfilingIsProfiling) {
console.profileEnd();
}
},
};
module.exports = BridgeProfiling;

View File

@@ -17,6 +17,7 @@ var ReactUpdates = require('ReactUpdates');
var invariant = require('invariant');
var warning = require('warning');
var BridgeProfiling = require('BridgeProfiling');
var JSTimersExecution = require('JSTimersExecution');
var INTERNAL_ERROR = 'Error in MessageQueue implementation';
@@ -277,7 +278,9 @@ var MessageQueueMixin = {
if (DEBUG_SPY_MODE) {
console.log('N->JS: Callback#' + cbID + '(' + JSON.stringify(args) + ')');
}
BridgeProfiling.profile('Callback#' + cbID + '(' + JSON.stringify(args) + ')');
cb.apply(scope, args);
BridgeProfiling.profileEnd();
} catch(ie_requires_catch) {
throw ie_requires_catch;
} finally {
@@ -311,7 +314,9 @@ var MessageQueueMixin = {
'N->JS: ' + moduleName + '.' + methodName +
'(' + JSON.stringify(params) + ')');
}
BridgeProfiling.profile(moduleName + '.' + methodName + '(' + JSON.stringify(params) + ')');
var ret = jsCall(this._requireFunc(moduleName), methodName, params);
BridgeProfiling.profileEnd();
return ret;
},
@@ -330,7 +335,8 @@ var MessageQueueMixin = {
processBatch: function(batch) {
var self = this;
return guardReturn(function () {
BridgeProfiling.profile('MessageQueue.processBatch()');
var flushedQueue = guardReturn(function () {
ReactUpdates.batchedUpdates(function() {
batch.forEach(function(call) {
invariant(
@@ -346,8 +352,12 @@ var MessageQueueMixin = {
'Unrecognized method called on BatchedBridge: ' + call.method);
}
});
BridgeProfiling.profile('React.batchedUpdates()');
});
BridgeProfiling.profileEnd();
}, null, this._flushedQueueUnguarded, this);
BridgeProfiling.profileEnd();
return flushedQueue;
},
setLoggingEnabled: function(enabled) {
@@ -472,10 +482,12 @@ var MessageQueueMixin = {
},
_flushedQueueUnguarded: function() {
BridgeProfiling.profile('JSTimersExecution.callImmediates()');
ReactUpdates.batchedUpdates(() => {
// Call the functions registered via setImmediate
JSTimersExecution.callImmediates();
});
BridgeProfiling.profileEnd();
var currentOutgoingItems = this._outgoingItems;
this._swapAndReinitializeBuffer();