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

commits at source.squeak.org commits at source.squeak.org
Tue Dec 18 18:41:09 UTC 2012

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

==================== Summary ====================

Name: VMMaker.oscog-eem.239
Author: eem
Time: 18 December 2012, 10:35:18.772 am
UUID: 3087e16d-bf3c-4fdc-b2ec-14791deff66f
Ancestors: VMMaker.oscog-eem.238

Third time lucky.  Fix bug in changeClass:from: so that if receiver has
long header and class is compact, receiver still gets compact class
field set, not cleared.  No matter what header an instance has, if its
class is compact it should have the compact class index set.

=============== Diff against VMMaker.oscog-eem.238 ===============

Item was changed:
  ----- Method: ObjectMemory>>changeClassOf:to: (in category 'interpreter access') -----
  changeClassOf: rcvr to: argClass
  	"Attempt to change the class of the receiver into the class of the the argument given that the
  	 format of the receiver matches the format of the argument. If successful answer 0, otherwise
  	 answer an error code indicating the reason for failure.  Fail if receiver or argument are
  	 SmallIntegers, or the receiver is an instance of a compact class and the argument isn't, or when
  	 the format of the receiver is different from the format of the argument's class, or when the
  	 arguments class is fixed and the receiver's size differs from the size that an instance of the
  	 argument's class should have."
  	| classHdr sizeHiBits byteSize argFormat rcvrFormat rcvrHdr ccIndex |
  	"Check what the format of the class says"
  	classHdr := self formatOfClass: argClass. "Low 2 bits are 0"
  	"Compute the size of instances of the class (used for fixed field classes only)"
  	sizeHiBits := (classHdr bitAnd: 16r60000) >> 9.
  	classHdr := classHdr bitAnd: 16r1FFFF.
  	byteSize := (classHdr bitAnd: SizeMask) + sizeHiBits. "size in bytes -- low 2 bits are 0"
  	"Check the receiver's format against that of the class"
  	argFormat := self formatOfHeader: classHdr.
  	rcvrHdr := self baseHeader: rcvr.
  	rcvrFormat := self formatOfHeader: rcvrHdr.
  	"If the receiver is a byte object we need to clear the number of odd bytes from the format."
  	rcvrFormat > 8 ifTrue:
  		[rcvrFormat := rcvrFormat bitAnd: 16rC].
  	argFormat = rcvrFormat ifFalse:
  		[^PrimErrInappropriate]. "no way"
  	"For fixed field classes, the sizes must match.
  	Note: byteSize-4 because base header is included in class size."
  	argFormat < 2
  			[(byteSize - BaseHeaderSize) ~= (self byteSizeOf: rcvr) ifTrue:
  			[argFormat = 3 ifTrue: "For indexable plus fixed fields the receiver must be at least big enough."
  				[(byteSize - BaseHeaderSize) > (self byteSizeOf: rcvr) ifTrue:
  	ccIndex := classHdr bitAnd: CompactClassMask.
  	(self headerTypeOfHeader: rcvrHdr) = HeaderTypeShort
  		ifTrue: "Compact classes. Check if the arg's class is compact and exchange ccIndex"
  			[ccIndex = 0 ifTrue:
  				[^PrimErrInappropriate]. "class is not compact"
  			self cppIf: IMMUTABILITY
  				ifTrue: [(rcvrHdr bitAnd: ImmutabilityBit) ~= 0 ifTrue:
  			self baseHeader: rcvr
  				put: (((self longAt: rcvr) bitClear: CompactClassMask) bitOr: ccIndex)]
  		ifFalse: "Exchange the class pointer, which could make rcvr a root for argClass.  Don't forget to set ccIndex."
  			[self cppIf: IMMUTABILITY
  				ifTrue: [(rcvrHdr bitAnd: ImmutabilityBit) ~= 0 ifTrue:
+ 			self baseHeader: rcvr
+ 				put: (((self baseHeader: rcvr) bitClear: CompactClassMask) bitOr: ccIndex).			
- 			(self compactClassIndexOf: rcvr) ~= 0 ifTrue:
- 				[self baseHeader: rcvr
- 					put: (((self baseHeader: rcvr) bitClear: CompactClassMask) bitOr: ccIndex)].			
  			self longAt: rcvr-BaseHeaderSize put: (argClass bitOr: (self headerType: rcvr)).
  			(self oop: rcvr isLessThan: youngStart) ifTrue:
  				[self possibleRootStoreInto: rcvr value: argClass]].

More information about the Vm-dev mailing list