Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.831.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.831 Author: eem Time: 22 July 2014, 7:40:53.16 am UUID: c231d214-1763-4c79-9b58-a5bf3385b0c9 Ancestors: VMMaker.oscog-eem.830
Spur: Fix bug with class table management and two-way become. Because two-way become may do an in-place become, obj1 & obj2 in SpurMemoryManager>>doBecome:and:copyHash: may not be forwarded after the inner become. Hence they should not be followed if not forwarded. The bug manifested as Object's identityHash changing: superclass is the first slot in a class. Following an unforwarded subclass of object yields Object. Setting the hash bits of the followed object smashes Object's identityHash.
Thanks to Stéphane Rollandin for finding the bug.
=============== Diff against VMMaker.oscog-eem.830 ===============
Item was changed: ----- Method: SpurMemoryManager>>doBecome:and:copyHash: (in category 'become implementation') ----- doBecome: obj1 and: obj2 copyHash: copyHashFlag "Inner dispatch for two-way become" | o1ClassIndex o2ClassIndex | copyHashFlag ifFalse: ["in-lined classIndex := (self isInClassTable: obj) ifTrue: [self rawHashBitsOf: obj] ifFalse: [0] for speed." o1ClassIndex := self rawHashBitsOf: obj1. (o1ClassIndex ~= 0 and: [(self classAtIndex: o1ClassIndex) ~= obj1]) ifTrue: [o1ClassIndex := 0]. o2ClassIndex := self rawHashBitsOf: obj2. (o2ClassIndex ~= 0 and: [(self classAtIndex: o2ClassIndex) ~= obj2]) ifTrue: [o2ClassIndex := 0]]. (self numSlotsOf: obj1) = (self numSlotsOf: obj2) ifTrue: [self inPlaceBecome: obj1 and: obj2 copyHashFlag: copyHashFlag] ifFalse: [self outOfPlaceBecome: obj1 and: obj2 copyHashFlag: copyHashFlag]. "if copyHashFlag then nothing changes, since hashes were also swapped." copyHashFlag ifTrue: [^self]. "if copyHash is false then the classTable entries must be updated." o1ClassIndex ~= 0 ifTrue: [o2ClassIndex ~= 0 ifTrue: "both were in the table; just swap entries" [| tmp | tmp := self classAtIndex: o1ClassIndex. self classAtIndex: o1ClassIndex put: obj2. self classAtIndex: o2ClassIndex put: tmp] ifFalse: "o2 wasn't in the table; put it there" [| newObj2 | + (self isForwarded: obj1) + ifTrue: [newObj2 := self followForwarded: obj1] + ifFalse: [newObj2 := obj1]. - newObj2 := self followForwarded: obj1. self assert: (self rawHashBitsOf: newObj2) = 0. self setHashBitsOf: newObj2 to: o1ClassIndex. self classAtIndex: o1ClassIndex put: newObj2]] ifFalse: [o2ClassIndex ~= 0 ifTrue: [| newObj1 | + (self isForwarded: obj2) + ifTrue: [newObj1 := self followForwarded: obj2] + ifFalse: [newObj1 := obj2]. - newObj1 := self followForwarded: obj2. self assert: (self rawHashBitsOf: newObj1) = 0. self setHashBitsOf: newObj1 to: o2ClassIndex. self classAtIndex: o2ClassIndex put: newObj1]]!
vm-dev@lists.squeakfoundation.org