-
Notifications
You must be signed in to change notification settings - Fork 124
Open
Description
When searching for a free entry to use for a new Class, minorIndex should be set to zero after searching the first page. Otherwise, only entries between the initial minorIndex and the end of each subsequent page are searched. Also, when incrementing majorIndex, the wrap mask should be self classTableRootSlots - 1 and not self classIndexMask (see below **).
I think the missing reset of minorIndex has led to holes in the class table for the currently released Squeak and Cuis images. (Cuis has fewer than 2000 classes in the image but the table has them spread over around 20 sparsely populated pages (~20000 entries)).
enterIntoClassTable: aBehavior
"Enter aBehavior into the class table and answer 0. Otherwise answer a primitive failure code."
<inline: false>
| initialMajorIndex majorIndex minorIndex page |
majorIndex := classTableIndex >> self classTableMajorIndexShift.
initialMajorIndex := majorIndex.
"classTableIndex should never index the first page; it's reserved for known classes"
self assert: initialMajorIndex > 0.
minorIndex := classTableIndex bitAnd: self classTableMinorIndexMask.
[page := self fetchPointer: majorIndex ofObject: hiddenRootsObj.
page = nilObj ifTrue:
[page := self allocateSlotsInOldSpace: self classTablePageSize
format: self arrayFormat
classIndex: self arrayClassIndexPun.
page ifNil:
[^PrimErrNoMemory halt].
self fillObj: page numSlots: self classTablePageSize with: nilObj.
self storePointer: majorIndex
ofObject: hiddenRootsObj
withValue: page.
numClassTablePages := numClassTablePages + 1.
minorIndex := 0].
minorIndex to: self classTablePageSize - 1 do:
[:i|
(self fetchPointer: i ofObject: page) = nilObj ifTrue:
[classTableIndex := majorIndex << self classTableMajorIndexShift + i.
"classTableIndex must never index the first page, which is reserved for classes known to the VM."
self assert: classTableIndex >= (1 << self classTableMajorIndexShift).
self storePointer: i
ofObject: page
withValue: aBehavior.
self setHashBitsOf: aBehavior to: classTableIndex.
self assert: (self classAtIndex: (self rawHashBitsOf: aBehavior)) = aBehavior.
^0]].
"** Missing: minorIndex := 0. **"
"** classIndexMask is 22 bits; instead the following should be using (self classTableRootSlots - 1) **"
majorIndex := (majorIndex + 1 bitAnd: self classIndexMask) max: 1.
majorIndex = initialMajorIndex ifTrue: "wrapped; table full"
[^PrimErrLimitExceeded]] repeat
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels