develooper Front page | perl.perl5.porters | Postings from March 2006

use arenas for NewOp's

Thread Next
From:
Jim Cromie
Date:
March 18, 2006 17:55
Subject:
use arenas for NewOp's
Message ID:
441CBA10.2030006@gmail.com
hi Nicholas, p5p,

Following your observation that PERL_OP_SLAB_ALLOC
is off by default, I agree that arenas for OPs may be a win over current.
So heres a WIP patch which attempts to allocate all OPs from arenas.

heres what patch does:

- split out arenas_by_type[] from bodies_by_type[] and move
supporting code around.

- enlarged PERL_ARENA_ROOTS_SIZE = SVt_LAST + OPt_LAST
to hold body-roots for the different *OP types also.

- added arena-details and body-details entries for new *OP_SLOTS

- copied S_new_body()  to Perl_new_body(), and added it to embed.fnc.
(this internal-api change allows replacing S_new_he() and S_more_he(),
and possibly other spots too).

- added new defns for NewOp, etc
(I had to Zero each body, else op_sibling gets values that blow things up)

- some cleanup of comments around arenas, mid-level allocation routines.


Im not entirely happy with the coupling between sv.c and op.c,
and between enum svtype and OP-slots.  it could probably be cleaned up 
some,
but the coupling is somewhat intrinsic, so Im deferring it pending 
suggestions.

In particular, the helper macro that adapts NewOp's  type arg  to a  
slot-value
feels a bit baroque, but is necessary to avoid changing all the calls to 
NewOp.

It also feels vaguely dirty to allocate by type, but to free by the 
op-class.
It relies on the 1-1 pairing of class to type, so that freed blocks are 
returned to
the right free-body-list.



Also, it breaks :-/

$ ./miniperl -Dm -Ilib configpm --heavy=lib/Config_heavy.pl lib/Config.pm
....
arena 10 added: 97fb2b0 size 4080
arena 97fb2b0 end 97fc288 arena-size 4080 type 22 size 24 ct 170
new 22 body 97fb2b0
newop SVOP
0x97f8888: (00480) malloc 8 bytes
0x97ea540: (00481) rfree
0x97fc2a8: (00482) realloc 784 bytes
0x97f55e8: (00483) malloc 16 bytes
0x97f8538: (00484) malloc 16 bytes
0x97f8550: (00485) malloc 8 bytes
new 22 body 97fb2c8
newop SVOP
0x97f7fe0: (00486) malloc 28 bytes
new 22 body 97fb2e0
newop SVOP
0x97fc5c0: (00487) malloc 4060 bytes
arena 11 added: 97fc5c0 size 4060
arena 97fc5c0 end 97fd580 arena-size 4060 type 20 size 28 ct 145
new 20 body 97fc5c0
newop LISTOP
0x97fd5a0: (00488) malloc 4080 bytes
arena 12 added: 97fd5a0 size 4080
arena 97fd5a0 end 97fe57c arena-size 4080 type 16 size 20 ct 204
new 16 body 97fd5a0
newop OP
0x97fe598: (00489) malloc 4080 bytes
arena 13 added: 97fe598 size 4080
arena 97fe598 end 97ff560 arena-size 4080 type 26 size 40 ct 102
new 26 body 97fe598
newop COP
new 20 body 97fc5dc
newop LISTOP
new 26 body 97fe5c0
newop COP
0x97ff590: (00490) malloc 4080 bytes
arena 14 added: 97ff590 size 4080
arena 97ff590 end 9800568 arena-size 4080 type 17 size 24 ct 170
new 17 body 97ff590
newop UNOP
0x97f4c68: (00491) rfree
0x97f4c68: (00492) realloc 12 bytes
Segmentation fault

the stacktrace:

Program received signal SIGSEGV, Segmentation fault.
0x080fd557 in Perl_new_body (sv_type=26) at sv.c:1142
/home/jimc/perl/core/dev/ar-3/sv.c:1142:33554:beg:0x80fd557
(gdb) bt
#0  0x080fd557 in Perl_new_body (sv_type=26) at sv.c:1142
#1  0x080565e4 in Perl_newSTATEOP (flags=0, label=0x0, o=0x9680b40) at 
opmini.c:3886
#2  0x0805517a in Perl_utilize (aver=1, floor=112, version=0x0, 
idop=0x967b868, arg=0x0) at opmini.c:3509
#3  0x081f80f5 in Perl_yyparse () at perly.y:415
#4  0x080dd11a in S_parse_body (env=0x0, xsinit=0x804b7c0 <xs_init>) at 
perl.c:2218
#5  0x080db68c in perl_parse (my_perl=0x9662008, xsinit=0x804b7c0 
<xs_init>, argc=6, argv=0xbfbdd404, env=0x0) at perl.c:1584
#6  0x0804b773 in main (argc=6, argv=0xbfbdd404, env=0xbfbdd420) at 
miniperlmain.c:101
(gdb)



Best I can tell, Im getting a pointer corruption in the COP free-list 
somewhere after
S_more_bodies creates it (Ive inspected it in debugger),
and the 2nd call to NewOp(v,COP), where the memory has been overwritten by
something.  Ive tried to set watchpoints on thi list, but I cant catch 
the overwrite.


(gdb) n
(gdb)
new 26 body 8c3bb58
(gdb) x/50w *r3wt
0x8c3bb80:    0x08c3bba8    0x00000000    0x00000000    0x00000000
0x8c3bb90:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bba0:    0x00000000    0x00000000    0x08c3bbd0    0x00000000
0x8c3bbb0:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bbc0:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bbd0:    0x08c3bbf8    0x00000000    0x00000000    0x00000000
0x8c3bbe0:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bbf0:    0x00000000    0x00000000    0x08c3bc20    0x00000000
0x8c3bc00:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bc10:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bc20:    0x08c3bc48    0x00000000    0x00000000    0x00000000
0x8c3bc30:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bc40:    0x00000000    0x00000000
(gdb) watch PL_body_roots[26]
Hardware watchpoint 2: PL_body_roots[26]
(gdb) watch 0x8c3bb58
Watchpoint 3: 147045208
(gdb) c
Continuing.
newop COP

Breakpoint 1, Perl_new_body (sv_type=20) at sv.c:1138
(gdb) c
Continuing.
new 20 body 8c39b9c
newop LISTOP

Breakpoint 1, Perl_new_body (sv_type=26) at sv.c:1138
(gdb) n
(gdb)
(gdb) x/50w *r3wt
0x8c3bb80:    0x00000002    0x00000000    0x00000000    0x00000000
0x8c3bb90:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bba0:    0x00000000    0x00000000    0x08c3bbd0    0x00000000
0x8c3bbb0:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bbc0:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bbd0:    0x08c3bbf8    0x00000000    0x00000000    0x00000000
0x8c3bbe0:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bbf0:    0x00000000    0x00000000    0x08c3bc20    0x00000000
0x8c3bc00:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bc10:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bc20:    0x08c3bc48    0x00000000    0x00000000    0x00000000
0x8c3bc30:    0x00000000    0x00000000    0x00000000    0x00000000
0x8c3bc40:    0x00000000    0x00000000
(gdb) s
Hardware watchpoint 2: PL_body_roots[26]

Old value = (void *) 0x8c3bb80
New value = (void *) 0x2
Perl_new_body (sv_type=26) at sv.c:1145
/home/jimc/perl/core/dev/ar-all-1/sv.c:1145:33606:beg:0x80fd55e
(gdb)


Im at something of a loss as to whats going on.
It looks like the watchpoint doesnt actually break, or,
well Im tired of guessing, and would like a code review for a
change of pace / perspective.

thanks for reading,
jimc

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About