Getting rid of Compact classes (Was: Re: [squeak-dev] The Primitive: I am not a number- I am a named prim! - SqueakPeople article)

Igor Stasenko siguctua at gmail.com
Mon Jun 30 19:55:22 UTC 2008


2008/6/30 tim Rowledge <tim at rowledge.org>:
>
> On 30-Jun-08, at 12:15 PM, Igor Stasenko wrote:
>
>> 2008/6/30 tim Rowledge <tim at rowledge.org>:
>>>
>>> I am trying to make time to post a few articles on some future directions
>>> I
>>> consider interesting for the core system.
>>>
>>> First one is up at http://people.squeakfoundation.org/article/89.html -
>>> do
>>> please comment on the relevant page, or even here.
>>>
>>
>> This is not the only things which i don't like.
>> For instance look into ObjectMemory>>fetchClassOf:
>> it fetching class depending on object header. Either from compact
>> classes array (by index), or from slot, reserved for class reference.
>> I think eliminating compact classes would simplify the access to
>> object's class and free us some bits again: type mask bit (at least).
>>
>> It also will make fetching a class oop faster and uniform, so there
>> will be no branching.
>> Fetching a class from Compact classes array, requires:  getting oop at
>> index in special objects array, and then getting oop from this object:
>>
>> class := fetchPointer: ccIndex - 1 ofObject: (self fetchPointer:
>> CompactClasses ofObject: specialObjectsOop)
>>
>> A drawback of getting rid of compact classes is additional memory cost
>> per each instance of classes which were compact.
>
> Good points but perhaps for another thread?
>
>

Here is an extended info, from ObjectMemory class comment:

	3 bits	reserved for gc (mark, root, unused)
	12 bits	object hash (for HashSets)
	5 bits	compact class index
	4 bits	object format
	6 bits	object size in 32-bit words
	2 bits	header type (0: 3-word, 1: 2-word, 2: forbidden, 3: 1-word)


If a class is in the compact class table, then this is the only header
information needed.  If it is not, then it will have another header
word at offset -4 bytes with its class in the high 30 bits, and the
header type repeated in its low 2 bits.
-----

So, as you would see, removing a compact classes will free 5 bits in
common header , which then can be used by any object for what you
mentioned: immutable flag, proxy flag etc.
A tradeoff is increasing memory by 4 bytes (in 32bit images) for
storing class oop in each instance of classes which were compact.

Here the list of classes which is used as compact:

Smalltalk compactClassesArray

#(CompiledMethod MethodProperties Array PseudoContext
LargePositiveInteger Float MethodDictionary Association Point
Rectangle ByteString TranslatedMethod BlockContext MethodContext nil
Bitmap nil nil nil nil nil nil nil nil nil nil nil nil nil nil nil)

And here the code which can tell us, how larger image would be after
removing compact classes:

| count |
count := 0.
Smalltalk compactClassesArray do: [:each |
	each ifNotNil: [ count := count + each allInstances size ]
].
count * 4

In my image its 2315548 extra bytes.

The image size is 36368500 bytes. So, in percentage its roughly 6%
space increase.

I can't measure how faster (or slower) image would be if we remove
compact classes, because it requires a conversion :)

-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list