[M3devel] small objects
Tony Hosking
hosking at cs.purdue.edu
Wed Apr 8 05:55:00 CEST 2009
On 8 Apr 2009, at 13:22, Mika Nystrom wrote:
> Tony Hosking writes:
> ...
>>
>> It is impossible to dereference an expression statically typed as
>> REFANY, so there is no need for a "tagged" check on dereference.
>> Because a tagged REFANY cannot be assigned to anything other than
>> something typed REFANY, it can never propagate to a place where it
>> can
>> be dereferenced.
> ...
>
> But it's correct, isn't it, that you get an extra one-bit check for
> ISTYPE, TYPECASE, TYPECODE, and NARROW? There's no problem with
> dereferencing, nor is there a problem with assignment. No need to
> introduce overhead for either of those, since dereferencing can't
> happen and assignment is transparent (or an implicit NARROW).
Correct.
> I was going to say to Rodney that I think that Modula-3 programmers
> know that using REFANY does cause some overhead (it must), and in
> any case the normal ISTYPE code is going to be hundreds of times
> slower than the single-bit check, and no one (except me) seems to
> have had any problem with this so far.
Right.
> So yes, the change does affect existing code, but only code that's
> already using REFANY, ISTYPE, TYPECASE, and the extra overhead is
> very minor compared to the work ISTYPE and TYPECASE are already
> doing.
It affects only performance. Existing code won't know about
SmallInteger.T, so will never test for that type.
> I think I really like the idea of boxing it in this other opaque
> type if that doesn't cause any problems, specifically because it
> doesn't make any semantic change to the language at all.
Yeah. It should probably be BRANDED REF [FIRST(INTEGER) DIV 2 ..
LAST(INTEGER) DIV 2] instead of an object type. I don't want to think
about having "builtin" methods that apply to this type. I'd rather
implement it like the builtin Word.T operations. I think the
following interface is about right:
INTERFACE ValRef;
TYPE T <: REFANY;
CONST
First = FIRST(INTEGER) DIV 2;
Last = LAST(INTEGER) DIV 2;
TYPE Range = [First .. Last];
PROCEDURE New(val: Range): T;
PROCEDURE Val(ref: T): Range;
END ValRef.
On further thought, the notion that someone could do
RTAllocator.NewTraced(TYPECODE(ValRef.T)) makes me a little nervous.
We would need to intercept that in RTAllocator.NewTraced and return
ValRef.New(0). Of course, there is no way to create any ValRef.T that
has a value other than 0 in this way. The pickler would need to have
a pickle special for TYPECODE(ValRef.T) that simply extracts the value
as the pickled representation, and invokes ValRef.New(value) when
unpickliing.
> Actually, it is important for the application of embedded interpreters
> that these tagged types be compatible with a standard REFANY. The
> whole point is to be able to write a fast interpreter that deals
> in normal Modula-3 types and not in a special parallel hierarchy...
> Look at how the various languages embedded in Java (JScheme, Groovy,
> Jython(?)) do these things: it's really pretty nifty. But *they*
> can't do efficient small integers!
Indeed.
More information about the M3devel
mailing list