Add memnodes.pl script to process output stream.
[p5sagit/Devel-Size.git] / memnodes.pl
1 #!/bin/env perl
2
3 use strict;
4 use warnings;
5
6 my @stack;
7 my %seqn2node;
8
9 sub pop_stack {
10     my $x = pop @stack;
11     delete $seqn2node{$x->{seqn}};
12     my $size = 0; $size += $_  for values %{$x->{leaves}};
13     $x->{self_size} = $size;
14     if (my $parent = $stack[-1]) {
15         # link to parent
16         $x->{parent_seqn} = $parent->{seqn};
17         # accumulate into parent
18         $parent->{kids_node_count} += 1 + ($x->{kids_node_count}||0);
19         $parent->{kids_size} += $size + $x->{kids_size};
20         push @{$parent->{child_seqn}}, $x->{seqn};
21     }
22     # output
23     # ...
24     return $x;
25 }
26
27 while (<>) {
28     chomp;
29     my ($type, $seqn, $val, $name, $extra) = split / /, $_, 5;
30     if ($type eq "N") {     # Node ($val is depth)
31         while ($val < @stack) {
32             my $x = pop_stack();
33             warn "N $seqn d$val ends $x->{seqn} d$x->{depth}: size $x->{self_size}+$x->{kids_size}\n";
34         }
35         die 1 if $stack[$val];
36         my $node = $stack[$val] = { seqn => $seqn, name => $name, extra => $extra, attr => [], leaves => {}, depth => $val, self_size=>0, kids_size=>0 };
37         $seqn2node{$seqn} = $node;
38     }
39     elsif ($type eq "L") {  # Leaf name and memory size
40         my $node = $seqn2node{$seqn} || die;
41         $node->{leaves}{$name} += $val;
42     }
43     elsif ($type eq "A") {  # Attribute name and value
44         my $node = $seqn2node{$seqn} || die;
45         push @{ $node->{attr} }, $name, $val; # pairs
46     }
47     else {
48         warn "Invalid type '$type' on line $. ($_)";
49     }
50 }
51
52 my $x;
53 while (@stack > 1) {
54     $x = pop_stack() while @stack;
55     warn "EOF ends $x->{seqn} d$x->{depth}: size $x->{self_size}+$x->{kids_size}\n";
56 }
57 use Data::Dumper;
58 warn Dumper(\$x);
59 warn Dumper(\%seqn2node);
60
61 =for
62 SV(PVAV) fill=1/1       [#1 @0] 
63 :   +64 sv =64 
64 :   +16 av_max =80 
65 :   AVelem->        [#2 @1] 
66 :   :   SV(RV)      [#3 @2] 
67 :   :   :   +24 sv =104 
68 :   :   :   RV->        [#4 @3] 
69 :   :   :   :   SV(PVAV) fill=-1/-1     [#5 @4] 
70 :   :   :   :   :   +64 sv =168 
71 :   AVelem->        [#6 @1] 
72 :   :   SV(IV)      [#7 @2] 
73 :   :   :   +24 sv =192 
74 192 at -e line 1.
75 =cut
76 __DATA__
77 N 1 0 SV(PVAV) fill=1/1
78 L 1 64 sv
79 L 1 16 av_max
80 N 2 1 AVelem->
81 N 3 2 SV(RV)
82 L 3 24 sv
83 N 4 3 RV->
84 N 5 4 SV(PVAV) fill=-1/-1
85 L 5 64 sv
86 N 6 1 AVelem->
87 N 7 2 SV(IV)
88 L 7 24 sv