[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