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

commits at source.squeak.org commits at source.squeak.org
Tue Sep 7 03:04:59 UTC 2021


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

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

Name: VMMaker.oscog-eem.3061
Author: eem
Time: 6 September 2021, 8:04:47.262323 pm
UUID: f660358c-9f5e-474e-8a1d-c41b4226a48c
Ancestors: VMMaker.oscog-eem.3060

SpurMemoryManager: newSpaceLimit is equal to oldSpaceStart and therefore surplus to requirements.

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

Item was changed:
  ----- Method: Spur32BitCoMemoryManager>>checkMemoryMap (in category 'debug support') -----
  checkMemoryMap
  	"Override to check that Cog methods are considered neither young nor old.
  	 Being young would cause them to be scavenged.
  	 Being old would cause them to be remembered if stored into (but wait, they don't get stored into)."
  
+ 	super checkMemoryMap.
- 	self assert: (self isYoungObject: newSpaceStart).
- 	self assert: (self isYoungObject: newSpaceLimit - self wordSize).
- 	self assert: (self isOldObject: newSpaceStart) not.
- 	self assert: (self isOldObject: newSpaceLimit - self wordSize) not.
- 	self assert: (self isYoungObject: newSpaceLimit) not.
- 	self assert: (self isYoungObject: oldSpaceStart) not.
- 	self assert: (self isYoungObject: endOfMemory) not.
- 	self assert: (self isOldObject: oldSpaceStart).
- 	self assert: (self isOldObject: endOfMemory).
  
  	"we would like the following to be true, but we either choose one boundary check for
  	 cogMethods vs objects (isMachineCodeFrame: et al) or one boundary check for
  	 copyAndForward:.  We can't have both, and the former is likely the highest dynamic
  	 frequency."
  	false ifTrue:
  		[self assert: (self isYoungObject: cogit minCogMethodAddress) not.
  		 self assert: (self isYoungObject: cogit maxCogMethodAddress) not].
  	self assert: (self isOldObject: cogit minCogMethodAddress) not.
  	self assert: (self isOldObject: cogit maxCogMethodAddress) not!

Item was changed:
  ----- Method: Spur32BitCoMemoryManager>>initializeFreeSpaceForFacadeFrom:to: (in category 'simulation only') -----
  initializeFreeSpaceForFacadeFrom: base to: limit
  	"c.f. initializeFreeSpacePostLoad: freeListObj."
  	| freeListObj freeBytes |
+ 	oldSpaceStart := freeStart := base.
- 	newSpaceLimit := oldSpaceStart := freeStart := base.
  	endOfMemory := limit.
  	scavengeThreshold := limit * 3 // 4.
  	segmentManager initSegmentForInImageCompilationFrom: base to: limit.
  	freeListObj := self allocateSlots: self numFreeLists
  						format: self wordIndexableFormat
  						classIndex: self wordSizeClassIndexPun.
  	freeLists := self firstIndexableField: freeListObj.
  	freeListsMask := 0.
  	0 to: self numFreeLists - 1 do:
  		[:i|
  		(freeLists at: i) ~= 0 ifTrue:
  			[freeListsMask := freeListsMask bitOr: (1 << i).
  			 freeLists at: i put: (segmentManager swizzleObj: (freeLists at: i))]].
  	freeBytes := segmentManager lastSegment segLimit - self bridgeSize - freeStart.
  	freeLists at: 0 put: (self initFreeChunkWithBytes: freeBytes at: freeStart).
  	totalFreeOldSpace := freeBytes!

Item was changed:
  ----- Method: Spur32BitCoMemoryManager>>isReallyYoungObject: (in category 'object testing') -----
  isReallyYoungObject: objOop
  	<api>
  	"Answer if obj is young. Require that obj is non-immediate. Override to filter-out Cog methods"
  	self assert: (self isNonImmediate: objOop).
+ 	^(self oop: objOop isLessThan: oldSpaceStart)
- 	^(self oop: objOop isLessThan: newSpaceLimit)
  	  and: [self oop: objOop isGreaterThanOrEqualTo: newSpaceStart]!

Item was changed:
  ----- Method: Spur64BitCoMemoryManager>>checkMemoryMap (in category 'debug support') -----
  checkMemoryMap
  	"Override to check that Cog methods are considered neither young nor old.
  	 Being young would cause them to be scavenged.
  	 Being old would cause them to be remembered if stored into (but wait, they don't get stored into)."
  
+ 	super checkMemoryMap.
- 	self assert: (self isYoungObject: newSpaceStart).
- 	self assert: (self isYoungObject: newSpaceLimit - self wordSize).
- 	self assert: (self isOldObject: newSpaceStart) not.
- 	self assert: (self isOldObject: newSpaceLimit - self wordSize) not.
- 	self assert: (self isYoungObject: newSpaceLimit) not.
- 	self assert: (self isYoungObject: oldSpaceStart) not.
- 	self assert: (self isYoungObject: endOfMemory) not.
- 	self assert: (self isOldObject: oldSpaceStart).
- 	self assert: (self isOldObject: endOfMemory).
  
  	"we would like the following to be true, but we either choose one boundary check for
  	 cogMethods vs objects (isMachineCodeFrame: et al) or one boundary check for
  	 copyAndForward:.  We can't have both, and the former is likely the highest dynamic
  	 frequency."
  	false ifTrue:
  		[self assert: (self isYoungObject: cogit minCogMethodAddress) not.
  		 self assert: (self isYoungObject: cogit maxCogMethodAddress) not].
  	self assert: (self isOldObject: cogit minCogMethodAddress) not.
  	self assert: (self isOldObject: cogit maxCogMethodAddress) not!

Item was changed:
  ----- Method: Spur64BitCoMemoryManager>>initializeFreeSpaceForFacadeFrom:to: (in category 'simulation only') -----
  initializeFreeSpaceForFacadeFrom: base to: limit
  	"c.f. initializeFreeSpacePostLoad: freeListObj."
  	| freeListObj freeBytes |
+ 	oldSpaceStart := freeStart := base.
- 	newSpaceLimit := oldSpaceStart := freeStart := base.
  	endOfMemory := limit.
  	scavengeThreshold := limit * 3 // 4.
  	segmentManager initSegmentForInImageCompilationFrom: base to: limit.
  	freeListObj := self allocateSlots: self numFreeLists
  						format: self wordIndexableFormat
  						classIndex: self wordSizeClassIndexPun.
  	freeLists := self firstIndexableField: freeListObj.
  	freeListsMask := 0.
  	0 to: self numFreeLists - 1 do:
  		[:i|
  		(freeLists at: i) ~= 0 ifTrue:
  			[freeListsMask := freeListsMask bitOr: (1 << i).
  			 freeLists at: i put: (segmentManager swizzleObj: (freeLists at: i))]].
  	freeBytes := segmentManager lastSegment segLimit - self bridgeSize - freeStart.
  	freeLists at: 0 put: (self initFreeChunkWithBytes: freeBytes at: freeStart).
  	totalFreeOldSpace := freeBytes!

Item was changed:
  ----- Method: Spur64BitCoMemoryManager>>isReallyYoungObject: (in category 'object testing') -----
  isReallyYoungObject: objOop
  	<api>
  	"Answer if obj is young. Require that obj is non-immediate. Override to filter-out Cog methods"
  	self assert: (self isNonImmediate: objOop).
+ 	^(self oop: objOop isLessThan: oldSpaceStart)
- 	^(self oop: objOop isLessThan: newSpaceLimit)
  	  and: [self oop: objOop isGreaterThanOrEqualTo: newSpaceStart]!

Item was changed:
  CogClass subclass: #SpurMemoryManager
(excessive size, no diff calculated)

Item was changed:
  ----- Method: SpurMemoryManager class>>declareCVarsIn: (in category 'translation') -----
  declareCVarsIn: aCCodeGenerator
  	self class == thisContext methodClass ifFalse: [^self]. "Don't duplicate decls in subclasses"
  	aCCodeGenerator removeVariable: 'memory'. "memory is a simulation time thing only"
+ 	self declareCAsOop: #(	freeStart scavengeThreshold newSpaceStart pastSpaceStart
+ 							oldSpaceStart lowSpaceThreshold freeOldSpaceStart endOfMemory)
- 	self declareCAsOop: #(	freeStart scavengeThreshold newSpaceStart newSpaceLimit pastSpaceStart
- 							lowSpaceThreshold freeOldSpaceStart oldSpaceStart endOfMemory)
  		in: aCCodeGenerator.
  	self declareCAsUSqLong: (self allInstVarNames select: [:ivn| ivn endsWith: 'Usecs']), #(statAllocatedBytes)
  		in: aCCodeGenerator.
  	aCCodeGenerator
  		var: #lastHash type: #usqInt;
  		var: #freeListsMask type: #usqInt;
  		var: #freeLists type: #'sqInt *';
  		var: #objStackInvalidBecause type: #'char *';
  		var: #unscannedEphemerons type: #SpurContiguousObjStack;
  		var: #heapGrowthToSizeGCRatio type: #float;
  		var: #heapSizeAtPreviousGC type: #usqInt;
  		var: #totalFreeOldSpace type: #usqInt;
  		var: #maxOldSpaceSize type: #usqInt.
  	aCCodeGenerator
  		var: #oldSpaceUsePriorToScavenge type: #sqLong.
  	aCCodeGenerator
  		var: #remapBuffer
  		declareC: 'sqInt remapBuffer[RemapBufferSize + 1 /* ', (RemapBufferSize + 1) printString, ' */]'.
  	aCCodeGenerator
  		var: #extraRoots
  		declareC: 'sqInt *extraRoots[ExtraRootsSize + 1 /* ', (ExtraRootsSize + 1) printString, ' */]'!

Item was changed:
  ----- Method: SpurMemoryManager>>allocateMemoryOfSize:newSpaceSize:stackSize:codeSize: (in category 'spur bootstrap') -----
  allocateMemoryOfSize: memoryBytes newSpaceSize: newSpaceBytes stackSize: stackBytes codeSize: codeBytes
  	"Intialize the receiver for bootsraping an image.
  	 Set up a large oldSpace and an empty newSpace and set-up freeStart and scavengeThreshold
  	 to allocate in oldSpace.  Later on (in initializePostBootstrap) freeStart and scavengeThreshold
  	 will be set to sane values."
  	<doNotGenerate>
  	self assert: (memoryBytes \\ self allocationUnit = 0
  				and: [newSpaceBytes \\ self allocationUnit = 0
  				and: [codeBytes \\ self allocationUnit = 0]]).
  	self allocateMemoryOfSize: memoryBytes + newSpaceBytes + codeBytes + stackBytes.
  	newSpaceStart := codeBytes + stackBytes.
  	endOfMemory := freeOldSpaceStart := memoryBytes + newSpaceBytes + codeBytes + stackBytes.
  	"leave newSpace empty for the bootstrap"
  	freeStart := newSpaceBytes + newSpaceStart.
+ 	oldSpaceStart := newSpaceBytes + newSpaceStart.
- 	oldSpaceStart := newSpaceLimit := newSpaceBytes + newSpaceStart.
  	scavengeThreshold := memory size * memory bytesPerElement. "i.e. /don't/ scavenge."
  	scavenger := SpurGenerationScavenger simulatorClass new.
  	scavenger manager: self.
  	scavenger newSpaceStart: newSpaceStart
  				newSpaceBytes: newSpaceBytes
  				survivorBytes: newSpaceBytes // self scavengerDenominator.
  	compactor := self class compactorClass simulatorClass new manager: self; yourself!

Item was changed:
  ----- Method: SpurMemoryManager>>checkMemoryMap (in category 'debug support') -----
  checkMemoryMap
  	self assert: (self isYoungObject: newSpaceStart).
- 	self assert: (self isYoungObject: newSpaceLimit - self wordSize).
  	self assert: (self isOldObject: newSpaceStart) not.
+ 	self assert: (self isYoungObject: oldSpaceStart - self wordSize).
+ 	self assert: (self isOldObject: oldSpaceStart - self wordSize) not.
- 	self assert: (self isOldObject: newSpaceLimit - self wordSize) not.
- 	self assert: (self isYoungObject: newSpaceLimit) not.
  	self assert: (self isYoungObject: oldSpaceStart) not.
- 	self assert: (self isYoungObject: endOfMemory) not.
- 	self assert: (self isOldObject: newSpaceLimit).
  	self assert: (self isOldObject: oldSpaceStart).
+ 	self assert: (self isYoungObject: endOfMemory) not.
  	self assert: (self isOldObject: endOfMemory)!

Item was changed:
  ----- Method: SpurMemoryManager>>checkOkayYoungReferrer: (in category 'debug support') -----
  checkOkayYoungReferrer: obj
  	"Verify that the given obj is a valid youngReferrer. Check remembered is set and
  	 is in remembered set.  Answer true if OK.  Otherwise print reason and answer false.
  	 Assumes the object contains young references."
  
+ 	(self oop: obj isLessThan: oldSpaceStart) ifTrue:
- 	(self oop: obj isLessThan: newSpaceLimit) ifTrue:
  		[^true].
  
  	(self isRemembered: obj) ifFalse:
  		[ self print: 'remembered bit is not set in '; printHex: obj; cr. ^false ].
  
  	(scavenger isInRememberedSet: obj) ifTrue: [^true].
  
  	self printHex: obj; print: ' has remembered bit set but is not in remembered set'; cr.
  
  	^false
  !

Item was changed:
  ----- Method: SpurMemoryManager>>flushNewSpace (in category 'gc - scavenging') -----
  flushNewSpace
  	"Fush everything in new space.  Do so by setting the tenure
+ 	 threshold above everything in newSpace, i.e. oldSpaceStart."
- 	 threshold above everything in newSpace, i.e. newSpaceLimit."
  	| savedTenuringThreshold |
  	savedTenuringThreshold := scavenger getRawTenuringThreshold.
+ 	scavenger setRawTenuringThreshold: oldSpaceStart.
- 	scavenger setRawTenuringThreshold: newSpaceLimit.
  	self scavengingGCTenuringIf: TenureByAge.
  	scavenger setRawTenuringThreshold: savedTenuringThreshold.
  	self assert: scavenger rememberedSetSize = 0.
  	self assert: pastSpaceStart = scavenger pastSpace start.
  	self assert: freeStart = scavenger eden start!

Item was changed:
  ----- Method: SpurMemoryManager>>isInNewSpace: (in category 'object testing') -----
  isInNewSpace: objOop
+ 	^(self oop: objOop isLessThan: oldSpaceStart)
- 	^(self oop: objOop isLessThan: newSpaceLimit)
  	  and: [self oop: objOop isGreaterThanOrEqualTo: newSpaceStart]!

Item was changed:
  ----- Method: SpurMemoryManager>>isYoung: (in category 'object testing') -----
  isYoung: oop
  	<api>
  	"Answer if oop is young."
  	^(self isNonImmediate: oop)
+ 	 and: [self oop: oop isLessThan: oldSpaceStart]!
- 	 and: [self oop: oop isLessThan: newSpaceLimit]!

Item was changed:
  ----- Method: SpurMemoryManager>>isYoungObject: (in category 'object testing') -----
  isYoungObject: objOop
  	<api>
  	"Answer if obj is young. Require that obj is non-immediate."
  	self assert: (self isNonImmediate: objOop).
+ 	^self oop: objOop isLessThan: oldSpaceStart!
- 	^self oop: objOop isLessThan: newSpaceLimit!

Item was removed:
- ----- Method: SpurMemoryManager>>newSpaceLimit (in category 'accessing') -----
- newSpaceLimit
- 	<cmacro: '() GIV(newSpaceLimit)'>
- 	^newSpaceLimit!

Item was changed:
  ----- Method: SpurMemoryManager>>objectAfter: (in category 'object enumeration') -----
  objectAfter: objOop
  	<api>
  	"Object parsing.
  	1. all objects have at least a word following the header, for a forwarding pointer.
  	2. objects with an overflow size have a preceeing word with a saturated slotSize.  If the word following
  	    an object doesn't have a saturated size field it must be a single-header object.  If the word following
  	   does have a saturated slotSize it must be the overflow size word."
  	<inline: false>
+ 	(self oop: objOop isLessThan: oldSpaceStart) ifTrue:
- 	(self oop: objOop isLessThan: newSpaceLimit) ifTrue:
  		[(self isInEden: objOop) ifTrue:
  			[^self objectAfter: objOop limit: freeStart].
  		 (self isInPastSpace: objOop) ifTrue:
  			[^self objectAfter: objOop limit: pastSpaceStart].
  		 ^self objectAfter: objOop limit: scavenger futureSurvivorStart].
  	^self objectAfter: objOop limit: endOfMemory!

Item was changed:
  ----- Method: SpurMemoryManager>>objectBefore: (in category 'object enumeration') -----
  objectBefore: objOop
  	<api>
  	| prev |
  	prev := nil.
+ 	(self oop: objOop isLessThan: oldSpaceStart) ifTrue:
- 	(self oop: objOop isLessThan: newSpaceLimit) ifTrue:
  		[self allNewSpaceEntitiesDo:
  			[:o|
  			 (self oop: o isGreaterThanOrEqualTo: objOop) ifTrue:
  				[^prev].
  			 prev := o].
  		 ^prev].
  	self allOldSpaceEntitiesDo:
  		[:o|
  		 (self oop: o isGreaterThanOrEqualTo: objOop) ifTrue:
  			[^prev].
  		 prev := o].
  	^prev!

Item was changed:
  ----- Method: SpurMemoryManager>>scavengingGCTenuringIf: (in category 'gc - scavenging') -----
  scavengingGCTenuringIf: tenuringCriterion
  	"Run the scavenger."
  	<inline: false>
  	self assert: remapBufferCount = 0.
  	(self asserta: scavenger eden limit - freeStart > coInterpreter interpreterAllocationReserveBytes) ifFalse:
  		[coInterpreter tab;
  			printNum: scavenger eden limit - freeStart; space;
  			printNum: coInterpreter interpreterAllocationReserveBytes; space;
  			printNum: coInterpreter interpreterAllocationReserveBytes - (scavenger eden limit - freeStart); cr].
  	self checkMemoryMap.
  	self checkFreeSpace: GCModeNewSpace.
  	self runLeakCheckerFor: GCModeNewSpace.
  
  	coInterpreter
  		preGCAction: GCModeNewSpace;
  		"would prefer this to be in mapInterpreterOops, but
  		 compatibility with ObjectMemory dictates it goes here."
+ 		flushMethodCacheFrom: newSpaceStart to: oldSpaceStart.
- 		flushMethodCacheFrom: newSpaceStart to: newSpaceLimit.
  	needGCFlag := false.
  
  	gcStartUsecs := coInterpreter ioUTCMicrosecondsNow.
  
  	self doScavenge: tenuringCriterion.
  
  	statScavenges := statScavenges + 1.
  	statGCEndUsecs := coInterpreter ioUTCMicrosecondsNow.
  	statSGCDeltaUsecs := statGCEndUsecs - gcStartUsecs.
  	statScavengeGCUsecs := statScavengeGCUsecs + statSGCDeltaUsecs.
  	statRootTableCount := scavenger rememberedSetSize.
  
  	scavenger logScavenge.
  
  	coInterpreter postGCAction: GCModeNewSpace.
  
  	self runLeakCheckerFor: GCModeNewSpace.
  	self checkFreeSpace: GCModeNewSpace!

Item was changed:
  ----- Method: SpurMemoryManager>>setHeapBase:memoryLimit:endOfMemory: (in category 'snapshot') -----
  setHeapBase: baseOfHeap memoryLimit: memLimit endOfMemory: memEnd
  	"Set the dimensions of the heap, answering the start of oldSpace. edenBytes holds the desired ``size of eden''
  	 which is actually the total size of new space minus the reserve.  edenBytes is then divided up between eden
  	 and the two survivor spaces, where each survivor space is a scavengerDenominator (one seventh) of the total."
  	"Transcript
  		cr; nextPutAll: 'heapBase: '; print: baseOfHeap; nextPut: $/; nextPutAll: baseOfHeap hex;
  		nextPutAll: ' memLimit '; print: memLimit; nextPut: $/; nextPutAll: memLimit hex;
  		nextPutAll: ' memEnd '; print: memEnd; nextPut: $/; nextPutAll: memEnd hex; cr; flush."
  	"This is more than a little counter-intuitive.  Eden must include interpreterAllocationReserveBytes."
  	<inline: #never>
  	| reserve |
  	reserve := coInterpreter interpreterAllocationReserveBytes.
  	newSpaceStart := baseOfHeap.
+ 	oldSpaceStart := baseOfHeap + edenBytes + reserve.
- 	newSpaceLimit := baseOfHeap + edenBytes + reserve.
  	scavenger newSpaceStart: newSpaceStart
+ 				newSpaceBytes: oldSpaceStart - newSpaceStart
+ 				survivorBytes: oldSpaceStart - newSpaceStart - reserve // self scavengerDenominator.
- 				newSpaceBytes: newSpaceLimit - newSpaceStart
- 				survivorBytes: newSpaceLimit - newSpaceStart - reserve // self scavengerDenominator.
  
  	freeStart := scavenger eden start.
  	pastSpaceStart := scavenger pastSpace start.
  
- 	oldSpaceStart := newSpaceLimit.
  	freeOldSpaceStart := memEnd.
  	endOfMemory := memLimit.
  
  	^baseOfHeap!

Item was changed:
  ----- Method: SpurMemoryManager>>storeCheckBoundary (in category 'accessing') -----
  storeCheckBoundary
+ 	"A renaming for the Cogit, which can't make sense of GIV(oldSpaceStart)"
- 	"A renaming for the Cogit, which couldn't make sense of GIV(newSpaceLimit)"
  	<api>
+ 	^oldSpaceStart!
- 	^newSpaceLimit!

Item was changed:
  ----- Method: SpurSegmentManager>>initializeFromFreeChunks: (in category 'simulation only') -----
  initializeFromFreeChunks: freeChunks
  	<doNotGenerate>
  	"For testing, create a set of segments using the freeChunks as bridges."
  	self assert: (freeChunks allSatisfy: [:f| manager hasOverflowHeader: f]).
  	numSegments := freeChunks size.
  	freeChunks do:
  		[:f|
  		manager initSegmentBridgeWithBytes: (manager bytesInBody: f) at: (manager startOfObject: f).
  		self assert: (manager isSegmentBridge: f)].
  	segments := (1 to: numSegments) collect:
  					[:i| | bridge start size |
  					bridge := freeChunks at: i.
  					start := i = 1
+ 								ifTrue: [manager oldSpaceStart]
- 								ifTrue: [manager newSpaceLimit]
  								ifFalse: [manager addressAfter: (freeChunks at: i - 1)].
  					size := bridge + manager baseHeaderSize - start.
  					SpurSegmentInfo new
  						segStart: start;
  						segSize: size;
  						yourself].
  	manager setEndOfMemory: segments last segLimit.
  	segments := CArrayAccessor on: segments.
  	freeChunks with: segments object do:
  		[:bridge :segment|
  		self assert: (self isValidSegmentBridge: bridge).
  		self assert: bridge = (self bridgeFor: segment)]!



More information about the Vm-dev mailing list