[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