-
-
Save timo/2d4bf518f27465cd7a51 to your computer and use it in GitHub Desktop.
This file contains 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
diff --git a/src/vm/moar/HLL/Backend.nqp b/src/vm/moar/HLL/Backend.nqp | |
index aabf430..8c76486 100644 | |
--- a/src/vm/moar/HLL/Backend.nqp | |
+++ b/src/vm/moar/HLL/Backend.nqp | |
@@ -75,13 +75,29 @@ class HLL::Backend::MoarVM { | |
$escaped_squote := q{\\'}; | |
} | |
+ my $id_to_thing := nqp::hash(); | |
+ | |
sub post_process_call_graph_node($node) { | |
if $node<allocations> { | |
for $node<allocations> -> %alloc_info { | |
my $type := %alloc_info<type>; | |
- %alloc_info<type> := $type.HOW.name($type); | |
+ unless nqp::existskey($id_to_thing, %alloc_info<id>) { | |
+ $id_to_thing{%alloc_info<id>} := $type.HOW.name($type); | |
+ } | |
+ nqp::deletekey(%alloc_info, "type"); | |
} | |
} | |
+ unless nqp::existskey($id_to_thing, $node<id>) { | |
+ my $shared_data := nqp::hash( | |
+ "file", $node<file>, | |
+ "line", $node<line>, | |
+ "name", $node<name>, | |
+ ); | |
+ $id_to_thing{$node<id>} := $shared_data; | |
+ } | |
+ nqp::deletekey($node, "file"); | |
+ nqp::deletekey($node, "line"); | |
+ nqp::deletekey($node, "name"); | |
if $node<callees> { | |
for $node<callees> { | |
post_process_call_graph_node($_); | |
@@ -89,6 +105,35 @@ class HLL::Backend::MoarVM { | |
} | |
} | |
+ sub sorted_keys($hash) { | |
+ my @keys; | |
+ for $hash { | |
+ nqp::push(@keys, $_.key); | |
+ } | |
+ if +@keys == 0 { | |
+ return @keys; | |
+ } | |
+ | |
+ # we expect on the order of 6 or 7 keys here, so bubble sort is fine. | |
+ my int $start := 0; | |
+ my int $numkeys := +@keys; | |
+ my str $swap; | |
+ my int $current; | |
+ while $start < $numkeys - 1 { | |
+ $current := 0; | |
+ while $current < $numkeys - 1 { | |
+ if @keys[$current] lt @keys[$current + 1] { | |
+ $swap := @keys[$current]; | |
+ @keys[$current] := @keys[$current + 1]; | |
+ @keys[$current + 1] := $swap; | |
+ } | |
+ $current++; | |
+ } | |
+ $start++; | |
+ } | |
+ return @keys; | |
+ } | |
+ | |
sub to_json($obj) { | |
if nqp::islist($obj) { | |
nqp::push_s(@pieces, '['); | |
@@ -107,7 +152,7 @@ class HLL::Backend::MoarVM { | |
elsif nqp::ishash($obj) { | |
nqp::push_s(@pieces, '{'); | |
my $first := 1; | |
- for $obj { | |
+ for sorted_keys($obj) { | |
if $first { | |
$first := 0; | |
} | |
@@ -115,9 +160,9 @@ class HLL::Backend::MoarVM { | |
nqp::push_s(@pieces, ','); | |
} | |
nqp::push_s(@pieces, '"'); | |
- nqp::push_s(@pieces, $_.key); | |
+ nqp::push_s(@pieces, $_); | |
nqp::push_s(@pieces, '":'); | |
- to_json($_.value); | |
+ to_json($obj{$_}); | |
} | |
nqp::push_s(@pieces, '}'); | |
} | |
@@ -155,6 +200,8 @@ class HLL::Backend::MoarVM { | |
post_process_call_graph_node($_<call_graph>); | |
} | |
+ nqp::unshift($data, $id_to_thing); | |
+ | |
if $want_json { | |
to_json($data); | |
nqp::printfh($profile_fh, nqp::join('', @pieces)); | |
diff --git a/src/vm/moar/profiler/template.html b/src/vm/moar/profiler/template.html | |
index edc7966..6aaad62 100644 | |
--- a/src/vm/moar/profiler/template.html | |
+++ b/src/vm/moar/profiler/template.html | |
@@ -707,6 +707,12 @@ | |
<script> | |
var rawData = JSON.parse('{{{PROFILER_OUTPUT}}}'); | |
+ // 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 = {}; | |
@@ -714,9 +720,10 @@ | |
(function () { | |
function walkCallGraphNode(node) { | |
if (!nodeIdToName[node.id]) { | |
- 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; | |
+ var existing_data = id_to_things[node.id.toString()]; | |
+ nodeIdToName[node.id] = existing_data.name == "" ? "<anon>" : existing_data.name; | |
+ nodeIdToLine[node.id] = existing_data.line < 1 ? "<unknown>" : existing_data.line; | |
+ nodeIdToFile[node.id] = existing_data.file == "" ? "<unknown>" : existing_data.file; | |
} | |
if (node.callees) | |
node.callees.map(walkCallGraphNode); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment