Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.3347.mcz
==================== Summary ====================
Name: VMMaker.oscog-eem.3347 Author: eem Time: 24 January 2024, 8:37:34.392423 pm UUID: 7e4df21b-b561-434b-b2d3-45e8806d7875 Ancestors: VMMaker.oscog-topa.3346
Integrate Jörg Belger's fixes to growing memory by the right ammount when the first attempt fails at growing the remembered set and/or an obj stack.
Revert the regression introduced by the non-fix for inlining in VMMaker.oscog-eem.3340. It needs more careful work (and currently affects only the threaded VM).
Inline CogObjectRepresentationForSpur>>#cacheTagIsMarked: always. Fix a typo.
=============== Diff against VMMaker.oscog-topa.3346 ===============
Item was changed: ----- Method: CCodeGenerator>>structClassForType: (in category 'C code generator') ----- structClassForType: structureTypeString + | index structureTypeName | - | index sturctureTypeName | index := structureTypeString findFirst: [:c| c isLetter not]. + structureTypeName := index = 0 - sturctureTypeName := index = 0 ifTrue: [structureTypeString] ifFalse: [structureTypeString first: index - 1]. + ^(Smalltalk classNamed: structureTypeName) ifNil: - ^(Smalltalk classNamed: sturctureTypeName) ifNil: [VMStructType allSubclasses + detect: [:sc| sc structTypeName = structureTypeName] - detect: [:sc| sc structTypeName = sturctureTypeName] ifNone: nil]!
Item was changed: ----- Method: CogObjectRepresentationForSpur>>cacheTagIsMarked: (in category 'garbage collection') ----- cacheTagIsMarked: cacheTag "Answer if the cacheTag is not unmarked, i.e. answer true for compact class indices and immediates; only answer false for unmarked objects. In Spur linked send cache tags are class indices so effectively they're always marked." + <inline: #always> ^true!
Item was changed: ----- Method: SpurGenerationScavenger>>growRememberedSet (in category 'remembered set') ----- growRememberedSet | obj numSlots newObj base | <inline: false> "Don't ruin locality in remember:" <var: #base type: #'sqInt *'> obj := manager rememberedSetObj. numSlots := manager numSlotsOf: obj. self assert: numSlots >= 1024. newObj := manager allocatePinnedSlots: numSlots * 2. newObj ifNil: [newObj := manager allocatePinnedSlots: numSlots + 1024. newObj ifNil: + [(manager growOldSpaceByAtLeast: (numSlots + 1024) * self bytesPerOop) ifNil: [self error: 'could not grow remembered set']. - [(manager growOldSpaceByAtLeast: numSlots + 1024) ifNil: [self error: 'could not grow remembered set']. newObj := manager allocatePinnedSlots: numSlots + 1024. "cannot fail"]]. manager rememberedSetObj: newObj. base := manager firstIndexableField: newObj. 0 to: rememberedSetSize - 1 do: [:i| base at: i put: (rememberedSet at: i)]. "if growing in the middle of a GC, need to preserve marked status." (manager isMarked: obj) ifTrue: [manager setIsMarkedOf: newObj to: true; setIsMarkedOf: obj to: false]. manager freeObject: obj. rememberedSet := base. rememberedSetLimit := manager numSlotsOf: newObj. self setRememberedSetRedZone!
Item was changed: ----- Method: SpurMemoryManager>>ensureRoomOnObjStackAt: (in category 'obj stacks') ----- ensureRoomOnObjStackAt: objStackRootIndex "An obj stack is a stack of objects stored in a hidden root slot, such as the markStack or the ephemeronQueue. It is a linked list of segments, with the hot end at the head of the list. It is a word object. The stack pointer is in ObjStackTopx and 0 means empty. The list goes through ObjStackNextx. We don't want to shrink objStacks, since they're used in GC and its good to keep their memory around. So unused pages created by popping emptying pages are kept on the ObjStackFreex list." | stackOrNil freeOrNewPage | stackOrNil := self fetchPointer: objStackRootIndex ofObject: hiddenRootsObj. (stackOrNil = nilObj or: [(self fetchPointer: ObjStackTopx ofObject: stackOrNil) >= ObjStackLimit]) ifTrue: [freeOrNewPage := stackOrNil = nilObj ifTrue: [0] ifFalse: [self fetchPointer: ObjStackFreex ofObject: stackOrNil]. freeOrNewPage ~= 0 ifTrue: "the free page list is always on the new page." [self storePointer: ObjStackFreex ofObjStack: stackOrNil withValue: 0. self assert: (marking not or: [self isMarked: freeOrNewPage])] ifFalse: [freeOrNewPage := self allocateSlotsInOldSpace: ObjStackPageSlots format: self wordIndexableFormat classIndex: self wordSizeClassIndexPun. freeOrNewPage ifNil: ["Allocate a new segment an retry. This is very uncommon. But it happened to me (Clement)." + self growOldSpaceByAtLeast: ObjStackPageSlots * self bytesPerOop. - self growOldSpaceByAtLeast: ObjStackPageSlots. freeOrNewPage := self allocateSlotsInOldSpace: ObjStackPageSlots format: self wordIndexableFormat classIndex: self wordSizeClassIndexPun. freeOrNewPage ifNil: [self error: 'no memory to allocate or extend obj stack']]. self storePointer: ObjStackFreex ofObjStack: freeOrNewPage withValue: 0. marking ifTrue: [self setIsMarkedOf: freeOrNewPage to: true]]. self storePointer: ObjStackMyx ofObjStack: freeOrNewPage withValue: objStackRootIndex; storePointer: ObjStackNextx ofObjStack: freeOrNewPage withValue: (stackOrNil = nilObj ifTrue: [0] ifFalse: [stackOrNil]); storePointer: ObjStackTopx ofObjStack: freeOrNewPage withValue: 0; storePointer: objStackRootIndex ofObject: hiddenRootsObj withValue: freeOrNewPage. self assert: (self isValidObjStackAt: objStackRootIndex). "Added a new page; now update and answer the relevant cached first page." stackOrNil := self updateRootOfObjStackAt: objStackRootIndex with: freeOrNewPage]. self assert: (self isValidObjStackAt: objStackRootIndex). ^stackOrNil!
Item was added: + ----- Method: TMethod>>isStructMethod (in category 'testing') ----- + isStructMethod + ^[definingClass isStructClass] + on: MessageNotUnderstood + do: [:ex| false]!
Item was changed: ----- Method: TMethod>>renameVarsForInliningInto:except:in: (in category 'inlining support') ----- renameVarsForInliningInto: destMethod except: doNotRename in: aCodeGen "Rename any variables that would clash with those of the destination method."
| destVars usedVars varMap newVarName | destVars := aCodeGen globalsAsSet copy. destVars addAll: destMethod locals. destVars addAll: destMethod args. usedVars := destVars copy. "keeps track of names in use" usedVars addAll: args; addAll: locals. varMap := Dictionary new: 100. locals, args do: [ :v | ((doNotRename includes: v) not and: [destVars includes: v]) ifTrue: [newVarName := self unusedNamePrefixedBy: v avoiding: usedVars. varMap at: v put: newVarName]]. - self protectToBeExcludedReceiversForInlining. self renameVariablesUsing: varMap!
Item was changed: ----- Method: TSendNode>>nodeIsThisSendsStructReceiver: (in category 'inlining support') ----- + nodeIsThisSendsStructReceiver: aTParseNode - nodeIsThisSendsStructReceiver: aTParseNode - selector == #'atomic_store:_:' ifTrue: [self halt]. ^aTParseNode == receiver and: [receiver name beginsWith: 'self_in_']!
vm-dev@lists.squeakfoundation.org