Re: GC design

2002-05-27 Thread Jerome Vouillon

On Sun, May 26, 2002 at 08:20:23AM -0700, Sean O'Rourke wrote:
> I'm sure it's been discussed before somewhere, but why can't we guarantee
> that we only do GC runs between ops?  Each op would just have to guarantee
> that all of its persistent data is reachable before it returns.  It seems
> like this would avoid the need for a neonate flag entirely.

If you know how much memory the op is going to need, then you can run
the GC just before executing the op to make sure that at least this
amount of memory is available (and non fragmented).  But this seems to
be a pretty strong requirement.

Otherwise, you should be able to run the GC whenever you allocate some
memory.

> > "Mike Lambert" wrote:
> > > Another proposal is to walk the C stack.

What about managing explicitly a stack of Parrot values?
Something like this:

  /* Save the top of the stack */
  struct parrot_frame *parent = parrot_stack;

  /* Create a variable "x" which contains Parrot values */
  parrot_value x = 0;   /* This is the variable */
  struct parrot_frame frame;/* Allocate a stack frame */
  frame.val = &x;   /* Push the value into the stack */
  frame.next = parrot_stack;
  parrot_stack = &frame;

  /* ... Body of the function */

  parrot_stack = parent;/* Pop the stack */
  return;   /* Exit the function */

With a suitable set of macros, this should be manageable.

-- Jerome



Re: Hashtable+GC problems

2002-05-27 Thread Jerome Vouillon

On Sun, May 19, 2002 at 10:43:20PM -0400, Mike Lambert wrote:
[...]
> 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.

In my opinion, there should be a low level string_compare which does
not allocate anything.  Instead, it should fail if its arguments do
not have the same encoding.  Of course, the string_compare opcode can
be smarter and perform some transcoding.

Then, the hashtable code should explicitely transcode the key before
using it.

-- Jerome



[netlabs #628] [PATCH] Make hash.c depend on parrot headers

2002-05-27 Thread Peter Gibbs

# New Ticket Created by  "Peter Gibbs" 
# Please include the string:  [netlabs #628]
# in the subject line of all future correspondence about this issue. 
# http://bugs6.perl.org/rt2/Ticket/Display.html?id=628 >


Following patch adds dependencies entry for hash.c to Makefile.

Stops things from getting very confusing when changing layout of String
and/or Buffer structs!

--
Peter Gibbs
EmKel Systems

Index: config/gen/makefiles/root.in
===
RCS file: /home/perlcvs/parrot/config/gen/makefiles/root.in,v
retrieving revision 1.2
diff -u -r1.2 root.in
--- config/gen/makefiles/root.in24 May 2002 16:34:19 -  1.2
+++ config/gen/makefiles/root.in27 May 2002 10:23:12 -
@@ -292,6 +292,8 @@

 pmc$(O) : $(GENERAL_H_FILES)

+hash$(O) : $(GENERAL_H_FILES)
+
 jit$(O) : $(GENERAL_H_FILES)

 jit_cpu$(O): $(GENERAL_H_FILES) $(INC)/jit_emit.h





Re: GC design

2002-05-27 Thread Sean O'Rourke

On Mon, 27 May 2002, Jerome Vouillon wrote:

> On Sun, May 26, 2002 at 08:20:23AM -0700, Sean O'Rourke wrote:
> > I'm sure it's been discussed before somewhere, but why can't we guarantee
> > that we only do GC runs between ops?  Each op would just have to guarantee
> > that all of its persistent data is reachable before it returns.  It seems
> > like this would avoid the need for a neonate flag entirely.
>
> If you know how much memory the op is going to need, then you can run
> the GC just before executing the op to make sure that at least this
> amount of memory is available (and non fragmented).  But this seems to
> be a pretty strong requirement.

But there are two kinds of "available" here: available without asking the
operating system for more; and available period.  If we're in the first
situation, it seems reasonable to just ask the OS for a new block and keep
going, noting that collecting soon would be a Good Thing.  Our memory
requirements have probably increased, so we'd be asking for more soon
anyways, and if they haven't, we'll reclaim a lot of memory on the next
collection, and only be "wasting" 8 or 16k.  We can even try to give some
back, though the OS probably won't take it.  If we're in the second
situation, then either (1) we've gone far too long without collectiong, or
(2) we're in serious trouble anyways.  And even in this situation, we can
wriggle out of it most of the time by keeping some amount of "emergency"
memory stashed away.

This may not work on embedded systems, but not having developed for one, I
hate to just throw away the idea based on my ill-founded suspicions.

> Otherwise, you should be able to run the GC whenever you allocate some
> memory.

Since our memory-allocating routines return NULL quite a ways back up the
call chain (all the way through e.g. string_grow()), here's another way to
do this -- if allocation returns NULL all the way to an op function, it
can make the things it wants to keep reachable from somewhere, do a
collection, and retry.  By the way, neither of string_grow()'s callers
checks its return value now, which indicates to me that this may be
error-prone.

/s




[netlabs #629] [PATCH] Memory manager/garbage collector - major revision

2002-05-27 Thread Peter Gibbs

# New Ticket Created by  "Peter Gibbs" 
# Please include the string:  [netlabs #629]
# in the subject line of all future correspondence about this issue. 
# http://bugs6.perl.org/rt2/Ticket/Display.html?id=629 >


Attached patch does some fairly radical things to the memory manager.

1) Cycle counter added to interpreter structure; incremented by opcodes that
have something vaguely resembling a function call in their body.
2) Buffer-like objects have their date of birth (cycle counter value)
recorded
3) Neonate flag is deprecated; functionality replaced by the above i.e. no
buffer
header will be freed during the same opcode as it was created
4) Free pool array replaced by a linked list within the arenas
5) Minimum/maximum ratio of memory pool physical size to used size
controlled
by new tuning parameters (fixed #define's for now)
6) DOD run performed during memory allocation if compaction will not reclaim
enough memory

The 'function-call like' logic (which is very primitive at present) for
adding the
cycle count increment into an op's body means that most simple opcodes
should not incur additional overhead. Once an op starts calling functions,
the
additional overhead of a single increment is likely to be minor.
After much thought and playing around, this seems to be the best answer to
the problem of infant mortality. Dan's suggestion of reversing the logic of
DOD
runs would work for the pure infant mortality situation (except perhaps for
the odd
pathological op), but it still leaves problems with the dependency of buffer
memory collection on prior dead object detection.
These changes do cause a slight performance degradation, but I believe it is
worth it for the overall simplification of transparent protection of the
newborn.
Performance can only be a secondary goal, after correct behaviour.

The runaway memory usage of programs like zip and quicksort has hopefully
been resolved; I have successfully run zip.pasm against core_ops.c.

Note that the neonate flag has not been removed; if this patch is applied,
all
use of the neonate flag can be removed, followed by the flag itself. The
flag is
not used in the new GC logic.

The problem of having buffer memory move around still remains; that should
be
addressed shortly.

--
Peter Gibbs
EmKel Systems




Re: [netlabs #629] [PATCH] Memory manager/garbage collector -major revision

2002-05-27 Thread Dan Sugalski

At 4:33 PM + 5/27/02, "Peter Gibbs" (via RT) wrote:
>Dan's suggestion of reversing the logic of
>DOD runs would work for the pure infant mortality situation (except 
>perhaps for the odd pathological op), but it still leaves problems 
>with the dependency of buffer memory collection on prior dead object 
>detection.

That dependency, as such, is in there on purpose, and it's not really 
a problem. It's a win with mutable strings, something we don't take 
as much advantage of as we should.

>These changes do cause a slight performance degradation, but I believe it is
>worth it for the overall simplification of transparent protection of the
>newborn.

Unfortunately I don't. I'm willing to live with a performance 
degredation in those spots where it's truly necessary, but only 
there. The performance hit has to be localized to those places where 
infant mortality is actually a problem. Those spots are currently 
reasonably rare, and I'm not sure that the hoops we're building to 
jump through (and I'm as guilty as anyone) are worth it.

>Performance can only be a secondary goal, after correct behaviour.

But performance has to be given up as grudgingly as possible.
-- 
 Dan

--"it's like this"---
Dan Sugalski  even samurai
[EMAIL PROTECTED] have teddy bears and even
   teddy bears get drunk



[COMMIT] Added preprocessor layer to newasm.

2002-05-27 Thread Jeff

newasm now handles constants, macros, and local labels within. Here's a
short test program that exercises all three featurs. Doesn't do much,
but here it is:


print "Everything else is as usual.\n"
..macro MyMacro ( FOO, Bar ) # Macros are now prepended with '.'.
  print .FOO # . also prepends our arguments
  add I3,I3,.BAR
..local $MyLabel: print "Label\n" # And label definitions
  if I3,.$MyLabel
  branch GlobalLabel
..endm
  print "Some stuff\n"
  .constant HelloWorld "Hello, World!\n"
  set S0,.HelloWorld
GlobalLabel: print "Infinite loop here.\n"
  print "About to call the macro.\n"
  .MyMacro(S0,I3) # Invoke the macro. Note that the macro branches
  # to -before- this macro, so it's an infinite loop.
  print "We'll never get here, but here's the value of PerlArray: "
  print .PerlArray # It's a constant, but predefined.
  new P0,.PerlArray
  set P0[I1],.HelloWorld # Of course, keyed access still works.
  end

Documentation in newasm has been updated, and the documentation should
help explain things. Macros are not allowed to be recursive, and must be
defined before they can be used. Same thing with constants.

Also, note that -any- text of the form '.Foo' is a fair candidate for
expansion. Also, they don't expand recursively. '.constant FOO
"blah"\n.constant BAR "Hey, .FOO"' won't do what you want, sadly.

It's passed the tests that I managed to change over to the new style.
Feel free to report bugs and make your own changes. The most clamor that
I've heard after this seems to be an all-Perl bytecode generator, so
that's what I'll work on next.
--
Jeff <[EMAIL PROTECTED]>