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

commits at source.squeak.org commits at source.squeak.org
Mon Jun 20 20:35:47 UTC 2016


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

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

Name: VMMaker.oscog-eem.1889
Author: eem
Time: 20 June 2016, 1:33:14.0061 pm
UUID: 24dcf481-d07a-4e68-a4bf-7d6d8ce2ae4f
Ancestors: VMMaker.oscog-eem.1888

Fix a bug in Spur become validation, a regression from supporting copyHash properly.  The check for there being available memroy for copies of all arguments should only occur in the two-way case, not in the one-way copyHash case.  Refactor Clément's checker into ifOopInvalidForBecome:errorCodeInto: and use it to check all checked arguments.

This fixes Bert's (ByteString new: 20000000) writeStream nextPut: (Character value: 128169) case.

In 1889  Herman Hollerith receives a patent for his electric tabulating machine in the United States, Vincent van Gogh paints The Starry Night at Saint-Rémy-de-Provence, and the Eiffel Tower is inaugurated and opens on May 6. At 300 m, its height exceeds the previous tallest structure in the world by 130 m.

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

Item was changed:
  ----- Method: SpurMemoryManager>>become:with:twoWay:copyHash: (in category 'become api') -----
  become: array1 with: array2 twoWay: twoWayFlag copyHash: copyHashFlag
  	"All references to each object in array1 are swapped with all references to the
  	 corresponding object in array2. That is, all pointers to one object are replaced
  	 with with pointers to the other. The arguments must be arrays of the same length. 
  	 Answers PrimNoErr if the primitive succeeds, otherwise a relevant error code."
  	"Implementation: Uses lazy forwarding to defer updating references until message send."
+ 	<inline: false>
  	| ec |
  	self assert: becomeEffectsFlags = 0.
  	self runLeakCheckerFor: GCModeBecome.
  	(self isArray: array1) ifFalse:
  		[^PrimErrBadReceiver].
  	((self isArray: array2)
  	 and: [(self numSlotsOf: array1) = (self numSlotsOf: array2)]) ifFalse:
  		[^PrimErrBadArgument].
+ 	ec := self containsOnlyValidBecomeObjects: array1 and: array2 twoWay: twoWayFlag copyHash: copyHashFlag.
- 	(twoWayFlag or: [copyHashFlag])
- 		ifTrue:
- 			[ec := self containsOnlyValidBecomeObjects: array1 and: array2]
- 		ifFalse:
- 			[self followForwardedObjectFields: array2 toDepth: 0.
- 			ec := self containsOnlyValidBecomeObjects: array1].
  	ec ~= 0 ifTrue:
  		[becomeEffectsFlags := 0.
  		 ^ec].
  
  	coInterpreter preBecomeAction.
  	twoWayFlag
  		ifTrue:
  			[self innerBecomeObjectsIn: array1 and: array2 copyHash: copyHashFlag]
  		ifFalse:
  			[self innerBecomeObjectsIn: array1 to: array2 copyHash: copyHashFlag].
  	self followSpecialObjectsOop.
  	"N.B. perform coInterpreter's postBecomeAction: *before* postBecomeScanClassTable:
  	 to allow the coInterpreter to void method cache entries by spotting classIndices that
  	 refer to forwarded objects. postBecomeScanClassTable: follows forwarders in the table."
  	coInterpreter postBecomeAction: becomeEffectsFlags.
  	self postBecomeScanClassTable: becomeEffectsFlags.
  	becomeEffectsFlags := 0.
  
  	self assert: self validClassTableHashes.
  	self runLeakCheckerFor: GCModeBecome.
  
  	^PrimNoErr "success"!

Item was removed:
- ----- Method: SpurMemoryManager>>containsOnlyValidBecomeObjects: (in category 'become implementation') -----
- containsOnlyValidBecomeObjects: array
- 	"Answer 0 if the array contains only unpinned non-immediates.
- 	 Otherwise answer an informative error code.
- 	 Can't become: immediates!!  Shouldn't become pinned objects."
- 	| fieldOffset effectsFlags oop errCode |
- 	fieldOffset := self lastPointerOfArray: array.
- 	effectsFlags := 0.
- 	"same size as array2"
- 	[fieldOffset >= self baseHeaderSize] whileTrue:
- 		[oop := self longAt: array + fieldOffset.
- 		 (self isOopForwarded: oop) ifTrue:
- 			[oop := self followForwarded: oop.
- 			 self longAt: array + fieldOffset put: oop].
- 		 (errCode := self isOopValidBecome: oop) = 0 ifFalse: [^ errCode].
- 		 effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop).
- 		 fieldOffset := fieldOffset - self bytesPerOop].
- 	"only set flags after checking all args."
- 	becomeEffectsFlags := effectsFlags.
- 	^0!

Item was removed:
- ----- Method: SpurMemoryManager>>containsOnlyValidBecomeObjects:and: (in category 'become implementation') -----
- containsOnlyValidBecomeObjects: array1 and: array2
- 	"Answer 0 if neither array contains only unpinned non-immediates.
- 	 Otherwise answer an informative error code.
- 	 Can't become: immediates!!  Shouldn't become pinned objects."
- 	| fieldOffset effectsFlags oop size |
- 	fieldOffset := self lastPointerOf: array1.
- 	effectsFlags := size := 0.
- 	"same size as array2"
- 	[fieldOffset >= self baseHeaderSize] whileTrue:
- 		[oop := self longAt: array1 + fieldOffset.
- 		 (self isOopForwarded: oop) ifTrue:
- 			[oop := self followForwarded: oop.
- 			 self longAt: array1 + fieldOffset put: oop].
- 		 (self isImmediate: oop) ifTrue: [^PrimErrInappropriate].
- 		 (self isPinned: oop) ifTrue: [^PrimErrObjectIsPinned].
- 		 effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop).
- 		 size := size + (self bytesInObject: oop).
- 		 oop := self longAt: array2 + fieldOffset.
- 		 (self isOopForwarded: oop) ifTrue:
- 			[oop := self followForwarded: oop.
- 			 self longAt: array2 + fieldOffset put: oop].
- 		 (self isImmediate: oop) ifTrue: [^PrimErrInappropriate].
- 		 (self isPinned: oop) ifTrue: [^PrimErrObjectIsPinned].
- 		 effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop).
- 		 size := size + (self bytesInObject: oop).
- 		 fieldOffset := fieldOffset - self bytesPerOop].
- 	size >= (totalFreeOldSpace + (scavengeThreshold - freeStart)) ifTrue:
- 		[^PrimErrNoMemory].
- 	"only set flags after checking all args."
- 	becomeEffectsFlags := effectsFlags.
- 	^0!

Item was added:
+ ----- Method: SpurMemoryManager>>containsOnlyValidBecomeObjects:and:twoWay:copyHash: (in category 'become implementation') -----
+ containsOnlyValidBecomeObjects: array1 and: array2 twoWay: isTwoWay copyHash: copyHash
+ 	"Answer 0 if neither array contains an object inappropriate for the become operation.
+ 	 Otherwise answer an informative error code for the first offending object found:
+ 		Can't become: immediates => PrimErrInappropriate
+ 		Shouldn't become pinned objects => PrimErrObjectIsPinned.
+ 		Shouldn't become immutable objects => PrimErrNoModification.
+ 		Can't copy hash into immediates => PrimErrInappropriate.
+ 		Two-way become may require memory to create copies => PrimErrNoMemory.
+ 	 As a side-effect unforward any forwarders in the two arrays if answering 0."
+ 	<inline: true>
+ 	| fieldOffset effectsFlags oop1 oop2 size |
+ 	fieldOffset := self lastPointerOf: array1.
+ 	effectsFlags := size := 0.
+ 	"array1 is known to be the same size as array2"
+ 	[fieldOffset >= self baseHeaderSize] whileTrue:
+ 		[oop1 := self longAt: array1 + fieldOffset.
+ 		 (self isOopForwarded: oop1) ifTrue:
+ 			[oop1 := self followForwarded: oop1.
+ 			 self longAt: array1 + fieldOffset put: oop1].
+ 		 self ifOopInvalidForBecome: oop1 errorCodeInto: [:errCode| ^errCode].
+ 		 effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop1).
+ 		 oop2 := self longAt: array2 + fieldOffset.
+ 		 (self isOopForwarded: oop2) ifTrue:
+ 			[oop2 := self followForwarded: oop2.
+ 			 self longAt: array2 + fieldOffset put: oop2].
+ 		 isTwoWay
+ 			ifTrue:
+ 				[self ifOopInvalidForBecome: oop2 errorCodeInto: [:errCode| ^errCode].
+ 				 size := size + (self bytesInObject: oop1) + (self bytesInObject: oop2).
+ 				 effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop2)]
+ 			ifFalse:
+ 				[(copyHash and: [self isImmediate: oop2]) ifTrue:
+ 					[^PrimErrInappropriate]].
+ 		 fieldOffset := fieldOffset - self bytesPerOop].
+ 	size >= (totalFreeOldSpace + (scavengeThreshold - freeStart)) ifTrue:
+ 		[^PrimErrNoMemory].
+ 	"only set flags after checking all args."
+ 	becomeEffectsFlags := effectsFlags.
+ 	^0!

Item was added:
+ ----- Method: SpurMemoryManager>>ifOopInvalidForBecome:errorCodeInto: (in category 'become implementation') -----
+ ifOopInvalidForBecome: oop errorCodeInto: aBlock
+ 	"Evaluates aBlock with an appropriate error if oop is invalid for become."
+ 	<inline: true>
+ 	(self isImmediate: oop) ifTrue:
+ 		[^aBlock value: PrimErrInappropriate].
+ 	(self isPinned: oop) ifTrue:
+ 		[^aBlock value: PrimErrObjectIsPinned].
+ 	(self isObjImmutable: oop) ifTrue:
+ 		[^aBlock value: PrimErrNoModification]!

Item was removed:
- ----- Method: SpurMemoryManager>>isOopValidBecome: (in category 'become implementation') -----
- isOopValidBecome: oop
- 	"Answers 0 if the oop can be become.
- 	Answers an error code in the other case"
- 	(self isImmediate: oop) ifTrue: [^PrimErrInappropriate].
- 	(self isPinned: oop) ifTrue: [^PrimErrObjectIsPinned].
- 	(self isObjImmutable: oop) ifTrue: [^PrimErrNoModification].
- 	^0!



More information about the Vm-dev mailing list