[COMMIT] store_global/find_global ops
store_global/find_global ops are in. Added storage of PMCs to PerlHash. Sample: new P0, PerlString set P0, "Melvin\n" store_global "first", P0 new P0, PerlString set P0, "Smith\n" store_global "last", P0 find_global P1, "first" find_global P2, "last" print P1 print P2 end -Melvin
Configure.pl, version 2.0
I've finished a new version of Configure which splits up the giant script into a bunch of small files and moves all of Configure's files into a new config/ directory. I just need a few guinea pigs^W^Wtesters to make sure it works okay on various systems, especially systems with hint files. I would send this as a patch, but it moves a lot of files and creates many new directories, so the patch would be huge. Instead, I'm putting a copy of Parrot with the new Configure in it. In a few hours, a 600KB tarball should appear on the CPAN: $CPAN/authors/id/B/BR/BRENTDAX/parrot/parrot-cfg.tar.gz This is a full Parrot distribution with the new Configure. Unpack it to an empty directory, run the normal Configure/make/make test, and report the results. The new Configure is fully functional, except for reconfig, which needs some reworking to work under the new model. A screen paste of one of my Configure sessions is below my sig. It's been tested on Windows and Linux; all tests pass. The directory was last cvs updated a few days ago, so some recent bugs may not be fixed. Special thanks to Melvin--I had been trying to figure out a bug for two days, and he took ten minutes to diagnose the problem. Thanks also to Robert, who pushed me to write this (and then pointed out all the deficiencies in the design :^) ). (And yes, this time Configure *does* have an actual design, described in the ~200 lines of POD at the bottom of Configure.pl.) Share and enjoy. --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) blink: Text blinks (alternates between visible and invisible). Conforming user agents are not required to support this value. --The W3C CSS-2 Specification C:\Brent\Visual Studio Projects\Perl 6\parrot-cfg\parrot>perl Configure.pl Parrot Version 0.0.5 Configure 2.0 Copyright (C) 2001-2002 Yet Another Society Hello, I'm Configure. My job is to poke and prod your system to figure out how to build Parrot. I'll also ask a few questions along the way, unless you passed in the '--defaults' flag on the command line. Since you're running this script, you obviously have Perl 5--I'll be pulling some defaults from its configuration. Checking MANIFEST...done. Setting up Configure's data structures...done. Loading platform hints file...done. Okay, I'm going to start by asking you a couple questions about your compiler and linker. Default values are in square brackets; you can hit ENTER to accept them. If you don't understand a question, the default will usually work--they've been intuited from your Perl 5 configuration. What C compiler do you want to use? [cl] How about your linker? [link] What flags should your C compiler receive? [-nologo -O1 -MD -DNDEBUG -DWIN32 -D_CONSOLE -DNO_STRICT ] And your linker? [-nologo -nodefaultlib -release-machine:x86] What libraries should your C compiler use? [oldnames.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib netapi32.lib uuid.lib wsock32.lib mpr.lib winmm.lib version.lib odbc32.lib odbccp32.lib msvcrt.lib] Do you want a debugging build of Parrot? [n] Thanks. Now I need a little information on certain types. Same rules as the last section. How big would you like your integers to be? [long] And your floats? [double] What's your native opcode type? [long] Now I have to find out what opcode files you would like to compile into your Parrot. The following opcode files are available: core.ops io.ops obscure.ops rx.ops Which opcode files would you like? [core.ops io.ops rx.ops] Parrot sometimes has experimental systems. I'll now ask about any that currently exist. Answer 'n' unless you know otherwise. Enable experimental networking? [n] Probing for C headers...done. Determining some sizes...done. Computing native byteorder for Parrot's wordsize...done. Figuring out how to pack() Parrot's types...done. Figuring out what formats should be used for sprintf...done. Determining if your C compiler is actually gcc...done. Determining architecture, OS and JIT capability...done. Verifying that the compiler supports function pointer casts...done. Determining if your compiler supports computed goto...done. Generating config.h...done. Writing Parrot::Config module...done. Generating Makefiles...done. Moving platform files into place...done. Okay, we're done! You can now use `make' (or your platform's equivalent to `make') to build your Parrot. After that, you can use `make test' to run the test suite. Happy Hacking, The Parrot Team
Re: New assembler difficulties.
Clinton A. Pierce: > No line number, no context, nearly impossible to find to debug. > I think you're right, and you were given a pig in a poke. Thanks, Clint and Jeff. I'll be sure not to contribute anything again. -- Life's a switch() and then you die().
Re: New assembler difficulties.
Jeff: > > >Well, it's unhappy when you do lots of things. The code I was given was > > >not as complete/functional as I had been led to believe, inasmuch as it Eh, I didn't lead you to believe anything, and in fact I think I said it had portability issues. > > Unparsable argument, starting from '"', QUOTE > > No line number, no context, nearly impossible to find to debug. That's an internal error with the assembler, shouldn't happen. It suggests the string regexp is broken. I deliberately didn't add contextual information because I wanted the assembler to be machine-oriented rather than human-oriented, and we can depend on machines to produce well-formed bytecode or it's an internal error on *their* side. > the final PMC issue solutions, at least I hope. It was written back when > keys were going to be a separate set of registers, and we don't do that > any more. I don't think I assumed that keys were going to be a set of registers anywhere, and there's nothing about that in the key PDD or the assembler PDD, or in the original code I have kicking around. I don't understand what you mean here. Maybe one of the PDDs needs updating? -- "There are two major products that come out of Berkeley: LSD and UNIX. We don't believe this to be a coincidence." - Jeremy S. Anderson
Re: New assembler difficulties.
At 10:29 AM 5/19/2002 +0100, Simon Cozens wrote: > > > Unparsable argument, starting from '"', QUOTE > > > No line number, no context, nearly impossible to find to debug. > >That's an internal error with the assembler, shouldn't happen. It >suggests the string regexp is broken. I deliberately didn't add contextual >information because I wanted the assembler to be machine-oriented rather >than human-oriented, and we can depend on machines to produce well-formed >bytecode or it's an internal error on *their* side. I suggest that at some point an input line number should probably be generated in the message. At the very least because some poor schmuck has to actually write software to generate these machine-oriented instructions and he's gonna need to debug his own programming. The assembler knows there's a problem, it knows about where, we should throw the poor guy a bone.
Re: New assembler difficulties.
Simon Cozens wrote: > > Jeff: > > > >Well, it's unhappy when you do lots of things. The code I was given was > > > >not as complete/functional as I had been led to believe, inasmuch as it > > Eh, I didn't lead you to believe anything, and in fact I think I said it had > portability issues. Many apologies for my earlier comments. I made my comments late at night, and wasn't in a proper frame of mind. After looking at the situation, I understand why it was written the way it was, and that I'm (of course) trying to use it for some things that were designed in after it was written. My comments were solely borne out of frustration over some other issues that shouldn't have come in to this. And thank you, Simon, for explaining your viewpoint. I think I'm fully in agreement with the concept of a machine-oriented assembler, but until we have machines writing the majority of code, it's my feeling that we need a few concessions for human authors. It was in the process of adding those concessions that I grew frustrated, and the two should never have been related. I am more aware than most people of your contributions to Parrot, Simon, and I realize that what I said offended. It was never my intention to alienate you, and that thought should simply never have been expressed at all. Maybe this episode will teach me to wait until morning to send potentially controversial email. Thank you for your attention, and potential future contributions. -- Jeff <[EMAIL PROTECTED]>
RE: New assembler difficulties.
Simon Cozens: # Clinton A. Pierce: # > No line number, no context, nearly impossible to find to debug. I # > think you're right, and you were given a pig in a poke. # # Thanks, Clint and Jeff. I'll be sure not to contribute anything again. God, Simon, get over it. You might very well say the same thing if Jeff had written it and left it in the state you'd left it in. I'm sure they appreciate what you've managed to achieve with it thus far. But you know as well as anyone that when you're frustrated with a piece of software you say things you don't really mean. The mistake here was saying them in a public forum. --Brent Dax <[EMAIL PROTECTED]> @roles=map {"Parrot $_"} qw(embedding regexen Configure) blink: Text blinks (alternates between visible and invisible). Conforming user agents are not required to support this value. --The W3C CSS-2 Specification
Re: [COMMIT] inc/dec/add ops and new PMC methods
On Sun, May 19, 2002 at 01:39:30AM -0400, Melvin Smith wrote: > Filled in some missing holes: > -Implement PMC inc/dec functions and add ops to engine. > 'inc P0, 5' is faster than 'set P0, P1, 5' which uses a vtable. > -Corrected 'inc Nx, Ny' to 'inc Nx, Iy' as per the PDD > -Added missing 'add Nx, Ny, Iz' op Good. :-) > Updated mops_p.pasm to use dec op, however, the intent was > not to optimize mops_p benchmark, but to optimize for a very > common operation, which mops_p just happens to do. We now need > to re-evaluate mops_p and how to accurately represent a cross-section > of operations and not a specific case. Good. :-) > Er, hmm we might need a few new tests, I was too lazy to write them, Bad. :-( > I did fix the existing ones for the erroneous inc Nx, Ny op. Good. :-) > Btw, mops_p runs 20% faster, for now, but I wouldn't get too excited since > it only uses 2 specific ops. Good. :-) Net result is Good. [If it wasn't clear, thanks for this, thanks for all the other good work you've done on parrot] Seriously though - is it possible to automate testing how many ops don't have tests? That way we could have a test that looked for untested ops, and failed if any weren't tested. I guess it couldn't easily be very sophisticated, in that it would really only have to verify that all ops were mentioned somewhere in the body of a test, but I think it could be quite useful. Otherwise useful op patches will go it with the honest intent to have tests follow shortly, but there will inevitably be some occasions where the tests themselves are forgotten, and then the fact that the tests still need to be written will be forgotten, and then we'll have some untested ops in the core that will get broken without anyone realising. I'm not suggesting that we do this all the time, but it might be a good rule for any official release - for release all ops must have tests. Nicholas Clark -- Even better than the real thing:http://nms-cgi.sourceforge.net/
Re: Profiling PMCs
On Sat, May 18, 2002 at 07:33:53PM -0400, Dan Sugalski wrote: > At 7:25 PM -0400 5/18/02, Melvin Smith wrote: > >Yeh I know that word is yucky and from Java land, but in this case, > >I think that > >"system" PMCs should take liberties for optimization. > > *All* PMCs should take liberties for optimization. PMC vtable entries > are the only things that should know the internal structures, and > they're allowed--heck, encouraged--to take any liberties needed for > speed. > > I don't much care if it breaks inheritance at the PMC level. Too bad. > The speed's more important here. Is there any understandable and maintainable way that we can use the same (base) code to generate two sets of core PMCs - one set that have all the "cheating" optimisations, and another set (or set of code) that is internally clean and can be inherited from? That way we could have the benefit of speed for the common case, but also let people derive from them easily. In theory, all it would need to be would be two sets of vtables, wouldn't it? One "clean" vtable that implements all calls back in via the vtable, and one "grubby" vtable that cheats. (the "final class" version). Nicholas Clark -- Even better than the real thing:http://nms-cgi.sourceforge.net/
Re: [COMMIT] inc/dec/add ops and new PMC methods
>Net result is Good. > >[If it wasn't clear, thanks for this, thanks for all the other good work >you've >done on parrot] Thank you. >Seriously though - is it possible to automate testing how many ops don't >have tests? That way we could have a test that looked for untested ops, and >failed if any weren't tested. I'm sure someone could hack up something non-sophisticated which at least does a grep of the test suite based off of the op list. I'm probably the main culprit of committing ops without tests, however I always run my own tests on them. >I'm not suggesting that we do this all the time, but it might be a good rule >for any official release - for release all ops must have tests. I agree. Before next release (and each subsequent one) this would be worth addressing. -Melvin
Re: Configure.pl, version 2.0
On 19 May 2002 at 1:24, Brent Dax wrote: > $CPAN/authors/id/B/BR/BRENTDAX/parrot/parrot-cfg.tar.gz > > This is a full Parrot distribution with the new Configure. Unpack it to > an empty directory, run the normal Configure/make/make test, and report > the results. Cygwin (downloaded 2001-07-04) with Win98SE is OK -- Markus Laire 'malaire' <[EMAIL PROTECTED]>
[PATCH] classes/Makefile
I think I finally figured out what the problem was with the classes/ makefile, that caused strange things to happen. :) Patch included below. Should the various files also depend upon pmc2c.pl, so they will be regenerated in the event of a change to the generator? Or is that going too far? Technically, all of the .ops generation code would also need to be a dependancy for the core_ops*.c files themselves. Mike Lambert Index: classes/Makefile.in === RCS file: /cvs/public/parrot/classes/Makefile.in,v retrieving revision 1.19 diff -u -r1.19 Makefile.in --- classes/Makefile.in 29 Jan 2002 04:26:21 - 1.19 +++ classes/Makefile.in 20 May 2002 00:37:39 - @@ -26,7 +26,7 @@ all : $(O_FILES) -array.c array.h: array.pmc +array.c array.h: array.pmc default.pmc $(PMC2C) array.pmc array$(O): $(H_FILES) @@ -36,42 +36,42 @@ default$(O): $(H_FILES) -perlint.c perlint.h: perlint.pmc +perlint.c perlint.h: perlint.pmc default.pmc $(PMC2C) perlint.pmc perlint$(O): $(H_FILES) -perlnum.c perlnum.h: perlnum.pmc +perlnum.c perlnum.h: perlnum.pmc default.pmc $(PMC2C) perlnum.pmc perlnum$(O): $(H_FILES) -perlstring.c perlstring.h: perlstring.pmc +perlstring.c perlstring.h: perlstring.pmc default.pmc $(PMC2C) perlstring.pmc perlstring$(O): $(H_FILES) -perlarray.c perlarray.h: perlarray.pmc +perlarray.c perlarray.h: perlarray.pmc default.pmc $(PMC2C) perlarray.pmc perlarray$(O): $(H_FILES) -perlhash.c perlhash.h: perlhash.pmc +perlhash.c perlhash.h: perlhash.pmc default.pmc $(PMC2C) perlhash.pmc perlhash$(O): $(H_FILES) -perlundef.c perlundef.h: perlundef.pmc +perlundef.c perlundef.h: perlundef.pmc default.pmc $(PMC2C) perlundef.pmc perlundef$(O): $(H_FILES) -parrotpointer.c: parrotpointer.pmc +parrotpointer.c parrotpointer.h: parrotpointer.pmc default.pmc $(PMC2C) parrotpointer.pmc parrotpointer$(O): $(H_FILES) -intqueue.c: intqueue.pmc +intqueue.c intqueue.h: intqueue.pmc default.pmc $(PERL) pmc2c.pl intqueue.pmc intqueue$(O): $(H_FILES)
[APPLIED] Re: More memory management changes
On Sat, May 18, 2002 at 06:58:40PM -0400, Dan Sugalski wrote [to P. Gibbs]: > Did we get you commit privs? If so, commit it. If not, get me your > perl.org login and I'll get it taken care of. In the meantime, I committed that patch.
[PATCH] Warnings cleanup
This patch removes a bunch of warnings that have accumulated with MSVC recently. Mike Lambert Index: byteorder.c === RCS file: /cvs/public/parrot/byteorder.c,v retrieving revision 1.9 diff -u -r1.9 byteorder.c --- byteorder.c 9 May 2002 23:12:09 - 1.9 +++ byteorder.c 20 May 2002 00:55:56 - @@ -52,10 +52,10 @@ #if PARROT_BIGENDIAN return w; #else -INTVAL r; # if INTVAL_SIZE == 4 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff) >> 8) | (w>>24); # else +INTVAL r; r = w << 56; r |= (w & 0xff00) << 40; r |= (w & 0xff) << 24; @@ -77,11 +77,11 @@ #if PARROT_BIGENDIAN return w; #else -opcode_t r; # if OPCODE_T_SIZE == 4 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0x00ff) >> 8) | ((w & 0xff00) >>24); # else +opcode_t r; r = w << 56; r |= (w & 0xff00) << 40; r |= (w & 0xff) << 24; Index: core.ops === RCS file: /cvs/public/parrot/core.ops,v retrieving revision 1.141 diff -u -r1.141 core.ops --- core.ops19 May 2002 07:49:50 - 1.141 +++ core.ops20 May 2002 00:55:57 - @@ -1936,7 +1936,6 @@ inline op pack(inout STR, in INT, in STR) { STRING *t,*s = $3; UINTVAL len = (UINTVAL)$2; -char *c = s->bufstart; char buf[3]; if (s->buflen < len) { @@ -1956,8 +1955,7 @@ char *c = (char *)&$3, *n; STRING *s; const char *t,*f; -int i; - + s = string_make(interpreter, c, (UINTVAL)$2, NULL, 0, NULL); /* XXX this is EVIL, use string_replace */ n = $1->bufstart; @@ -3205,6 +3203,7 @@ /* Should just assign undef, but we don't have one yet */ $1->vtable = YOU_LOSE_VTABLE; $1->flags = PMC_live_FLAG; + goto NEXT(); } Index: hash.c === RCS file: /cvs/public/parrot/hash.c,v retrieving revision 1.2 diff -u -r1.2 hash.c --- hash.c 18 May 2002 02:32:27 - 1.2 +++ hash.c 20 May 2002 00:55:57 - @@ -211,7 +211,6 @@ UINTVAL i; UINTVAL old_pool_size = hash->bucket_pool->buflen / sizeof(HASHBUCKET); UINTVAL new_pool_size = new_size * MAXFULL_PERCENT / 100; -HASHBUCKET* old_pool = (HASHBUCKET*) hash->bucket_pool->bufstart; Parrot_reallocate(interpreter, hash, new_size * sizeof(HASHBUCKET*)); Parrot_reallocate(interpreter, hash->bucket_pool, @@ -282,7 +281,6 @@ static HASHBUCKET * find_bucket(Interp *interpreter, HASHBUCKET *head, STRING *key) { -KEY_ATOM *pair = NULL; if (head != NULL) { if (key != NULL) { while (head != NULL) { Index: memory.c === RCS file: /cvs/public/parrot/memory.c,v retrieving revision 1.34 diff -u -r1.34 memory.c --- memory.c15 May 2002 04:07:20 - 1.34 +++ memory.c20 May 2002 00:55:57 - @@ -98,7 +98,6 @@ void mem_setup_allocator(struct Parrot_Interp *interpreter) { -size_t temp_len; interpreter->arena_base = mem_sys_allocate(sizeof(struct Arenas)); interpreter->arena_base->sized_header_pools = NULL; interpreter->arena_base->num_sized = 0; Index: packfile.c === RCS file: /cvs/public/parrot/packfile.c,v retrieving revision 1.47 diff -u -r1.47 packfile.c --- packfile.c 9 May 2002 20:57:18 - 1.47 +++ packfile.c 20 May 2002 00:55:58 - @@ -837,7 +837,7 @@ #if TRACE_PACKFILE fprintf(stderr, "FIXME: PackFile_Constant_unpack_number: assuming size of FLOATVAL!\n"); #endif -self->number = PackFile_fetch_nv(pf, (unsigned char *)cursor); +self->number = PackFile_fetch_nv(pf, (opcode_t *)cursor); self->type = PFC_NUMBER; /*self->number = f.value; */ Index: resources.c === RCS file: /cvs/public/parrot/resources.c,v retrieving revision 1.54 diff -u -r1.54 resources.c --- resources.c 15 May 2002 01:13:52 - 1.54 +++ resources.c 20 May 2002 00:55:59 - @@ -781,13 +781,12 @@ else header_pool = interpreter->arena_base->sized_header_pools[j]; if (header_pool == NULL) continue; -for (cur_buffer_arena = header_pool->last_Arena; - NULL != cur_buffer_arena; +for (cur_buffer_arena = header_pool->last_Arena; + NULL != cur_buffer_arena; cur_buffer_arena = cur_buffer_arena->prev) { -Buffer *buffer_array = cur_buffer_arena->start_Buffer; UINTV
Re: [PATCH] Warnings cleanup
> This patch removes a bunch of warnings that have accumulated with MSVC > recently. And since I tested the patch with MSVC running, I forgot to run make to rebuild core_ops.c. Attached patch should be used instead of the previous one, as this one actually compiles. :) Mike Lambert Index: byteorder.c === RCS file: /cvs/public/parrot/byteorder.c,v retrieving revision 1.9 diff -u -r1.9 byteorder.c --- byteorder.c 9 May 2002 23:12:09 - 1.9 +++ byteorder.c 20 May 2002 01:08:00 - @@ -52,10 +52,10 @@ #if PARROT_BIGENDIAN return w; #else -INTVAL r; # if INTVAL_SIZE == 4 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0xff) >> 8) | (w>>24); # else +INTVAL r; r = w << 56; r |= (w & 0xff00) << 40; r |= (w & 0xff) << 24; @@ -77,11 +77,11 @@ #if PARROT_BIGENDIAN return w; #else -opcode_t r; # if OPCODE_T_SIZE == 4 return (w << 24) | ((w & 0xff00) << 8) | ((w & 0x00ff) >> 8) | ((w & 0xff00) >>24); # else +opcode_t r; r = w << 56; r |= (w & 0xff00) << 40; r |= (w & 0xff) << 24; Index: core.ops === RCS file: /cvs/public/parrot/core.ops,v retrieving revision 1.141 diff -u -r1.141 core.ops --- core.ops19 May 2002 07:49:50 - 1.141 +++ core.ops20 May 2002 01:08:01 - @@ -1936,7 +1936,6 @@ inline op pack(inout STR, in INT, in STR) { STRING *t,*s = $3; UINTVAL len = (UINTVAL)$2; -char *c = s->bufstart; char buf[3]; if (s->buflen < len) { @@ -1955,9 +1954,9 @@ inline op pack(inout STR, in INT, in INT, in INT) { char *c = (char *)&$3, *n; STRING *s; -const char *t,*f; +const char *t; int i; - + s = string_make(interpreter, c, (UINTVAL)$2, NULL, 0, NULL); /* XXX this is EVIL, use string_replace */ n = $1->bufstart; @@ -3205,6 +3204,7 @@ /* Should just assign undef, but we don't have one yet */ $1->vtable = YOU_LOSE_VTABLE; $1->flags = PMC_live_FLAG; + goto NEXT(); } Index: hash.c === RCS file: /cvs/public/parrot/hash.c,v retrieving revision 1.2 diff -u -r1.2 hash.c --- hash.c 18 May 2002 02:32:27 - 1.2 +++ hash.c 20 May 2002 01:08:01 - @@ -211,7 +211,6 @@ UINTVAL i; UINTVAL old_pool_size = hash->bucket_pool->buflen / sizeof(HASHBUCKET); UINTVAL new_pool_size = new_size * MAXFULL_PERCENT / 100; -HASHBUCKET* old_pool = (HASHBUCKET*) hash->bucket_pool->bufstart; Parrot_reallocate(interpreter, hash, new_size * sizeof(HASHBUCKET*)); Parrot_reallocate(interpreter, hash->bucket_pool, @@ -282,7 +281,6 @@ static HASHBUCKET * find_bucket(Interp *interpreter, HASHBUCKET *head, STRING *key) { -KEY_ATOM *pair = NULL; if (head != NULL) { if (key != NULL) { while (head != NULL) { Index: memory.c === RCS file: /cvs/public/parrot/memory.c,v retrieving revision 1.34 diff -u -r1.34 memory.c --- memory.c15 May 2002 04:07:20 - 1.34 +++ memory.c20 May 2002 01:08:01 - @@ -98,7 +98,6 @@ void mem_setup_allocator(struct Parrot_Interp *interpreter) { -size_t temp_len; interpreter->arena_base = mem_sys_allocate(sizeof(struct Arenas)); interpreter->arena_base->sized_header_pools = NULL; interpreter->arena_base->num_sized = 0; Index: packfile.c === RCS file: /cvs/public/parrot/packfile.c,v retrieving revision 1.47 diff -u -r1.47 packfile.c --- packfile.c 9 May 2002 20:57:18 - 1.47 +++ packfile.c 20 May 2002 01:08:02 - @@ -837,7 +837,7 @@ #if TRACE_PACKFILE fprintf(stderr, "FIXME: PackFile_Constant_unpack_number: assuming size of FLOATVAL!\n"); #endif -self->number = PackFile_fetch_nv(pf, (unsigned char *)cursor); +self->number = PackFile_fetch_nv(pf, (opcode_t *)cursor); self->type = PFC_NUMBER; /*self->number = f.value; */ Index: resources.c === RCS file: /cvs/public/parrot/resources.c,v retrieving revision 1.54 diff -u -r1.54 resources.c --- resources.c 15 May 2002 01:13:52 - 1.54 +++ resources.c 20 May 2002 01:08:03 - @@ -781,13 +781,12 @@ else header_pool = interpreter->arena_base->sized_header_pools[j]; if (header_pool == NULL) continue; -for (cur_buffer_arena = header_pool->last_Arena; - NULL != cur_buffer
Re: [PATCH] Warnings cleanup
At 09:11 PM 5/19/2002 -0400, Mike Lambert wrote: > > This patch removes a bunch of warnings that have accumulated with MSVC > > recently. Mostly applied. Here is your rejected hunk, sir. -Melvin resources.c.rej Description: Binary data
Re: [PATCH] Warnings cleanup
> Mostly applied. Here is your rejected hunk, sir. Much appreciated. Looks like Peter's patch also did some of the same formatting fixes. Below is a re-patch that fixes the problem. Mike Lambert Index: resources.c === RCS file: /cvs/public/parrot/resources.c,v retrieving revision 1.55 diff -u -r1.55 resources.c --- resources.c 20 May 2002 00:51:13 - 1.55 +++ resources.c 20 May 2002 01:40:32 - @@ -741,7 +741,6 @@ NULL != cur_buffer_arena; cur_buffer_arena = cur_buffer_arena->prev) { -Buffer *b = cur_buffer_arena->start_Buffer; UINTVAL i; for (i = 0; i < cur_buffer_arena->used; i++) { /* Is the buffer live, and can we move it? */
Re: [PATCH] Warnings cleanup
Arg, looks like I'm on a roll today. Ignore this latest patch. Looks like this particular line was needed with the recent set of changes, and the below patch compilation of resources.c. I need to learn to test even the most trivial of changes, as my assumptions changed out from under me. Just be glad I don't have commit access. ;) Mike Lambert Mike Lambert wrote: > Date: Sun, 19 May 2002 21:43:22 -0400 (EDT) > From: Mike Lambert <[EMAIL PROTECTED]> > To: Melvin Smith <[EMAIL PROTECTED]> > Cc: [EMAIL PROTECTED] > Subject: Re: [PATCH] Warnings cleanup > > > Mostly applied. Here is your rejected hunk, sir. > > Much appreciated. Looks like Peter's patch also did some of the same > formatting fixes. Below is a re-patch that fixes the problem. > > Mike Lambert > > Index: resources.c > === > RCS file: /cvs/public/parrot/resources.c,v > retrieving revision 1.55 > diff -u -r1.55 resources.c > --- resources.c 20 May 2002 00:51:13 - 1.55 > +++ resources.c 20 May 2002 01:40:32 - > @@ -741,7 +741,6 @@ > NULL != cur_buffer_arena; > cur_buffer_arena = cur_buffer_arena->prev) > { > -Buffer *b = cur_buffer_arena->start_Buffer; > UINTVAL i; > for (i = 0; i < cur_buffer_arena->used; i++) { > /* Is the buffer live, and can we move it? */ > > >
Hashtable+GC problems
I started to look into the GC crashes with the perlhash tests. I'm not sure I found the exact problem, but I found a bunch of dangerous things that were being done, and could possibly cause the GC problems. restore_invariants is an ugly hack that is prone to error. You have to remember to restore_invariants after *any* header retrieval or memory allocation, or anything that could cause that. For example, take hash_delete. It restores invariants properly at the start of the procedure. But if you'll notice down below in the body, it uses string_compare. Due to transcoding issues, that can trigger a full GC, which means you need to restore_invariants inside that loop. And that invalidates your 'chain' which you've already placed on the local C stack, and restore_invariants can't fix that. Same thing with hash_put, which calls find_bucket, which also calls string_compare, with all the same problems. And same deal with hash_get, which calls hash_lookup, which calls find_bucket, etc. I think you should go for an index-based approach to the hashtable problem, to make this work nice and easily. If your concerned about code clarity, I'd be happy to try and go in and attempt to clean things up. Probably just needs a little macro usage to abstract out your hashtable futzoring. (Just one level of macros, no need to worry. ;) Thoughts? Mike Lambert
GC design
I'm remailing this idea since we haven't discussed it in a while. I would like an elegant, easy to use solution for making the GC play nicely. I propose a solution that allows us to draw a electric fence around the current scope by using some call as follows: gc_crit(); gc_leave_crit(); These could be called recursively, and they would result in "generations" of objects. Here is how I would implement it, and yes it does add an overhead word to the headers. In the interpreter struct we keep struct interp { int gc_cur_gen; int gc_bottom_gen; int gc_top_gen; ... } gc_crit() { if(cur_gen < top_gen) { cur_gen = top_gen; } cur_gen++; top_gen++; } gc_leave_crit() { cur_gen--; if(cur_gen == bottom_gen) # We are out of all nested calls, release this window bottom_gen = top_gen; } } gc_alloc_mem() { obj->gen = interp->cur_gen; } gc_collect() { while(obj = next_obj()) { if(in_window(obj, interp->bottom_gen, interp->top_gen)) continue; } } This creates a sliding scope window that GC must not peep through, and provides a clean interface for internals writers. I've done kernel internal work with Linux and critical sections are the norm, and I think the idiom applies well to GC. Lets hammer this one design issue out for good because I'm tired of worrying about it and I think its hindering current Parrot developers and confusing potential newcomers. As Bryan Warnock said (I think), this stuff is for internals programmers only, but the fact that everyone has a different opinion of how to get around GC bugs me. Lets define a solution, document it, and enforce its usage. If it is not what I propose, lets at least discuss alternatives. -Melvin
Re: Accessor methods ?
Aaron Sherman writes: : > Alternately, I think we should be able to mark subs as 'final' or 'inline' : > to indicate our guarantee that they won't be modified. Of course, it'll : > conflict with auto memoizing or auto currying modules that'd want to : > override it, but that's their fault. :) : : Yes, I suggested "inline" or "const" I can't imagine that we would : want to do without this, regardless of what we call it. Otherwise, : auto-accessors will always be slower than using the variable. Would : everyone agree that this property should default to being set for : auto-accessors? No, that would undo the whole point of making them accessors in the first place. : > And even though distributed .pbc files and seperate compilation are some : > goals of perl6, I still think we're okay. If we inline a function in : > module A, and module A changes, Perl6 should ensure that the original : > version is still loaded for our code, and thus our inlining should still : > be valid. : : Oh, that one's easy (I think/hope/pray). : : There're three stages: : : 1. "compile time" -- When a module or program is byte-coded : 2. "load time" -- When byte-code is loaded off of disk : 3. "run time" -- When the program begins to execute : : There are complexities, but you get the idea. "Load time", I assume is : also when BEGIN executes. Actually, BEGIN has to execute at compile time. INIT runs between load time and run time. : In this model, you only ever inline at load time ***OR*** when the : compiler is attempting to produce a self-contained byte-code executable : (e.g. one which has all of the modules in it), in which case it executes : that part of the load time process early. If you like, call this a : sub-stage of load time, which I shall dub "link time". Link time can : only happen once per program, so it must happen when we actually know : what all of the program components are. It seems like an assumption that link time can only happen once. An incremental linker might feel like it can relink any time it feels like it. Some very useful programs never completely know what their components are. : Any other way of doing this would seem to me to be a very dangerous : weapon to brandish so close to so many unsuspecting feet. :-( We've never shied away from issuing people enough rope. But I don't think that has to be the case here. We'll likely have an inline property. : > Another avenue is that of self-modifying code. I know it would break : > threads, or cause code duplication between threads, but when A changes, we : > can either re-inline the new subroutine, or eliminate the 'if-else' check : > to avoid the branch we know will be false from then on. Creating code : > which optimizes itself as it's run based upon internal profiling would be : > cool. But that's the topic of a different thread. :) : : Code that does this by changing sub references should still work. Code : that does this by changing its own internal representation gets what it : paid for. But methods don't have a unique sub ref until you know the type. One could inline a jump table of sub refs based on known types, and default to ordinary method lookup for unknown types. But there's no guarantee that would actually be faster than a decent vtable lookup. Larry
Re: Using closures for regex control
Me writes: : [modified repost due to warnock's dilemma] : : Would something like these DWIM? : : # match pat1 _ pat2 and capture pat2 match: : / pat1 { ($foo) = / pat2 / } / Yes, though I think we'll see people doing it more like this: / pat1 ( pat2 ) { $foo = $-1 } / We might allow something like / pat1 $foo=( pat2 ) / as a shorthand for that. But in the general case, the closure can put the value anywhere, and this will be particularly important for building parse trees. : # match pat1 _ 'foo bar': : / pat1 { 'foo bar' } / Probably not. I can think of several other good uses for return values from inner closures, such as building a parse tree. But at the moment I'm thinking that the return value will be ignored. If so, {'foo bar'} might be the way to inline comments in place of (?#foo bar). : # match pat2 if not pat1 : / { ! /pat1/ } pat2 } / Same issue. You can always write / { /pat1/ or fail } pat2 /. I don't think the return of the closure will be interpreted as a boolean. Closures will be used for side effects, and I'd hate to see a lot of closures ending in a cryptic C<0;>. It's better to make the assertions explicit. Could even have a unary "fail unless" operator: / { assert /pat1/ } pat2 } / There might be a better word than assert. : # match pat2 if pat1 behind : / { .lookbehind /pat1/ } pat2 } / Sure, presuming .lookbehind knows how to fail. But is much more readable, I think. Larry
Re: GC design
> I would like an elegant, easy to use solution for making the GC > play nicely. So would we all. :) > This creates a sliding scope window that GC must not peep through, > and provides a clean interface for internals writers. I think you've explained this idea before, but I complained about it because I thought that the bottom_gen never got set to top_gen, and figured a lot of stuff would end up permanently allocated. Now that I see how it works, it seems to make a lot of sense. Problems with your approach: GC-sensitive functions must remember to mark themselves as critical. This will be a source of bugs (whether that's a big enough of a complaint is up for debate. ;) Most vtable methods, and/or people that call vtable methods, will end up making themselves critical. This overhead will be imposed on most function calls, etc. Lots of the string api will require the users to mark themselves as critical. > Lets hammer this one design issue out for good because I'm tired of worrying > about it and I think its hindering current Parrot developers and > confusing potential newcomers. > If it is not what I propose, lets at least discuss alternatives. If I remember correctly, this did get hammered out with a directive from Dan. ;) His approach was: the live flag is valid only within GC. all newly-allocated headers are marked as uncollectable there is a clear-uncollectable op, which iterates over the headers, and marks them all as collectable Basically, you need to have assigned all your headers to something traceable by the root set before your current op ends. The advantages of this are that nobody needs to worry about the GC implications of their code. The disadvantage are: - very expensive ops can allocate lots of uncollectable headers? - you must explicitly allow for marking headers as collectable in your opcode, at strategically placed locations. otherwise, nothing gets collected and you have no dod results, although collection will still occur normally. Any other contenders to the ring? Anyone have any other major dis/advantages they'd like to contribute about the above approaches? FWIW, I feel confident enough about my understanding of Dan's idea to implement that, should we choose it. Melvin's idea would require that much more work on the multitude of functions, and so I can't imagine it being as easy to implement. :) Mike Lambert
Re: GC design
At 02:23 AM 5/20/2002 -0400, Mike Lambert wrote: >GC-sensitive functions must remember to mark themselves as critical. >This will be a source of bugs (whether that's a big enough of a >complaint is up for debate. ;) I'll think about debating it tomorrow. :) >Most vtable methods, and/or people that call vtable methods, will end up >making themselves critical. This overhead will be imposed on most function >calls, etc. Lots of the string api will require the users to mark >themselves as critical. I don't think this is accurate. People calling vtable methods have no need to mark themselves as critical. The things that mark themselves critical are internals that are allocating and holding onto objects. I think very few vtable methods even fall into this category, but I'd have to survey the .pmc files before continuing this discussion. > > Lets hammer this one design issue out for good because I'm tired of > worrying > > about it and I think its hindering current Parrot developers and > > confusing potential newcomers. > > > If it is not what I propose, lets at least discuss alternatives. > >If I remember correctly, this did get hammered out with a directive from >Dan. ;) I've seen no evidence of that hammering. I still think we are having GC crashes on this issue. >His approach was: >the live flag is valid only within GC. >all newly-allocated headers are marked as uncollectable >there is a clear-uncollectable op, which iterates over the headers, and > marks them all as collectable >Basically, you need to have assigned all your headers to something >traceable by the root set before your current op ends. > >The advantages of this are that nobody needs to worry about the GC >implications of their code. Yes they do, they have to call an explicit routine, clear_uncollectable >The disadvantage are: >- very expensive ops can allocate lots of uncollectable headers? >- you must explicitly allow for marking headers as collectable in your >opcode, at strategically placed locations. otherwise, nothing gets >collected and you have no dod results, although collection will still >occur normally. > >Any other contenders to the ring? Anyone have any other major >dis/advantages they'd like to contribute about the above approaches? > >FWIW, I feel confident enough about my understanding of Dan's idea to >implement that, should we choose it. Melvin's idea would require that >much more work on the multitude of functions, and so I can't imagine it >being as easy to implement. :) I'd just like to see someone implement a solution, and give benchmarks to back it up. I'd like to see both approaches compared, personally, and I think neither requires a whole lot of thought to implement. I also think we should reference existing research and implementations, since we aren't the first to do this. -Melvin
Dynamic register frames?
I may be approaching semi-radical territory here with this idea. I've read all the FAQs and reasons on why we choose a register architecture versus a stack architecture. However, I recently thought of a combination idea which, (although it was probably discovered in the 70s sometime,) I think provides the best of both worlds, and would like to propose it before I shove it off to the dust-bin. Problems with register architecture: with caller-save, we're saving 0.5KB (4types*32registers*4bytes) of data per function call, which might add up with deeply-nested functions. If we want more than 32 elements, we need to start doing stack-pushing to get around limitations. One thing that I wanted to do in a regex implementation was use the full set of registers to store off certain points in the compiled regex. With 32 registers, longer regexes will require stack pushing at a certain point, and that will make a certain transition of the regex slower than the other portions of the regex. Problems with stack architecture: time spent pushing/popping ops (also happens with parrot registers if we use >32 elements) stack grows at runtime Now, my proposal is simply that instead of hardcoding to 32 elements, we allow the function to determine the number of elements in each register type. This gives us: each function uses a minimal of space, since it only uses as many registers as it requires leaf accessor functions have 0 or 1 registers for the most part, so we don't need to allocate a whole new set of registers for them. Caller-save is just pushing the current register frame onto the stack, and allocating a properly-sized register frame for the current leaf function, which is very small. Should be efficient. the register stack only gets used for functions. For the most part, functions allocate all the space they know they'll need, and that's it. (Of course, I suppose there are probably legit reasons for functions to use the register stack frames, however). We can use more than 32 elements. This means a 120-node regex can allocate 120 int registers for it's operation and execution. (Not saying that it's 1:1, more like 1:1 for non-greedy regex ops only, but still) No need to worry about register liveness/allocation to make things work. We now only need to do it if we want to make things run faster by using *less* than one register per C/perl stack variable. It's probably a bit late in the parrot development cycle to be propsing an idea like this, but I suppose since this idea couldn't have been implemented until we had functions which could store register requirement information, this might actually be a good time to suggest it. :) Thoughts or comments? Thanks, Mike Lambert
Re: GC design
> >Most vtable methods, and/or people that call vtable methods, will end up > >making themselves critical. This overhead will be imposed on most function > >calls, etc. Lots of the string api will require the users to mark > >themselves as critical. > > I don't think this is accurate. People calling vtable methods have no need > to mark themselves as critical. The things that mark themselves critical > are internals that are allocating and holding onto objects. I think very > few vtable methods even fall into this category, but I'd have to survey > the .pmc files before continuing this discussion. Perl strings, arrays, and hashes all require buffer manipulation, and will probably fall prey to this. I agree that I was probably generalizing a bit, and that in theory PMCs can criticalize their own methods. > >If I remember correctly, this did get hammered out with a directive from > >Dan. ;) > > I've seen no evidence of that hammering. I still think we are having GC > crashes on this issue. I said Dan gave a directive. I didn't say anyone listened to Dan, or implemented what he suggested. ;) > >The advantages of this are that nobody needs to worry about the GC > >implications of their code. > > Yes they do, they have to call an explicit routine, clear_uncollectable Ah, but as internals designers, we don't need to worry about that. We get to push it into the compiler writers. Isn't it fun? :) I initially had the same opposition to Dan's idea that you have. I'm not sure why I eventually gave in...perhaps the lack of any other solution? Don't really recall. :) > I'd just like to see someone implement a solution, and give benchmarks > to back it up. > > I'd like to see both approaches compared, personally, and I think neither > requires a whole lot of thought to implement. I also think we should reference > existing research and implementations, since we aren't the first to do this. That's true. I believe most implementations have taken advantage of the ability to access the C stack, something we don't have the liberty of with our wide-reaching compatibility goals. I think this will be similar to the cost of a reference counting solution versus a tracing system, where the former amortizes the cost over the entire system, but ends up being slower in terms of total time used. Your approach would involve lots of computation in lots of little functions over parrot's execution, whereas Dan's would involve a full trace (equivalent to a DOD) to be performed every now and again. But that's just hypothetical posturing because I don't have any real benchmarks, of course. Mike Lambert