diff options
author | Florian Weikert <fwe@google.com> | 2015-11-09 21:33:26 +0000 |
---|---|---|
committer | Damien Martin-Guillerez <dmarting@google.com> | 2015-11-10 10:28:23 +0000 |
commit | 6edbf3b3fd0a6f2f49e08f74785571d4ff61185e (patch) | |
tree | 0f4b2ae3fc91538c599eb305b6a78799a41e2010 /src/main | |
parent | 3bde7d9519b9e6b2a4212210219cf57df56e540e (diff) |
Add profiler support for compiled Skylark.
--
MOS_MIGRATED_REVID=107416625
Diffstat (limited to 'src/main')
6 files changed, 92 insertions, 5 deletions
diff --git a/src/main/java/com/google/devtools/build/lib/profiler/ProfileInfo.java b/src/main/java/com/google/devtools/build/lib/profiler/ProfileInfo.java index 10de620193..2183e2015a 100644 --- a/src/main/java/com/google/devtools/build/lib/profiler/ProfileInfo.java +++ b/src/main/java/com/google/devtools/build/lib/profiler/ProfileInfo.java @@ -460,6 +460,7 @@ public class ProfileInfo { public List<Task> rootTasksById; // Not final due to the late initialization. public final List<Task> phaseTasks; private ListMultimap<String, Task> userFunctions; + private ListMultimap<String, Task> compiledUserFunctions; private ListMultimap<String, Task> builtinFunctions; public final Map<Task, Task[]> actionDependencyMap; @@ -543,6 +544,7 @@ public class ProfileInfo { */ private void calculateSkylarkStatistics() { userFunctions = ListMultimapBuilder.treeKeys().arrayListValues().build(); + compiledUserFunctions = ListMultimapBuilder.treeKeys().arrayListValues().build(); builtinFunctions = ListMultimapBuilder.treeKeys().arrayListValues().build(); for (Task task : allTasksById) { @@ -550,6 +552,8 @@ public class ProfileInfo { builtinFunctions.put(task.getDescription(), task); } else if (task.type == ProfilerTask.SKYLARK_USER_FN) { userFunctions.put(task.getDescription(), task); + } else if (task.type == ProfilerTask.SKYLARK_USER_COMPILED_FN) { + compiledUserFunctions.put(task.getDescription(), task); } } } @@ -567,6 +571,17 @@ public class ProfileInfo { /** * {@link #calculateSkylarkStatistics} must have been called before. + * @return The {@link Task}s profiled for each user-defined Skylark function name. + */ + public ListMultimap<String, Task> getCompiledSkylarkUserFunctionTasks() { + if (compiledUserFunctions == null) { + calculateSkylarkStatistics(); + } + return compiledUserFunctions; + } + + /** + * {@link #calculateSkylarkStatistics} must have been called before. * @return The {@link Task}s profiled for each builtin Skylark function name. */ public ListMultimap<String, Task> getSkylarkBuiltinFunctionTasks() { diff --git a/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java b/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java index c8bcd012b7..b1f7a54247 100644 --- a/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java +++ b/src/main/java/com/google/devtools/build/lib/profiler/ProfilerTask.java @@ -89,6 +89,7 @@ public enum ProfilerTask { SKYLARK_PARSER("Skylark Parser"), SKYLARK_USER_FN("Skylark user function call", -1, 0xCC0033, 0), SKYLARK_BUILTIN_FN("Skylark builtin function call", -1, 0x990033, 0), + SKYLARK_USER_COMPILED_FN("Skylark compiled user function call", -1, 0xCC0033, 0), UNKNOWN("Unknown event", -1, 0x339966, 0); // Size of the ProfilerTask value space. diff --git a/src/main/java/com/google/devtools/build/lib/profiler/output/SkylarkHtml.java b/src/main/java/com/google/devtools/build/lib/profiler/output/SkylarkHtml.java index 769e4e3b7f..0fe1b7fc16 100644 --- a/src/main/java/com/google/devtools/build/lib/profiler/output/SkylarkHtml.java +++ b/src/main/java/com/google/devtools/build/lib/profiler/output/SkylarkHtml.java @@ -127,6 +127,11 @@ public final class SkylarkHtml extends HtmlPrinter { "user", stats.getUserTotalNanos()); printStatsJs( + stats.getCompiledUserFunctionStatistics(), + stats.getCompiledUserFunctionSelfStatistics(), + "compiled", + stats.getCompiledUserTotalNanos()); + printStatsJs( stats.getBuiltinFunctionStatistics(), stats.getBuiltinFunctionSelfStatistics(), "builtin", @@ -138,6 +143,9 @@ public final class SkylarkHtml extends HtmlPrinter { lnPrint("document.querySelector('#user-close').onclick = function() {"); lnPrint(" document.querySelector('#user-histogram').style.display = 'none';"); lnPrint("};"); + lnPrint("document.querySelector('#compiled-close').onclick = function() {"); + lnPrint(" document.querySelector('#compiled-histogram').style.display = 'none';"); + lnPrint("};"); lnPrint("document.querySelector('#builtin-close').onclick = function() {"); lnPrint(" document.querySelector('#builtin-histogram').style.display = 'none';"); lnPrint("};"); @@ -149,6 +157,7 @@ public final class SkylarkHtml extends HtmlPrinter { down(); printHistogramData(stats.getBuiltinFunctionDurations(), "builtin"); printHistogramData(stats.getUserFunctionDurations(), "user"); + printHistogramData(stats.getCompiledUserFunctionDurations(), "compiled"); up(); lnPrint("}"); } @@ -261,6 +270,13 @@ public final class SkylarkHtml extends HtmlPrinter { lnClose(); // div user-histogram lnElement("div", "class", "skylark-table", "id", "user_function_stats"); + lnElement("h4", "Compiled function execution time"); + lnOpen("div", "class", "skylark-histogram", "id", "compiled-histogram"); + lnElement("div", "class", "skylark-chart", "id", "compiled-chart"); + lnElement("button", "id", "user-close", "Hide"); + lnClose(); // div compiled-histogram + lnElement("div", "class", "skylark-table", "id", "compiled_function_stats"); + lnElement("h4", "Builtin function execution time"); lnOpen("div", "class", "skylark-histogram", "id", "builtin-histogram"); lnElement("div", "class", "skylark-chart", "id", "builtin-chart"); diff --git a/src/main/java/com/google/devtools/build/lib/profiler/statistics/SkylarkStatistics.java b/src/main/java/com/google/devtools/build/lib/profiler/statistics/SkylarkStatistics.java index db491d1f2c..50a4e32a5b 100644 --- a/src/main/java/com/google/devtools/build/lib/profiler/statistics/SkylarkStatistics.java +++ b/src/main/java/com/google/devtools/build/lib/profiler/statistics/SkylarkStatistics.java @@ -36,20 +36,25 @@ import java.util.Map.Entry; public final class SkylarkStatistics { private final Map<String, LongArrayList> userFunctionDurations; + private final Map<String, LongArrayList> userCompiledDurations; private final Map<String, LongArrayList> builtinFunctionDurations; /** * Self duration is the time taken just within a function itself, but not other subtasks of it. */ private final Map<String, LongArrayList> userFunctionSelfDurations; + private final Map<String, LongArrayList> userCompiledSelfDurations; private final Map<String, LongArrayList> builtinFunctionSelfDurations; private long userTotalNanos; + private long userCompiledTotalNanos; private long builtinTotalNanos; public SkylarkStatistics() { userFunctionDurations = new HashMap<>(); + userCompiledDurations = new HashMap<>(); builtinFunctionDurations = new HashMap<>(); userFunctionSelfDurations = new HashMap<>(); + userCompiledSelfDurations = new HashMap<>(); builtinFunctionSelfDurations = new HashMap<>(); } @@ -62,7 +67,10 @@ public final class SkylarkStatistics { * Adds Skylark function task durations from a {@link ProfileInfo} file. */ public void addProfileInfo(ProfileInfo info) { - computeStatistics(info.getSkylarkUserFunctionTasks(), info.getSkylarkBuiltinFunctionTasks()); + computeStatistics( + info.getSkylarkUserFunctionTasks(), + info.getCompiledSkylarkUserFunctionTasks(), + info.getSkylarkBuiltinFunctionTasks()); } /** @@ -75,6 +83,13 @@ public final class SkylarkStatistics { /** * @return the total time taken by all calls to user-defined Skylark functions */ + public long getCompiledUserTotalNanos() { + return userCompiledTotalNanos; + } + + /** + * @return the total time taken by all calls to user-defined Skylark functions + */ public long getUserTotalNanos() { return userTotalNanos; } @@ -113,6 +128,37 @@ public final class SkylarkStatistics { /** * @return The execution durations of all calls to user-defined Skylark functions. */ + public Map<String, LongArrayList> getCompiledUserFunctionDurations() { + return userCompiledDurations; + } + + /** + * return The execution durations of all calls to user-defined functions excluding the durations + * of all subtasks. + */ + public Map<String, LongArrayList> getCompiledUserFunctionSelfDurations() { + return userCompiledSelfDurations; + } + + /** + * Builds and returns the {@link TasksStatistics} for the durations of each user-defined + * function. The return value is not cached and will be recomputed on another call. + */ + public Map<String, TasksStatistics> getCompiledUserFunctionStatistics() { + return buildTasksStatistics(userCompiledDurations); + } + + /** + * Builds and returns the {@link TasksStatistics} for the self-times of each user-defined + * function. The return value is not cached and will be recomputed on another call. + */ + public Map<String, TasksStatistics> getCompiledUserFunctionSelfStatistics() { + return buildTasksStatistics(userCompiledSelfDurations); + } + + /** + * @return The execution durations of all calls to user-defined Skylark functions. + */ public Map<String, LongArrayList> getUserFunctionDurations() { return userFunctionDurations; } @@ -145,8 +191,12 @@ public final class SkylarkStatistics { * For each Skylark function get the list of durations and self durations from the task maps. */ private void computeStatistics( - Multimap<String, Task> userTasks, Multimap<String, Task> builtinTasks) { + Multimap<String, Task> userTasks, + Multimap<String, Task> userCompiledTasks, + Multimap<String, Task> builtinTasks) { userTotalNanos += addDurations(userTasks, userFunctionDurations, userFunctionSelfDurations); + userCompiledTotalNanos += + addDurations(userCompiledTasks, userCompiledDurations, userCompiledSelfDurations); builtinTotalNanos += addDurations(builtinTasks, builtinFunctionDurations, builtinFunctionSelfDurations); } diff --git a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java index 4bc35865a4..76e8ba0243 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/DotExpression.java @@ -67,7 +67,7 @@ public final class DotExpression extends Expression { * Throws the correct error message if the result is null depending on the objValue. */ public static Object checkResult(Object objValue, Object result, String name, Location loc) - throws EvalException { + throws EvalException { if (result == null) { if (objValue instanceof ClassObject) { String customErrorMessage = ((ClassObject) objValue).errorMessage(name); @@ -75,8 +75,10 @@ public final class DotExpression extends Expression { throw new EvalException(loc, customErrorMessage); } } - throw new EvalException(loc, Printer.format("Object of type '%s' has no field %r", - EvalUtils.getDataTypeName(objValue), name)); + throw new EvalException( + loc, + Printer.format( + "Object of type '%s' has no field %r", EvalUtils.getDataTypeName(objValue), name)); } return result; } diff --git a/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java b/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java index cb6691c433..365681eca0 100644 --- a/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java +++ b/src/main/java/com/google/devtools/build/lib/syntax/UserDefinedFunction.java @@ -153,6 +153,8 @@ public class UserDefinedFunction extends BaseFunction { private Object callCompiledFunction(Object[] arguments, FuncallExpression ast, Environment env) { compilerDebug("Calling compiled function " + getLocationPathAndLine() + " " + getName()); try { + Profiler.instance().startTask(ProfilerTask.SKYLARK_USER_COMPILED_FN, + getLocationPathAndLine() + "#" + getName()); env.enterScope(this, ast, definitionGlobals); return method @@ -167,6 +169,7 @@ public class UserDefinedFunction extends BaseFunction { compilerDebug("Error running compiled version", e.getCause()); return null; } finally { + Profiler.instance().completeTask(ProfilerTask.SKYLARK_USER_COMPILED_FN); env.exitScope(); } } |