You can subscribe to this list here.
| 2002 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(54) |
Jun
(3) |
Jul
|
Aug
(23) |
Sep
(33) |
Oct
(14) |
Nov
(1) |
Dec
|
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
(5) |
Jun
|
Jul
|
Aug
(15) |
Sep
(4) |
Oct
|
Nov
|
Dec
|
| 2004 |
Jan
(1) |
Feb
|
Mar
(26) |
Apr
(130) |
May
(5) |
Jun
|
Jul
(21) |
Aug
(3) |
Sep
(24) |
Oct
(10) |
Nov
(37) |
Dec
(2) |
| 2005 |
Jan
(30) |
Feb
(15) |
Mar
(4) |
Apr
(1) |
May
(1) |
Jun
(1) |
Jul
(1) |
Aug
(2) |
Sep
(2) |
Oct
|
Nov
(2) |
Dec
|
| 2006 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
(1) |
Nov
(2) |
Dec
(10) |
| 2007 |
Jan
(1) |
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
|
From: Dan I. <Da...@Sq...> - 2004-04-09 17:04:45
|
Hi, Guys - I'm actually going to take the weekend off (Easter on Catalina with Kat and Charlie). I just wanted to let you know that silence on this end doesn't mean lack of interest. I'll read email for two more hours, then gone. Hey, make some decisions. Finish the project. It's OK with me ;-). Happy Easter - Dan |
|
From: Dan I. <Da...@Sq...> - 2004-04-09 17:00:10
|
>[Anthony's closure work] >> Is this a modified St-80 Compiler, or one based on SmaCC? > >SmaCC. Hi, Guys - Just anticipating the release process... 1. I haven't played with SMACC. I assume it's good. I gather Marcus has also used this to do some fun work with Parse Trees. 2. Is there a pretty clean package that converts a current Squeak to use SMACC with decent reliability? 2a. Is this a part of Anthony's Closure package? 3. Is there general agreement on this list that SMACC is the way to go? ... If so, then I want to work with the Guides to get SMACC into 3.8alpha asap, so that it's not an added cause of confusion later, when we merge the other (lower-level) V4 stuff with 3.8. Thanks - Dan |
|
From: Bert F. <be...@im...> - 2004-04-09 16:58:09
|
Am 09.04.2004 um 18:36 schrieb Tim Rowledge: > Bert Freudenberg <be...@im...> wrote: > >> Am 09.04.2004 um 01:57 schrieb Tim Rowledge: >>>>> Flat Rectangles >> >> Actually, Point>>x: does not exist (can't remember when we removed >> it). >> So this should be no problem at all. > double-plus-good. > > This is another class I ought to have a filein for but damned if I can > find it. Still, not a large class IIRC. The only trick will be > substituting it for ordinary Rectangle in the tracer but we really > ought to be able to handle that ok. Why wouldn't this work with a normal changeset? Does the VM know about Rectangles? - Bert - |
|
From: Dan I. <Da...@Sq...> - 2004-04-09 15:40:11
|
>Cees de Groot wrote: >>Well, as far as you can classify my thinking on this subject as being serious (me being a total nitwit in this area), pseudocode-wise it would be: >> >>Object>>instVarAt: anInteger put: anObject >> self isImmutable ifTrue: [ >> AttemptToWriteImmutableObjectException new receiver: self; index: anInteger; value: anObject; >> raise]. >> <original code> >> >> >> Hi, Hans-Martin - >The instVarAt:put: primitive (and the at:put: primitive for indexed access) can just check the immutability bit - the additional overhead should be small. >The inst var assignments in methods are more complicated. >One possible optimization would be to allow immutability only for old objects - when assigning into old objects, we need additional code anyway. >The beImmutable primitive would make sure that the receiver is either old already, or it would move the oldspace boundary to point after the objects. >Does that sound sane? I worry a lot about any interference with the GC's own movements of objects. I can say more about this, but at another time. The thought I had is to use the multiple interpreters hack here -- one dispatch table if the receiver is immutable, another if it's not. Almost all the tables are the same except for storeInstVar and friends. So the net overhead is zero except for the one test at send time. I haven't thought what the analog is for a JIT. - Dan |
|
From: Bryce K. <br...@ka...> - 2004-04-09 14:45:58
|
> Finally, analogous to being able to add extra instance variables to > CompiledMethod, I would like that same ability for MethodContexts. Being able to cleanly add instance variables to MethodContexts would be nice. I'd like it to make it easier to detect compiled methods when returning back into them. A SmallInteger pointer to the machine code would make it both easy and fast to re-enter a method. The code sequence would be to check if the address is not nil. If it is an SmallInteger detag it then jump to that address. Bryce |
|
From: Anthony H. <aj...@co...> - 2004-04-09 13:18:41
|
Ian Piumarta <ian...@in...> wrote: > > > Code in the block and its outer > > methods access these changeable values by sending get and set messages > > to the ValueHolder. > > Is the only reason to send messages to these things the lack of > bytecodes to encode the additional indirections? (Type: > "load/store/pop free var N from enclosing environment at level M".) Right. Although, I only need one indirection. Each closure (environment) is flat and only holds what it needs (its free vars). This means values are copied down for each nested block, but it's better for garbage collection since only values that are needed by the block are copied down and held by the block. Also, I forgot to mention that if an instance variable is captured by a block (is free in the block) then the receiver is captured in the closure environment. Then access to the instance variables is done through instVarAt:(put:) messages. (Actually, instead of "object instVarAt: index put: value" its "value storeIn: object instVar: index" which I added to ProtoObject. This is preferred to maintain the storeTemp pattern which assumes the value is on top of the stack first then you want to store it somewhere.) Finally, analogous to being able to add extra instance variables to CompiledMethod, I would like that same ability for MethodContexts. Cheers, Anthony |
|
From: Cees de G. <cg...@cd...> - 2004-04-09 12:48:10
|
On Fri, 2004-04-09 at 14:41, Andreas Raab wrote: > How important is it that *all* objects individually can be tagged > immutable in this way? Would it be sufficient if there would be "certain > kinds" of objects (say, classes which have a special format or similar) > which could be used that way? > Ideally persistence is as transparent as possible (but, to paraphrase Einstein, not more transparent). The persistence (transaction, .... - there are more uses of this bit but I'll use persistence as example) engine would ideally be able to handle all sorts of objects in the same way: read them in, mark them immutable, handle the exception (put them on the 'dirty' list and mark them mutable again), whether the object is a Date or a MySpecialBusinessObject. So my first answer would be: yes, it is important to have it everywhere. |
|
From: Cees de G. <cg...@cd...> - 2004-04-09 12:44:33
|
On Fri, 2004-04-09 at 14:32, Hans-Martin Mosner wrote: > One possible optimization would be to allow immutability only for old > objects - when assigning into old objects, we need additional code anyway. > I don't know enough about the VM to know why this makes a difference, but one datapoint: you typically make objects immutable directly after instantiation (e.g. reading from the datastore). Forcing them to oldspace might have some negative performance effects. |
|
From: Andreas R. <and...@gm...> - 2004-04-09 12:41:57
|
> The instVarAt:put: primitive (and the at:put: primitive for indexed > access) can just check the immutability bit - the additional overhead > should be small. > The inst var assignments in methods are more complicated. > One possible optimization would be to allow immutability only for old > objects - when assigning into old objects, we need additional code anyway. > The beImmutable primitive would make sure that the receiver is either > old already, or it would move the oldspace boundary to point after the > objects. > Does that sound sane? Something disturbs me about this but I'm not sure what. Maybe it's that "bit" term - if we'd take the "immutability bit" literally it would mean we'd have some fairly generic stuff to be dealt with here. So here's another question: How important is it that *all* objects individually can be tagged immutable in this way? Would it be sufficient if there would be "certain kinds" of objects (say, classes which have a special format or similar) which could be used that way? Cheers, - Andreas |
|
From: Hans-Martin M. <hm...@he...> - 2004-04-09 12:33:02
|
Cees de Groot wrote: >>Immutability bit >>This sounds intriguing. Has anyone here thought seriously about what is needed to support it? >> >> >> >Well, as far as you can classify my thinking on this subject as being serious (me being a total nitwit in this area), pseudocode-wise it would be: > >Object>>instVarAt: anInteger put: anObject > self isImmutable ifTrue: [ > AttemptToWriteImmutableObjectException new > receiver: self; > index: anInteger; > value: anObject; > raise]. > <original code> > > > > The instVarAt:put: primitive (and the at:put: primitive for indexed access) can just check the immutability bit - the additional overhead should be small. The inst var assignments in methods are more complicated. One possible optimization would be to allow immutability only for old objects - when assigning into old objects, we need additional code anyway. The beImmutable primitive would make sure that the receiver is either old already, or it would move the oldspace boundary to point after the objects. Does that sound sane? Cheers, Hans-Martin |
|
From: Andreas R. <and...@gm...> - 2004-04-09 12:31:06
|
Hi Guys, Here's a cheap little proposal for evaluation and comments. It does just what I said - disabling GC in #primitiveResponse and checking if we have one pending afterwards. AFAICT, this should do the trick. Cheers, - Andreas |
|
From: Cees de G. <cg...@cd...> - 2004-04-09 12:02:27
|
> Immutability bit > This sounds intriguing. Has anyone here thought seriously about what is needed to support it? > Well, as far as you can classify my thinking on this subject as being serious (me being a total nitwit in this area), pseudocode-wise it would be: Object>>instVarAt: anInteger put: anObject self isImmutable ifTrue: [ AttemptToWriteImmutableObjectException new receiver: self; index: anInteger; value: anObject; raise]. <original code> Object>>beImmutable: aBoolean <primitive...> that's probably all support you'd need, an extra bit and some code in #primitiveInstVarAtPut. I'm using this feature in VisualWorks to support automatic dirty marking, and it is really nice - it allows you to build very complex persistent object models that you'd normally avoid because of the dirty marking hassles. |
|
From: Ian P. <ian...@in...> - 2004-04-09 10:41:37
|
[subject line changed to reduce the stress on Craig's mail client ;-] Hi Anthony, > Also, I haven't heard anyone mention refactoring the bytecodes (eg. > getting rid of doubleExtendedDoAnythingBytecode). I bet a JIT would > prefer an alternative encoding. I think you know that's true. ;) To get anywhere with even the simplest code analysis, the first thing a JIT will do is to convert the bytecodes into a "canonical form" where there's only 1 form of each operation and (probably) all bytecodes are the same size (e.g., a word for each operation containing 1 byte of opcode and up to 3 bytes of operands). This kind of transformation reduces 253 or so bytecodes down to about 20 or so "canonical" operations. > Code in the block and its outer > methods access these changeable values by sending get and set messages > to the ValueHolder. Is the only reason to send messages to these things the lack of bytecodes to encode the additional indirections? (Type: "load/store/pop free var N from enclosing environment at level M".) Or have I missed something? > If we change the > bytecodes, maybe we should add the ValueHolder create, get, and set > messages, and the createBlockClosure message as special common selector > bytecodes. Certainly. (Or maybe we could do even better...) Cheers, Ian |
|
From: Bert F. <be...@im...> - 2004-04-09 10:40:08
|
Am 09.04.2004 um 01:57 schrieb Tim Rowledge: >>> Flat Rectangles > Chief advantage is a reduction in allocation traffic; one object > instead of three etc. You do have to be careful about some inadvertent > semantic changes though; currently > aRect origin x:foo > will actually change the x value of aRect's origin point. A flat > rectangle would almost certainly implement #origin as > ^originX@originY > and thus aRect origin x: foo would have a rather different effect. Actually, Point>>x: does not exist (can't remember when we removed it). So this should be no problem at all. - Bert - |
|
From: Craig L. <cr...@ne...> - 2004-04-09 05:10:39
|
Hi all-- It'd be really cool if we could use different threads for different topics. :) "v4 changes" is a bit overly broad... (I'm drowning in mail from various sources) thanks, -C -- Craig Latta improvisational musical informaticist cr...@ne... www.netjam.org [|] Proceed for Truth! |
|
From: Craig L. <cr...@ne...> - 2004-04-09 04:58:11
|
Hi Andreas-- > > The current Squat implementation checks if the receiver's class is > > a special "proxy" class (currently called "Other"), which is in the > > special objects array. If it is, it kicks the send back to image, > > using the same mechanism as for >>doesNotUnderstand:, so that the > > message may be forwarded by the proxy. > > I'm missing something here - if it uses the same mechanism why would > we need to change the lookup? Heh; by "same mechanism" I mean I use >>createActualMessageTo: and the remapping stuff, similar to the message-not-understood support later on in Interpreter>>lookupMethodInClass:. I didn't literally mean the message-not-understood behavior itself. Hopefully you've seen my version of >>lookupMethodInClass:, to see what I mean. > Put differently, wouldn't it have the same effect if you just make > Other a ProtoObject? I think it's useful that (with this VM support) Other can be anywhere in the class hierarchy. In particular, it's impervious to whatever junk ends up in any potential superclasses (*especially* Object or ProtoObject ;). Also, I think having multiple class hierarchy roots is unnecessary, but let's please not rehash that in this thread. > > The VM is the thing that does the activation marking. I'm using that > > mark to tell when any method from a method dictionary has been run; > > it's useful for, e.g., calculating which classes can be swapped out > > of an image at some point in time. (There are also primitives for > > reading and clearing the marks.) > > I'm missing something here too (guess I'll have to check the code). > This sounds as if a method dictionary with an extra iVar or so would > achieve the same effect at the same cost. Here again, in addition to cost I'm also concerned with security. I'd like to use a mechanism for this which is less exposed to interference from the image. I don't want this information to be reachable from, e.g., >>instVarAt:put:. I'd prefer that people have to go a bit more (and more informed) effort to manipulate the marks, and be less likely to change them inappropriately by accident. Basically, I think this is properly considered "special VM knowledge" that happens to be attached to these objects, but shouldn't be directly visible in the normal ways to object memory inhabitants. thanks again, -C -- Craig Latta improvisational musical informaticist cr...@ne... www.netjam.org [|] Proceed for Truth! |
|
From: Anthony H. <aj...@co...> - 2004-04-09 04:55:20
|
Dan Ingalls <Da...@Sq...> wrote: > > > CompiledMethods > >> A major question to decide is whether to split up bytecodes and literals (and source pointer) as in Tim's NewCompiledMethod work. This adds a little space overhead, but it certainly makes things simpler. I'm going to assume that we go with Tim's 2-object format, and throw in a "serendipity" field for fun this summer. > >IIRC the difference is:- > >header > >bytecodes > >literals > >other ivars > > > >or > >header > >bytecodes > >other ivars > >indexed literals > > > >The difference is that to allow adding ivars in subclasses the second > >option means the VM has to check the number of fixed fields so it can > >find the literals correctly. ... not if the literal index (stored in the bytecode) includes the fixed fields. Then, to the VM, all fields (fixed and variable) are literals. If you don't want to waste bytecodes on literals 1 and 2 which will never get used, just stored literalIndex - 2 in the bytecodes then add 2 in the VM. Also, I haven't heard anyone mention refactoring the bytecodes (eg. getting rid of doubleExtendedDoAnythingBytecode). I bet a JIT would prefer an alternative encoding. Are we going to use Eliot's HPS bytecodes? Finally, about the Block Closures. They work with the current image format so contexts, etc. don't have to change. A closure object contains a method (code for just the block) plus an environment (array) holding values for free variables in that method. But to save an extra object the environment is the BlockClosure itself with a single fixed field holding the method. The home context is not held in the environment unless the block can do a remote return. Also, for free variables that may change, the environment holds a ValueHolder (actually a different class that doesn't subclass Model) that is shared amongst the closure and its outer environments. Code in the block and its outer methods access these changeable values by sending get and set messages to the ValueHolder. Also ValueHolders have to be created initially by their home method. But ValueHolders are rare. Most free vars are fixed, so most methods (including home methods whose vars are captured by blocks) can access their vars directly as usual. When #value: is sent to a BlockClosure, a new context is activated, the closure remains as the receiver, and its method becomes the executing method. Free vars sit in the indexable slots of the closure but are accessed as if they were receiver instance variables. If we change the bytecodes, maybe we should add the ValueHolder create, get, and set messages, and the createBlockClosure message as special common selector bytecodes. Cheers, Anthony |
|
From: Tim R. <ti...@su...> - 2004-04-09 02:21:56
|
In message <p0521061dbc9bab05c832@[192.168.1.100]>
Dan Ingalls <Da...@Sq...> wrote:
>
>
> Not to choose sides yet, but I figured this offset would go in the method cache, where it's hardly significant added to the cost of setting up the base reg anyway.
Hmm, caching it. Must admit I hadn't thought of caching that particular
value in the mcache.
> And I don't wee why "you lose subclassability".
If you cache the offset as a vm 'global' (which is what we did on
one of the Interval versions) then you can only manage the one value and
thus all your cm's must be the same shape. IIRC it cost a bit less than
1% on the benchmarks used back then to look up fixedFieldsOf each time.
But we different machines and different benchmarks now so who knows?
tim
--
Tim Rowledge, ti...@su..., http://sumeru.stanford.edu/tim
Emacs is a nice operating system, but I prefer UNIX. - Tom Christiansen
|
|
From: Dan I. <Da...@Sq...> - 2004-04-09 01:29:09
|
> > CompiledMethods >> A major question to decide is whether to split up bytecodes and literals (and source pointer) as in Tim's NewCompiledMethod work. This adds a little space overhead, but it certainly makes things simpler. I'm going to assume that we go with Tim's 2-object format, and throw in a "serendipity" field for fun this summer. >IIRC the difference is:- >header >bytecodes >literals >other ivars > >or >header >bytecodes >other ivars >indexed literals > >The difference is that to allow adding ivars in subclasses the second >option means the VM has to check the number of fixed fields so it can >find the literals correctly. So it's an extra object or an extra size >check on every send (well one could cache it in some limited >implementations but you lose subclassability). I'd go for the extra >object, personally. Not to choose sides yet, but I figured this offset would go in the method cache, where it's hardly significant added to the cost of setting up the base reg anyway. And I don't wee why "you lose subclassability". - D |
|
From: Tim R. <ti...@su...> - 2004-04-09 01:02:54
|
In message <p05210605bc99dfc4d28a@[192.168.1.100]>
Dan Ingalls <Da...@Sq...> wrote:
> First of these is the split primitive field of method headers. I think there's good agreement on returning to a 9-bit field and doing away with (or converting to named access) all those that were using higher indices. I have a specific proposal which I will document soon on the web site, but it is essentially what Tim suggested, except I would drop of the loadInstVar range so we leave room for 50 or so unused inedexed primitives at the top. My reasoning is that, ugly or not, indexed primitives are the easiest way for curious hackers to experiment with new capabilities in Squeak.
>
> [By the way, it looks like "External primitive support primitives" 570-574 are still in use and would need to be slid down]
Whoops, forgot about them for a moment. Still, this shouldn't be a
problem since there appears to be 110 primitiveObsoleteIndexedPrimitive
in the primitiveTable as well as 50 primitiveFail (some of which are
needed I guess).
> CompiledMethods
> A major question to decide is whether to split up bytecodes and literals (and source pointer) as in Tim's NewCompiledMethod work. This adds a little space overhead, but it certainly makes things simpler. I'm going to assume that we go with Tim's 2-object format, and throw in a "serendipity" field for fun this summer.
IIRC the difference is:-
header
bytecodes
literals
other ivars
or
header
bytecodes
other ivars
indexed literals
The difference is that to allow adding ivars in subclasses the second
option means the VM has to check the number of fixed fields so it can
find the literals correctly. So it's an extra object or an extra size
check on every send (well one could cache it in some limited
implementations but you lose subclassability). I'd go for the extra
object, personally.
tim
--
Tim Rowledge, ti...@su..., http://sumeru.stanford.edu/tim
Bug? That's not a bug, that's a feature. -T. John Wendel
|
|
From: Ian P. <ian...@in...> - 2004-04-09 00:52:03
|
On 09 Apr 2004, at 02:48, Tim Rowledge wrote: >> Teeny reminder (which may be irrelevant): Itanium cannot add -1 into >> an > And at umpty-eleven gazillion gigglehertz, do we care? Besides, itanium > is actually Itanic and is about to sink into the deep. Why did I say: "which may be irrelevant"? ;) Ian |
|
From: Tim R. <ti...@su...> - 2004-04-09 00:50:41
|
In message <805...@in...>
Ian Piumarta <ian...@in...> wrote:
> On 08 Apr 2004, at 21:46, Bryce Kampjes wrote:
>
> > This sequence is possible if we change from integers having tag 1 to
> > integers having tag 0 leaving the tag in the lower bits. The Self
> > community wrote some nice papers on tagging and high performance
> > simple garbage collection.
>
> Teeny reminder (which may be irrelevant): Itanium cannot add -1 into an
> effective address without introducing an additional add instruction and
> stop bit (!) before each ld/st insn.
And at umpty-eleven gazillion gigglehertz, do we care? Besides, itanium
is actually Itanic and is about to sink into the deep.
tim
--
Tim Rowledge, ti...@su..., http://sumeru.stanford.edu/tim
Strange OpCodes: CAO: Compare Apples to Oranges
|
|
From: Ian P. <ian...@in...> - 2004-04-09 00:26:14
|
On 08 Apr 2004, at 21:46, Bryce Kampjes wrote: > This sequence is possible if we change from integers having tag 1 to > integers having tag 0 leaving the tag in the lower bits. The Self > community wrote some nice papers on tagging and high performance > simple garbage collection. Teeny reminder (which may be irrelevant): Itanium cannot add -1 into an effective address without introducing an additional add instruction and stop bit (!) before each ld/st insn. (Unless I'm missing some neat trick on the Itanium? If so, someone please enlighten me! ;) > It would probably be more worthwhile looking at at: and at:put:. Could > Tim's improvements to primitives be used to create simple at: > primitives that are quick to execute? To get the same benefits as the existing at-cache you'd need two levels. The first in the method cache (to get you to the right accessor implementation, with fixed field size being stored in a // MC slot presumably?) then another instance-specific one (to get you to the object's indexable size). Maybe all this is saying is that we might want to rethink how object size is encoded in the header to make it trivially easy to extract the indexable size, whatever the format of the object. (What we really want is to generate format-specific accessor primtives on-the-fly. The fixed field size is then implicit in the implementation and all that's needed is the primitive implementation address slot in the method cache.) Bye, Ian |
|
From: Tim R. <ti...@su...> - 2004-04-08 23:57:55
|
In message <017b01c41dbd$c16ac180$6688b8d9@R22>
"Andreas Raab" <and...@gm...> wrote:
> > Decoupling GC from Primitives
> > This seems like an all-around win, although not really V4-related.
> > i would love it if someone would take it upon themselves to spec
> > this and estimate difficulty, so we can review it, and then actually
> > do it.
>
> Sounds good. I'm not sure I'll find the time to do it myself but I'll see if
> I can stick it in one lazy afternoon (say, wasn't there an easter weekend
> somewhere? hm...)
allocateChunk:, sufficientSpaceAfterGC: are first targets of course,
then the callers to provide a back out route. I think the VM changes are
quite small.
I've managed to track down the (ancient) code for returning error codes
from prims - from 2.7 days believe it or not. It's mostly Parser changes
but the curent compiler stuff has changed enought that there appears to be
quite a disconnect. Essentially the idea is to add an optional named temp to
each prim calling method with a default (the brilliantly named
'primErrorReturnVariable') if the writer can't be bothered. This temp is
always the first one and so the VM know where to stick the return object.
Image code can use it to find out what happened and obviously one of the main
interests here is to know that a GC is needed.
Since it's such a tiny piece of code I've attached it FYI.
I hope we can get round to this: I've been asking for it for several
years...
>
> > Flat Rectangles
Chief advantage is a reduction in allocation traffic; one object
instead of three etc. You do have to be careful about some inadvertent
semantic changes though; currently
aRect origin x:foo
will actually change the x value of aRect's origin point. A flat
rectangle would almost certainly implement #origin as
^originX@originY
and thus aRect origin x: foo would have a rather different effect.
tim
--
Tim Rowledge, ti...@su..., http://sumeru.stanford.edu/tim
Strange OpCodes: IOP: Insult OPerator
|
|
From: Ian P. <ian...@in...> - 2004-04-08 23:52:51
|
Hi Ian,
On 09 Apr 2004, at 01:27, Ian Piumarta wrote:
>> Hm... this would actually be a strong argument against introducing
>> more
>> immediates. They would have similar properties wouldn't they?
>
> Yes, absolutely. (At least in the lower magnitudes of the
> price/performance equation.)
No, not necessarily.
We have an array containing the classes for each tag combination (init
from splObj at startup, ensure remap during GC) then (for a 2-bit tag
field):
Interp
instVars: '... immediateClasses ...'
Interp>>classOf: anObj
| tag |
self inline: true.
^(tag _ anObj bitAnd: 3) == 0
ifTrue: [self classHeaderOf: anObj]
ifFalse: [immediateClasses at: tag]
or something similar. Costs the same as if we only had one tag bit
(with ClassSmallInt sucked out of splObj).
Cheers,
Ian
|