[M3devel] REFANY-keyed tables?

Rodney M. Bates rodney_bates at lcwb.coop
Thu Feb 27 16:39:56 CET 2014


I did some grepping for uses of RefIntTbl and found a couple of interesting variations.
See, e.g., m3-ui/juno-2/juno-machine/src/JunoRT.m3 and JunoValue.[im]3.

First, I was thinking of using a narrower reference type than REFANY, with its own
Hash function, to instantiate Tbl.  But you can use RefIntTbl and provide a different
Hash function another way.  Tbl just uses Key.Hash to initialize Default.keyHash.
You can use the instantiation with REFANY, then create a subtype of RefIntTbl.Default
that overrides Default.keyHash with another hash function.  This is probably a bit
quicker to code.  It can create the false impresssion that the table is keyed by
REFANY in its full generality, using Refany.Hash.

Second, in this example, the table there can contain a mixture of three different
reference types as keys, but they have no common ancestor narrower than REFANY
and no common fields.  The Hash function in JunoValue just does a TYPECASE on
the key and uses different fields of the different objects to compute its hash
value.  It still won't work on all of REFANY, just the subtypes it explicitly
codes for.



On 02/26/2014 10:01 PM, JC Chu wrote:
>> Hmm, can you point out where these are?
>
> See for example <https://modula3.elegosoft.com/cm3/doc/help/interfaces.html#table>.

Unfortunately, this documentation page gives no clue that the REFANY-keyed tables
will have to have an override for their Hash function, unlike the other types.
Somewhere, there is an explanation of this, but I don't remember where.

BTW, this documentation says the instantiating interfaces (e.g. Refany.i3) can
be found in either m3core and libm3.  I see they are only in m3core.  Could two
interfaces with the same name in a link closure have ever linked successfully?

Further BTW, does it seem odd that while these type interfaces are in m3core,
libm3 has pure renaming interfaces RealType and LongrealType but no others?
Just to save some particular favored client code from having to be edited?

>
>> I have some pointer-keyed tables, but they use techniques like giving every object an object sequence number field, explicitly initialized when an object is allocated, and using that for the Hash function.  But this won't work for REFANY, because it can have no fields.
>
> The keys are indeed objects that require explicit initialization.  Thanks for the suggestion.
>
>> The garbage collector is a (partially) compacting collector, which means it can move a heap object and adjust all the pointers to it, if it knows where they all are, which holds for some objects.  So the bit contents of a REFANY can change.
>
> Just out of curiosity, is there any way to lock the GC temporarily?
>
> — JC Chu
>
> -----Original Message-----
> From: Rodney M. Bates [mailto:rodney_bates at lcwb.coop]
> Sent: Thursday, February 27, 2014 11:28
> To: m3devel at elegosoft.com
> Subject: Re: [M3devel] REFANY-keyed tables?
>
>
>
> On 02/26/2014 11:08 AM, JC Chu wrote:
>> Hi,
>>
>> I need a REFANY-to-INTEGER table in my program but RefIntTbl.Default is giving me runtime errors.  Apparently Table(Key, Value) uses Key.Equal() and Key.Hash(), but those procedures in Refany, which is use to instantiate RefIntTbl, both raise a fatal exception.
>>
>
> The garbage collector is a (partially) compacting collector, which means it can move a heap object and adjust all the pointers to it, if it knows where they all are, which holds for some objects.  So the bit contents of a REFANY can change. This means it is not possible to have a consistent Hash on the pointer value alone.
>
> So Refany.Hash is deliberately coded to raise this exception, to prevent a far more insidious bug.
>
>> I’m a bit confused since a number of REFANY-keyed tables are shipped with CM3.  Is this actually the expected behavior or am I doing anything wrong?
>>
>
> Hmm, can you point out where these are?
>
> I have some pointer-keyed tables, but they use techniques like giving every object an object sequence number field, explicitly initialized when an object is allocated, and using that for the Hash function.  But this won't work for REFANY, because it can have no fields.
>
> So the table can only work on a narrower set of allocated object types than REFANY.
> If you need the table to hold addresses of a mixture of different types, you can still do that with a hierarchy of OBJECT types, but they will have to have a common supertype that contains whatever fields the Hash function needs for consistency.
>
> It would be possible that pointers get passed around in REFANY-typed (statically) variables, but it is carefully arranged that they all have an allocated type that has fields a Hash function can work on.  Hash would then have to do a NARROW or TYPECASE to the type it expected.
>
> Rodney Bates
>
>> Thanks.
>>
>> — JC Chu
>>
>
>




More information about the M3devel mailing list