aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-09-18 12:57:07 -0700
committerAlon Zakai <alonzakai@gmail.com>2011-09-18 12:57:07 -0700
commit984d19ba2e67ec66dbd936323d2fec9543ce521c (patch)
tree1b8aaeccae60f0c5fbf5617f5563db54787126c8 /src
parent00d573c696084b8cc5f3beb8c2eead00552dbc22 (diff)
profiling option
Diffstat (limited to 'src')
-rw-r--r--src/jsifier.js15
-rw-r--r--src/preamble.js30
-rw-r--r--src/settings.js2
3 files changed, 47 insertions, 0 deletions
diff --git a/src/jsifier.js b/src/jsifier.js
index c5a6ec9d..da8c4db7 100644
--- a/src/jsifier.js
+++ b/src/jsifier.js
@@ -431,6 +431,15 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
func.JS = '\nfunction ' + func.ident + '(' + func.paramIdents.join(', ') + ') {\n';
+ if (PROFILE) {
+ func.JS += ' if (PROFILING) { '
+ + 'var __parentProfilingNode__ = PROFILING_NODE; PROFILING_NODE = PROFILING_NODE.children["' + func.ident + '"]; '
+ + 'if (!PROFILING_NODE) __parentProfilingNode__.children["' + func.ident + '"] = PROFILING_NODE = { time: 0, children: {}, calls: 0 };'
+ + 'PROFILING_NODE.calls++; '
+ + 'var __profilingStartTime__ = Date.now() '
+ + '}\n';
+ }
+
func.JS += ' ' + RuntimeGenerator.stackEnter(func.initialStack) + ';\n';
if (LABEL_DEBUG) func.JS += " print(INDENT + ' Entering: " + func.ident + "'); INDENT += ' ';\n";
@@ -723,6 +732,12 @@ function JSify(data, functionsOnly, givenFunctions, givenGlobalVariables) {
});
makeFuncLineActor('return', function(item) {
var ret = RuntimeGenerator.stackExit(item.funcData.initialStack) + ';\n';
+ if (PROFILE) {
+ ret += 'if (PROFILING) { '
+ + 'PROFILING_NODE.time += Date.now() - __profilingStartTime__; '
+ + 'PROFILING_NODE = __parentProfilingNode__ '
+ + '}\n';
+ }
if (LABEL_DEBUG) {
ret += "print(INDENT + 'Exiting: " + item.funcData.ident + "');\n"
+ "INDENT = INDENT.substr(0, INDENT.length-2);\n";
diff --git a/src/preamble.js b/src/preamble.js
index 2bc47aac..b597d570 100644
--- a/src/preamble.js
+++ b/src/preamble.js
@@ -274,6 +274,36 @@ var INDENT = '';
var START_TIME = Date.now();
#endif
+#if PROFILE
+var PROFILING = 0;
+var PROFILING_ROOT = { time: 0, children: {}, calls: 0 };
+var PROFILING_NODE;
+
+function startProfiling() {
+ PROFILING_NODE = PROFILING_ROOT;
+ PROFILING = 1;
+}
+
+function stopProfiling() {
+ PROFILING = 0;
+ assert(PROFILING_NODE === PROFILING_ROOT, 'Must have popped all the profiling call stack');
+}
+
+function printProfiling() {
+ function dumpData(name_, node, indent) {
+ print(indent + ('________' + node.time).substr(-8) + ': ' + name_ + ' (' + node.calls + ')');
+ var children = [];
+ for (var child in node.children) {
+ children.push(node.children[child]);
+ children[children.length-1].name_ = child;
+ }
+ children.sort(function(x, y) { return y.time - x.time });
+ children.forEach(function(child) { dumpData(child.name_, child, indent + ' ') });
+ }
+ dumpData('root', PROFILING_ROOT, ' ');
+}
+#endif
+
//========================================
// Runtime essentials
//========================================
diff --git a/src/settings.js b/src/settings.js
index 1d67e5b4..ef8b3999 100644
--- a/src/settings.js
+++ b/src/settings.js
@@ -114,6 +114,8 @@ AUTO_OPTIMIZE = 0; // When run with the CHECK_* options, will not fail on errors
// checking enabled and which do not, that is, this is a way to automate the
// generation of line data for CORRECT_*_LINES options
+PROFILE = 0; // Enables runtime profiling. See test_profiling for a usage example.
+
EXPORTED_FUNCTIONS = ['_main']; // Functions that are explicitly exported, so they are guaranteed to
// be accessible outside of the generated code.