Created
July 12, 2018 15:43
-
-
Save bduggan/70455720b4e63e3cb88b7d69a7ecc42f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en" ng-app="moarProfApp" ng-controller="NavigationController"> | |
<head> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>MoarVM Profiler Results</title> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> | |
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap-theme.min.css"> | |
<style> | |
body { | |
min-height: 500px; | |
padding-top: 70px; | |
} | |
.icyclegraph .call { | |
display: block; | |
border: 1px solid black; | |
overflow: hidden; | |
} | |
.icyclegraph .child { | |
float: left; | |
} | |
.icyclegraph a { | |
color: black; | |
} | |
</style> | |
</head> | |
<body > | |
<div class="navbar navbar-default navbar-fixed-top" role="navigation"> | |
<div class="container"> | |
<div class="navbar-header"> | |
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse"> | |
<span class="sr-only">Toggle navigation</span> | |
<span class="icon-bar"></span> | |
<span class="icon-bar"></span> | |
<span class="icon-bar"></span> | |
</button> | |
<a class="navbar-brand">MoarVM Profiler Results</a> | |
</div> | |
<div class="navbar-collapse collapse"> | |
<ul class="nav navbar-nav"> | |
<li ng-class="Tab == 'Overview' ? 'active' : ''"><a href="#overview" ng-click="Tab = 'Overview'">Overview</a></li> | |
<li ng-class="Tab == 'Routines' ? 'active' : ''"><a href="#routines" ng-click="Tab = 'Routines'">Routines</a></li> | |
<li ng-class="Tab == 'Call Graph' ? 'active' : ''"><a href="#callgraph" ng-click="Tab = 'Call Graph'">Call Graph</a></li> | |
<li ng-class="Tab == 'Allocations' ? 'active' : ''"><a href="#allocations" ng-click="Tab = 'Allocations'">Allocations</a></li> | |
<li ng-class="Tab == 'GC' ? 'active' : ''"><a href="#gc" ng-click="Tab = 'GC'">GC</a></li> | |
<li ng-class="Tab == 'OSR/Deopt' ? 'active' : ''"><a href="#osrdeopt" ng-click="Tab = 'OSR/Deopt'">OSR / Deopt</a></li> | |
</ul> | |
</div> | |
</div> | |
</div> | |
<div class="container" ng-show="Tab == 'Overview'"> | |
<div ng-controller="OverviewController"> | |
<h3>Time Spent</h3> | |
<p>The profiled code ran for <strong>{{TotalTime}}ms</strong>. Of this, | |
<strong>{{GCOverheadTime}}ms</strong> were spent on garbage collection | |
(that's <strong>{{GCOverheadTimePercent}}%</strong>). | |
</p> | |
<p>The dynamic optimizer was active for <strong>{{SpeshTimePercent}}%</strong> of the program's run time. | |
<table class="table table-striped table-condensed table-bordered"> | |
<tbody> | |
<tr> | |
<td><strong>Executing Code</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{ExecutingTimePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{ExecutingTimePercent}}% | |
({{ExecutingTime}}ms) | |
</div> | |
</td> | |
</tr> | |
<tr> | |
<td><strong>Garbage Collection</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-warning" role="progressbar" style="width: {{GCTimePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{GCTimePercent}}% | |
({{GCTime}}ms) | |
</div> | |
</td> | |
</tr> | |
<tr> | |
<td><strong>Dynamic Optimization</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-warning" role="progressbar" style="width: {{SpeshTimePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{SpeshTimePercent}}% | |
({{SpeshTime}}ms) | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<h3>Call Frames</h3> | |
<p>In total, <strong>{{EntriesWithoutInline}} call frames</strong> were | |
entered and exited by the profiled code. Inlining eliminated the need | |
to create <strong>{{EntriesInline}} call frames</strong> (that's | |
<strong>{{InlinePercent}}%</strong>). | |
</p> | |
<table class="table table-striped table-condensed table-bordered"> | |
<tbody> | |
<tr> | |
<td><strong>Interpreted Frames</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: {{InterpFramesPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{InterpFramesPercent}}% | |
({{InterpFrames}}) | |
</div> | |
</td> | |
</tr> | |
<tr> | |
<td><strong>Specialized Frames</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-warning" role="progressbar" style="width: {{SpeshFramesPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{SpeshFramesPercent}}% | |
({{SpeshFrames}}) | |
</div> | |
</td> | |
</tr> | |
<tr> | |
<td><strong>JIT-Compiled Frames</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{JITFramesPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{JITFramesPercent}}% | |
({{JITFrames}}) | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<h3>Garbage Collection</h3> | |
<p>The profiled code did <strong>{{GCRuns}} garbage collections</strong>. | |
There were <strong>{{FullGCRuns}} full collections</strong> involving | |
the entire heap. | |
</p> | |
<p ng-show="{{GCRuns > 0}}"> | |
The average nursery collection time was <strong>{{NurseryAverage}}ms</strong>. | |
<span ng-show="{{FullGCRuns > 0}}"> | |
The average full collection time was <strong>{{FullAverage}}ms</strong>. | |
</span> | |
<span ng-show="{{AverageParticipants > 1}}"> | |
On average, <strong>{{AverageParticipants}}</strong> threads participated in GC. | |
</span> | |
</p> | |
<h3>Dynamic Optimization</h3> | |
<p>Of {{OptimizedFrames}} specialized or JIT-compiled frames, there were | |
<strong>{{DeoptOnes}} deoptimizations</strong> (that's <strong> | |
{{DeoptOnePercent}}%</strong> of all optimized frames). | |
</p> | |
<p ng-show="DeoptAlls == 0"> | |
There was <strong>no global deoptimization</strong> triggered by the | |
profiled code. | |
</p> | |
<p ng-show="DeoptAlls == 1"> | |
There was <strong>one global deoptimization</strong> triggered by the | |
profiled code. | |
</p> | |
<p ng-show="DeoptAlls > 1"> | |
There were <strong>{{DeoptAlls}} global deoptimization</strong> triggered | |
by the profiled code. | |
</p> | |
<p ng-show="OSRs == 0"> | |
There was <strong>no On Stack Replacement</strong> performed while | |
executing the profiled code (normal if the code lacks long-running | |
loops with many iterations). | |
</p> | |
<p ng-show="OSRs == 1"> | |
There was <strong>one On Stack Replacement</strong> performed while | |
executing the profiled code. | |
</p> | |
<p ng-show="OSRs > 1"> | |
There were <strong>{{OSRs}} On Stack Replacements</strong> performed | |
while executing the profiled code. | |
</p> | |
</div> | |
</div> | |
<div class="container" ng-show="Tab == 'Routines'"> | |
<div ng-controller="RoutinesController"> | |
<table class="table table-striped table-condensed table-bordered"> | |
<thead> | |
<th> | |
<a href="" ng-click="reverse = predicate == 'Name' ? !reverse : false; predicate = 'Name';">Name</a> | |
<input ng-model="NameFilter"> | |
</th> | |
<th><a href="" ng-click="reverse = predicate == 'Entries' ? !reverse : true; predicate = 'Entries';">Entries</a></th> | |
<th><a href="" ng-click="reverse = predicate == 'InclusiveTime' ? !reverse : true; predicate = 'InclusiveTime';">Inclusive Time</a></th> | |
<th><a href="" ng-click="reverse = predicate == 'ExclusiveTime' ? !reverse : true; predicate = 'ExclusiveTime';">Exclusive Time</a></th> | |
<th> | |
<span class="text-danger" tooltip-placement="bottom" tooltip="Unoptimized interpreted code">Interp</span> / | |
<span class="text-warning" tooltip-placement="bottom" tooltip="Type-specialized interpreted code">Spesh</span> / | |
<span class="text-success" tooltip-placement="bottom" tooltip="Type-specialized, JIT-compiled code">JIT</span> | |
</th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="routine in Routines | filter:NameFilter | orderBy:predicate:reverse"> | |
<td> | |
<strong>{{routine.Name}}</strong><br /> | |
<span class="text-muted">{{routine.File}}:{{routine.Line}}</span> | |
</td> | |
<td>{{routine.Entries}}</td> | |
<td> | |
<div class="pull-left" style="width: 70px"> | |
<div class="progress" style="width: 60px"> | |
<div class="progress-bar" role="progressbar" style="width: {{routine.InclusiveTimePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
<strong>{{routine.InclusiveTimePercent}}%</strong> | |
({{routine.InclusiveTime}}ms) | |
</div> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 70px"> | |
<div class="progress" style="width: 60px"> | |
<div class="progress-bar" role="progressbar" style="width: {{routine.ExclusiveTimePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
<strong>{{routine.ExclusiveTimePercent}}%</strong> | |
({{routine.ExclusiveTime}}ms) | |
</div> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 110px"> | |
<div class="progress" style="width: 100px"> | |
<div class="progress-bar progress-bar-danger" style="width: {{routine.InterpEntriesPercent}}%"> | |
</div> | |
<div class="progress-bar progress-bar-warning" style="width: {{routine.SpeshEntriesPercent}}%"> | |
</div> | |
<div class="progress-bar progress-bar-success" style="width: {{routine.JITEntriesPercent}}%"> | |
</div> | |
</div> | |
</div> | |
<div> | |
<span class="label label-default" ng-show="routine.OSR">OSR</span> | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
<script type="text/ng-template" id="icycle_graph_callee_renderer.html"> | |
<a href="#" class="call" style="background-color:{{backgroundColor(callee)}}" ng-click="toCallee(callee)">{{callee.name}}</a> | |
<div class="child" style="width: {{callee.inclusive_time * 100 / Current.inclusive_time}}%;" ng-repeat="callee in callee.callees" title="{{callee.name}}" ng-include="'icycle_graph_callee_renderer.html'"></div> | |
</script> | |
<div class="container" ng-show="Tab == 'Call Graph'"> | |
<div ng-controller="CallGraphController"> | |
<ol class="breadcrumb"> | |
<li><strong>Callers:</strong></li> | |
<li ng-show="RecentCallers.length == 0"><em>None</em></li> | |
<li ng-repeat="caller in RecentCallers"> | |
<a href="" ng-click="toCaller(caller)"> | |
{{caller.name == '' ? '<anon>' : caller.name}} | |
</a> | |
</li> | |
</ol> | |
<p> | |
<span class="lead">{{Current.name == '' ? '<anon>' : Current.name}}</span><br /> | |
<span class="text-muted">{{File}}:{{Line}}</span> | |
</p> | |
<div class="icyclegraph"> | |
<div class="child" ng-repeat="callee in [Current]" ng-include="'icycle_graph_callee_renderer.html'"></div> | |
</div> | |
<table class="table table-striped table-condensed table-bordered"> | |
<tbody> | |
<tr> | |
<td><strong>Calls <span class="text-success">(Inlined)</span></strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar" role="progressbar" style="width: {{Percent}}%;"> | |
</div> | |
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{InlinePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div ng-show="InlinePercent == 0"> | |
{{Entries}} | |
</div> | |
<div ng-show="InlinePercent != 0"> | |
{{Entries}} + | |
<span class="text-success">{{InlineEntries}} ({{InlinePercent}}%)</span> | |
</div> | |
</td> | |
</tr> | |
<tr> | |
<td><strong>Interpreted Calls</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: {{InterpPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{InterpPercent}}% | |
({{InterpEntries}}) | |
</div> | |
</td> | |
</tr> | |
<tr> | |
<td><strong>Specialized Calls</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-warning" role="progressbar" style="width: {{SpeshPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{SpeshPercent}}% | |
({{SpeshEntries}}) | |
</div> | |
</td> | |
</tr> | |
<tr> | |
<td><strong>JIT-Compiled Calls</strong></td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{JITPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{JITPercent}}% | |
({{JITEntries}}) | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<div class="panel panel-default"> | |
<div class="panel-heading">Callees</div> | |
<table class="table table-striped table-condensed table-bordered" ng-show="Callees.length > 0"> | |
<thead> | |
<th> | |
<a href="" ng-click="reverse = predicate == 'Name' ? !reverse : false; predicate = 'Name';">Name</a> | |
<input ng-model="NameFilter"> | |
</th> | |
<th><a href="" ng-click="reverse = predicate == 'Calls' ? !reverse : true; predicate = 'Calls';">Calls</a></th> | |
<th><a href="" ng-click="reverse = predicate == 'Time' ? !reverse : true; predicate = 'Time';">Time In Callee</a></th> | |
<th> | |
<span class="text-danger" tooltip-placement="bottom" tooltip="Unoptimized interpreted code">Interp</span> / | |
<span class="text-warning" tooltip-placement="bottom" tooltip="Type-specialized interpreted code">Spesh</span> / | |
<span class="text-success" tooltip-placement="bottom" tooltip="Type-specialized, JIT-compiled code">JIT</span> | |
</th> | |
<th> | |
<span tooltip-placement="bottom" tooltip="Code from this callee was flattened into the routine by the optimizer">Inlined</span> | |
</th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="callee in Callees | filter:NameFilter | orderBy:predicate:reverse"> | |
<td> | |
<strong><a href="" ng-click="toCallee(callee.Node)">{{callee.Name}}</a></strong><br /> | |
<span class="text-muted">{{callee.File}}:{{callee.Line}}</span> | |
</td> | |
<td>{{callee.Calls}}</td> | |
<td> | |
<div class="pull-left" style="width: 70px"> | |
<div class="progress" style="width: 60px"> | |
<div class="progress-bar" role="progressbar" style="width: {{callee.TimePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
<strong>{{callee.TimePercent}}%</strong> | |
({{callee.Time}}ms) | |
</div> | |
</td> | |
<td> | |
<div class="progress" style="width: 100px"> | |
<div class="progress-bar progress-bar-danger" style="width: {{callee.InterpCallsPercent}}%"> | |
</div> | |
<div class="progress-bar progress-bar-warning" style="width: {{callee.SpeshCallsPercent}}%"> | |
</div> | |
<div class="progress-bar progress-bar-success" style="width: {{callee.JITCallsPercent}}%"> | |
</div> | |
</div> | |
</td> | |
<td> | |
<div ng-show="callee.VeryInline"> | |
<span class="text-success"> | |
<span class="glyphicon glyphicon-star"></span> | |
</span> | |
{{callee.InlinedPercent}}% | |
</div> | |
<div ng-show="callee.SometimesInline"> | |
<span class="text-muted"> | |
<span class="glyphicon glyphicon-star-empty"></span> | |
</span> | |
{{callee.InlinedPercent}}% | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<div class="panel-body" ng-show="Callees.length == 0"> | |
This code has no callees. | |
</div> | |
</div> | |
</div> | |
</div> | |
<div class="container" ng-show="Tab == 'Allocations'"> | |
<div ng-controller="AllocationsController"> | |
<table class="table table-striped table-condensed table-bordered"> | |
<thead> | |
<th> | |
<a href="" ng-click="reverse = predicate == 'Name' ? !reverse : false; predicate = 'Name';">Name</a> | |
<input ng-model="NameFilter"> | |
</th> | |
<th><a href="" ng-click="reverse = predicate == 'Allocations' ? !reverse : true; predicate = 'Allocations';">Allocations</a></th> | |
<th>Allocating Routines</th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="alloc in AllocationSummary | filter:NameFilter | orderBy:predicate:reverse"> | |
<td><strong>{{alloc.Name}}</strong></td> | |
<td> | |
<div class="pull-left" style="width: 210px"> | |
<div class="progress" style="width: 200px"> | |
<div class="progress-bar progress-bar-danger" role="progressbar" style="width: {{alloc.AllocationsInterpPercent}}%;"> | |
</div> | |
<div class="progress-bar progress-bar-warning" role="progressbar" style="width: {{alloc.AllocationsSpeshPercent}}%;"> | |
</div> | |
<div class="progress-bar progress-bar-success" role="progressbar" style="width: {{alloc.AllocationsJitPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{alloc.Allocations}} | |
</div> | |
</td> | |
<td> | |
<a href="" ng-click="showAllocatingRoutines(alloc)">View</a> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<script type="text/ng-template" id="myModalContent.html"> | |
<div class="modal-header"> | |
<button type="button" ng-click="modalInstance.close()" | |
class="close" data-dismiss="modal"> | |
<span aria-hidden="true">×</span><span class="sr-only">Close</span> | |
</button> | |
<h4 class="modal-title" id="allocatingRoutinesModalLabel"> | |
Routines Allocating {{CurrentAllocatingRoutine}} | |
</h4> | |
</div> | |
<div class="modal-body"> | |
<table class="table table-striped table-condensed table-bordered"> | |
<thead> | |
<th> | |
<a href="" ng-click="routineReverse = routinePredicate == 'Name' ? !routineReverse : false; routinePredicate = 'Name';">Name</a> | |
<input ng-model="RoutineNameFilter"> | |
</th> | |
<th><a href="" ng-click="routineReverse = routinePredicate == 'Allocations' ? !routineReverse : true; routinePredicate = 'Allocations';">Allocations</a></th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="routine in CurrentAllocatingRoutineStats | filter:RoutineNameFilter | orderBy:routinePredicate:routineReverse"> | |
<td> | |
<strong>{{routine.Name}}</strong><br /> | |
<span class="text-muted">{{routine.File}}:{{routine.Line}}</span> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 210px"> | |
<div class="progress" style="width: 200px"> | |
<div class="progress-bar progress-bar-danger" style="width: {{routine.AllocationsInterpPercent}}%;"> | |
</div> | |
<div class="progress-bar progress-bar-warning" style="width: {{routine.AllocationsSpeshPercent}}%;"> | |
</div> | |
<div class="progress-bar progress-bar-success" style="width: {{routine.AllocationsJitPercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{routine.Allocations}} | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
<div class="modal-footer"> | |
<button type="button" ng-click="modalInstance.close()" | |
class="btn btn-default" data-dismiss="modal">Close</button> | |
</div> | |
</script> | |
</div> | |
</div> | |
<div class="container" ng-show="Tab == 'GC'"> | |
<div ng-controller="GCController"> | |
<table class="table table-striped table-condensed table-bordered"> | |
<thead> | |
<th> | |
<a href="" ng-click="reverse = predicate == 'StartTime' ? !reverse : false; predicate = 'StartTime';">Start Time</a> | |
</th> | |
<th> | |
<a href="" ng-click="reverse = predicate == 'Run' ? !reverse : false; predicate = 'Run';">Run</a> | |
</th> | |
<th>Full</th> | |
<th> | |
<a href="" ng-click="reverse = predicate == 'Time' ? !reverse : false; predicate = 'Time';">Time</a> | |
</th> | |
<th> | |
Nursery: | |
<span class="text-danger" tooltip-placement="bottom" tooltip="Bytes retained in the nursery">Retained</span> / | |
<span class="text-warning" tooltip-placement="bottom" tooltip="Bytes promoted to gen2 and now available in nursery">Promoted</span> / | |
<span class="text-success" tooltip-placement="bottom" tooltip="Bytes released and now availabe in nursery">Freed</span> | |
</th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="gc in GCs | orderBy:predicate:reverse"> | |
<td>{{gc.StartTime}}ms</td> | |
<td><strong>{{gc.Run}}</strong></td> | |
<td> | |
<span class="text-success" ng-show="gc.Full"> | |
<span class="glyphicon glyphicon-star"></span> | |
</span> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 210px"> | |
<div class="progress" style="width: 200px"> | |
<div class="progress-bar" role="progressbar" style="width: {{gc.TimePercent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{gc.Time}}ms | |
</div> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 210px"> | |
<div class="progress" style="width: 200px"> | |
<div class="progress-bar progress-bar-danger" style="width: {{gc.RetainedPercent}}%"> | |
</div> | |
<div class="progress-bar progress-bar-warning" style="width: {{gc.PromotedPercent}}%"> | |
</div> | |
<div class="progress-bar progress-bar-success" style="width: {{gc.ClearedPercent}}%"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{gc.RetainedKilobytes}}KB / | |
{{gc.PromotedKilobytes}}KB / | |
{{gc.ClearedKilobytes}}KB ... | |
<small>{{gc.Gen2Roots}} gen2 roots</small> | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
</div> | |
</div> | |
<div class="container" ng-show="Tab == 'OSR/Deopt'"> | |
<div ng-controller="OSRDeoptController"> | |
<h3>OSR</h3> | |
<p>On Stack Replacement detects routines containing hot loops that are | |
being interpreted, and replaces them with specialized or JIT-compiled | |
code.</p> | |
<table class="table table-striped table-condensed table-bordered" ng-show="OSRs.length > 0"> | |
<thead> | |
<th> | |
Routine | |
</th> | |
<th>On Stack Replacements</th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="osr in OSRs | orderBy:predicate:reverse"> | |
<td> | |
<strong>{{osr.Name}}</strong><br /> | |
<span class="text-muted">{{osr.File}}:{{osr.Line}}</span> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar" role="progressbar" style="width: {{osr.Percent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{osr.Count}} | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<p ng-show="OSRs.length == 0"> | |
<em>No OSR was performed during this profile.</em> | |
</p> | |
<h3>Local Deoptimization</h3> | |
<p>Local deoptimization happens when a guard in specialized or JIT-compiled | |
code fails. Since the code was produced assuming the guard would hold, | |
the VM falls back to running the safe, but slower, interpreted code.</p> | |
<table class="table table-striped table-condensed table-bordered" ng-show="DeoptOnes.length > 0"> | |
<thead> | |
<th> | |
Routine | |
</th> | |
<th>Deoptimizations</th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="deopt in DeoptOnes | orderBy:predicate:reverse"> | |
<td> | |
<strong>{{deopt.Name}}</strong><br /> | |
<span class="text-muted">{{deopt.File}}:{{deopt.Line}}</span> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar" role="progressbar" style="width: {{deopt.Percent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{deopt.Count}} | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<p ng-show="DeoptOnes.length == 0"> | |
<em>No local deoptimizations occurred during this profile.</em> | |
</p> | |
<h3>Global Deoptimization</h3> | |
<p>Global deoptimization happens when an event occurs that renders | |
all currently type-specialized or JIT-compiled code on the call | |
stack potentially invalid. Mixins - changing the type of an object | |
in place - are a common reason.</p> | |
<table class="table table-striped table-condensed table-bordered" ng-show="DeoptAlls.length > 0"> | |
<thead> | |
<th> | |
Routine | |
</th> | |
<th>Deoptimizations</th> | |
</thead> | |
<tbody> | |
<tr ng-repeat="deopt in DeoptAlls | orderBy:predicate:reverse"> | |
<td> | |
<strong>{{deopt.Name}}</strong><br /> | |
<span class="text-muted">{{deopt.File}}:{{deopt.Line}}</span> | |
</td> | |
<td> | |
<div class="pull-left" style="width: 310px"> | |
<div class="progress" style="width: 300px"> | |
<div class="progress-bar" role="progressbar" style="width: {{deopt.Percent}}%;"> | |
</div> | |
</div> | |
</div> | |
<div> | |
{{deopt.Count}} | |
</div> | |
</td> | |
</tr> | |
</tbody> | |
</table> | |
<p ng-show="DeoptAlls.length == 0"> | |
<em>No global deoptimizations occurred during this profile.</em> | |
</p> | |
</div> | |
</div> | |
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/2.2.0/ui-bootstrap-tpls.js"></script> | |
<script> | |
var rawData = JSON.parse('[{"9":{"name":"","line":3557,"file":"gen/moar/BOOTSTRAP.nqp"},"8":"CallCapture","7":"BOOTHash","64":{"name":"AT-POS","line":442,"file":"SETTING::src/core/Array.pm6"},"63":{"name":"is_narrower","line":2242,"file":"gen/moar/BOOTSTRAP.nqp"},"62":"BOOTIntArray","61":"NQPArrayIter","60":{"name":"","line":2212,"file":"gen/moar/BOOTSTRAP.nqp"},"6":{"name":"STORE","line":267,"file":"SETTING::src/core/Array.pm6"},"59":{"name":"AT-POS","line":252,"file":"SETTING::src/core/Any.pm6"},"58":{"name":"postcircumfix:<[ ]>","line":145,"file":"SETTING::src/core/array_slice.pm6"},"57":{"name":"postcircumfix:<[ ]>","line":94,"file":"SETTING::src/core/array_slice.pm6"},"56":{"name":"infix:<%>","line":307,"file":"SETTING::src/core/Int.pm6"},"55":{"name":"infix:<%>","line":229,"file":"SETTING::src/core/Numeric.pm6"},"54":{"name":"postfix:<++>","line":241,"file":"SETTING::src/core/Int.pm6"},"53":{"name":"postfix:<++>","line":481,"file":"SETTING::src/core/Any.pm6"},"52":{"name":"postfix:<++>","line":479,"file":"SETTING::src/core/Any.pm6"},"51":"Int","50":{"name":"","line":1,"file":"-e"},"5":"Array","49":"Block","48":{"name":"","line":2018,"file":"gen/moar/BOOTSTRAP.nqp"},"47":{"name":"assign-scalar-no-whence-no-typecheck","line":3927,"file":"gen/moar/BOOTSTRAP.nqp"},"46":{"name":"nominal","line":86,"file":"gen/moar/Metamodel.nqp"},"45":{"name":"archetypes","line":3056,"file":"gen/moar/Metamodel.nqp"},"44":{"name":"of","line":1141,"file":"gen/moar/BOOTSTRAP.nqp"},"43":{"name":"","line":3968,"file":"gen/moar/BOOTSTRAP.nqp"},"42":{"name":"push","line":31,"file":"SETTING::src/core/Array.pm6"},"41":{"name":"push-all","line":1746,"file":"SETTING::src/core/Rakudo/Iterator.pm6"},"40":{"name":"is-lazy","line":1757,"file":"SETTING::src/core/Rakudo/Iterator.pm6"},"4":{"name":"<unit>","line":1,"file":"-e"},"39":{"name":"push-until-lazy","line":69,"file":"SETTING::src/core/Iterator.pm6"},"38":"Array::ArrayReificationTarget","37":{"name":"new","line":22,"file":"SETTING::src/core/Array.pm6"},"36":{"name":"infix:<==>","line":466,"file":"SETTING::src/core/Num.pm6"},"35":{"name":"identity","line":3843,"file":"gen/moar/BOOTSTRAP.nqp"},"34":{"name":"","line":3869,"file":"gen/moar/BOOTSTRAP.nqp"},"33":{"name":"Bridge","line":25,"file":"SETTING::src/core/Num.pm6"},"32":"Num","31":{"name":"Bridge","line":68,"file":"SETTING::src/core/Int.pm6"},"30":{"name":"infix:<==>","line":151,"file":"SETTING::src/core/Real.pm6"},"3":"BOOTArray","29":{"name":"SET-SELF","line":1708,"file":"SETTING::src/core/Rakudo/Iterator.pm6"},"28":"<anon|19>","27":{"name":"new","line":1719,"file":"SETTING::src/core/Rakudo/Iterator.pm6"},"26":{"name":"","line":1703,"file":"SETTING::src/core/Rakudo/Iterator.pm6"},"25":{"name":"IntRange","line":1702,"file":"SETTING::src/core/Rakudo/Iterator.pm6"},"24":{"name":"infix:<->","line":283,"file":"SETTING::src/core/Int.pm6"},"23":{"name":"infix:<->","line":207,"file":"SETTING::src/core/Numeric.pm6"},"22":{"name":"infix:<+>","line":276,"file":"SETTING::src/core/Int.pm6"},"21":"Hash","20":{"name":"infix:<+>","line":203,"file":"SETTING::src/core/Numeric.pm6"},"2":"BOOTCode","19":"IntAttrRef","18":"Scalar","17":{"name":"iterator","line":107,"file":"SETTING::src/core/Range.pm6"},"16":"IterationBuffer","15":{"name":"STORE","line":268,"file":"SETTING::src/core/Array.pm6"},"14":{"name":"add_to_cache","line":2840,"file":"gen/moar/BOOTSTRAP.nqp"},"13":"BOOTInt","12":"NQPArray","11":{"name":"","line":2556,"file":"gen/moar/BOOTSTRAP.nqp"},"10":"List","1":{"name":"<unit-outer>","line":1,"file":"-e"},"0":{"name":"","line":1559,"file":"gen/moar/stage2/NQPHLL.nqp"}},{"total_time":15389477,"thread":1,"spesh_time":43442,"gcs":[{"time":10219,"start_time":46262,"sequence":0,"retained_bytes":834216,"responsible":1,"promoted_bytes":24,"gen2_roots":14968,"full":0,"cleared_bytes":3360048},{"time":7520,"start_time":118451,"sequence":1,"retained_bytes":40,"responsible":1,"promoted_bytes":6984163,"gen2_roots":19247,"full":0,"cleared_bytes":4292177389},{"time":4526,"start_time":206486,"sequence":2,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1582,"start_time":289763,"sequence":3,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1466,"start_time":370600,"sequence":4,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1470,"start_time":448815,"sequence":5,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":527080,"sequence":6,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1660,"start_time":605767,"sequence":7,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1680,"start_time":686406,"sequence":8,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":766628,"sequence":9,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1467,"start_time":847395,"sequence":10,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1508,"start_time":926887,"sequence":11,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1487,"start_time":1006333,"sequence":12,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1619,"start_time":1085693,"sequence":13,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":1166819,"sequence":14,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1479,"start_time":1246199,"sequence":15,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":1326545,"sequence":16,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1512,"start_time":1407103,"sequence":17,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1479,"start_time":1487773,"sequence":18,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1478,"start_time":1567991,"sequence":19,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1473,"start_time":1649719,"sequence":20,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1481,"start_time":1731883,"sequence":21,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1492,"start_time":1811509,"sequence":22,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1477,"start_time":1890951,"sequence":23,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1495,"start_time":1970666,"sequence":24,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":2049982,"sequence":25,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":2130593,"sequence":26,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":2209697,"sequence":27,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1479,"start_time":2290716,"sequence":28,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1721,"start_time":2372941,"sequence":29,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1628,"start_time":2452851,"sequence":30,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1552,"start_time":2532279,"sequence":31,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1506,"start_time":2612899,"sequence":32,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1527,"start_time":2692956,"sequence":33,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1517,"start_time":2772049,"sequence":34,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1470,"start_time":2851028,"sequence":35,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1646,"start_time":2932292,"sequence":36,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":3013658,"sequence":37,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":3093667,"sequence":38,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1471,"start_time":3173718,"sequence":39,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1519,"start_time":3252798,"sequence":40,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1488,"start_time":3333523,"sequence":41,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1487,"start_time":3413473,"sequence":42,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1483,"start_time":3492141,"sequence":43,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":3570680,"sequence":44,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":3651614,"sequence":45,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1487,"start_time":3730146,"sequence":46,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1692,"start_time":3808898,"sequence":47,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1465,"start_time":3889413,"sequence":48,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":3968459,"sequence":49,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1695,"start_time":4048148,"sequence":50,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1479,"start_time":4127603,"sequence":51,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1664,"start_time":4206594,"sequence":52,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1488,"start_time":4288458,"sequence":53,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1463,"start_time":4369782,"sequence":54,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1771,"start_time":4452189,"sequence":55,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1481,"start_time":4531291,"sequence":56,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":4610175,"sequence":57,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1466,"start_time":4688443,"sequence":58,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1471,"start_time":4770295,"sequence":59,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":4849355,"sequence":60,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1471,"start_time":4928433,"sequence":61,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1473,"start_time":5007799,"sequence":62,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":5087813,"sequence":63,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1460,"start_time":5166982,"sequence":64,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1473,"start_time":5246233,"sequence":65,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1590,"start_time":5332571,"sequence":66,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1625,"start_time":5412484,"sequence":67,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1774,"start_time":5494222,"sequence":68,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1574,"start_time":5575201,"sequence":69,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1508,"start_time":5660693,"sequence":70,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1493,"start_time":5741136,"sequence":71,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1485,"start_time":5823823,"sequence":72,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1488,"start_time":5905226,"sequence":73,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1584,"start_time":5987892,"sequence":74,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1557,"start_time":6067402,"sequence":75,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1817,"start_time":6148007,"sequence":76,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":6229776,"sequence":77,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1473,"start_time":6308866,"sequence":78,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1479,"start_time":6389020,"sequence":79,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1491,"start_time":6468147,"sequence":80,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1505,"start_time":6548390,"sequence":81,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1513,"start_time":6628363,"sequence":82,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1486,"start_time":6709040,"sequence":83,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1471,"start_time":6789478,"sequence":84,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1563,"start_time":6869017,"sequence":85,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1480,"start_time":6948378,"sequence":86,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1525,"start_time":7027467,"sequence":87,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1816,"start_time":7107727,"sequence":88,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":7188500,"sequence":89,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1532,"start_time":7267687,"sequence":90,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":7349153,"sequence":91,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1486,"start_time":7428311,"sequence":92,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1473,"start_time":7509624,"sequence":93,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1767,"start_time":7594638,"sequence":94,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1744,"start_time":7675212,"sequence":95,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1464,"start_time":7756275,"sequence":96,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1535,"start_time":7835677,"sequence":97,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1517,"start_time":7915195,"sequence":98,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1555,"start_time":7994496,"sequence":99,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":8073823,"sequence":100,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1527,"start_time":8154538,"sequence":101,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1500,"start_time":8234231,"sequence":102,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1516,"start_time":8315531,"sequence":103,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1533,"start_time":8394718,"sequence":104,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1502,"start_time":8473956,"sequence":105,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":8554178,"sequence":106,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1519,"start_time":8634171,"sequence":107,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1619,"start_time":8714989,"sequence":108,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1499,"start_time":8795169,"sequence":109,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1463,"start_time":8875057,"sequence":110,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":8956457,"sequence":111,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":9034756,"sequence":112,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":9116555,"sequence":113,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1473,"start_time":9198467,"sequence":114,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1480,"start_time":9277282,"sequence":115,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1467,"start_time":9357981,"sequence":116,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":9439758,"sequence":117,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1467,"start_time":9518509,"sequence":118,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1535,"start_time":9600541,"sequence":119,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1467,"start_time":9679286,"sequence":120,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1492,"start_time":9760063,"sequence":121,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1544,"start_time":9842900,"sequence":122,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1482,"start_time":9926615,"sequence":123,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":10006772,"sequence":124,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1710,"start_time":10086397,"sequence":125,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1475,"start_time":10167895,"sequence":126,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":10254080,"sequence":127,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1875,"start_time":10340223,"sequence":128,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1696,"start_time":10424156,"sequence":129,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1548,"start_time":10504346,"sequence":130,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1515,"start_time":10584814,"sequence":131,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1466,"start_time":10666829,"sequence":132,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":10747760,"sequence":133,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":10826503,"sequence":134,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1492,"start_time":10904881,"sequence":135,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1479,"start_time":10983285,"sequence":136,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":11062457,"sequence":137,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1478,"start_time":11142135,"sequence":138,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1477,"start_time":11221273,"sequence":139,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1475,"start_time":11299656,"sequence":140,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1480,"start_time":11380929,"sequence":141,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1465,"start_time":11459718,"sequence":142,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1483,"start_time":11538626,"sequence":143,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1488,"start_time":11620703,"sequence":144,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1478,"start_time":11699887,"sequence":145,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1469,"start_time":11778254,"sequence":146,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":11858652,"sequence":147,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1502,"start_time":11937559,"sequence":148,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1478,"start_time":12016028,"sequence":149,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":12095714,"sequence":150,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1480,"start_time":12176097,"sequence":151,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1474,"start_time":12254683,"sequence":152,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":12334663,"sequence":153,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1477,"start_time":12413542,"sequence":154,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1476,"start_time":12494652,"sequence":155,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1684,"start_time":12575735,"sequence":156,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1495,"start_time":12670062,"sequence":157,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1557,"start_time":12748971,"sequence":158,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1520,"start_time":12827956,"sequence":159,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1507,"start_time":12906626,"sequence":160,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1501,"start_time":12985679,"sequence":161,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1482,"start_time":13064321,"sequence":162,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1499,"start_time":13143205,"sequence":163,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1465,"start_time":13222300,"sequence":164,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1620,"start_time":13302285,"sequence":165,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1902,"start_time":13384548,"sequence":166,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1539,"start_time":13464694,"sequence":167,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1805,"start_time":13543472,"sequence":168,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1690,"start_time":13625441,"sequence":169,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1545,"start_time":13704050,"sequence":170,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1488,"start_time":13785822,"sequence":171,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1468,"start_time":13868359,"sequence":172,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1471,"start_time":13947041,"sequence":173,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":14026204,"sequence":174,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1469,"start_time":14105391,"sequence":175,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1465,"start_time":14184104,"sequence":176,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1471,"start_time":14265069,"sequence":177,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1470,"start_time":14344005,"sequence":178,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1477,"start_time":14422592,"sequence":179,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1645,"start_time":14503216,"sequence":180,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1562,"start_time":14599582,"sequence":181,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":2796,"start_time":14683396,"sequence":182,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1671,"start_time":14767302,"sequence":183,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1470,"start_time":14847662,"sequence":184,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1504,"start_time":14926533,"sequence":185,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1472,"start_time":15005371,"sequence":186,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1475,"start_time":15085120,"sequence":187,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1666,"start_time":15164404,"sequence":188,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1670,"start_time":15244534,"sequence":189,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240},{"time":1475,"start_time":15328716,"sequence":190,"retained_bytes":40,"responsible":1,"promoted_bytes":0,"gen2_roots":14,"full":0,"cleared_bytes":4194240}],"call_graph":{"inclusive_time":15078406,"id":"0","exclusive_time":20,"entries":1,"callees":[{"inclusive_time":15078385,"id":"1","exclusive_time":29,"entries":1,"callees":[{"osr":1,"jit_entries":1,"inclusive_time":15078356,"id":"4","exclusive_time":1997981,"entries":1,"callees":[{"inclusive_time":800,"id":"6","exclusive_time":143,"entries":1,"callees":[{"inclusive_time":1,"id":"9","exclusive_time":1,"entries":1,"allocations":[{"id":"10","count":1}]},{"inclusive_time":25,"id":"11","exclusive_time":23,"entries":1,"callees":[{"inclusive_time":1,"id":"14","exclusive_time":1,"entries":1}],"allocations":[{"id":"2","count":2},{"id":"12","count":2},{"id":"7","count":1},{"id":"13","count":1}]},{"inclusive_time":630,"id":"15","exclusive_time":107,"entries":1,"callees":[{"inclusive_time":388,"id":"17","exclusive_time":60,"entries":1,"callees":[{"inclusive_time":53,"id":"20","exclusive_time":17,"entries":1,"callees":[{"inclusive_time":34,"id":"11","exclusive_time":33,"entries":1,"callees":[{"inclusive_time":1,"id":"14","exclusive_time":1,"entries":1}],"allocations":[{"id":"2","count":2},{"id":"12","count":2},{"id":"7","count":1},{"id":"13","count":1}]},{"inclusive_time":1,"id":"22","exclusive_time":1,"entries":1}],"allocations":[{"id":"7","count":1},{"id":"21","count":1},{"id":"8","count":3}]},{"inclusive_time":42,"id":"23","exclusive_time":18,"entries":1,"callees":[{"inclusive_time":22,"id":"11","exclusive_time":21,"entries":1,"callees":[{"inclusive_time":1,"id":"14","exclusive_time":1,"entries":1}],"allocations":[{"id":"2","count":2},{"id":"12","count":2},{"id":"7","count":1},{"id":"13","count":1}]},{"inclusive_time":1,"id":"24","exclusive_time":1,"entries":1}],"allocations":[{"id":"7","count":1},{"id":"21","count":1},{"id":"8","count":3}]},{"inclusive_time":231,"id":"25","exclusive_time":125,"entries":1,"callees":[{"inclusive_time":1,"id":"26","exclusive_time":1,"entries":1,"allocations":[{"id":"18","count":1}]},{"inclusive_time":104,"id":"27","exclusive_time":24,"entries":1,"callees":[{"inclusive_time":79,"id":"29","exclusive_time":20,"entries":1,"callees":[{"inclusive_time":59,"id":"30","exclusive_time":33,"entries":1,"callees":[{"inclusive_time":1,"id":"31","exclusive_time":1,"entries":1,"allocations":[{"id":"7","count":1},{"id":"32","count":1}]},{"inclusive_time":22,"id":"33","exclusive_time":20,"entries":1,"callees":[{"inclusive_time":1,"id":"34","exclusive_time":1,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"7","count":1}]},{"inclusive_time":0,"id":"36","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}]},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"18","count":1},{"id":"7","count":1}]},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"7","count":1},{"id":"28","count":1}]},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"7","count":1}]},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"2","count":3},{"id":"7","count":1},{"id":"18","count":1},{"id":"19","count":2}]},{"inclusive_time":3,"id":"37","exclusive_time":3,"entries":1,"callees":[{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"7","count":1},{"id":"38","count":1}]},{"inclusive_time":131,"id":"39","exclusive_time":33,"entries":1,"callees":[{"inclusive_time":2,"id":"40","exclusive_time":2,"entries":1,"callees":[{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"7","count":1}]},{"inclusive_time":94,"id":"41","exclusive_time":16,"entries":1,"callees":[{"inclusive_time":77,"id":"42","exclusive_time":49,"entries":10,"callees":[{"inclusive_time":26,"id":"43","exclusive_time":24,"entries":1,"callees":[{"inclusive_time":0,"id":"44","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"45","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"46","exclusive_time":0,"entries":1}]},{"inclusive_time":1,"id":"47","exclusive_time":1,"entries":10},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":10}],"allocations":[{"id":"7","count":10},{"id":"18","count":10}]},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"18","count":1},{"id":"7","count":1}]},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"18","count":1},{"id":"7","count":1}]},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}],"allocations":[{"id":"7","count":1},{"id":"16","count":1}]}],"allocations":[{"id":"7","count":1},{"id":"3","count":1},{"id":"8","count":3}]},{"inclusive_time":1,"id":"48","exclusive_time":1,"entries":1,"allocations":[{"id":"49","count":1},{"id":"2","count":1}]},{"jit_entries":9991007,"inclusive_time":13079572,"id":"50","exclusive_time":4754112,"entries":10000000,"callees":[{"inclusive_time":94,"id":"52","exclusive_time":37,"entries":2,"callees":[{"inclusive_time":37,"id":"11","exclusive_time":34,"entries":2,"callees":[{"inclusive_time":2,"id":"14","exclusive_time":2,"entries":2}],"allocations":[{"id":"2","count":4},{"id":"12","count":4},{"id":"7","count":2},{"id":"13","count":2}]},{"inclusive_time":10,"id":"53","exclusive_time":4,"entries":1,"callees":[{"inclusive_time":5,"id":"43","exclusive_time":4,"entries":1,"callees":[{"inclusive_time":0,"id":"44","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"45","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"46","exclusive_time":0,"entries":1}]},{"inclusive_time":0,"id":"47","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}]},{"inclusive_time":8,"id":"54","exclusive_time":4,"entries":1,"callees":[{"inclusive_time":3,"id":"43","exclusive_time":3,"entries":1,"callees":[{"inclusive_time":0,"id":"44","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"45","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"46","exclusive_time":0,"entries":1}]},{"inclusive_time":0,"id":"47","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}]}],"allocations":[{"id":"7","count":2},{"id":"21","count":2},{"id":"8","count":6}]},{"inclusive_time":50,"id":"55","exclusive_time":31,"entries":1,"callees":[{"inclusive_time":15,"id":"11","exclusive_time":14,"entries":1,"callees":[{"inclusive_time":0,"id":"14","exclusive_time":0,"entries":1}],"allocations":[{"id":"2","count":2},{"id":"12","count":2},{"id":"7","count":1},{"id":"13","count":1}]},{"inclusive_time":3,"id":"56","exclusive_time":2,"entries":1,"callees":[{"inclusive_time":0,"id":"34","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"35","exclusive_time":0,"entries":1}]}],"allocations":[{"id":"7","count":1},{"id":"21","count":1},{"id":"8","count":3}]},{"inclusive_time":886,"id":"57","exclusive_time":21,"entries":1,"callees":[{"inclusive_time":0,"id":"9","exclusive_time":0,"entries":1,"allocations":[{"id":"10","count":1}]},{"inclusive_time":85,"id":"11","exclusive_time":84,"entries":1,"callees":[{"inclusive_time":0,"id":"14","exclusive_time":0,"entries":1}],"allocations":[{"id":"2","count":2},{"id":"12","count":3},{"id":"7","count":2},{"id":"13","count":1}]},{"inclusive_time":779,"id":"58","exclusive_time":16,"entries":1,"callees":[{"inclusive_time":762,"id":"59","exclusive_time":70,"entries":1,"callees":[{"inclusive_time":0,"id":"9","exclusive_time":0,"entries":1,"allocations":[{"id":"10","count":1}]},{"inclusive_time":689,"id":"11","exclusive_time":108,"entries":1,"callees":[{"inclusive_time":579,"id":"60","exclusive_time":339,"entries":1,"callees":[{"inclusive_time":240,"id":"63","exclusive_time":240,"entries":240}],"allocations":[{"id":"12","count":82},{"id":"61","count":17},{"id":"7","count":32},{"id":"62","count":32},{"id":"13","count":18}]},{"inclusive_time":0,"id":"14","exclusive_time":0,"entries":1}],"allocations":[{"id":"2","count":2},{"id":"12","count":2},{"id":"7","count":1},{"id":"13","count":1}]},{"inclusive_time":1,"id":"64","exclusive_time":1,"entries":1,"allocations":[{"id":"7","count":1}]}],"allocations":[{"id":"7","count":1},{"id":"3","count":1},{"id":"8","count":3}]}]}],"allocations":[{"id":"7","count":1},{"id":"3","count":1},{"id":"8","count":3}]},{"inclusive_time":6,"id":"43","exclusive_time":5,"entries":1,"callees":[{"inclusive_time":0,"id":"44","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"45","exclusive_time":0,"entries":1},{"inclusive_time":0,"id":"46","exclusive_time":0,"entries":1}]},{"jit_entries":9991346,"inlined_entries":9991007,"inclusive_time":524100,"id":"47","exclusive_time":524100,"entries":10000000},{"jit_entries":9991141,"inclusive_time":2665903,"id":"56","exclusive_time":2247202,"entries":9999999,"callees":[{"jit_entries":9999611,"inlined_entries":9991141,"inclusive_time":418700,"id":"35","exclusive_time":418700,"entries":9999999}]},{"jit_entries":9991261,"inlined_entries":9991007,"inclusive_time":2086644,"id":"58","exclusive_time":990051,"entries":9999999,"callees":[{"jit_entries":9991351,"inlined_entries":9991261,"inclusive_time":1096593,"id":"64","exclusive_time":1096593,"entries":9999999,"allocations":[{"id":"7","count":8648}]}]},{"jit_entries":9991325,"inlined_entries":9991007,"inclusive_time":3047773,"id":"54","exclusive_time":2104983,"entries":9999998,"callees":[{"jit_entries":9991345,"inlined_entries":9991325,"inclusive_time":559858,"id":"47","exclusive_time":559858,"entries":9999998},{"jit_entries":9999611,"inlined_entries":9991325,"inclusive_time":382931,"id":"35","exclusive_time":382931,"entries":9999998}],"allocations":[{"jit":9991325,"id":"51","count":9999986}]}],"allocations":[{"id":"18","count":1},{"jit":9991007,"id":"51","count":9999985}]}],"allocations":[{"id":"5","count":1}]}],"allocations":[{"id":"2","count":1},{"id":"3","count":1}]}]}},{"total_time":15343347,"thread":3,"spesh_time":0,"gcs":[{"time":7094,"start_time":46505,"sequence":0,"retained_bytes":192,"responsible":0,"promoted_bytes":0,"gen2_roots":59,"full":0,"cleared_bytes":240}]}]'); | |
// grab the "dictionary" from the very first entry | |
var id_to_things = rawData[0]; | |
// the rest of the program expects the list to contain callframes, not the dictionary | |
// so we just shift it off the beginning. | |
rawData.shift(); | |
// Extract some common things out of the raw data. | |
var nodeIdToName = {}; | |
var nodeIdToFile = {}; | |
var nodeIdToLine = {}; | |
(function () { | |
function walkCallGraphNode(node) { | |
if (!nodeIdToName[node.id]) { | |
var existing_data = id_to_things[node.id.toString()]; | |
node.name = existing_data.name; | |
node.line = existing_data.line; | |
node.file = existing_data.file; | |
nodeIdToName[node.id] = node.name == "" ? "<anon>" : node.name; | |
nodeIdToLine[node.id] = node.line < 1 ? "<unknown>" : node.line; | |
nodeIdToFile[node.id] = node.file == "" ? "<unknown>" : node.file; | |
} | |
if (node.callees) | |
node.callees.map(walkCallGraphNode); | |
} | |
rawData.forEach(function (thread) { | |
if (typeof thread.call_graph != "undefined") | |
walkCallGraphNode(thread.call_graph); | |
}); | |
}()); | |
var maxSeqNum = 0; | |
var gcParticipants = []; | |
var gcTimings = []; | |
(function() { | |
rawData.forEach(function (data, index) { | |
gcs = data.gcs; | |
if (gcs.length == 0) | |
return; | |
let seq = gcs[gcs.length - 1].sequence; | |
if (seq > maxSeqNum) | |
maxSeqNum = seq; | |
gcs.forEach(function (data) { | |
if (typeof gcParticipants[data.sequence] == "undefined") | |
gcParticipants[data.sequence] = []; | |
if (typeof gcTimings[data.sequence] == "undefined") | |
gcTimings[data.sequence] = { start: Infinity, end: -Infinity, full: 0 }; | |
gcParticipants[data.sequence].push(index); | |
if (data.start_time < gcTimings[data.sequence].start) | |
gcTimings[data.sequence].start = data.start_time; | |
if (data.start_time + data.time > gcTimings[data.sequence].end) | |
gcTimings[data.sequence].end = data.start_time + data.time; | |
gcTimings[data.sequence].full = data.full; | |
}); | |
}); | |
gcTimings.forEach(function (data) { | |
data.total = data.end - data.start; | |
}); | |
}()); | |
// Register application and add controllers, increase recursion depth for callGraphController | |
var moarProfApp = angular.module('moarProfApp', ['ui.bootstrap']).config(function($rootScopeProvider) { | |
$rootScopeProvider.digestTtl(100); | |
}); | |
moarProfApp.controller('NavigationController', function ($scope) { | |
$scope.Tab = 'Overview'; | |
}); | |
moarProfApp.controller('OverviewController', function ($scope) { | |
/* It's okay to take only the first thread's data here: | |
* - the total time of the main thread should be the maximum | |
* anyway, since all other threads are spawned from it. | |
* - Spesh time is stashed in the main thread's profile data, | |
* even though it's actually spent in another thread. | |
*/ | |
var totalTime = rawData[0].total_time; | |
var speshTime = rawData[0].spesh_time; | |
var gcTime = 0; | |
var gcNursery = 0; | |
var gcFull = 0; | |
var gcNurseryTime = 0; | |
var gcFullTime = 0; | |
var totalEntries = 0; | |
var inlineEntries = 0; | |
var jitEntries = 0; | |
var speshEntries = 0; | |
var deoptOnes = 0; | |
var deoptAlls = 0; | |
var osrs = 0; | |
var numThreads = rawData.length; | |
var averageParticipants = 0; | |
gcParticipants.forEach(function (run) { | |
averageParticipants += run.length; | |
}); | |
averageParticipants = averageParticipants / gcParticipants.length; | |
gcTimings.map(function (gc) { | |
gcTime += gc.total; | |
if (gc.full) { | |
gcFull++; | |
gcFullTime += gc.total; | |
} | |
else { | |
gcNursery++; | |
gcNurseryTime += gc.total; | |
} | |
}); | |
function walkCallGraphNode(node) { | |
totalEntries += node.entries || 0; | |
inlineEntries += node.inlined_entries || 0; | |
speshEntries += node.spesh_entries || 0; | |
jitEntries += node.jit_entries || 0; | |
deoptOnes += node.deopt_one || 0; | |
deoptAlls += node.deopt_all || 0; | |
osrs += node.osr || 0; | |
if (node.callees) | |
node.callees.map(walkCallGraphNode); | |
} | |
rawData.forEach(function (thread) { | |
if (typeof thread.call_graph != "undefined") | |
walkCallGraphNode(thread.call_graph); | |
}); | |
$scope.NumThreads = numThreads; | |
// Time spent | |
var overheadTime = gcTime; | |
var executingTime = totalTime - overheadTime; | |
$scope.TotalTime = +(totalTime / 1000).toFixed(2); | |
$scope.GCOverheadTime = +(overheadTime / 1000).toFixed(2); | |
$scope.GCOverheadTimePercent = +(100 * overheadTime / totalTime).toFixed(2); | |
$scope.ExecutingTime = +(executingTime / 1000).toFixed(2); | |
$scope.ExecutingTimePercent = +(100 * executingTime / totalTime).toFixed(2); | |
$scope.GCTime = +(gcTime / 1000).toFixed(2); | |
$scope.GCTimePercent = +(100 * gcTime / totalTime).toFixed(2); | |
$scope.SpeshTime = +(speshTime / 1000).toFixed(2); | |
$scope.SpeshTimePercent = +(100 * speshTime / totalTime).toFixed(2); | |
// Routines | |
var interpEntries = totalEntries - (jitEntries + speshEntries); | |
$scope.EntriesWithoutInline = totalEntries - inlineEntries; | |
$scope.EntriesInline = inlineEntries; | |
$scope.InlinePercent = +(100 * inlineEntries / totalEntries).toFixed(2); | |
$scope.InterpFrames = interpEntries; | |
$scope.InterpFramesPercent = +(100 * interpEntries / totalEntries).toFixed(2); | |
$scope.SpeshFrames = speshEntries; | |
$scope.SpeshFramesPercent = +(100 * speshEntries / totalEntries).toFixed(2); | |
$scope.JITFrames = jitEntries; | |
$scope.JITFramesPercent = +(100 * jitEntries / totalEntries).toFixed(2); | |
// Garbage collection | |
$scope.GCRuns = gcNursery + gcFull; | |
$scope.FullGCRuns = gcFull; | |
$scope.NurseryAverage = +((gcNurseryTime / 1000) / gcNursery).toFixed(2); | |
$scope.FullAverage = +((gcFullTime / 1000) / gcFull).toFixed(2); | |
$scope.AverageParticipants = averageParticipants.toFixed(2); | |
// Dynamic optimization | |
var optimizedFrames = speshEntries + jitEntries; | |
$scope.OptimizedFrames = optimizedFrames; | |
$scope.DeoptOnes = deoptOnes; | |
$scope.DeoptOnePercent = +(100 * deoptOnes / (optimizedFrames || 1)).toFixed(2); | |
$scope.DeoptAlls = deoptAlls; | |
$scope.OSRs = osrs; | |
}); | |
moarProfApp.controller('RoutinesController', function ($scope) { | |
// Walk call graph to build data. | |
var idToEntries = {}; | |
var idToSpeshEntries = {}; | |
var idToJITEntries = {}; | |
var idToExclusive = {}; | |
var idToInclusive = {}; | |
var idToOSR = {}; | |
var idRecDepth = {}; | |
var totalExclusive = 0; | |
var totalInclusive = rawData[0].call_graph.inclusive_time; | |
function walkCallGraphNode(node) { | |
if (!idToEntries[node.id]) { | |
idToEntries[node.id] = 0; | |
idToSpeshEntries[node.id] = 0; | |
idToJITEntries[node.id] = 0; | |
idToExclusive[node.id] = 0; | |
idToInclusive[node.id] = 0; | |
idToOSR[node.id] = false; | |
idRecDepth[node.id] = 0; | |
} | |
idToEntries[node.id] += node.entries || 0; | |
idToSpeshEntries[node.id] += node.spesh_entries || 0; | |
idToJITEntries[node.id] += node.jit_entries || 0; | |
idToExclusive[node.id] += node.exclusive_time || 0; | |
totalExclusive += node.exclusive_time || 0; | |
if (node.osr > 0) | |
idToOSR[node.id] = true; | |
if (idRecDepth[node.id] == 0) | |
idToInclusive[node.id] += node.inclusive_time; | |
if (node.callees) { | |
idRecDepth[node.id]++; | |
node.callees.map(walkCallGraphNode); | |
idRecDepth[node.id]--; | |
} | |
} | |
rawData.forEach(function (thread) { | |
if (typeof thread.call_graph != "undefined") | |
walkCallGraphNode(thread.call_graph); | |
}); | |
// Build object list per routine. | |
var routineList = []; | |
for (id in idToEntries) { | |
var speshEntriesPercent = +(100 * idToSpeshEntries[id] / idToEntries[id]).toFixed(2); | |
var jitEntriesPercent = +(100 * idToJITEntries[id] / idToEntries[id]).toFixed(2); | |
var interpEntriesPercent = 100 - (speshEntriesPercent + jitEntriesPercent); | |
var entry = { | |
Name: nodeIdToName[id], | |
Line: nodeIdToLine[id], | |
File: nodeIdToFile[id], | |
Entries: idToEntries[id], | |
InterpEntriesPercent: interpEntriesPercent, | |
SpeshEntriesPercent: speshEntriesPercent, | |
JITEntriesPercent: jitEntriesPercent, | |
InclusiveTime: +(idToInclusive[id] / 1000).toFixed(2), | |
InclusiveTimePercent: +(100 * idToInclusive[id] / totalInclusive).toFixed(2), | |
ExclusiveTime: +(idToExclusive[id] / 1000).toFixed(2), | |
ExclusiveTimePercent: +(100 * idToExclusive[id] / totalExclusive).toFixed(2), | |
OSR: idToOSR[id] | |
}; | |
routineList.push(entry); | |
} | |
$scope.Routines = routineList; | |
$scope.predicate = "InclusiveTime"; | |
$scope.reverse = true; | |
}); | |
moarProfApp.controller('CallGraphController', function ($scope) { | |
$scope.Current = rawData[0].call_graph; | |
$scope.total_time = rawData[0].total_time; | |
$scope.SuchCallers = false; | |
$scope.RecentCallers = []; | |
$scope.predicate = "Time"; | |
$scope.reverse = true; | |
var all_callers = []; | |
updateCurrentData(); | |
$scope.toCallee = function (callee) { | |
// Update caller history. | |
all_callers.push($scope.Current); | |
$scope.RecentCallers.push($scope.Current); | |
if ($scope.RecentCallers.length > 5) | |
$scope.RecentCallers.shift(); | |
// Update current node and callees. | |
$scope.Current = callee; | |
updateCurrentData(); | |
}; | |
$scope.toCaller = function (caller) { | |
// Update caller history. | |
while (all_callers.length > 0) { | |
var removed = all_callers.pop(); | |
if ($scope.RecentCallers.length > 0) | |
$scope.RecentCallers.pop(); | |
if (removed == caller) | |
break; | |
} | |
if (all_callers.length > $scope.RecentCallers.length) { | |
var ptr = all_callers.length - $scope.RecentCallers.length; | |
while (ptr >= 0 && $scope.RecentCallers.length < 5) { | |
$scope.RecentCallers.unshift(all_callers[ptr]); | |
ptr--; | |
} | |
} | |
// Update current node and callees. | |
$scope.Current = caller; | |
updateCurrentData(); | |
} | |
/* | |
* Given a callee, create a unique, repeatable color; | |
* h/t https://stackoverflow.com/questions/3426404 | |
*/ | |
$scope.backgroundColor = function (callee) { | |
var str = callee.$$hashKey + callee.file + callee.name; | |
for (var i = 0, hash = 0; i < str.length; hash = str.charCodeAt(i++) + ((hash << 5) - hash)); | |
for (var i = 0, colour = "#"; i < 3; colour += ("00" + ((hash >> i++ * 8) & 0xFF).toString(16)).slice(-2)); | |
return colour; | |
} | |
function updateCurrentData() { | |
// Line and file. | |
var current = $scope.Current; | |
$scope.Line = current.line; | |
$scope.File = current.file; | |
// Entry statistics. | |
var interpEntries = current.entries - (current.spesh_entries + current.jit_entries); | |
var nonInlineEntries = current.entries - current.inlined_entries; | |
$scope.Entries = nonInlineEntries; | |
$scope.Percent = (100 * nonInlineEntries / current.entries).toFixed(2); | |
$scope.InlineEntries = current.inlined_entries; | |
$scope.InlinePercent = (100 * current.inlined_entries / current.entries).toFixed(2); | |
$scope.InterpEntries = interpEntries; | |
$scope.InterpPercent = (100 * interpEntries / current.entries).toFixed(2); | |
$scope.SpeshEntries = current.spesh_entries; | |
$scope.SpeshPercent = (100 * current.spesh_entries / current.entries).toFixed(2); | |
$scope.JITEntries = current.jit_entries; | |
$scope.JITPercent = (100 * current.jit_entries / current.entries).toFixed(2); | |
// Callees. | |
$scope.Callees = calleesOf(current); | |
} | |
function calleesOf(node) { | |
if (!node.callees) | |
return []; | |
var totalExclusive = 0.0; | |
node.callees.map(function (c) { totalExclusive += c.exclusive_time; }); | |
return node.callees.map(function (c) { | |
var speshCallsPercent = +(100 * c.spesh_entries / c.entries).toFixed(2); | |
var jitCallsPercent = +(100 * c.jit_entries / c.entries).toFixed(2); | |
var interpCallsPercent = 100 - (speshCallsPercent + jitCallsPercent); | |
var inlinedPercent = +(100 * c.inlined_entries / c.entries).toFixed(2); | |
return { | |
Name: nodeIdToName[c.id], | |
Line: nodeIdToLine[c.id], | |
File: nodeIdToFile[c.id], | |
Calls: c.entries, | |
Time: +(c.inclusive_time / 1000).toFixed(2), | |
TimePercent: +(100 * c.inclusive_time / node.inclusive_time).toFixed(2), | |
InterpCallsPercent: interpCallsPercent, | |
SpeshCallsPercent: speshCallsPercent, | |
JITCallsPercent: jitCallsPercent, | |
InlinedPercent: inlinedPercent, | |
VeryInline: inlinedPercent >= 95, | |
SometimesInline: inlinedPercent < 95 && inlinedPercent > 10, | |
Node: c | |
}; | |
}); | |
} | |
}); | |
moarProfApp.controller('AllocationsController', function ($scope, $uibModal) { | |
// Traverse all call nodes, counting up the allocations. | |
var typeIdToName = {}; | |
var typeIdToAllocations = {}; | |
var typeIdToAllocationsByType = {}; | |
var typeIdToRoutineStats = {}; | |
var maxAllocations = 1; | |
function walkCallGraphNode(node) { | |
if (node.allocations) { | |
node.allocations.map(function (alloc) { | |
alloc.type = id_to_things[alloc.id]; | |
if (!typeIdToName[alloc.id]) { | |
typeIdToName[alloc.id] = alloc.type == "" ? "<anon>" : alloc.type; | |
typeIdToAllocations[alloc.id] = 0; | |
typeIdToAllocationsByType[alloc.id] = [0, 0, 0]; | |
typeIdToRoutineStats[alloc.id] = {}; | |
} | |
typeIdToAllocations[alloc.id] += alloc.count; | |
typeIdToAllocationsByType[alloc.id][0] += alloc.count - (alloc.spesh || 0) - (alloc.jit || 0); | |
typeIdToAllocationsByType[alloc.id][1] += alloc.spesh || 0; | |
typeIdToAllocationsByType[alloc.id][2] += alloc.jit || 0; | |
if (typeIdToAllocations[alloc.id] > maxAllocations) | |
maxAllocations = typeIdToAllocations[alloc.id]; | |
if (typeIdToRoutineStats[alloc.id][node.id]) { | |
typeIdToRoutineStats[alloc.id][node.id]['count'] += alloc.count || 0; | |
typeIdToRoutineStats[alloc.id][node.id]['spesh'] += alloc.spesh || 0; | |
typeIdToRoutineStats[alloc.id][node.id]['jit'] += alloc.jit || 0; | |
} else { | |
typeIdToRoutineStats[alloc.id][node.id] = { | |
count: alloc.count || 0, | |
spesh: alloc.spesh || 0, | |
jit: alloc.jit || 0 | |
}; | |
} | |
}); | |
} | |
if (node.callees) { | |
node.callees.map(walkCallGraphNode); | |
} | |
} | |
rawData.forEach(function (thread) { | |
if (typeof thread.call_graph != "undefined") | |
walkCallGraphNode(thread.call_graph); | |
}); | |
// Build allocation summary. | |
var allocationSummary = []; | |
for (id in typeIdToName) { | |
var maxAllocationByRoutine = 1; | |
for (var rid in typeIdToRoutineStats[id]) | |
if (typeIdToRoutineStats[id][rid]['count'] > maxAllocationByRoutine) | |
maxAllocationByRoutine = typeIdToRoutineStats[id][rid]['count']; | |
var routineStats = []; | |
for (var rid in typeIdToRoutineStats[id]) | |
routineStats.push({ | |
Name: nodeIdToName[rid], | |
Line: nodeIdToLine[rid], | |
File: nodeIdToFile[rid], | |
Allocations: typeIdToRoutineStats[id][rid]['count'], | |
AllocationsSpesh: typeIdToRoutineStats[id][rid]['spesh'], | |
AllocationsJit: typeIdToRoutineStats[id][rid]['jit'], | |
AllocationsPercent: (100 * typeIdToRoutineStats[id][rid]['count'] / maxAllocationByRoutine), | |
AllocationsInterpPercent: (100 * (typeIdToRoutineStats[id][rid]['count'] - typeIdToRoutineStats[id][rid]['jit'] - typeIdToRoutineStats[id][rid]['spesh']) / maxAllocationByRoutine), | |
AllocationsSpeshPercent: (100 * typeIdToRoutineStats[id][rid]['spesh'] / maxAllocationByRoutine), | |
AllocationsJitPercent: (100 * typeIdToRoutineStats[id][rid]['jit'] / maxAllocationByRoutine) | |
}); | |
var entry = { | |
Name: typeIdToName[id], | |
Allocations: typeIdToAllocations[id], | |
AllocationsPercent: +(100 * typeIdToAllocations[id] / maxAllocations).toFixed(2), | |
AllocationsInterpPercent: +(100 * typeIdToAllocationsByType[id][0] / maxAllocations).toFixed(2), | |
AllocationsSpeshPercent: +(100 * typeIdToAllocationsByType[id][1] / maxAllocations).toFixed(2), | |
AllocationsJitPercent: +(100 * typeIdToAllocationsByType[id][2] / maxAllocations).toFixed(2), | |
RoutineStats: routineStats | |
}; | |
allocationSummary.push(entry); | |
} | |
$scope.AllocationSummary = allocationSummary; | |
$scope.predicate = "Allocations"; | |
$scope.reverse = true; | |
$scope.routinePredicate = "Allocations"; | |
$scope.routineReverse = true; | |
// Allocating routines handlng. | |
$scope.modalInstance = null; | |
$scope.showAllocatingRoutines = function (alloc) { | |
// Show modal dialog with data. | |
$scope.CurrentAllocatingRoutine = alloc.Name; | |
$scope.CurrentAllocatingRoutineStats = alloc.RoutineStats; | |
$scope.modalInstance = $uibModal.open({ | |
templateUrl: 'myModalContent.html', | |
scope: $scope | |
}); | |
} | |
}); | |
moarProfApp.controller('GCController', function ($scope) { | |
// Find longest GC run. | |
var longestGC = 0; | |
gcTimings.map(function (timing) { | |
if (timing.total > longestGC) | |
longestGC = timing.total; | |
}); | |
// Produce something nice to render. | |
var run = 0; | |
$scope.GCs = rawData[0].gcs.map(function (gc) { | |
var totalBytes = gc.cleared_bytes + gc.retained_bytes + gc.promoted_bytes; | |
return { | |
Run: ++run, | |
StartTime: +(gc.start_time / 1000).toFixed(2), | |
Time: +(gc.time / 1000).toFixed(2), | |
Full: (gc.full != 0), | |
TimePercent: +(100 * gc.time / longestGC).toFixed(2), | |
RetainedKilobytes: Math.round(gc.retained_bytes / 1024), | |
PromotedKilobytes: Math.round(gc.promoted_bytes / 1024), | |
ClearedKilobytes: Math.round(gc.cleared_bytes / 1024), | |
RetainedPercent: +(100 * gc.retained_bytes / totalBytes).toFixed(2), | |
PromotedPercent: +(100 * gc.promoted_bytes / totalBytes).toFixed(2), | |
ClearedPercent: +(100 * gc.cleared_bytes / totalBytes).toFixed(2), | |
Gen2Roots: 'gen2_roots' in gc ? gc.gen2_roots : 0 | |
}; | |
}); | |
$scope.predicate = 'Run'; | |
$scope.reverse = false; | |
}); | |
moarProfApp.controller('OSRDeoptController', function ($scope) { | |
// Walk call graph to build data. | |
var idToOSR = {}; | |
var idToDeoptOne = {}; | |
var idToDeoptAll = {}; | |
var maxOSR = 1; | |
var maxDeoptOne = 1; | |
var maxDeoptAll = 1; | |
function walkCallGraphNode(node) { | |
if (!idToOSR[node.id]) { | |
idToOSR[node.id] = 0; | |
idToDeoptOne[node.id] = 0; | |
idToDeoptAll[node.id] = 0; | |
} | |
idToOSR[node.id] += node.osr || 0; | |
idToDeoptOne[node.id] += node.deopt_one || 0; | |
idToDeoptAll[node.id] += node.deopt_all || 0; | |
if (idToOSR[node.id] > maxOSR) | |
maxOSR = idToOSR[node.id]; | |
if (idToDeoptOne[node.id] > maxDeoptOne) | |
maxDeoptOne = idToDeoptOne[node.id]; | |
if (idToDeoptAll[node.id] > maxDeoptAll) | |
maxDeoptAll = idToDeoptAll[node.id]; | |
if (node.callees) | |
node.callees.map(walkCallGraphNode); | |
} | |
walkCallGraphNode(rawData[0].call_graph); | |
// Build up OSR, deopt one, and deopt all tables. | |
var osrs = []; | |
var deoptOnes = []; | |
var deoptAlls = []; | |
for (id in idToOSR) { | |
if (idToOSR[id] > 0) { | |
osrs.push({ | |
Name: nodeIdToName[id], | |
Line: nodeIdToLine[id], | |
File: nodeIdToFile[id], | |
Count: idToOSR[id], | |
Percent: Math.round(100 * idToOSR[id] / maxOSR) | |
}); | |
} | |
if (idToDeoptOne[id] > 0) { | |
deoptOnes.push({ | |
Name: nodeIdToName[id], | |
Line: nodeIdToLine[id], | |
File: nodeIdToFile[id], | |
Count: idToDeoptOne[id], | |
Percent: Math.round(100 * idToDeoptOne[id] / maxDeoptOne) | |
}); | |
} | |
if (idToDeoptAll[id] > 0) { | |
deoptAlls.push({ | |
Name: nodeIdToName[id], | |
Line: nodeIdToLine[id], | |
File: nodeIdToFile[id], | |
Count: idToDeoptAll[id], | |
Percent: Math.round(100 * idToDeoptAll[id] / maxDeoptAll) | |
}); | |
} | |
} | |
$scope.OSRs = osrs; | |
$scope.DeoptOnes = deoptOnes; | |
$scope.DeoptAlls = deoptAlls; | |
$scope.predicate = 'Count'; | |
$scope.reverse = true; | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment