Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

PDD15: per-class attribute offsets

6 views
Skip to first unread message

Peter Haworth

unread,
Mar 12, 2004, 1:14:17 PM3/12/04
to perl6-i...@perl.org
I have some issues with the way attributes are referenced. According to the
PDD:

> classoffset Ix, Py, Sz
>
> Returns the offset of the first attribute for class Sz in object Py.
>
> getattribute Px, Py, Iz
>
> Returns attribute Iz of object Py and puts it in Px. Note that the
> attribute number is an absolute offset.

So, compilers are expected to know the relative offsets of attributes within
each class? That's reasonable enough, assuming that attributes are only
directly accessed by code whose objects' classes have been declared.

> addattribute Px, Sy
>
> Add attribute Sy to class Px. This will add the attribute slot to all
> objects of class Px and children of class Px, with a default value of
> Null.

Should we just try to ensure that any class which wants to add attributes
to itself always uses the named version of getattribute? Do we allow code
which modifies other classes' attribute lists? Do we need to mark classes
as numeric/named attribute access, and restrict addattribute's use to
classes which use named attributes?

As well as involving much finding of instances, and moving of their attribute
values, this isn't thread safe (please excuse my lack of PASM syntax
knowledge):

classoffset Ioff, Pobj, Sclass
# Some other thread calls addattribute on Pobj's class
getattribute Pattr,Pobj,Ioff
# Now we have the value of the wrong attribute in Pattr

--
Peter Haworth p...@edison.ioppublishing.com
"There is no reason to use multithreading except if you are a marketing guy
at Sun or Microsoft and your analysis says that it is cheaper to ram
multithreading down people's throats than to fix the insanely huge process
creation latency of your broken poor excuse of an operating system."
-- Felix Leitner

Dan Sugalski

unread,
Mar 12, 2004, 2:07:56 PM3/12/04
to Peter Haworth, perl6-i...@perl.org
At 6:14 PM +0000 3/12/04, Peter Haworth wrote:
>I have some issues with the way attributes are referenced. According to the
>PDD:
>
>> classoffset Ix, Py, Sz
>>
>> Returns the offset of the first attribute for class Sz in object Py.
>>
>> getattribute Px, Py, Iz
>>
>> Returns attribute Iz of object Py and puts it in Px. Note that the
>> attribute number is an absolute offset.
>
>So, compilers are expected to know the relative offsets of attributes within
>each class? That's reasonable enough, assuming that attributes are only
>directly accessed by code whose objects' classes have been declared.

Yes. The assumption is that the compiler is keeping track of the
class its building. That seems reasonable, though you may run into
issues with classes whose definitions are scattered across multiple
independently loaded bytecode files. I'm OK with putting a "Don't
*do* that!" in the docs, though. :)

> > addattribute Px, Sy
>>
>> Add attribute Sy to class Px. This will add the attribute slot to all
>> objects of class Px and children of class Px, with a default value of
>> Null.
>
>Should we just try to ensure that any class which wants to add attributes
>to itself always uses the named version of getattribute?

Nope, not needed. If a class adds an attribute, it always goes on the
end of the attribute set for that class. Presumably (a presumption
I'm comfortable with) the code doing the adding knows that there are
already N attributes, and that its adding attribute N+1 to the list.
(I'm assuming the common case will be eval'ing source, in which case
the compiler can see the current layout and emit appropriate bytecode
for the new number)

> Do we allow code
>which modifies other classes' attribute lists? Do we need to mark classes
>as numeric/named attribute access, and restrict addattribute's use to
>classes which use named attributes?

No (sorta) and no, respectively. Removing a used attribute strikes me
as a Bad Thing, and I can't think of a reason to do it that shouldn't
result in horrible flaming death and bizarre behaviour. And adding
attributes, since they always go on the end of a class' list of
attributes, is harmless.

>As well as involving much finding of instances, and moving of their attribute
>values, this isn't thread safe (please excuse my lack of PASM syntax
>knowledge):

Yeah, adding an attribute requires a stop-the-world action, as every
object that has the modified class needs to be modified. That's a
non-trivial activity.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Dan Sugalski

unread,
Mar 13, 2004, 3:44:07 PM3/13/04
to Oli, perl6-i...@perl.org
At 9:06 PM +0100 3/13/04, Oli wrote:

>Dan Sugalski wrote:
>
>>>As well as involving much finding of instances, and moving of
>>>their attribute
>>>values, this isn't thread safe (please excuse my lack of PASM syntax
>>>knowledge):
>>
>>
>>Yeah, adding an attribute requires a stop-the-world action, as
>>every object that has the modified class needs to be modified.
>>That's a non-trivial activity.
>
>But, even if we stop everything until all objects got their
>attribute list updated, any offsets previously obtained via
>C<classoffset> may still be bogus afterwards. And there is no way
>for the code that holds the offset to know that either.

Which is a good reason to not cache the attribute offset value, yeah.
But, then, the PMC can change classes at a whim, sufficiently enough
to make even the class name invalid. I think we're reasonably safe
here, since the only place that we'll see a problem is in class
methods, which limits the damage.

I could certainly see fit to have a way to get a PMC rather than an
INT that represents the class, and make sure the magic always updates
the PMC to have the correct value.

However, I can also see that it might not be out of line to have the
class method lock the class such that the class itself can't be
altered if another thread is in one of the class' methods. This,
though, could be reasonably problematic, so I'm not sure it's a good
idea. (Though altering the structure of the class when other code is
using something of that class probably isn't the best thing either)

It definitely is an issue, though.

Jens Rieks

unread,
Mar 13, 2004, 7:09:48 PM3/13/04
to Dan Sugalski, perl6-i...@perl.org
Hi,

On Saturday 13 March 2004 21:44, Dan Sugalski wrote:
> At 9:06 PM +0100 3/13/04, Oli wrote:
> >Dan Sugalski wrote:
> >>>As well as involving much finding of instances, and moving of
> >>>their attribute
> >>>values, this isn't thread safe (please excuse my lack of PASM syntax
> >>>knowledge):
> >>
> >>Yeah, adding an attribute requires a stop-the-world action, as
> >>every object that has the modified class needs to be modified.
> >>That's a non-trivial activity.
> >
> >But, even if we stop everything until all objects got their
> >attribute list updated, any offsets previously obtained via
> >C<classoffset> may still be bogus afterwards. And there is no way
> >for the code that holds the offset to know that either.
>
> Which is a good reason to not cache the attribute offset value, yeah.
> But, then, the PMC can change classes at a whim, sufficiently enough
> to make even the class name invalid. I think we're reasonably safe
> here, since the only place that we'll see a problem is in class
> methods, which limits the damage.

Renaming the class is already possible.
Maybe its better if classname returns a copy of the string?
The attached program prints Bar, not Foo.

> I could certainly see fit to have a way to get a PMC rather than an
> INT that represents the class, and make sure the magic always updates
> the PMC to have the correct value.
>
> However, I can also see that it might not be out of line to have the
> class method lock the class such that the class itself can't be
> altered if another thread is in one of the class' methods. This,
> though, could be reasonably problematic, so I'm not sure it's a good
> idea. (Though altering the structure of the class when other code is
> using something of that class probably isn't the best thing either)
>
> It definitely is an issue, though.

> Dan
jens

classname.imc

Oli

unread,
Mar 13, 2004, 3:12:46 PM3/13/04
to perl6-i...@perl.org
Dan Sugalski wrote:

>> As well as involving much finding of instances, and moving of their
>> attribute
>> values, this isn't thread safe (please excuse my lack of PASM syntax
>> knowledge):
>
>
>
> Yeah, adding an attribute requires a stop-the-world action, as every
> object that has the modified class needs to be modified. That's a
> non-trivial activity.

But, even if we stop everything until all objects got their attribute
list updated, any offsets previously obtained via C<classoffset> may
still be bogus afterwards. And there is no way for the code that holds
the offset to know that either.

Maybe we should provide a version of C<getattribute> that takes relative
offset and the class name/PMC and then make that operation atomic?

Leopold Toetsch

unread,
Mar 14, 2004, 8:30:22 AM3/14/04
to Oli, perl6-i...@perl.org
Oli <lao...@fastmail.fm> wrote:

> But, even if we stop everything until all objects got their attribute
> list updated, any offsets previously obtained via C<classoffset> may
> still be bogus afterwards. And there is no way for the code that holds
> the offset to know that either.

Good point. It seems that after adding attributes to classes with
instantiated objects, attribute access can only be done by attribute
names with the current scheme. So if a class isn't marked final,
attribute access is named only.

> Maybe we should provide a version of C<getattribute> that takes relative
> offset and the class name/PMC and then make that operation atomic?

When the classoffset is relative the lookup is as expensive as with
attribute names (I estimate - the cost of a hash lookup), that's the
price of it.

leo

Dan Sugalski

unread,
Mar 16, 2004, 9:12:02 AM3/16/04
to l...@toetsch.at, Oli, perl6-i...@perl.org
At 2:30 PM +0100 3/14/04, Leopold Toetsch wrote:
>Oli <lao...@fastmail.fm> wrote:
>
>> But, even if we stop everything until all objects got their attribute
>> list updated, any offsets previously obtained via C<classoffset> may
>> still be bogus afterwards. And there is no way for the code that holds
>> the offset to know that either.
>
>Good point. It seems that after adding attributes to classes with
>instantiated objects, attribute access can only be done by attribute
>names with the current scheme. So if a class isn't marked final,
>attribute access is named only.

No, that's not the case. The offset returned is always found at
runtime, and is always relative to the current structure of the
object. It also should only be fetched by code which lives inside
methods of a class.

The only time this offset will be incorrect is if the object
structure changes between the time the offset is fetched and the time
that the offset is used, which is something that needs guarding
against.

The common case, by far, is to have objects that don't change
structure. It looks like the common case will also be to have methods
accessing multiple slots of an object in one go, though that's a bit
dodgier of an assumption. In that case, the current scheme's faster.

Also, don't forget that the current scheme supports selector
namespaces with fewer hoops to jump through, if we so desire. There's
also the speed win for those cases where the hierarchy's locked such
that new attributes *can't* be added.

I think I'd like to keep the scheme as-is for now. We can talk about
what we need to do to ensure consistency when we're in a position to
add attributes after the fact. (Those may well have to be accessed by
name--we can work the scheme out after we get the current stuff
actually functioning...)

Leopold Toetsch

unread,
Mar 16, 2004, 10:54:04 AM3/16/04
to Dan Sugalski, perl6-i...@perl.org
Dan Sugalski <d...@sidhe.org> wrote:

> The only time this offset will be incorrect is if the object
> structure changes between the time the offset is fetched and the time
> that the offset is used, which is something that needs guarding
> against.

Well, that's the point. You don't know in which REG_INT the offset is.
You can't adjust this offset or guard against.

leo

0 new messages