[M3devel] small objects

Mika Nystrom mika at async.caltech.edu
Thu Apr 9 16:13:38 CEST 2009


Well the point of what I was suggesting, anyhow, was that it would
be very nice to store an integer in a REFANY.  A REFANY is only a
single word, and I don't think it's practical to expand it to two
words.  Certainly no more so than requiring an LSB check for certain
(hopefully relatively rare) operations on REFANY...

     Mika

Jay writes:
>--_a0534b8e-9f94-40d7-a78a-5bfcfeb668e5_
>Content-Type: text/plain; charset="iso-8859-1"
>Content-Transfer-Encoding: quoted-printable
>
>
>Um=2C what do folks think of=2C like:
>
>=20
>
>struct
>
>{
>    void* Type=3B
>
>    union
>
>    {
>       size_t Integer=3B
>
>       void* Pointer=3B
>
>     } Value=3B
>
>} Variant=3B
>
>=20
>
>?
>
>You know -- something that is two pointers=2C one pointer for the type=2C o=
>ne for the value or integer?
>
>void* Type would actually be a pointer to something actually defined and el=
>aborate.
>
>=20
>
>Obviously this is twice as large=2C not as small as it could be=2C but much=
> more general and portable. No need to determine how many of bits can be th=
>e tag.
>
>=20
>
>And hope/assume for perf that such a small struct is passed in registers.
>
>On x86/NT 4 and 8 byte structs I think are.
>
>=20
>
>Type could also be an integer=2C index into some table=2C with some predefi=
>ned values.
>
>#define TYPE_INTEGER 0
>
>#define TYPE_FLOAT 1
>
>#define TYPE_DOUBLE 2
>
>#define TYPE_ADDRESS 3
>
>=20
>
>more generally the union would have a float=2C and maybe a double on 64bit =
>platforms.
>
>=20
>
>OR=2C on 64bit platforms=2C you probably can=2C with some porting work=2C d=
>edicate a whole 8 bits or so to a type index=2C and still the thing in one =
>"word". How many bits of address space does any 64bit platform these days o=
>r forseeable future actually implement?
>
>=20
>
>But 32 bits doesn't seem big enough to afford that=2C and still this is a p=
>ortability problem -- anything less than a full pointer.
>
>=20
>
> - Jay
>
>=20
>> From: hosking at cs.purdue.edu
>> To: rodney.m.bates at cox.net
>> Date: Thu=2C 9 Apr 2009 13:01:13 +1000
>> CC: m3devel at elegosoft.com
>> Subject: Re: [M3devel] small objects
>>=20
>> Sounds like you want something like:
>>=20
>> TAGGED REFANY FOR T
>>=20
>> where T must be a type that fits into BITS(REFANY)-1?
>>=20
>> Branding could be used to prevent mixing otherwise structurally=20
>> equivalent TAGGED REFANY.
>>=20
>> TAGGED BRANDED REFANY FOR T
>>=20
>> Where this breaks down is what are the subtyping rules=2C since I assume=
>=20
>> you'd like to store these in a REFANY and dynamically test for the=20
>> appropriate tagged type:
>>=20
>> TAGGED REFANY FOR T <: REFANY
>>=20
>> But then how do we distinguish all the different TAGGED REFANY from=20
>> each other at run-time?
>>=20
>> On 9 Apr 2009=2C at 12:13=2C Rodney M. Bates wrote:
>>=20
>> > Mika Nystrom wrote:
>> >> Hmm=2C ok=2C there's one big difference between what you're saying and
>> >> what Tony and I have been talking about. (I think your understanding
>> >> sounds pretty correct.)
>> >>
>> >> You want to do objects other than small integers. Like what? And=20
>> >> why?
>> >> I was thinking the trick would apply only to one specific type of=20
>> >> integer.
>> >>
>> >
>> > Yes=2C I want a language mechanism that can be used by various
>> > modules to implement various abstract data types=2C each of which
>> > can perform the sometimes dramatic space optimization of putting
>> > values that are common and will fit directly in the word.
>> > One module I spoke of implements general sets of integers with
>> > dynamically variable and sometimes large range. This differs from
>> > the builtin SET OF..=2C which must have a static (and probably=20
>> > relatively
>> > small) base subrange. Thus the general=2C heap-allocated values contain
>> > open arrays of Word.T=2C treated as sets=2C or if you prefer=2C packed=
>=20
>> > arrays
>> > of booleans=2C although I manipulate them with bit-twiddling operations
>> > from Word.
>> > There is another=2C static-sized=2C heap-allocated object in front of=20
>> > each array=2C
>> > containing biases on what bits correspond to what integers in the
>> > abstract set=2C etc. It all works fine now=2C but the usage pattern of=
>=20
>> > some
>> > clients has a high percentage very small sets that would fit in a=20
>> > word=2C
>> > and there would be an 11-to-1 space savings if that could be done.
>> > BTW=2C there are also two different kinds of heap objects=2C one that
>> > represents a range set by just its bounds. So I am TYPECASEing
>> > these already. It would be very convenient if I could just add=20
>> > another
>> > alternative to the TYPECASE for in-word values.
>> >
>> > In another case=2C I need truly dynamically variable sized arrays of
>> > integers in [0..15]=2C and the great majority are 7 elements or less=2C
>> > which would fit directly in the word=2C but I still the need full=20
>> > generality
>> > to be available=2C so it's open arrays all the time=2C with three=20
>> > additional
>> > words each.
>> >
>> > If you can pack a union of a pointer and an integer into a word and
>> > can separate them with runtime checks=2C then you can use the
>> > separated integer any way you want=2C with bit twiddling=2C type=20
>> > conversions=2C
>> > LOOPHOLE=2C or whatever. That is what I am trying to get=2C not just
>> > Smalltalk-like integers.
>> > Note that Smalltalk has zero static typing=2C so only one internal
>> > representation must do for the union of all possible values in
>> > the language. In Modula-3=2C it would be very inconsistent with
>> > the language's philosophy to be this restricted.
>> >> Hmm=2C so your idea is to statically determine what type the reference=
>s
>> >> can have if they are non-references. So you are thinking to put=20
>> >> various
>> >> kinds of subranges into the "TAGGED" types. But you have to be=20
>> >> able to
>> >> determine=2C statically=2C which subrange it is... am I understanding=
>=20
>> >> this
>> >> correctly?
>> >>
>> >
>> > From the language=2C all I want is to be able to dynamically determine
>> > whether it is a true pointer to a heap object or a value stored
>> > directly in the word=2C while preserving the safety principles and
>> > the semantics of everything already there. So I want some new
>> > types=2C different from any existing types=2C that statically are known
>> > to hold this kind of valueset union and can be converted/assigned
>> > to a variable of existing type that is statically known to be either a
>> > pointer or an integer (but not both)=2C with a suitable runtime check.
>> > It is also necessary to have a way to do this without risking a=20
>> > runtime
>> > error=2C if your code doesn't know yet which kind of value it has.
>> > Various ADT modules can take it from there.
>> >> Mika
>> >>
>> >> "Rodney M. Bates" writes:
>> >>
>> >>> Tony Hosking wrote:
>> >>>
>> >>>> On 8 Apr 2009=2C at 11:49=2C Rodney M. Bates wrote:
>> >>>>
>> >>>>
>> >>>>> Mika Nystrom wrote:
>> >>>>>
>> >>>>>> Hendrik=2C I think Tony's and my arguments that you can't break an=
>y
>> >>>>>> existing code by allowing the squirreling away of integers into
>> >>>>>> REFANYs are pretty solid. Pre-existing code simply can't do=20
>> >>>>>> anything
>> >>>>>> useful with unrevealed REFANYs.
>> >>>>>>
>> >>>>> This is only true of _unrevealed opaque subtypes_ of REFANY=2C
>> >>>>> not of REFANY itself. There is lots of existing code that uses=20
>> >>>>> REFANY=2C
>> >>>>> and there=2C ISTYPE=2C NARROW=2C TYPECASE=2C and assigment can be a=
>nd
>> >>>>> regularly are used on it. It is essential not to alter the=20
>> >>>>> semantics there.
>> >>>>>
>> >>>> Pre-existing code won't be able to do anything useful with tagged=20
>> >>>> REFANYs:
>> >>>>
>> >>>> Suppose we have
>> >>>>
>> >>>> VAR r: REFANY =3D SmallInteger.FromInt(0)=3B
>> >>>>
>> >>>> then
>> >>>>
>> >>>> ISTYPE(r=2C REFANY) =3D> TRUE
>> >>>> ISTYPE(r=2C T) =3D> FALSE for any T # REFANY
>> >>>>
>> >>>> Similarly=2C for TYPECASE=2C r will only trigger the REFANY branch.
>> >>>>
>> >>>> NARROW(r=2C REFANY) =3D> r
>> >>>> NARROW(r=2C T) =3D> run-time error for any T #REFANY
>> >>>>
>> >>>> VAR x: REFANY =3D> assignment succeeds
>> >>>> VAR x: T :=3D r =3D> run-time error for any T # REFANY (because of=20
>> >>>> implicit NARROW)
>> >>>>
>> >>> I think I am getting a bit lost in all the proposals=2C variations=2C=
>=20
>> >>> counterproposals=2C etc.=2C but
>> >>>
>> >> >from this argument I am inferring that your plan is that only=20
>> >> variables
>> >>> declared REFANY
>> >>> and not any proper subtype of REFANY can ever have a value with a=20
>> >>> tag bit set? Then
>> >>> the 4 narrowing operations=2C when and only when applied to an=20
>> >>> expression of static
>> >>> type REFANY=2C would change to make a runtime check for a tag bit=20
>> >>> and fail if it's set?
>> >>> It would take this to prevent a tagged value from getting into a=20
>> >>> variable declared a
>> >>> proper subtype of REFANY=2C which can be dereferenced.
>> >>>
>> >>> This would preclude making your abstract data type an opaque=20
>> >>> subtype of REFANY=2C
>> >>> and would mean all supposedly unrelated ADT modules that used the=20
>> >>> tag technique
>> >>> could be broken by client code that mixed up the REFANY values of=20
>> >>> one of them with
>> >>> those of another. I consider this a definite breach of Modula-3's=20
>> >>> otherwise bulletproof
>> >>> type safety.
>> >>>> It is impossible to dereference an expression statically typed as=20
>> >>>> REFANY=2C so there is no need for a "tagged" check on dereference.
>> >>>> Because a tagged REFANY cannot be assigned to anything other than=20
>> >>>> something typed REFANY=2C it can never propagate to a place where=20
>> >>>> it can be dereferenced.
>> >>>>
>> >>>>
>> >>>>> Aside from actual semantic changes=2C I agree with Tony that we=20
>> >>>>> should
>> >>>>> not burden any existing type with additional runtime work. Even=20
>> >>>>> though
>> >>>>> I expect small objects to support big performance gains in certain
>> >>>>> important cases=2C non-tagged references will still greatly=20
>> >>>>> predominate
>> >>>>> in most code. Create new type(s) for tagged references.
>> >>>>>
>> >>>> I'm not sure that we are seeing any semantic changes at all. And=20
>> >>>> with Mika's definition of SmallInteger.T as a "boxed" INTEGER=20
>> >>>> object (actually it would be a subrange for values that fit into=20
>> >>>> BITSIZE(Word.T)-1 bits)=2C it is essentially transparent. It just=20
>> >>>> happens to be a run-time optimization that unboxes the INTEGER=20
>> >>>> value.
>> >>>>
>> >>>>
>> >>>> I think I can implement the compiler and run-time support for=20
>> >>>> this very quickly.
>> >>>>
>> >>>>
>> >>>>
>> >>
>> >>
>>=20
>
>--_a0534b8e-9f94-40d7-a78a-5bfcfeb668e5_
>Content-Type: text/html; charset="iso-8859-1"
>Content-Transfer-Encoding: quoted-printable
>
><html>
><head>
><style>
>.hmmessage P
>{
>margin:0px=3B
>padding:0px
>}
>body.hmmessage
>{
>font-size: 10pt=3B
>font-family:Verdana
>}
></style>
></head>
><body class=3D'hmmessage'>
>Um=2C what do folks think of=2C like:<BR>
>&nbsp=3B<BR>
>struct<BR>
>{<BR>&nbsp=3B&nbsp=3B&nbsp=3B void* Type=3B<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B union<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B {<BR>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=
>=3B size_t&nbsp=3BInteger=3B<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B void* Pointer=3B<BR>
>&nbsp=3B&nbsp=3B&nbsp=3B&nbsp=3B } Value=3B<BR>
>}&nbsp=3BVariant=3B<BR>
>&nbsp=3B<BR>
>?<BR>
>You know -- something that is two pointers=2C one pointer for the type=2C o=
>ne for the value or integer?<BR>
>void* Type would actually be a pointer to something actually defined and el=
>aborate.<BR>
>&nbsp=3B<BR>
>Obviously this is twice as large=2C not as small as it could be=2C but much=
> more general and portable. No need to determine how many of bits can be th=
>e tag.<BR>
>&nbsp=3B<BR>
>And hope/assume for perf that such a small struct is passed in registers.<B=
>R>
>On x86/NT 4 and 8 byte structs I think are.<BR>
>&nbsp=3B<BR>
>Type could also be an integer=2C index into some table=2C with some predefi=
>ned values.<BR>
>#define TYPE_INTEGER 0<BR>
>#define TYPE_FLOAT 1<BR>
>#define TYPE_DOUBLE 2<BR>
>#define TYPE_ADDRESS 3<BR>
>&nbsp=3B<BR>
>more generally the union would have a float=2C and maybe a double on 64bit =
>platforms.<BR>
>&nbsp=3B<BR>
>OR=2C on 64bit platforms=2C you probably can=2C with some porting work=2C d=
>edicate a whole 8 bits or so to a type index=2C and still the thing in one =
>"word". How many bits of address space does any 64bit platform these days o=
>r forseeable future actually implement?<BR>
>&nbsp=3B<BR>
>But 32 bits doesn't seem big enough to afford that=2C and still this is a p=
>ortability problem -- anything less than a full pointer.<BR>
>&nbsp=3B<BR>
>&nbsp=3B- Jay<BR><BR>&nbsp=3B<BR>&gt=3B From: hosking at cs.purdue.edu<BR>&gt=
>=3B To: rodney.m.bates at cox.net<BR>&gt=3B Date: Thu=2C 9 Apr 2009 13:01:13 +=
>1000<BR>&gt=3B CC: m3devel at elegosoft.com<BR>&gt=3B Subject: Re: [M3devel] s=
>mall objects<BR>&gt=3B <BR>&gt=3B Sounds like you want something like:<BR>&=
>gt=3B <BR>&gt=3B TAGGED REFANY FOR T<BR>&gt=3B <BR>&gt=3B where T must be a=
> type that fits into BITS(REFANY)-1?<BR>&gt=3B <BR>&gt=3B Branding could be=
> used to prevent mixing otherwise structurally <BR>&gt=3B equivalent TAGGED=
> REFANY.<BR>&gt=3B <BR>&gt=3B TAGGED BRANDED REFANY FOR T<BR>&gt=3B <BR>&gt=
>=3B Where this breaks down is what are the subtyping rules=2C since I assum=
>e <BR>&gt=3B you'd like to store these in a REFANY and dynamically test for=
> the <BR>&gt=3B appropriate tagged type:<BR>&gt=3B <BR>&gt=3B TAGGED REFANY=
> FOR T &lt=3B: REFANY<BR>&gt=3B <BR>&gt=3B But then how do we distinguish a=
>ll the different TAGGED REFANY from <BR>&gt=3B each other at run-time?<BR>&=
>gt=3B <BR>&gt=3B On 9 Apr 2009=2C at 12:13=2C Rodney M. Bates wrote:<BR>&gt=
>=3B <BR>&gt=3B &gt=3B Mika Nystrom wrote:<BR>&gt=3B &gt=3B&gt=3B Hmm=2C ok=
>=2C there's one big difference between what you're saying and<BR>&gt=3B &gt=
>=3B&gt=3B what Tony and I have been talking about. (I think your understand=
>ing<BR>&gt=3B &gt=3B&gt=3B sounds pretty correct.)<BR>&gt=3B &gt=3B&gt=3B<B=
>R>&gt=3B &gt=3B&gt=3B You want to do objects other than small integers. Lik=
>e what? And <BR>&gt=3B &gt=3B&gt=3B why?<BR>&gt=3B &gt=3B&gt=3B I was think=
>ing the trick would apply only to one specific type of <BR>&gt=3B &gt=3B&gt=
>=3B integer.<BR>&gt=3B &gt=3B&gt=3B<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3B Yes=
>=2C I want a language mechanism that can be used by various<BR>&gt=3B &gt=
>=3B modules to implement various abstract data types=2C each of which<BR>&g=
>t=3B &gt=3B can perform the sometimes dramatic space optimization of puttin=
>g<BR>&gt=3B &gt=3B values that are common and will fit directly in the word=
>.<BR>&gt=3B &gt=3B One module I spoke of implements general sets of integer=
>s with<BR>&gt=3B &gt=3B dynamically variable and sometimes large range. Thi=
>s differs from<BR>&gt=3B &gt=3B the builtin SET OF..=2C which must have a s=
>tatic (and probably <BR>&gt=3B &gt=3B relatively<BR>&gt=3B &gt=3B small) ba=
>se subrange. Thus the general=2C heap-allocated values contain<BR>&gt=3B &g=
>t=3B open arrays of Word.T=2C treated as sets=2C or if you prefer=2C packed=
> <BR>&gt=3B &gt=3B arrays<BR>&gt=3B &gt=3B of booleans=2C although I manipu=
>late them with bit-twiddling operations<BR>&gt=3B &gt=3B from Word.<BR>&gt=
>=3B &gt=3B There is another=2C static-sized=2C heap-allocated object in fro=
>nt of <BR>&gt=3B &gt=3B each array=2C<BR>&gt=3B &gt=3B containing biases on=
> what bits correspond to what integers in the<BR>&gt=3B &gt=3B abstract set=
>=2C etc. It all works fine now=2C but the usage pattern of <BR>&gt=3B &gt=
>=3B some<BR>&gt=3B &gt=3B clients has a high percentage very small sets tha=
>t would fit in a <BR>&gt=3B &gt=3B word=2C<BR>&gt=3B &gt=3B and there would=
> be an 11-to-1 space savings if that could be done.<BR>&gt=3B &gt=3B BTW=2C=
> there are also two different kinds of heap objects=2C one that<BR>&gt=3B &=
>gt=3B represents a range set by just its bounds. So I am TYPECASEing<BR>&gt=
>=3B &gt=3B these already. It would be very convenient if I could just add <=
>BR>&gt=3B &gt=3B another<BR>&gt=3B &gt=3B alternative to the TYPECASE for i=
>n-word values.<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3B In another case=2C I need =
>truly dynamically variable sized arrays of<BR>&gt=3B &gt=3B integers in [0.=
>.15]=2C and the great majority are 7 elements or less=2C<BR>&gt=3B &gt=3B w=
>hich would fit directly in the word=2C but I still the need full <BR>&gt=3B=
> &gt=3B generality<BR>&gt=3B &gt=3B to be available=2C so it's open arrays =
>all the time=2C with three <BR>&gt=3B &gt=3B additional<BR>&gt=3B &gt=3B wo=
>rds each.<BR>&gt=3B &gt=3B<BR>&gt=3B &gt=3B If you can pack a union of a po=
>inter and an integer into a word and<BR>&gt=3B &gt=3B can separate them wit=
>h runtime checks=2C then you can use the<BR>&gt=3B &gt=3B separated integer=
> any way you want=2C with bit twiddling=2C type <BR>&gt=3B &gt=3B conversio=
>ns=2C<BR>&gt=3B &gt=3B LOOPHOLE=2C or whatever. That is what I am trying to=
> get=2C not just<BR>&gt=3B &gt=3B Smalltalk-like integers.<BR>&gt=3B &gt=3B=
> Note that Smalltalk has zero static typing=2C so only one internal<BR>&gt=
>=3B &gt=3B representation must do for the union of all possible values in<B=
>R>&gt=3B &gt=3B the language. In Modula-3=2C it would be very inconsistent =
>with<BR>&gt=3B &gt=3B the language's philosophy to be this restricted.<BR>&=
>gt=3B &gt=3B&gt=3B Hmm=2C so your idea is to statically determine what type=
> the references<BR>&gt=3B &gt=3B&gt=3B can have if they are non-references.=
> So you are thinking to put <BR>&gt=3B &gt=3B&gt=3B various<BR>&gt=3B &gt=
>=3B&gt=3B kinds of subranges into the "TAGGED" types. But you have to be <B=
>R>&gt=3B &gt=3B&gt=3B able to<BR>&gt=3B &gt=3B&gt=3B determine=2C staticall=
>y=2C which subrange it is... am I understanding <BR>&gt=3B &gt=3B&gt=3B thi=
>s<BR>&gt=3B &gt=3B&gt=3B correctly?<BR>&gt=3B &gt=3B&gt=3B<BR>&gt=3B &gt=3B=
><BR>&gt=3B &gt=3B From the language=2C all I want is to be able to dynamica=
>lly determine<BR>&gt=3B &gt=3B whether it is a true pointer to a heap objec=
>t or a value stored<BR>&gt=3B &gt=3B directly in the word=2C while preservi=
>ng the safety principles and<BR>&gt=3B &gt=3B the semantics of everything a=
>lready there. So I want some new<BR>&gt=3B &gt=3B types=2C different from a=
>ny existing types=2C that statically are known<BR>&gt=3B &gt=3B to hold thi=
>s kind of valueset union and can be converted/assigned<BR>&gt=3B &gt=3B to =
>a variable of existing type that is statically known to be either a<BR>&gt=
>=3B &gt=3B pointer or an integer (but not both)=2C with a suitable runtime =
>check.<BR>&gt=3B &gt=3B It is also necessary to have a way to do this witho=
>ut risking a <BR>&gt=3B &gt=3B runtime<BR>&gt=3B &gt=3B error=2C if your co=
>de doesn't know yet which kind of value it has.<BR>&gt=3B &gt=3B Various AD=
>T modules can take it from there.<BR>&gt=3B &gt=3B&gt=3B Mika<BR>&gt=3B &gt=
>=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B "Rodney M. Bates" writes:<BR>&gt=3B &gt=3B=
>&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B Tony Hosking wrote:<BR>&gt=3B &gt=3B&gt=
>=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B On 8 Apr 2009=2C at 11:49=2C R=
>odney M. Bates wrote:<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&g=
>t=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Mika Nystrom wrot=
>e:<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
>=3B&gt=3B&gt=3B Hendrik=2C I think Tony's and my arguments that you can't b=
>reak any<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B existing code by al=
>lowing the squirreling away of integers into<BR>&gt=3B &gt=3B&gt=3B&gt=3B&g=
>t=3B&gt=3B&gt=3B REFANYs are pretty solid. Pre-existing code simply can't d=
>o <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B anything<BR>&gt=3B &gt=3B=
>&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B useful with unrevealed REFANYs.<BR>&gt=3B &g=
>t=3B&gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B=
> This is only true of _unrevealed opaque subtypes_ of REFANY=2C<BR>&gt=3B &=
>gt=3B&gt=3B&gt=3B&gt=3B&gt=3B not of REFANY itself. There is lots of existi=
>ng code that uses <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B REFANY=2C<BR>&g=
>t=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B and there=2C ISTYPE=2C NARROW=2C TYPECA=
>SE=2C and assigment can be and<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B reg=
>ularly are used on it. It is essential not to alter the <BR>&gt=3B &gt=3B&g=
>t=3B&gt=3B&gt=3B&gt=3B semantics there.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&=
>gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B Pre-existing code won't be able to=
> do anything useful with tagged <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B REFANYs=
>:<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B Sup=
>pose we have<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=
>=3B&gt=3B VAR r: REFANY =3D SmallInteger.FromInt(0)=3B<BR>&gt=3B &gt=3B&gt=
>=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B then<BR>&gt=3B &gt=3B&gt=
>=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B ISTYPE(r=2C REFANY) =3D&=
>gt=3B TRUE<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B ISTYPE(r=2C T) =3D&gt=3B FALS=
>E for any T # REFANY<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=
>=3B&gt=3B&gt=3B Similarly=2C for TYPECASE=2C r will only trigger the REFANY=
> branch.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=
>=3B NARROW(r=2C REFANY) =3D&gt=3B r<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B NARR=
>OW(r=2C T) =3D&gt=3B run-time error for any T #REFANY<BR>&gt=3B &gt=3B&gt=
>=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B VAR x: REFANY =3D&gt=3B =
>assignment succeeds<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B VAR x: T :=3D r =3D&=
>gt=3B run-time error for any T # REFANY (because of <BR>&gt=3B &gt=3B&gt=3B=
>&gt=3B&gt=3B implicit NARROW)<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B =
>&gt=3B&gt=3B&gt=3B I think I am getting a bit lost in all the proposals=2C =
>variations=2C <BR>&gt=3B &gt=3B&gt=3B&gt=3B counterproposals=2C etc.=2C but=
><BR>&gt=3B &gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B &gt=3Bfrom this argume=
>nt I am inferring that your plan is that only <BR>&gt=3B &gt=3B&gt=3B varia=
>bles<BR>&gt=3B &gt=3B&gt=3B&gt=3B declared REFANY<BR>&gt=3B &gt=3B&gt=3B&gt=
>=3B and not any proper subtype of REFANY can ever have a value with a <BR>&=
>gt=3B &gt=3B&gt=3B&gt=3B tag bit set? Then<BR>&gt=3B &gt=3B&gt=3B&gt=3B the=
> 4 narrowing operations=2C when and only when applied to an <BR>&gt=3B &gt=
>=3B&gt=3B&gt=3B expression of static<BR>&gt=3B &gt=3B&gt=3B&gt=3B type REFA=
>NY=2C would change to make a runtime check for a tag bit <BR>&gt=3B &gt=3B&=
>gt=3B&gt=3B and fail if it's set?<BR>&gt=3B &gt=3B&gt=3B&gt=3B It would tak=
>e this to prevent a tagged value from getting into a <BR>&gt=3B &gt=3B&gt=
>=3B&gt=3B variable declared a<BR>&gt=3B &gt=3B&gt=3B&gt=3B proper subtype o=
>f REFANY=2C which can be dereferenced.<BR>&gt=3B &gt=3B&gt=3B&gt=3B<BR>&gt=
>=3B &gt=3B&gt=3B&gt=3B This would preclude making your abstract data type a=
>n opaque <BR>&gt=3B &gt=3B&gt=3B&gt=3B subtype of REFANY=2C<BR>&gt=3B &gt=
>=3B&gt=3B&gt=3B and would mean all supposedly unrelated ADT modules that us=
>ed the <BR>&gt=3B &gt=3B&gt=3B&gt=3B tag technique<BR>&gt=3B &gt=3B&gt=3B&g=
>t=3B could be broken by client code that mixed up the REFANY values of <BR>=
>&gt=3B &gt=3B&gt=3B&gt=3B one of them with<BR>&gt=3B &gt=3B&gt=3B&gt=3B tho=
>se of another. I consider this a definite breach of Modula-3's <BR>&gt=3B &=
>gt=3B&gt=3B&gt=3B otherwise bulletproof<BR>&gt=3B &gt=3B&gt=3B&gt=3B type s=
>afety.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B It is impossible to dereference a=
>n expression statically typed as <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B REFANY=
>=2C so there is no need for a "tagged" check on dereference.<BR>&gt=3B &gt=
>=3B&gt=3B&gt=3B&gt=3B Because a tagged REFANY cannot be assigned to anythin=
>g other than <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B something typed REFANY=2C =
>it can never propagate to a place where <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B=
> it can be dereferenced.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=
>=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B Aside from a=
>ctual semantic changes=2C I agree with Tony that we <BR>&gt=3B &gt=3B&gt=3B=
>&gt=3B&gt=3B&gt=3B should<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B not burd=
>en any existing type with additional runtime work. Even <BR>&gt=3B &gt=3B&g=
>t=3B&gt=3B&gt=3B&gt=3B though<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B I ex=
>pect small objects to support big performance gains in certain<BR>&gt=3B &g=
>t=3B&gt=3B&gt=3B&gt=3B&gt=3B important cases=2C non-tagged references will =
>still greatly <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B predominate<BR>&gt=
>=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B in most code. Create new type(s) for tag=
>ged references.<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&g=
>t=3B&gt=3B&gt=3B I'm not sure that we are seeing any semantic changes at al=
>l. And <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B with Mika's definition of SmallI=
>nteger.T as a "boxed" INTEGER <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B object (a=
>ctually it would be a subrange for values that fit into <BR>&gt=3B &gt=3B&g=
>t=3B&gt=3B&gt=3B BITSIZE(Word.T)-1 bits)=2C it is essentially transparent. =
>It just <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B happens to be a run-time optimi=
>zation that unboxes the INTEGER <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B value.<=
>BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&g=
>t=3B &gt=3B&gt=3B&gt=3B&gt=3B I think I can implement the compiler and run-=
>time support for <BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B this very quickly.<BR>=
>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=
>=3B &gt=3B&gt=3B&gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B<BR>&gt=3B &gt=3B&gt=3B<=
>BR>&gt=3B <BR></body>
></html>=
>
>--_a0534b8e-9f94-40d7-a78a-5bfcfeb668e5_--



More information about the M3devel mailing list