# New Ticket Created by Jürgen Bömmels # Please include the string: [perl #23124] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=23124 >
Hello, Next patch in the series of PIO refactoring. This time make the Standard handles PIO_STDIN et al. in the interpreter structure PMCs. The patch is quite straight forward: Change the type of the ParrotIOTable and lose some new_io_pmcs. The main problems were initialization and finalization. In the initialization code the memory system needs to be up and running when the PIO-system gets initialised. So I moved PIO_init() is moved a little down in make_interpreter(). Finalization is a bit more tricky. The standard filehandles must not be destroyed in the final sweep. Until a proper solution of DOD-ordering is found (see http://groups.google.de/groups?selm=71BEC0D4E1DED3118F7A009027B12028034C8D6E%40EXCH_MISSION) I used a trick of marking only a part of the rootset, the piodata. The changes in dod.c are to allow marking of parts of the rootset. pobject_lives will trace its children in the case that it is not called from trace_active_PMCs. bye boe -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/61785/45530/32a6ea/io15.diff
? log.9392.gz ? test.imc ? mprout.pl ? docs/core_ops.pod ? docs/io_ops.pod ? io/Makefile ? t/src/staticstring.t ? t/src/valgrind.t Index: dod.c =================================================================== RCS file: /cvs/public/parrot/dod.c,v retrieving revision 1.65 diff -u -r1.65 dod.c --- dod.c 23 Jul 2003 18:09:43 -0000 1.65 +++ dod.c 25 Jul 2003 12:50:57 -0000 @@ -31,6 +31,7 @@ #endif static size_t find_common_mask(size_t val1, size_t val2); +static void trace_children(struct Parrot_Interp *interpreter, PMC *current); #if ARENA_DOD_FLAGS @@ -38,6 +39,7 @@ { struct Small_Object_Arena *arena = GET_ARENA(obj); + PMC *children = NULL; size_t n = GET_OBJ_N(arena, obj); size_t ns = n >> ARENA_FLAG_SHIFT; UINTVAL nm = (n & ARENA_FLAG_MASK) << 2; @@ -50,14 +52,22 @@ if (*dod_flags & (PObj_is_special_PMC_FLAG << nm)) { if (((PMC*)obj)->pmc_ext) { /* put it on the end of the list */ - interpreter->mark_ptr->next_for_GC = (PMC *)obj; + if (interpreter->mark_ptr) + interpreter->mark_ptr->next_for_GC = (PMC *)obj; + else + children = (PMC *)obj; /* Explicitly make the tail of the linked list be * self-referential */ interpreter->mark_ptr = ((PMC*)obj)->next_for_GC = (PMC *)obj; } else if (PObj_custom_mark_TEST(obj)) VTABLE_mark(interpreter, (PMC *) obj); - return; + } + + /* children is only set if there isn't already a children trace active */ + if (children) { + trace_children(interpreter, children); + interpreter->mark_ptr = NULL; } } @@ -68,6 +78,8 @@ * individual pieces if they have private ones */ void pobject_lives(struct Parrot_Interp *interpreter, PObj *obj) { + PMC *children = NULL; + /* if object is live or on free list return */ if (PObj_is_live_or_free_TESTALL(obj)) { return; @@ -90,7 +102,10 @@ if (PObj_is_special_PMC_TEST(obj)) { if (((PMC*)obj)->pmc_ext) { /* put it on the end of the list */ - interpreter->mark_ptr->next_for_GC = (PMC *)obj; + if (interpreter->mark_ptr) + interpreter->mark_ptr->next_for_GC = (PMC *)obj; + else + children = (PMC *)obj; /* Explicitly make the tail of the linked list be * self-referential */ interpreter->mark_ptr = ((PMC*)obj)->next_for_GC = (PMC *)obj; @@ -109,6 +124,12 @@ obj, ((Buffer*)obj)->bufstart); } #endif + + /* children is only set if there isn't already a children trace active */ + if (children) { + trace_children(interpreter, children); + interpreter->mark_ptr = NULL; + } } #endif @@ -118,7 +139,7 @@ static void trace_active_PMCs(struct Parrot_Interp *interpreter) { - PMC *current, *prev = NULL; + PMC *current; /* Pointers to the currently being processed PMC, and * in the previously processed PMC in a loop. * @@ -129,14 +150,12 @@ unsigned int i = 0, j = 0; struct PRegChunk *cur_chunk = 0; struct Stash *stash = 0; - UINTVAL mask = PObj_is_PMC_ptr_FLAG | PObj_is_buffer_ptr_FLAG - | PObj_custom_mark_FLAG; /* We have to start somewhere, the interpreter globals is a good place */ interpreter->mark_ptr = current = interpreter->iglobals; /* mark it as used */ - pobject_lives(interpreter, (PObj *)current); + pobject_lives(interpreter, (PObj *)interpreter->iglobals); pobject_lives(interpreter, interpreter->ctx.warns); /* Now, go run through the PMC registers and mark them as live */ /* First mark the current set. */ @@ -182,13 +201,27 @@ mark_stack(interpreter, stacks[j]); } + + /* Walk the iodata */ + Parrot_IOData_mark(interpreter, interpreter->piodata); + /* Find important stuff on the system stack */ #if TRACE_SYSTEM_AREAS trace_system_areas(interpreter); #endif - /* Okay, we've marked the whole root set, and should have a good-sized * list 'o things to look at. Run through it */ + trace_children(interpreter, current); +} + +static void +trace_children(struct Parrot_Interp *interpreter, PMC *current) +{ + PMC *prev = NULL; + unsigned i = 0; + UINTVAL mask = PObj_is_PMC_ptr_FLAG | PObj_is_buffer_ptr_FLAG + | PObj_custom_mark_FLAG; + for (; current != prev; current = current->next_for_GC) { UINTVAL bits = PObj_get_FLAGS(current) & mask; Index: embed.c =================================================================== RCS file: /cvs/public/parrot/embed.c,v retrieving revision 1.75 diff -u -r1.75 embed.c --- embed.c 21 Jul 2003 18:00:24 -0000 1.75 +++ embed.c 25 Jul 2003 12:50:57 -0000 @@ -84,7 +84,7 @@ if (filename == NULL || strcmp(filename, "-") == 0) { /* read from STDIN */ - io = new_io_pmc(interpreter, PIO_STDIN(interpreter)); + io = PIO_STDIN(interpreter); /* read 1k at a time */ program_size = 0; } Index: interpreter.c =================================================================== RCS file: /cvs/public/parrot/interpreter.c,v retrieving revision 1.179 diff -u -r1.179 interpreter.c --- interpreter.c 24 Jul 2003 20:20:29 -0000 1.179 +++ interpreter.c 25 Jul 2003 12:50:57 -0000 @@ -680,11 +680,6 @@ * mem_setup_allocator() is called. */ interpreter->flags = flags; - /* PANIC will fail until this is done */ - SET_NULL(interpreter->piodata); - PIO_init(interpreter); - - if (is_env_var_set("PARROT_GC_DEBUG")) { #if ! DISABLE_GC_DEBUG Interp_flags_SET(interpreter, PARROT_GC_DEBUG_FLAG); @@ -701,6 +696,10 @@ /* initialize classes */ Parrot_init(interpreter, 0); + /* PANIC will fail until this is done */ + SET_NULL(interpreter->piodata); + PIO_init(interpreter); + /* Need an empty stash */ interpreter->perl_stash = mem_sys_allocate(sizeof(struct Stash)); interpreter->perl_stash->stash_hash = @@ -822,6 +821,11 @@ * no DOD run, so everything is considered dead */ + /* XXX boe: This hack explicitly marks the piodata, these filehandles + * need to be open until PIO_finish is called + */ + Parrot_IOData_mark(interpreter, interpreter->piodata); + if (interpreter->has_early_DOD_PMCs) free_unused_pobjects(interpreter, interpreter->arena_base->pmc_pool); @@ -829,6 +833,9 @@ * if the --leak-test commandline was given */ + /* Now the PIOData gets also cleared */ + PIO_finish(interpreter); + if (! (interpreter->parent_interpreter || Interp_flags_TEST(interpreter, PARROT_DESTROY_FLAG))) return; @@ -884,8 +891,6 @@ stack_destroy(interpreter->ctx.control_stack); /* intstack */ intstack_free(interpreter, interpreter->ctx.intstack); - - PIO_finish(interpreter); mem_sys_free(interpreter); } Index: io.ops =================================================================== RCS file: /cvs/public/parrot/io.ops,v retrieving revision 1.29 diff -u -r1.29 io.ops --- io.ops 21 Jul 2003 18:00:24 -0000 1.29 +++ io.ops 25 Jul 2003 12:50:57 -0000 @@ -104,17 +104,17 @@ =cut inline op getstdin(out PMC) { - $1 = new_io_pmc(interpreter, PIO_STDIN(interpreter)); + $1 = PIO_STDIN(interpreter); goto NEXT(); } inline op getstdout(out PMC) { - $1 = new_io_pmc(interpreter, PIO_STDOUT(interpreter)); + $1 = PIO_STDOUT(interpreter); goto NEXT(); } inline op getstderr(out PMC) { - $1 = new_io_pmc(interpreter, PIO_STDERR(interpreter)); + $1 = PIO_STDERR(interpreter); goto NEXT(); } @@ -189,8 +189,7 @@ op print(in STR) { STRING *s = $1; if (s && string_length(s)) { - PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)), - s); + PIO_putps(interpreter, PIO_STDOUT(interpreter), s); } goto NEXT(); } @@ -199,8 +198,7 @@ PMC *p = $1; STRING *s = (VTABLE_get_string(interpreter, p)); if (s) { - PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)), - s); + PIO_putps(interpreter, PIO_STDOUT(interpreter), s); } goto NEXT(); } @@ -232,8 +230,7 @@ op printerr(in STR) { STRING *s = $1; if (s && string_length(s)) { - PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDERR(interpreter)), - s); + PIO_putps(interpreter, PIO_STDERR(interpreter), s); } goto NEXT(); } @@ -242,8 +239,7 @@ PMC *p = $1; STRING *s = (VTABLE_get_string(interpreter, p)); if (s) { - PIO_putps(interpreter, new_io_pmc(interpreter, PIO_STDOUT(interpreter)), - s); + PIO_putps(interpreter, PIO_STDOUT(interpreter), s); } goto NEXT(); } @@ -332,7 +328,7 @@ n = $2; $1 = string_make(interpreter, NULL, n, NULL, 0, NULL); memset(($1)->strstart, 0, n); - nr = PIO_read(interpreter, new_io_pmc(interpreter, PIO_STDIN(interpreter)), + nr = PIO_read(interpreter, PIO_STDIN(interpreter), ($1)->strstart, (size_t)n); if(nr > 0) ($1)->strlen = ($1)->bufused = nr; Index: trace.c =================================================================== RCS file: /cvs/public/parrot/trace.c,v retrieving revision 1.37 diff -u -r1.37 trace.c --- trace.c 21 Jul 2003 18:00:24 -0000 1.37 +++ trace.c 25 Jul 2003 12:50:57 -0000 @@ -247,7 +247,7 @@ } /* Flush *stderr* now that we've output the trace info */ - PIO_flush(interpreter, new_io_pmc(interpreter, PIO_STDERR(interpreter))); + PIO_flush(interpreter, PIO_STDERR(interpreter)); } Index: include/parrot/io.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/io.h,v retrieving revision 1.35 diff -u -r1.35 io.h --- include/parrot/io.h 21 Jul 2003 18:00:42 -0000 1.35 +++ include/parrot/io.h 25 Jul 2003 12:51:09 -0000 @@ -140,7 +140,7 @@ typedef struct _ParrotIOBuf ParrotIOBuf; typedef struct _ParrotIO ParrotIO; typedef struct _ParrotIOData ParrotIOData; -typedef struct _ParrotIO **ParrotIOTable; +typedef PMC **ParrotIOTable; struct _ParrotIO { PIOHANDLE fd; /* Low level OS descriptor */ @@ -335,6 +335,8 @@ extern INTVAL PIO_eprintf(theINTERP, const char *s, ...); extern INTVAL PIO_getfd(theINTERP, PMC *io); extern PIOOFF_T PIO_tell(theINTERP, PMC *io); + +extern void Parrot_IOData_mark(theINTERP, ParrotIOData *piodata); /* Put platform specific macros here if you must */ #ifdef PIO_OS_WIN32 Index: include/parrot/pobj.h =================================================================== RCS file: /cvs/public/parrot/include/parrot/pobj.h,v retrieving revision 1.24 diff -u -r1.24 pobj.h --- include/parrot/pobj.h 24 Jul 2003 01:16:37 -0000 1.24 +++ include/parrot/pobj.h 25 Jul 2003 12:51:09 -0000 @@ -31,15 +31,15 @@ typedef union UnionVal { + struct { /* Buffers structure */ + void * bufstart; + size_t buflen; + } b; INTVAL int_val; /* PMC unionval members */ FLOATVAL num_val; DPOINTER* struct_val; struct parrot_string_t * string_val; PMC* pmc_val; - struct { /* Buffers structure */ - void * bufstart; - size_t buflen; - } b; } UnionVal; /* Parrot Object - base class for all others */ Index: io/io.c =================================================================== RCS file: /cvs/public/parrot/io/io.c,v retrieving revision 1.48 diff -u -r1.48 io.c --- io/io.c 21 Jul 2003 18:00:45 -0000 1.48 +++ io/io.c 25 Jul 2003 12:51:09 -0000 @@ -203,6 +203,11 @@ { ParrotIOLayer *p; +#if 0 + /* The ParrotIO-Class must be initialized at this point */ + Parrot_ParrotIO_class_init(interpreter, enum_class_ParrotIO); +#endif + /* First push the platform specific OS layer */ /* Optimize this to keep a default stack and just * call copy stack. @@ -733,8 +738,7 @@ if(interpreter) { str=Parrot_vsprintf_c(interpreter, s, args); - ret=PIO_putps(interpreter, - new_io_pmc(interpreter, PIO_STDOUT(interpreter)), str); + ret=PIO_putps(interpreter, PIO_STDOUT(interpreter), str); } else { /* Be nice about this... @@ -759,8 +763,7 @@ if(interpreter) { str=Parrot_vsprintf_c(interpreter, s, args); - ret=PIO_putps(interpreter, - new_io_pmc(interpreter, PIO_STDERR(interpreter)), str); + ret=PIO_putps(interpreter, PIO_STDERR(interpreter), str); } else { /* Be nice about this... @@ -778,20 +781,32 @@ PIO_getfd(theINTERP, PMC *pmc) { INTVAL i; - ParrotIO *io = PMC_data(pmc); ParrotIOTable table = ((ParrotIOData*)interpreter->piodata)->table; for(i = 0; i < PIO_NR_OPEN; i++) { - if (table[i] == io) return i; + if (table[i] == pmc) return i; if (table[i] == NULL) { - table[i] = io; + table[i] = pmc; return i; } } /* XXX boe: increase size of the fdtable */ return -1; +} + +void +Parrot_IOData_mark(theINTERP, ParrotIOData *piodata) +{ + INTVAL i; + ParrotIOTable table = piodata->table; + + for (i = 0; i < PIO_NR_OPEN; i++) { + if (table[i]) { + pobject_lives(interpreter, (PObj *)table[i]); + } + } } /* Index: io/io_buf.c =================================================================== RCS file: /cvs/public/parrot/io/io_buf.c,v retrieving revision 1.6 diff -u -r1.6 io_buf.c --- io/io_buf.c 21 Jul 2003 18:00:45 -0000 1.6 +++ io/io_buf.c 25 Jul 2003 12:51:09 -0000 @@ -72,9 +72,10 @@ PIO_buf_init(theINTERP, ParrotIOLayer *layer) { if (PIO_STDOUT(interpreter)) - PIO_buf_setlinebuf(interpreter, layer, PIO_STDOUT(interpreter)); + PIO_buf_setlinebuf(interpreter, layer, + PMC_data(PIO_STDOUT(interpreter))); if (PIO_STDIN(interpreter)) - PIO_buf_setbuf(interpreter, layer, PIO_STDIN(interpreter), + PIO_buf_setbuf(interpreter, layer, PMC_data(PIO_STDIN(interpreter)), PIO_UNBOUND); return 0; } Index: io/io_unix.c =================================================================== RCS file: /cvs/public/parrot/io/io_unix.c,v retrieving revision 1.26 diff -u -r1.26 io_unix.c --- io/io_unix.c 21 Jul 2003 18:00:45 -0000 1.26 +++ io/io_unix.c 25 Jul 2003 12:51:09 -0000 @@ -88,17 +88,28 @@ { ParrotIOData *d = GET_INTERP_IOD(interpreter); if (d != NULL && d->table != NULL) { - if ((PIO_STDIN(interpreter) = - PIO_unix_fdopen(interpreter, layer, STDIN_FILENO, - PIO_F_READ | PIO_F_SHARED)) - && (PIO_STDOUT(interpreter) = - PIO_unix_fdopen(interpreter, layer, STDOUT_FILENO, - PIO_F_WRITE | PIO_F_SHARED)) - && (PIO_STDERR(interpreter) = - PIO_unix_fdopen(interpreter, layer, STDERR_FILENO, - PIO_F_WRITE | PIO_F_SHARED)) - ) - return 0; + ParrotIO *io; + + INTVAL has_early = interpreter->has_early_DOD_PMCs; + + io = PIO_unix_fdopen(interpreter, layer, STDIN_FILENO, PIO_F_READ); + if (!io) return -1; + PIO_STDIN(interpreter) = new_io_pmc(interpreter, io); + PObj_needs_early_DOD_CLEAR(PIO_STDIN(interpreter)); + + io = PIO_unix_fdopen(interpreter, layer, STDOUT_FILENO, PIO_F_WRITE); + if (!io) return -1; + PIO_STDOUT(interpreter) = new_io_pmc(interpreter, io); + PObj_needs_early_DOD_CLEAR(PIO_STDOUT(interpreter)); + + io = PIO_unix_fdopen(interpreter, layer, STDERR_FILENO, PIO_F_WRITE); + if (!io) return -1; + PIO_STDERR(interpreter) = new_io_pmc(interpreter, io); + PObj_needs_early_DOD_CLEAR(PIO_STDERR(interpreter)); + + interpreter->has_early_DOD_PMCs = has_early; + + return 0; } return -1; } Index: lib/Parrot/Test.pm =================================================================== RCS file: /cvs/public/parrot/lib/Parrot/Test.pm,v retrieving revision 1.41 diff -u -r1.41 Test.pm --- lib/Parrot/Test.pm 2 Jul 2003 13:48:56 -0000 1.41 +++ lib/Parrot/Test.pm 25 Jul 2003 12:51:12 -0000 @@ -54,6 +54,10 @@ open STDOUT, ">$out" or die "Can't redirect stdout" if $out; open STDERR, ">$err" or die "Can't redirect stderr" if $err; + if (defined $ENV{VALGRIND}) { + $command = "$ENV{VALGRIND} $command"; + } + system $command; my $exit_code = $? >> 8;