Skip to content

Commit fcdb29f

Browse files
committed
deduplicate filename/lineno/routine name and type names in profile
1 parent 8966cfd commit fcdb29f

File tree

2 files changed

+72
-13
lines changed

2 files changed

+72
-13
lines changed

src/vm/moar/HLL/Backend.nqp

Lines changed: 62 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,68 @@ class HLL::Backend::MoarVM {
7575
$escaped_squote := q{\\'};
7676
}
7777

78+
my $id_to_thing := nqp::hash();
79+
7880
sub post_process_call_graph_node($node) {
79-
if $node<allocations> {
80-
for $node<allocations> -> %alloc_info {
81-
my $type := %alloc_info<type>;
82-
%alloc_info<type> := $type.HOW.name($type);
81+
try {
82+
if nqp::existskey($node, "allocations") {
83+
for $node<allocations> -> %alloc_info {
84+
my $type := %alloc_info<type>;
85+
unless nqp::existskey($id_to_thing, %alloc_info<id>) {
86+
$id_to_thing{%alloc_info<id>} := $type.HOW.name($type);
87+
}
88+
nqp::deletekey(%alloc_info, "type");
89+
}
8390
}
91+
unless nqp::existskey($id_to_thing, $node<id>) {
92+
my $shared_data := nqp::hash(
93+
"file", $node<file>,
94+
"line", $node<line>,
95+
"name", $node<name>,
96+
);
97+
$id_to_thing{$node<id>} := $shared_data;
98+
}
99+
nqp::deletekey($node, "file");
100+
nqp::deletekey($node, "line");
101+
nqp::deletekey($node, "name");
102+
if nqp::existskey($node, "callees") {
103+
for $node<callees> {
104+
post_process_call_graph_node($_);
105+
}
106+
}
107+
CATCH {
108+
note(nqp::getmessage($!));
109+
}
110+
}
111+
}
112+
113+
sub sorted_keys($hash) {
114+
my @keys;
115+
for $hash {
116+
nqp::push(@keys, $_.key);
84117
}
85-
if $node<callees> {
86-
for $node<callees> {
87-
post_process_call_graph_node($_);
118+
if +@keys == 0 {
119+
return @keys;
120+
}
121+
122+
# we expect on the order of 6 or 7 keys here, so bubble sort is fine.
123+
my int $start := 0;
124+
my int $numkeys := +@keys;
125+
my str $swap;
126+
my int $current;
127+
while $start < $numkeys - 1 {
128+
$current := 0;
129+
while $current < $numkeys - 1 {
130+
if @keys[$current] lt @keys[$current + 1] {
131+
$swap := @keys[$current];
132+
@keys[$current] := @keys[$current + 1];
133+
@keys[$current + 1] := $swap;
134+
}
135+
$current++;
88136
}
137+
$start++;
89138
}
139+
return @keys;
90140
}
91141

92142
sub to_json($obj) {
@@ -107,17 +157,17 @@ class HLL::Backend::MoarVM {
107157
elsif nqp::ishash($obj) {
108158
nqp::push_s(@pieces, '{');
109159
my $first := 1;
110-
for $obj {
160+
for sorted_keys($obj) {
111161
if $first {
112162
$first := 0;
113163
}
114164
else {
115165
nqp::push_s(@pieces, ',');
116166
}
117167
nqp::push_s(@pieces, '"');
118-
nqp::push_s(@pieces, $_.key);
168+
nqp::push_s(@pieces, $_);
119169
nqp::push_s(@pieces, '":');
120-
to_json($_.value);
170+
to_json($obj{$_});
121171
}
122172
nqp::push_s(@pieces, '}');
123173
}
@@ -155,6 +205,8 @@ class HLL::Backend::MoarVM {
155205
post_process_call_graph_node($_<call_graph>);
156206
}
157207

208+
nqp::unshift($data, $id_to_thing);
209+
158210
if $want_json {
159211
to_json($data);
160212
nqp::printfh($profile_fh, nqp::join('', @pieces));

src/vm/moar/profiler/template.html

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -707,16 +707,23 @@ <h3>Global Deoptimization</h3>
707707
<script>
708708
var rawData = JSON.parse('{{{PROFILER_OUTPUT}}}');
709709

710+
// grab the "dictionary" from the very first entry
711+
var id_to_things = rawData[0];
712+
// the rest of the program expects the list to contain callframes, not the dictionary
713+
// so we just shift it off the beginning.
714+
rawData.shift();
715+
710716
// Extract some common things out of the raw data.
711717
var nodeIdToName = {};
712718
var nodeIdToFile = {};
713719
var nodeIdToLine = {};
714720
(function () {
715721
function walkCallGraphNode(node) {
716722
if (!nodeIdToName[node.id]) {
717-
nodeIdToName[node.id] = node.name == "" ? "<anon>" : node.name;
718-
nodeIdToLine[node.id] = node.line < 1 ? "<unknown>" : node.line;
719-
nodeIdToFile[node.id] = node.file == "" ? "<unknown>" : node.file;
723+
var existing_data = id_to_things[node.id.toString()];
724+
nodeIdToName[node.id] = existing_data.name == "" ? "<anon>" : existing_data.name;
725+
nodeIdToLine[node.id] = existing_data.line < 1 ? "<unknown>" : existing_data.line;
726+
nodeIdToFile[node.id] = existing_data.file == "" ? "<unknown>" : existing_data.file;
720727
}
721728
if (node.callees)
722729
node.callees.map(walkCallGraphNode);

0 commit comments

Comments
 (0)