Exposing the Garbage Collector

9 views
Skip to first unread message

Piers Cawley

unread,
Jul 23, 2005, 6:01:38 PM7/23/05
to perl6-l...@perl.org
Let's say I have a class, call it Foo which has a bunch of attributes, and I've
created a few of them. Then, at runtime I do:

eval 'class Foo { has $.a_new_attribute is :default<10> }';

Assuming I've got the syntax right for defaulting an attribute, and lets assume
I have, the Perl runtime needs to chase down every instance of Foo or its
subclasses and add an attribute slot (adding a method to a class is nowhere
near as interesting, because every instance of the class shares a single class
object).

One way to do this is for a class to keep track of all its instances, which is
all very well until you start subclassing because subclasses have to both keep
track of their instances and inform their superclasses about any new instances,
which seems an awfully heavyweight thing to have to do just to be ready for the
occasional programmer like me who wants to develop classes in an image based
IDE or someone else who wants to add a role to a class at runtime or
whatever. Also, the class's links to its instances needs to be week, otherwise
you end up with instances that never get collected, which isn't good.

It seems to me, that the way to get at all the instances of a class is to ask
the Garbage Collector to do the heavy lifting for us, and ideally I'd like to
see this exposed at the Perl level. It doesn't really have to expose that many
methods of course -- a simple map/grep would do nicely, then it'd be possible
to write, say:

class Class {
method all_instances ($class:) {
$*GC.grep {$^obj.isa($class)}
}
}

Note that, *of course* this is slow, but I suggest that this sort of thing
should be slow (or, at the very least, you shouldn't require everything else to
pay a runtime cost just to allow people to use reflective tools like this).

Brent 'Dax' Royal-Gordon

unread,
Jul 23, 2005, 11:41:12 PM7/23/05
to Piers Cawley, perl6-l...@perl.org
Piers Cawley <pdca...@bofh.org.uk> wrote:
> It seems to me, that the way to get at all the instances of a class is to ask
> the Garbage Collector to do the heavy lifting for us, and ideally I'd like to
> see this exposed at the Perl level.

It's entirely possible that Perl will be used on virtual machines
where this can't be done.

I'd suggest that we simply declare that every metaclass must support a
".all" method which returns an arrayish thing containing all active
objects it is managing:

grep { .isa($class) } MetaClass.all;

Whether this works by interfacing with the garbage collector, keeping
an array of weak references, or waving a wooden wand and yelling
"Accio objects" is completely up to the metaclass in question.

(Sorry, been reading too much Potter lately...)

--
Brent 'Dax' Royal-Gordon <br...@brentdax.com>
Perl and Parrot hacker

Chromatic

unread,
Jul 24, 2005, 1:30:34 AM7/24/05
to br...@brentdax.com, Piers Cawley, perl6-l...@perl.org
On Sat, 2005-07-23 at 20:41 -0700, Brent 'Dax' Royal-Gordon wrote:

> Piers Cawley <pdca...@bofh.org.uk> wrote:

> > It seems to me, that the way to get at all the instances of a class is to ask
> > the Garbage Collector to do the heavy lifting for us, and ideally I'd like to
> > see this exposed at the Perl level.
>
> It's entirely possible that Perl will be used on virtual machines
> where this can't be done.

Will those VMs support string eval? If not, Piers' *specific* problem
here mostly goes away. How much introspection and intromanipulation
should Parrot guarantee on small or limited platforms in general?

-- c

Sam Vilain

unread,
Jul 24, 2005, 3:56:53 AM7/24/05
to Piers Cawley, perl6-l...@perl.org
Piers Cawley wrote:
> Let's say I have a class, call it Foo which has a bunch of attributes, and I've
> created a few of them. Then, at runtime I do:
> eval 'class Foo { has $.a_new_attribute is :default<10> }';
> Assuming I've got the syntax right for defaulting an attribute, and lets assume
> I have, the Perl runtime needs to chase down every instance of Foo or its
> subclasses and add an attribute slot (adding a method to a class is nowhere
> near as interesting, because every instance of the class shares a single class
> object).

But adding an attribute is simply defining a new method in the Class'
instance methods. And you don't need to chase down the objects for that.

What you wrote could be implemented as;

class Foo {
has $a_new_attribute is :default(10);
sub a_new_attribute is accessor
:FETCH{ $a_new_attribute },
:STORE -> $val { $a_new_attribute = $val },
}
}

So this way the extra attribute can be lazily added. The other ways of
finding out that the property should be there, such as the visitor
pattern interface, will "trip" the part that adds the slot to the object.

However I think this is somewhat besides your original point.

Sam.

David Formosa )

unread,
Jul 25, 2005, 12:02:44 AM7/25/05
to perl6-l...@perl.org
On Sat, 23 Jul 2005 23:01:38 +0100, Piers Cawley <pdca...@bofh.org.uk> wrote:

[...]

> It seems to me, that the way to get at all the instances of a class is to ask
> the Garbage Collector to do the heavy lifting for us, and ideally I'd like to
> see this exposed at the Perl level.

I'm going to hijack this thread to discuss something else. We are
should have an API to talk to the GC and give it hints about when it
should run, and tweek the verious paramitors for its running.

For example

GC::run(); # Trigger the Garbige collector to run at this moment

GC::exclude(&code); # Don't run the Garbige collector while &code is
being executed.

--
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.

Matt Fowles

unread,
Jul 25, 2005, 10:07:41 AM7/25/05
to dfor...@dformosa.zeta.org.au, perl6-l...@perl.org
David~

On 25 Jul 2005 04:02:44 -0000, David Formosa (aka ? the Platypus)


<dfor...@dformosa.zeta.org.au> wrote:
>
> I'm going to hijack this thread to discuss something else.

Speaking for summarizers everywhere. AHHHH! Damn you!

Matt
--
"Computer Science is merely the post-Turing Decline of Formal Systems Theory."
-Stan Kelly-Bootle, The Devil's DP Dictionary

Piers Cawley

unread,
Jul 26, 2005, 8:16:36 AM7/26/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
"TSa (Thomas Sandlaß)" <Thomas....@orthogon.com> writes:

> Piers Cawley wrote:
>> Let's say I have a class, call it Foo which has a bunch of attributes, and I've
>> created a few of them. Then, at runtime I do:
>> eval 'class Foo { has $.a_new_attribute is :default<10> }';
>> Assuming I've got the syntax right for defaulting an attribute,
>

> I think you need a 'class Foo is extended' to re-open the class.
> Otherwise you produce a redefinition error if the scope you call
> eval in already contains---or is that extains because of the name
> search beeing *outwards*---one you start from scratch.

Oh for heaven's sake! That's the last time I go trying to come up with concrete
examples for this sort of thing. Of course, you're right, I should have said
'is extended', but if I were doing it for real, the eval would fail and I'd
have a meaningful error message.

[ An explanation of why this particular case doesn't require iterating over the
live set ]

I really shouldn't go picking concrete examples that can be worked around
should I? Suffice to say that sometimes (say for debugging purposes, or program
analysis -- Smalltalk can do some cunning typer inferencing tricks by examining
the live set for instance) I would like to be able to iterate over all the
objects in the live set. ISTM that exposing the Garbage Collector at the
Language level is the neatest way of doing this (or coming up with something
like Ruby's ObjectSpace, but conceptually I reckon the GC is the right place to
hang it).

Luke Palmer

unread,
Jul 27, 2005, 5:10:27 AM7/27/05
to TSa (Thomas Sandlaß), perl6-l...@perl.org
On 7/26/05, "TSa (Thomas Sandlaß)" <Thomas....@orthogon.com> wrote:

> Piers Cawley wrote:
> > I would like to be able to iterate over all the
> > objects in the live set.
>
> My Idea actually is to embedd that into the namespace syntax.
> The idea is that of looking up non-negativ integer literals
> with 0 beeing the namespace owner.
>
> for ::Namespace -> $instance
> {
> if +$instance != 0 { reconfigure $instance }
> }

Oh, so a namespace can behave as an array then. Well, to avoid
auto-flattening problems in other, more common places, we ought to
make that:

for *::Namespace -> $instance {...}

However, this is very huffmanly incorrect. First of all, what you're
doing may take a quarter of a second or more for a large program
(which isn't a short amount of time by any means). Second, the fact
that you're using it means you're doing something evil. Third, only a
fraction of 1/omega perl programmers will be using this feature.
Therefore, it should probably look like:

use introspection;
for introspection::ALL_INSTANCES(::Namespace) -> $instance {...}

And it might even be platform-specific, given the constraints of some
of our targets.

Luke

Piers Cawley

unread,
Aug 3, 2005, 5:57:00 AM8/3/05
to Luke Palmer, TSa (Thomas Sandlaß), perl6-l...@perl.org
Luke Palmer <lrpa...@gmail.com> writes:

And if my proposal or something like it were accepted, the implementation could
simply look like:

module introspection {
class Class is extended {
method all_instances($class:) {
fail unless $*PLATFORM.GC.can_iterate_over_liveset;
$*PLATFORM.GC.grep -> $instance { $instance.isa($class) }
}
}

sub ALL_INSTANCES($class) {
$class.all_instances
}
}

The point about my proposal to have the garbage collector or something like it
expose methods to iterate over the live set isn't that it's syntactically
gorgeous, but that it's a useful minimal behaviour that can be used to
implement nicer syntaxes which can be loaded as required. If we're going to
allow such reflective stuff (on platforms that can do it) then there needs to
be some minimal core functionality that other modules can use. The point about
iterating over the live set is that it's essentially free until you use it; the
garbage collector must *already* hold onto the information needed to do the
iteration.

Reply all
Reply to author
Forward
0 new messages