GC API from discussion

14 views
Skip to first unread message

David Formosa )

unread,
Aug 14, 2005, 9:13:37 PM8/14/05
to perl6-l...@perl.org
After a very fruitful discussion I've rewritten my suggested GC API.
Comments please. Is this the path we should be going down? What
needs more work? What needs clarification? Have I totally lost the
plot?

=pod

=head1 NAME

GC - The interface to the runtime Garbage collector.

=head1 SYNOPSIS

class Philosopher is GC::timely {

has Fork::Lock $.lfork;
has Fork::Lock $.rfork;

method dine {
$.lfork.grab;
$.rfork.grab;
...
}

method DESTORY {
$.rfork.release;
$.lfork.release;
}
}


my $long_lived_configuration_verbal_that_dosnt_need_much_checking is GC:tardy;

my @pantheon of God is GC::immortal;

sub draw ($display,@frames) {
no GC::delay; # Slowing down to check garbige would upset our little
# animation.
for @frames -> {$display.show($_)}
}

=head1 ADJECTIVES

The GC API supplies the following adjectives.

=over

=item GC::timely

Requests timely destruction, that is the object is collected as soon
as it is no longer visable. Uses for this taint are to ensure release
of expencive resources, and to support porting of Perl5 code that
expects timely destruction.

=item GC::tardy

Indercates to the GC the object is long lived and unlikely to leave
program visability. GC's may use this infomation for optimization,
for example generational GC's could artificially age object's marked
as tardy.

=item GC::immortal

Prevents collection of this object even when it has passed out of
visability.

# Is this even a good idea? It may be usefull for FFI. Though its
# clearly a heavy wizardy type of thing. If nobody thinks it may be
# usefull I think this dangerous beast can be removed even before it
# sees the light of day.

=item GC::keystone

Indercates to the GC the objects that this object has references to
are only referenced by this object. Hence if this object is no longer
visible then all of the objects that this object refers to are also no
longer visable.

GC's may use this infomation for optimization. The behavour of the GC
when encountering an object that is marked keystone but does not have
the keystone property is unspecified, and likely to be inconsistent.

=back

The Adjectives can be used meaningfully in the following ways.

=over 4

=item As a scalar variable taint.

my $item is GC::timely;

Whatever is stored within the scalar verable requires timely
collection.

=item As a taint on a collection.

my @array is GC::timely;

Each member of the @array requires timely collection.

=item As a taint on a value.

"A string" is GC::timely; # Or should this be C<but CG:timely> ?
{a => "hash"} is GC::timely; # corrections/confirmation please.

The string/hash requires timely collection.

=item As a taint on a class or a role

class Philosopher is GC::timely {...}

The Philosopher object requires timely collection.

=item As a taint on a sub declaration.

sub ($x) is GC::timely {...}

The closure created by this sub requires timely collection.

=item As a Pragma

use GC::timely;

Every memory consuming object declared in this lexical scope requires
timely collection

=back

=head1 PRAGMAS

=over

=item no GC::delay / use GC::delay

Requests that the GC avoid CPU intensive operations while the program
is within this lexical scope. GC's that don't induce delays may
ignore this. use GC::delay relaxes the request with in its lexical
scope.

=back

=head1 SUBS

=over

=item sub GC::delay(+Int|u $depth=1 --> Int|undef) {...}

Requests that GC's with CPU interacting operations run at this time.
For example a this will trigger a mark and sweep style GC's mark and
sweep operation. GC::delay will cause a delay even in blocks marked
no GC::delay. The meaning of the $depth is for the most part
implementation specific, with the following limmitations.

=over

=item $depth==0

Requests an optional GC run. That is the CG may run if the GC thinks
its necessary ( This is equiverlent to {use GC::delay} ).

=item $depth==1

Requrests a normal GC run.

=item $depth>1

Requrests a more intensive GC run, with higher values
implying greater intensiveness.

=back

GC::delay may return the number of bytes freed.

=item sub GC::type(--> Str) {...}

Returns a string interacting the type of GC being used.

=back

=head1 METHODS

=over

=item method GC::new(::Class $class: --> GC) {...}

Returns a GC object permitting implementation specific requests.

=back

=cut

--
Please excuse my spelling as I suffer from agraphia. See
http://dformosa.zeta.org.au/~dformosa/Spelling.html to find out more.
Free the Memes.

Adrian Howard

unread,
Aug 15, 2005, 7:40:05 AM8/15/05
to perl6-l...@perl.org
On 15 Aug 2005, at 02:13, David Formosa ((aka ? the Platypus)) wrote:

> After a very fruitful discussion I've rewritten my suggested GC API.
> Comments please.

[snip]

I'm speaking from complete ignorance since I've only been vaguely
following the subject... but four additional things that strike me as
useful (because I found them so in Pop-11 when I used it) would be:

1) Some way of declaring objects as being "fixed" so we can pass them
to external code without having to worry about the GC moving them
around.

2) Some way of being able to tell the garbage collector to ignore the
current contents of the heap for the purposes of GC. One Pop-11 idiom
was to do something like:

;;; create a whole bunch of complicated self referencing
;;; objects that we know are going to persist over time

sys_garbage(); ;;; run the garbage collector
sys_lock_heap(); ;;; lock stuff currently in the heap

;;; do lots of stuff that now runs quicker since the GC doesn't
;;; have to worry about marking the objects that we know are
;;; not going away

sys_unlock_heap(); ;;; give the GC full rein again


3) Some way of marking structures/fields so their reference doesn't
count. Weakrefs basically.

4) Hooks to run code before/after GC. Occasionally very useful. (e.g.
with the gc hooks and heap locking/unlocking you could implement your
own ephemeral GC system in Pop-11).

Hopefully this makes some vague sort of sense.

Cheers,

Adrian

Yuval Kogman

unread,
Aug 15, 2005, 8:17:18 AM8/15/05
to Adrian Howard, perl6-l...@perl.org
On Mon, Aug 15, 2005 at 12:40:05 +0100, Adrian Howard wrote:
> On 15 Aug 2005, at 02:13, David Formosa ((aka ? the Platypus)) wrote:
>
> >After a very fruitful discussion I've rewritten my suggested GC API.
> >Comments please.
> [snip]
>
> I'm speaking from complete ignorance since I've only been vaguely following the subject... but four additional things that strike me as useful (because I found them so in
> Pop-11 when I used it) would be:
>
> 1) Some way of declaring objects as being "fixed" so we can pass them to external code without having to worry about the GC moving them around.

A handle to an object should always be fixed, I would think... Even
under a copying mechanism, you can have an arena for handles, and an
arena for the actual data which is actually collected, and points
back to the data.

Optimized access (auto unboxing, various inferrencing by the
compiler) could be made such that it doesn't go through the handle
unless absolutely necessary.

> 2) Some way of being able to tell the garbage collector to ignore the current contents of the heap for the purposes of GC. One Pop-11 idiom was to do something like:
>
> ;;; create a whole bunch of complicated self referencing
> ;;; objects that we know are going to persist over time
>
> sys_garbage(); ;;; run the garbage collector
> sys_lock_heap(); ;;; lock stuff currently in the heap
>
> ;;; do lots of stuff that now runs quicker since the GC doesn't
> ;;; have to worry about marking the objects that we know are
> ;;; not going away
>
> sys_unlock_heap(); ;;; give the GC full rein again

We are trying to design a requirement based interface, so that the
GC can be changed, but behavior remains consistent.

This should be more like

do :GC::priority(:low) {
# anything that isn't GC::timely or possibly affecting
# something that is GC::timely is not cleaned up till
# later
}

do :GC::nodelay {
# the GC can work, but timeliness and throughput are
# ignored for the sake of performance of "real" code
# this means that most GCs are disabled, but a
# background thread GC will just have it's priority
# lowered

# implies that 'timely' now means 'at some point'
}

do :GC::nodestroy {
# the GC is told to completely freeze the state of
# things, delaying all work until after the block exits
# this means that you can rely on GC::timely objects
# being alive even when they shouldn't be.

# this is orthogonal to GC::nodelay - under plain
# GC::disabled objects may be collected for overall
# performance reasons, and then simply put on the
# finalize queue for finalization on block exit.

# applying both nodelay and nodestroy causes the GC
# system to completely turn off, so that objects are
# neither finalized nor collected.
}

do :GC::disabled {
# nodelay and nodestroy together
}

do :GC::priority(:high) {
# work very hard to conserve memory
}

do :GC::critical {
# it's like GC::timely for everything
}

Possibly with e.g. $*RUNTIME.Memory.GarbageCollector.disable thrown
in for flexibility.

Block scoped behavior has some advantages:

Exceptions raised from the block will cause augmented behavior
to be reverted on scope exit

Structure is clearer

But it's not as capable, since behavior cannot be changed to affect
calling scopes. This is important, but should be discouraged from
normal use.

> 3) Some way of marking structures/fields so their reference doesn't count. Weakrefs basically.

Yes... i think this is a container trait. Anybody got an opinion?

my $var is weakref = $object;

> 4) Hooks to run code before/after GC. Occasionally very useful. (e.g. with the gc hooks and heap locking/unlocking you could implement your own ephemeral GC system in Pop-11).

This is possibly done by introspecting
$*RUNTIME.Memory.GarbageCollector, and seeing if it supports events.

What if it's a thread continuously running in the background, which
is only synched when something GC::timely may be involved?

This is getting me thinking though:

$*RUNTIME.Memory.GarbageCollector.dispose($object); # force it,
# even if it should be alive

$*RUNTIME.Memory.GarbageCollector.clean($object); # check it

These two are non recursive by default, and they accept the
':recursive(1)' optional param to imply that referred subobjects
should be applied too. They should also allow very tight loops to be
controlled under do :GC::disabled, without wasting lots of memory.

On block exit a consistent state is reached - any timely objects
that should have been destroyed in the nested block will be
finalized.

Hmmm... ;-)

sub nothingness () {
$*RUNTIME.Memory.GarbageCollector.dispose($*RUNTIME, :recursive(1));
}

--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &
/\ kung foo master: /me sneaks up from another MIME part: neeyah!!!!!

Adrian Howard

unread,
Aug 15, 2005, 10:59:34 AM8/15/05
to perl6-l...@perl.org
On 15 Aug 2005, at 13:17, Yuval Kogman wrote:
> On Mon, Aug 15, 2005 at 12:40:05 +0100, Adrian Howard wrote:
[snip]

>> 1) Some way of declaring objects as being "fixed" so we can pass
>> them to external code without having to worry about the GC moving
>> them around.
>
> A handle to an object should always be fixed, I would think... Even
> under a copying mechanism, you can have an arena for handles, and an
> arena for the actual data which is actually collected, and points
> back to the data.
>
> Optimized access (auto unboxing, various inferrencing by the
> compiler) could be made such that it doesn't go through the handle
> unless absolutely necessary.

I'm not sure what you're proposing here. A separate arena for stuff
you want to allocate and not be moved by the GC? How would I tell the
compiler?

>> 2) Some way of being able to tell the garbage collector to ignore
>> the current contents of the heap for the purposes of GC. One
>> Pop-11 idiom was to do something like:
>>
>> ;;; create a whole bunch of complicated self referencing
>> ;;; objects that we know are going to persist over time
>>
>> sys_garbage(); ;;; run the garbage collector
>> sys_lock_heap(); ;;; lock stuff currently in the heap
>>
>> ;;; do lots of stuff that now runs quicker since the GC doesn't
>> ;;; have to worry about marking the objects that we know are
>> ;;; not going away
>>
>> sys_unlock_heap(); ;;; give the GC full rein again
>>
>
> We are trying to design a requirement based interface, so that the
> GC can be changed, but behavior remains consistent.
>
> This should be more like

[interesting options snipped]

How about

do : GC::priority(:new) {
# only GC things allocated during the lifetime
# of the block
}

?

[snip]
> do :GC::nodelay {
[snip]
> do :GC::nodestroy {
[snip]

no_delay and no_destroy please (I spent a minute trying to figure out
what a "node lay" was :-)

[snip]


>> 4) Hooks to run code before/after GC. Occasionally very useful.
>> (e.g. with the gc hooks and heap locking/unlocking you could
>> implement your own ephemeral GC system in Pop-11).
>
> This is possibly done by introspecting
> $*RUNTIME.Memory.GarbageCollector, and seeing if it supports events.

[snip]

Actually, since to my naive eyes it looks like the GC is a first
class object the problem can probably be solver better by adding your
own.

Adrian

David Formosa

unread,
Aug 16, 2005, 1:14:06 AM8/16/05
to perl6-l...@perl.org
On Mon, 15 Aug 2005 12:40:05 +0100, Adrian Howard <adr...@quietstars.com> wrote:
> On 15 Aug 2005, at 02:13, David Formosa ((aka ? the Platypus)) wrote:
>
>> After a very fruitful discussion I've rewritten my suggested GC API.
>> Comments please.
> [snip]
>
> I'm speaking from complete ignorance since I've only been vaguely
> following the subject... but four additional things that strike me as
> useful (because I found them so in Pop-11 when I used it) would be:

Stealing usefull things from other langagues is good.

> 1) Some way of declaring objects as being "fixed" so we can pass them
> to external code without having to worry about the GC moving them
> around.

I think that the FFI would take care of that via handels.

[...]

> 2) Some way of being able to tell the garbage collector to ignore the
> current contents of the heap for the purposes of GC. One Pop-11 idiom
> was to do something like:

Part of that is why we have the GC::tardy traint and C<no GC::delay>.
But C<no GC::destroy> preventing the desctruction of objects in its
lexical scope.

[...]

> 3) Some way of marking structures/fields so their reference doesn't
> count. Weakrefs basically.

I have strongly thought about adding weakrefs into the API. However I
recall $larry basically saying the need for weak refs means you have
got your design wrong. However google doesn't seem to find it.
Unless I hear words otherwise I'll add it in the next revision.

> 4) Hooks to run code before/after GC. Occasionally very useful. (e.g.
> with the gc hooks and heap locking/unlocking you could implement your
> own ephemeral GC system in Pop-11).

Not all GC's have before and after concepts. (pure refcounting and
mulithreaded models for example). I think that these hooks would be
added via the object interface.

> Hopefully this makes some vague sort of sense.

Thankyou it was helpfull.

David Formosa

unread,
Aug 16, 2005, 1:32:50 AM8/16/05
to perl6-l...@perl.org
On Mon, 15 Aug 2005 15:17:18 +0300, Yuval Kogman <nothi...@woobling.org> wrote:
[...]

>> 2) Some way of being able to tell the garbage collector to ignore
>> the current contents of the heap for the purposes of GC. One
>> Pop-11 idiom was to do something like:

[...]

> We are trying to design a requirement based interface, so that the
> GC can be changed, but behavior remains consistent.
>
> This should be more like
>
> do :GC::priority(:low) {
> # anything that isn't GC::timely or possibly affecting
> # something that is GC::timely is not cleaned up till
> # later
> }

I don't think that making use of "use" and "no" would be shorter and
far more Perlish. Also this allows us to switch off the
modifications.

So this would be

{
use GC::priority :low;


# anything that isn't GC::timely or possibly affecting
# something that is GC::timely is not cleaned up till
# later
}

> do :GC::nodelay {
> # the GC can work, but timeliness and throughput are
> # ignored for the sake of performance of "real" code
> # this means that most GCs are disabled, but a
> # background thread GC will just have it's priority
> # lowered
>
> # implies that 'timely' now means 'at some point'
> }

{
no GC::delay;
...
}


> do :GC::nodestroy {
> # the GC is told to completely freeze the state of
> # things, delaying all work until after the block exits
> # this means that you can rely on GC::timely objects
> # being alive even when they shouldn't be.
>
> # this is orthogonal to GC::nodelay - under plain
> # GC::disabled objects may be collected for overall
> # performance reasons, and then simply put on the
> # finalize queue for finalization on block exit.
>
> # applying both nodelay and nodestroy causes the GC
> # system to completely turn off, so that objects are
> # neither finalized nor collected.
> }

{
no GC::destory;
...
}

>
> do :GC::disabled {
> # nodelay and nodestroy together
> }

{
no CG::destory;
no GC::delay;
...
}

# Or

{
no GC;
...
}

> do :GC::priority(:high) {
> # work very hard to conserve memory
> }

{
use GC::priority :high;
...
}

> do :GC::critical {
> # it's like GC::timely for everything
> }

I'm not sure "critical" is the right name.

[...]

>> 3) Some way of marking structures/fields so their reference doesn't count. Weakrefs basically.
>
> Yes... i think this is a container trait. Anybody got an opinion?
>
> my $var is weakref = $object;

is GC::weak

> This is getting me thinking though:
>
> $*RUNTIME.Memory.GarbageCollector.dispose($object); # force it,
> # even if it should be alive

Isn't that what we have undefine(...) for?

> $*RUNTIME.Memory.GarbageCollector.clean($object); # check it

Possably as an argument for GC::delay(...) ?

Yuval Kogman

unread,
Aug 16, 2005, 12:46:29 PM8/16/05
to David Formosa (aka ? the Platypus), perl6-l...@perl.org
On Tue, Aug 16, 2005 at 05:32:50 -0000, David Formosa (aka ? the Platypus) wrote:

> I don't think that making use of "use" and "no" would be shorter and
> far more Perlish. Also this allows us to switch off the
> modifications.


Uh, why didn't I think of that =)

> > This is getting me thinking though:
> >
> > $*RUNTIME.Memory.GarbageCollector.dispose($object); # force it,
> > # even if it should be alive
>
> Isn't that what we have undefine(...) for?


No:

my Dog $spot .= new;
my $spot_II = $spot; # another reference
$*RUNTIME.Memory.GarbageCollector.dispose($spot);

# $spot_II is undefined now, because the object was disposed

Furthermore:

my Dog $spot .= new;
my $spot_II = $spot;
undefine($spot); # still referenced by a root set member
undefine($spot_II); # no more refs

# the object may still be alive, if it didn't say it needed
# timely destruction



--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &

/\ kung foo master: /me spreads pj3Ar using 0wnage: neeyah!!!!!!!!!!!

Yuval Kogman

unread,
Aug 16, 2005, 1:14:43 PM8/16/05
to Adrian Howard, perl6-l...@perl.org
On Mon, Aug 15, 2005 at 15:59:34 +0100, Adrian Howard wrote:
> On 15 Aug 2005, at 13:17, Yuval Kogman wrote:

> I'm not sure what you're proposing here. A separate arena for
> stuff you want to allocate and not be moved by the GC? How would
> I tell the compiler?

You won't, the language glue is responsible for setting that up for
you, and it does that by assuming it's always there, and the
compiler simply optimizes the cases where it's never going to be
needed.

> How about
>
> do : GC::priority(:new) {
> # only GC things allocated during the lifetime
> # of the block
> }

I think that's not "priority" but "limit" or "scoped" or
"origin(:local)" or something like that...


Let's define some terms:

scope/origin - where objects are created

priority - how important is it that garbage is collected
(high priority == more cpu use, less ram use)

delay - pauses in the main flow that have nothing to do with
priority. No delay could mean less performaance, but more
responsiveness. Applicable to event loops and such.

timelyness - the property of an object such that it's
finalization subroutine is called the moment it becomes
unreachable. This is important for objects using finalizers for
resource management, especially when an unreleased resource
could cause deadlock.

finalization - the act of calling an object's finalize
subroutine, and the release of it's memory.

The aspects of control we need:

scope - which objects get cleaned up

priority - what performance tradeoffs we want to make

delay - whether or not the normal program flow will ever be
paused when it is known that no timely objects need to be
destroyed. Also possibly the maximum amount of time (in
milliseconds?) that a GC iteration may take.

timelyness - whether all objects, some objects (That are marked
using 'but' or by their class), or no objects should be checked
for timely destruction

finalization - whether objects should be cleaned up at all

> Actually, since to my naive eyes it looks like the GC is a first
> class object the problem can probably be solver better by adding
> your own.

Well, as I see it the GC is a subobject of the runtime. The amount
of control that this object can give you can be checked using the
strong support for reflection that perl 6 will have, or by simply
asking the runtime to switch GC (if it lets you do that).

--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &

/\ kung foo master: uhm, no, I think I'll sit this one out..: neeyah!

Adrian Howard

unread,
Aug 16, 2005, 7:59:52 PM8/16/05
to perl6-l...@perl.org
On 16 Aug 2005, at 18:14, Yuval Kogman wrote:
> On Mon, Aug 15, 2005 at 15:59:34 +0100, Adrian Howard wrote:
>> I'm not sure what you're proposing here. A separate arena for
>> stuff you want to allocate and not be moved by the GC? How would
>> I tell the compiler?
>
> You won't, the language glue is responsible for setting that up for
> you, and it does that by assuming it's always there, and the
> compiler simply optimizes the cases where it's never going to be
> needed.

Sorry - I don't understand. If I do:

call_to_external_c_library_foo( $foo );
call_to_external_c_library_bar( $bar );

Then how does the compiler know that $foo is only used temporarily
and can be moved around, while $bar is cached in the external library
and shouldn't be moved by any heap de-fragmentation that the garbage
collector might do?

>> How about
>>
>> do : GC::priority(:new) {
>> # only GC things allocated during the lifetime
>> # of the block
>> }
>
> I think that's not "priority" but "limit" or "scoped" or
> "origin(:local)" or something like that...

[reasonable sounding terms snipped]

Sounds nice :-)

>> Actually, since to my naive eyes it looks like the GC is a first
>> class object the problem can probably be solver better by adding
>> your own.
>
> Well, as I see it the GC is a subobject of the runtime. The amount
> of control that this object can give you can be checked using the
> strong support for reflection that perl 6 will have, or by simply
> asking the runtime to switch GC (if it lets you do that).

Nice.

Thanks for answering my mad ramblings :-)

Cheers,

Adrian

David Formosa

unread,
Aug 17, 2005, 1:06:55 AM8/17/05
to perl6-l...@perl.org
On Tue, 16 Aug 2005 20:14:43 +0300, Yuval Kogman <nothi...@woobling.org> wrote:

[...]

> Let's define some terms:

These are all very good and I'm going to incorprate them in the API docs.

> scope/origin - where objects are created

I would refine this one.

origin scope - The lexical scope where an object was created.

current scope - The lexicial scope where this thread is currently executing.

[...]

> timelyness - the property of an object such that it's
> finalization subroutine is called the moment it becomes
> unreachable. This is important for objects using finalizers for
> resource management, especially when an unreleased resource
> could cause deadlock.

This should be changed, timelyness will not prevent deadlock. However
it will prevent resource starvation aka livelock.

[...]

> The aspects of control we need:
>
> scope - which objects get cleaned up
>
> priority - what performance tradeoffs we want to make
>
> delay - whether or not the normal program flow will ever be
> paused when it is known that no timely objects need to be
> destroyed. Also possibly the maximum amount of time (in
> milliseconds?) that a GC iteration may take.
>
> timelyness - whether all objects, some objects (That are marked
> using 'but' or by their class), or no objects should be checked
> for timely destruction
>
> finalization - whether objects should be cleaned up at all

Looks good, I would also add to this

optimisation - giving infomation to the GC to allow it to work more
effectivly.

>> Actually, since to my naive eyes it looks like the GC is a first
>> class object the problem can probably be solver better by adding
>> your own.

I'm not sure that replacing the GC is going to be easy, I expect
thats going to involve heavy magic.

David Formosa

unread,
Aug 17, 2005, 12:06:26 AM8/17/05
to perl6-l...@perl.org
On Tue, 16 Aug 2005 19:46:29 +0300, Yuval Kogman <nothi...@woobling.org> wrote:

[...]

> On Tue, Aug 16, 2005 at 05:32:50 -0000, David Formosa (aka ? the Platypus) =
> wrote:

>> > This is getting me thinking though:

>> >=20


>> > $*RUNTIME.Memory.GarbageCollector.dispose($object); # force it,
>> > # even if it should be alive

>>=20


>> Isn't that what we have undefine(...) for?
>
>
> No:
>

> my Dog $spot .=3D new;
> my $spot_II =3D $spot; # another reference
> $*RUNTIME.Memory.GarbageCollector.dispose($spot);

In the GC API this would be

sub GC::dispose (Any $thing is rw,+Bool $recursive=Bool::false --> Int) {...}

And also thinking about it.

sub GC::size (Any $thing,+Bool $recursive=Bool::false --> Int) {...}

Use the GC to sweep accross an object and tell you the size of the object in memory.

Yuval Kogman

unread,
Aug 17, 2005, 7:18:12 AM8/17/05
to Adrian Howard, perl6-l...@perl.org
On Wed, Aug 17, 2005 at 00:59:52 +0100, Adrian Howard wrote:
> Sorry - I don't understand. If I do:
>
> call_to_external_c_library_foo( $foo );
> call_to_external_c_library_bar( $bar );
>
> Then how does the compiler know that $foo is only used temporarily and can be moved around, while $bar is cached in the
> external library and shouldn't be moved by any heap de-fragmentation that the garbage collector might do?


$foo points to the object structure, which also has a "static"
handle, that is allocated in a static arena (something that isn't
defragmented or copied by the GC).

this handle is simply a pointer that points back to the object
structure (and is updated as this object moves). The object has it's
address, and it has the object's address.

When an object is given to a foreign function, that function gets
the handle to the object (the address of the staticly located
pointer to the dynamically located object).

When the compiler is sure that an object is never ever given to an
external function, it can omit the code that keeps handles to the
objects.

This is just a small solution for a GC scheme that copies or
defragments - I personally doubt that this will be the case any time
in the forseeable future, but it's runtime and GC dependant, and
there are other solutions, this is just one.

--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &

/\ kung foo master: /me wields bonsai kittens: neeyah!!!!!!!!!!!!!!!!

Yuval Kogman

unread,
Aug 17, 2005, 7:27:58 AM8/17/05
to David Formosa (aka ? the Platypus), perl6-l...@perl.org
On Wed, Aug 17, 2005 at 05:06:55 -0000, David Formosa (aka ? the Platypus) wrote:

> This should be changed, timelyness will not prevent deadlock. However
> it will prevent resource starvation aka livelock.

What I meant is deadlock due to resource starvation:

my $semaphore = Sempahore.new(5);

my $object = Moose.new($semaphore); # takes as much as it likes,
# destructor releases semaphore

...

undefined($object);
my $other = Moose.new($semaphore); # this might or might not
# hang till the GC kicks in

BTW, we need an interface like:

class Resource { # a mutex of sorts
has enum<<Locked Free>> $:state = Free;
method claim ($claimee = $?CALLER::SELF) : atomic {
$:state = Locked;
$claimee but GC::timely GC::append_finalize({ $:state = Free });
}
}

then an object can say:

class Object {
method use_this ($resource){
$resource.claim;
}
}

And without worrying about adding a finalizer of it's own (the added
finalizers don't conflict either, and due to post order happen
before the class's finalizer).

> I'm not sure that replacing the GC is going to be easy, I expect
> thats going to involve heavy magic.

If the runtime has an interface where it allows you to replace the
GC with some pluggable GCs it supports, then why not?

--
() Yuval Kogman <nothi...@woobling.org> 0xEBD27418 perl hacker &

/\ kung foo master: /me does not drink tibetian laxative tea: neeyah!

Reply all
Reply to author
Forward
0 new messages