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

commits at source.squeak.org commits at source.squeak.org
Tue Apr 14 21:03:25 UTC 2020

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

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

Name: VMMaker.oscog-eem.2741
Author: eem
Time: 14 April 2020, 2:03:09.122947 pm
UUID: 809e8b1f-fe07-4d33-bfc1-db9e5ab13a99
Ancestors: VMMaker.oscog-eem.2740

Spur: Make sure that becomeForward: answers a useful error code for read-only targets (when copyHash is true).

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

Item was changed:
  ----- 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].
  		 oop2 := self longAt: array2 + fieldOffset.
  		 (self isOopForwarded: oop2) ifTrue:
  			[oop2 := self followForwarded: oop2.
  			 self longAt: array2 + fieldOffset put: oop2].
+ 		 oop1 ~= oop2 ifTrue:
+ 			[isTwoWay
+ 				ifTrue:
+ 					[self ifOopInvalidForBecome: oop2 errorCodeInto: [:errCode| ^errCode].
+ 					 size := size + (self bytesInObject: oop1) + (self bytesInObject: oop2).
- 		 isTwoWay
- 			ifTrue:
- 				[self ifOopInvalidForBecome: oop2 errorCodeInto: [:errCode| ^errCode].
- 				 oop1 ~= oop2 ifTrue:
- 					[size := size + (self bytesInObject: oop1) + (self bytesInObject: oop2).
  					 effectsFlags := (effectsFlags
  										bitOr: (self becomeEffectFlagsFor: oop1))
+ 										bitOr: (self becomeEffectFlagsFor: oop2)]
+ 				ifFalse:
+ 					[copyHash ifTrue:
+ 						[(self isImmediate: oop2) ifTrue:
+ 							[^PrimErrInappropriate].
+ 						 (self isObjImmutable: oop2) ifTrue:
+ 							[^PrimErrNoModification]].
+ 					 effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop1)]].
- 										bitOr: (self becomeEffectFlagsFor: oop2)]]
- 			ifFalse:
- 				[(copyHash and: [(self isImmediate: oop2) or: [self isImmutable: oop2]]) ifTrue:
- 					[^PrimErrInappropriate].
- 				 oop1 ~= oop2 ifTrue:
- 					[effectsFlags := effectsFlags bitOr: (self becomeEffectFlagsFor: oop1)]].
  		 fieldOffset := fieldOffset - self bytesPerOop].
  	size >= (totalFreeOldSpace + (scavengeThreshold - freeStart)) ifTrue:
  	"only set flags after checking all args."
  	becomeEffectsFlags := effectsFlags.

Item was changed:
  ----- Method: SpurMemoryManager>>postBecomeScanClassTable: (in category 'become implementation') -----
  postBecomeScanClassTable: effectsFlags
  	"Scan the class table post-become (iff an active class object was becommed) to ensure no
  	 forwarding pointers, and no unhashed classes exist in the class table.
  	 Note that one-way become can cause duplications in the class table.
+ 	 So if pointer objects have been becommed, scan all pages in the class table
+ 	 and eliminate ay entries that have a zero hash. doBecome:and:copyHash: has
+ 	 already ensured that any becomed class has been stored at the right index."
- 	 When can these be eliminated?  We use the classTableBitmap to mark classTable entries
- 	 (not the classes themselves, since marking a class doesn't help in knowing if its index is used).
- 	 On image load, and during incrememtal scan-mark and full GC, classIndices are marked.
- 	 We can somehow avoid following classes from the classTable until after this mark phase."
  	self assert: self validClassTableRootPages.
  	(effectsFlags anyMask: BecamePointerObjectFlag) ifFalse: [^self].
  	0 to: numClassTablePages - 1 do:
  		[:i| | page |
  		page := self fetchPointer: i ofObject: hiddenRootsObj.
  		self assert: (self isForwarded: page) not.
  		0 to: (self numSlotsOf: page) - 1 do:
  			[:j| | classOrNil |
  			classOrNil := self fetchPointer: j ofObject: page.
  			classOrNil ~= nilObj ifTrue:
  				[(self isForwarded: classOrNil) ifTrue:
  					[classOrNil := self followForwarded: classOrNil.
  					 self storePointer: j ofObject: page withValue: classOrNil].
  				 (self rawHashBitsOf: classOrNil) = 0 ifTrue:
  					[self storePointerUnchecked: j ofObject: page withValue: nilObj.
  					 "If the removed class is before the classTableIndex, set the
  					  classTableIndex to point to the empty slot so as to reuse it asap."
  					 (i << self classTableMajorIndexShift + j) < classTableIndex ifTrue:
  						[classTableIndex := i << self classTableMajorIndexShift + j]]]]].
  	"classTableIndex must never index the first page, which is reserved for classes known to the VM."
  	self assert: classTableIndex >= (1 << self classTableMajorIndexShift)!

More information about the Vm-dev mailing list