You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl-cvs@perl.apache.org by do...@apache.org on 2001/01/07 23:43:36 UTC
cvs commit: modperl-2.0/util sizeof.pl
dougm 01/01/07 14:43:36
Added: pod modperl_sizeof.pod
util sizeof.pl
Log:
researching sizeof() things
Revision Changes Path
1.1 modperl-2.0/pod/modperl_sizeof.pod
Index: modperl_sizeof.pod
===================================================================
=head1 NAME
modperl_sizeof - measure sizeof structures
=head1 DESCRIPTION
This pod documents the sizeof various structures, as determined by
I<util/sizeof.pl>. These measurements are mainly for research
purposes into making Perl things smaller, or rather, how to use less
Perl things.
=head1 Perl Structures
Structures diagrams are courtesy gdb (print pretty) and a bit of hand crafting.
=over 4
=item CV - 229 minimum, 254 minimum w/ symbol table entry
cv = {
sv_any = { // XPVCV *
xpv_pv = 0x0, // char *
xpv_cur = 0, // STRLEN
xpv_len = 0, // STRLEN
xof_off = 0 , // IV
xnv_nv = 0, // NV
xmg_magic = 0x0, // MAGIC *
xmg_stash = 0x0, // HV *
xcv_stash = 0x0, // HV *
xcv_start = 0x0, // OP *
xcv_root = 0x0, // OP *
xcv_xsub = 0x0, // void (*)(register PerlInterpreter *, CV *)
xcv_xsubany = { // ANY
any_ptr = 0x0,
any_i32 = 0,
any_iv = 0,
any_long = 0,
any_dptr = 0,
any_dxptr = 0
},
xcv_gv = { // GV *
sv_any = { // void *
xpv_pv = 0x0, // char *
xpv_cur = 0, // STRLEN
xpv_len = 0, // STRLEN
xiv_iv = 0, // IV
xnv_nv = 0, // NV
xmg_magic = { // MAGIC *
mg_moremagic = 0x0, // MAGIC *
mg_virtual = 0x0, // MGVTBL *
mg_private = 0, // U16
mg_type = 0, // char
mg_flags = 0, // U8
mg_obj = 0x0, // SV *
mg_ptr = 0x0, // char *
mg_len = 0, // I32
},
xmg_stash = 0x0, // HV *
xgv_gp = { // GP *
gp_sv = { // SV *
sv_any = 0x0, // void *
sv_refcnt = 0, // U32
sv_flags = 0 // U32
},
gp_refcnt = 0, // U32
gp_io = 0x0, // struct io *
gp_form = 0x0, // CV *
gp_av = 0x0, // AV *
gp_hv = 0x0, // HV *
gp_egv = 0x0, // GV *
gp_cv = 0x0, // CV *
gp_cvgen = 0, // U32
gp_flags = 0, // U32
gp_line = 0, // line_t
gp_file = 0x0, // char *
},
xgv_name = 0x0, // char *
xgv_namelen = 0, // STRLEN
xgv_stash = 0x0, // void *
xgv_flags = 0, // U8
},
sv_refcnt = 0, // U32
sv_flags = 0, // U32
},
xcv_file = 0x0, // char *
xcv_depth = 0, // long
xcv_padlist = 0x0, // AV *
xcv_outside = 0x0, // CV *
xcv_flags = 0, // cv_flags_t
}
sv_refcnt = 0, // U32
sv_flags = 0, // U32
};
In addition to the minimum bytes:
=over 4
=item name of the subroutine: GvNAMELEN(CvGV(cv))+1
=item symbol table entry: HvENTRY (25 + GvNAMELEN(CvGV(cv))+1)
=item minimum sizeof(AV) * 3: xcv_padlist if !CvXSUB(cv)
=item CvROOT(cv) optree
=back
=item HV - 60 minmum
hv = {
sv_any = { // SV *
xhv_array = 0x0, // char *
xhv_fill = 0, // STRLEN
xhv_max = 0, // STRLEN
xhv_keys = 0, // IV
xnv_nv = 0, // NV
xmg_magic = 0x0, // MAGIC *
xmg_stash = 0x0, // HV *
xhv_riter = 0, // I32
xhv_eiter = 0x0, // HE *
xhv_pmroot = 0x0, // PMOP *
xhv_name = 0x0 // char *
},
sv_refcnt = 0, // U32
sv_flags = 0, // U32
};
Each entry adds sizeof(HvENTRY), minimum of 7 (initial xhv_max).
Note that keys of the same value share sizeof(HEK), across all hashes.
=item HvENTRY - 25 + HeKLEN+1
sizeof(HE *) + sizeof(HE) + sizeof(HEK)
=item HE - 12
he = {
hent_next = 0x0, // HE *
hent_hek = 0x0, // HEK *
hent_val = 0x0 // SV *
};
=item HEK - 9 + hek_len
hek = {
hek_hash = 0, // U32
hek_len = 0, // I32
hek_key = 0, // char
};
=item AV - 53
av = {
sv_any = { // SV *
xav_array = 0x0, // char *
xav_fill = 0, // size_t
xav_max = 0, // size_t
xof_off = 0, // IV
xnv_nv = 0, // NV
xmg_magic = 0x0, // MAGIC *
xmg_stash = 0x0, // HV *
xav_alloc = 0x0, // SV **
xav_arylen = 0x0, // SV *
xav_flags = 0, // U8
},
sv_refcnt = 0, // U32
sv_flags = 0 // U32
};
In addition to the minimum bytes:
=over 4
=item AvFILL(av) * sizeof(SV *)
=back
=back
=head1 SEE ALSO
perlguts(3), B::Size(3),
http://gisle.aas.no/perl/illguts/
=head1 AUTHOR
Doug MacEachern
1.1 modperl-2.0/util/sizeof.pl
Index: sizeof.pl
===================================================================
#calculate structure sizes listed in pod/modperl_sizeof.pod via sizeof()
use strict;
use ExtUtils::Embed;
use Config;
my $file = shift || 'pod/modperl_sizeof.pod';
open my $pod, $file or die "open $file: $!";
FINDSTRUCT: {
while (<$pod>) {
next unless /^\s*(\w+)\s*=\s*\{/;
my $name = $1;
my $size = sizeof($name, $pod);
print "sizeof $name => $size\n";
redo FINDSTRUCT;
}
}
sub sizeof {
my($struct, $h) = @_;
my @elts;
while (<$h>) {
last if /^\s*\}\;$/;
next unless m:(\w+).*?//\s*(.*):;
push @elts, "sizeof($2) /* $1 */";
}
my $name = "perl_sizeof_$struct";
my $tmpfile = "$name.c";
open my $fh, '>', $tmpfile or die "open $tmpfile: $!";
local $" = " + \n";
print $fh <<EOF;
#include <stdio.h>
static FILE *outfp = stdout;
#define PERLIO_NOT_STDIO 0
#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
int main(void) {
int size = @elts;
fprintf(outfp, "%d", size);
return 1;
}
EOF
my $opts = ccopts();
system "$Config{cc} -o $name $tmpfile $opts";
my $size = `$name`;
unlink $name, $tmpfile;
return $size;
}