[Vm-dev] VM Maker: VMMaker.oscog-eem.831.mcz

commits at source.squeak.org commits at source.squeak.org
Tue Jul 22 17:44:04 UTC 2014

Eliot Miranda uploaded a new version of VMMaker to project VM Maker:

==================== 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

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:
  			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)
  			[self inPlaceBecome: obj1 and: obj2 copyHashFlag: copyHashFlag]
  			[self outOfPlaceBecome: obj1 and: obj2 copyHashFlag: copyHashFlag].
  	"if copyHashFlag then nothing changes, since hashes were also swapped."
  	copyHashFlag ifTrue:
  	"if copyHash is false then the classTable entries must be updated."
  	o1ClassIndex ~= 0
  			[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]]
  			[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]]!

More information about the Vm-dev mailing list