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

commits at source.squeak.org commits at source.squeak.org
Thu Mar 14 22:43:22 UTC 2013


Eliot Miranda uploaded a new version of VMMaker to project VM Maker:
http://source.squeak.org/VMMaker/VMMaker-eem.306.mcz

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

Name: VMMaker-eem.306
Author: eem
Time: 14 March 2013, 3:42:10.684 pm
UUID: eab36ce1-1996-4294-bdcd-5863a9ae5bcf
Ancestors: VMMaker-eem.305

Remove erroneous flushing of method class on changing an
object's class.  Make sure that the class mutation primitives
*do* flush the AtCache.
Changing the class of an object doesn't invalidate the
entries in the method lookup cache which are from
class x selector to method x primtive.
*do* flush the AtCache since changing an object's class
can change how it is accessed.

=============== Diff against VMMaker-eem.305 ===============

Item was changed:
  ----- Method: Interpreter>>changeClassOf:to: (in category 'object access primitives') -----
  changeClassOf: rcvr to: argClass
  	"Change the class of the receiver into the class specified by the argument given that the format of the receiver matches the format of the argument. 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 argument's class is compact and the receiver 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 ccIndex |
  	"Check what the format of the class says"
  	classHdr := objectMemory 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: objectMemory sizeMask) + sizeHiBits. "size in bytes -- low 2 bits are 0"
  
  	"Check the receiver's format against that of the class"
  	argFormat := (classHdr >> 8) bitAnd: 16rF.
  	rcvrFormat := objectMemory formatOf: rcvr.
  	argFormat = rcvrFormat ifFalse:[^self primitiveFail]. "no way"
  
  	"For fixed field classes, the sizes must match.
  	Note: byteSize-4 because base header is included in class size."
  	argFormat < 2 ifTrue:[(byteSize - objectMemory baseHeaderSize) = (objectMemory byteSizeOf: rcvr) ifFalse:[^self primitiveFail]].
  
  	(objectMemory headerType: rcvr) = HeaderTypeShort
  		ifTrue:[ "Compact classes. Check if the arg's class is compact and exchange ccIndex"
  			ccIndex := classHdr bitAnd: CompactClassMask.
  			ccIndex = 0 ifTrue:[^self primitiveFail]. "class is not compact"
  			objectMemory longAt: rcvr put:
  				(((objectMemory longAt: rcvr) bitAnd: CompactClassMask bitInvert32)
  					bitOr: ccIndex)]
  		ifFalse:["Exchange the class pointer, which could make rcvr a root for argClass"
  			objectMemory longAt: rcvr - objectMemory baseHeaderSize put: (argClass bitOr: (objectMemory headerType: rcvr)).
  			(objectMemory oop: rcvr isLessThan: objectMemory youngStart)
+ 				ifTrue: [objectMemory possibleRootStoreInto: rcvr value: argClass]]!
- 				ifTrue: [objectMemory possibleRootStoreInto: rcvr value: argClass]].
- 
- 	"Flush cache because rcvr's class has changed"
- 	self flushMethodCache.
- !

Item was changed:
  ----- Method: Interpreter>>primitiveChangeClassWithClass (in category 'object access primitives') -----
  primitiveChangeClassWithClass
  	"Primitive. Change the class of the receiver into the class of the argument given that the format of the receiver matches the format of the argument's class. 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 argument's class is compact and the receiver 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."
  	| rcvr argClass |
  	<export: true>
  	self methodArgumentCount = 1 ifFalse: [self primitiveFail. ^ nil].
  
  	argClass := self stackObjectValue: 0.
  	rcvr := self stackObjectValue: 1.
  
  	self changeClassOf: rcvr to: argClass.
+ 	self successful ifTrue: [ self flushAtCache. self pop: 1 ].
- 	self successful ifTrue: [ self pop: 1 ].
  	^ nil.
  !

Item was changed:
  ----- Method: InterpreterPrimitives>>primitiveChangeClass (in category 'object access primitives') -----
  primitiveChangeClass
  	"Primitive. Change the class of the receiver into the class of the argument given that the format of the receiver matches the format of the argument's class. 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 argument's class is compact and the receiver 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."
  	| arg rcvr argClass |
  
  	self methodArgumentCount = 1 ifFalse: [self primitiveFail. ^ nil].
  
  	arg := self stackObjectValue: 0.
  	rcvr := self stackObjectValue: 1.
  	argClass := objectMemory fetchClassOf: arg.
  	self changeClassOf: rcvr to: argClass.
+ 	self successful ifTrue: [ self flushAtCache. self pop: 1 ].
- 	self successful ifTrue: [ self pop: 1 ].
  	^ nil.
  !



More information about the Vm-dev mailing list