Eliot Miranda uploaded a new version of VMMaker to project VM Maker: http://source.squeak.org/VMMaker/VMMaker.oscog-eem.1867.mcz ==================== Summary ==================== Name: VMMaker.oscog-eem.1867 Author: eem Time: 25 May 2016, 9:38:19.765577 pm UUID: 17d41c8f-18a0-4dd0-8b35-1eba4ffa1d53 Ancestors: VMMaker.oscog-eem.1866 Fixes for ephemerons. Fix bug in markAllUnscannedEphemerons. Now Gille's test case works for 50k elements, but not yet for 200k. Fix asserts in various functions. =============== Diff against VMMaker.oscog-eem.1866 =============== Item was changed: ----- Method: SpurGenerationScavenger>>fireEphemeronsOnEphemeronList (in category 'weakness and ephemerality') ----- fireEphemeronsOnEphemeronList "There are ephemerons to be fired in the remembered set. Fire them and scavenge their keys. Be careful since copyAndForward: can remember ephemerons (ephemerons pointing to ephemerons)." | ephemeron ephemeronCorpse key oldList oldCorpse | "old ones for debugging" ephemeronList ifNil: [^self]. oldCorpse := nil. ephemeronCorpse := self firstCorpse: ephemeronList. "Reset the list head so that new ephemerons will get added to a new list, not concatenated on the one we are scanning." oldList := ephemeronList. ephemeronList := nil. + [ephemeronCorpse notNil] whileTrue: + [self assert: ((manager isYoung: ephemeronCorpse) and: [manager isForwarded: ephemeronCorpse]). - [self assert: (manager isYoung: ephemeronCorpse). - ephemeronCorpse notNil] whileTrue: - [self assert: (manager isForwarded: ephemeronCorpse). ephemeron := manager followForwarded: ephemeronCorpse. key := manager keyOfMaybeFiredEphemeron: ephemeron. (self isScavengeSurvivor: key) ifFalse: [coInterpreter fireEphemeron: ephemeron. manager storePointerUnchecked: 0 ofObject: ephemeron withValue: (self copyAndForward: key)]. "Fired ephemerons should have had their format changed." self deny: ((self isScavengeSurvivor: key) and: [manager isEphemeron: ephemeron]). self cCoerceSimple: (self scavengeReferentsOf: ephemeron) to: #void. oldCorpse := ephemeronCorpse. ephemeronCorpse := self nextCorpseOrNil: ephemeronCorpse]! Item was changed: ----- Method: SpurMemoryManager>>allUnscannedEphemeronsAreActive (in category 'weakness and ephemerality') ----- allUnscannedEphemeronsAreActive unscannedEphemerons start to: unscannedEphemerons top - self bytesPerOop by: self bytesPerOop do: [:p| | key | + key := self keyOfMaybeFiredEphemeron: (self longAt: p). - key := self keyOfEphemeron: (self longAt: p). ((self isImmediate: key) or: [self isMarked: key]) ifTrue: [^false]]. ^true! Item was added: + ----- Method: SpurMemoryManager>>followedKeyOfMaybeFiredEphemeron: (in category 'object access') ----- + followedKeyOfMaybeFiredEphemeron: objOop + "Answer the object the ephemeron guards. This is its first element." + self assert: ((self isNonImmediate: objOop) and: [self isMaybeFiredEphemeron: objOop]). + ^self followOopField: 0 ofObject: objOop! Item was changed: ----- Method: SpurMemoryManager>>is:onObjStack: (in category 'obj stacks') ----- is: oop onObjStack: objStack <inline: false> | index nextPage | + objStack = nilObj ifTrue: + [^false]. self assert: (self numSlotsOfAny: objStack) = ObjStackPageSlots. "There are four fixed slots in an obj stack, and a Topx of 0 indicates empty, so if there were 6 slots in an oop stack, full would be 2, and the last 0-rel index is 5." index := (self fetchPointer: ObjStackTopx ofObject: objStack) + ObjStackNextx. [index >= ObjStackFixedSlots] whileTrue: [oop = (self fetchPointer: index ofObject: objStack) ifTrue: [^true]. index := index - 1]. nextPage := self fetchPointer: ObjStackNextx ofObject: objStack. nextPage ~= 0 ifTrue: [(self is: oop onObjStack: nextPage) ifTrue: [^true]]. ^false! Item was changed: ----- Method: SpurMemoryManager>>markAllUnscannedEphemerons (in category 'weakness and ephemerality') ----- markAllUnscannedEphemerons "After firing the unscanned ephemerons we must scan-mark them. + The wrinkle is that doing so may add more ephemerons to the set. + So we remove the first element, by overwriting it with the last element, + and decrementing the top, and then markAndTrace its contents." - The wrinkle is that doing so may add more ephemerons to the set." - | ptr | self assert: (self noUnscannedEphemerons) not. self assert: self allUnscannedEphemeronsAreActive. + [unscannedEphemerons top > unscannedEphemerons start] whileTrue: + [| ephemeron key lastptr | + ephemeron := self longAt: unscannedEphemerons start. + lastptr := unscannedEphemerons top - self bytesPerOop. + lastptr > unscannedEphemerons start ifTrue: + [self longAt: unscannedEphemerons start put: (self longAt: lastptr)]. + unscannedEphemerons top: lastptr. + key := self followedKeyOfMaybeFiredEphemeron: ephemeron. + self setIsMarkedOf: ephemeron to: false. "to get it to be fully scanned in markAndTrace:" - ptr := unscannedEphemerons top - self wordSize. - [ptr >= unscannedEphemerons start] whileTrue: - [| ephemeron key | - key := self followedKeyOfEphemeron: (ephemeron := self longAt: ptr). self markAndTrace: key; + markAndTrace: ephemeron]! - markAndTrace: ephemeron. - unscannedEphemerons top: unscannedEphemerons top - self bytesPerOop. - ptr < unscannedEphemerons top ifTrue: - ["not the last entry; remove it by overwriting it with the last - ephemeron (which must have been newly added by markAndTrace:)." - self longAt: ptr put: (self longAt: unscannedEphemerons top)]. - ptr := ptr - self bytesPerOop]! Item was changed: ----- Method: SpurMemoryManager>>noCheckPush:onObjStack: (in category 'obj stacks') ----- noCheckPush: objOop onObjStack: objStack "Push an element on an objStack. Split from push:onObjStack: for testing." | topx | self eassert: [self isValidObjStack: objStack]. + self cCode: '' "for debugging markAndTrace: set (MarkStackRecord := OrderedCollection new)" - self cCode: [] "for debugging markAndTrace: set (MarkStackRecord := OrderedCollection new)" inSmalltalk: + [MarkStackRecord ifNotNil: + [(self fetchPointer: ObjStackMyx ofObject: objStack) = MarkStackRootIndex ifTrue: + [MarkStackRecord addLast: {#push. objOop}]]]. - [(self fetchPointer: ObjStackMyx ofObject: objStack) = MarkStackRootIndex ifTrue: - [MarkStackRecord ifNotNil: [MarkStackRecord addLast: {#push. objOop}]]]. topx := self fetchPointer: ObjStackTopx ofObject: objStack. topx >= ObjStackLimit ifTrue: [self noCheckPush: objOop onObjStack: (self ensureRoomOnObjStackAt: (self fetchPointer: ObjStackMyx ofObject: objStack))] ifFalse: [self storePointer: ObjStackFixedSlots + topx ofObjStack: objStack withValue: objOop. self storePointer: ObjStackTopx ofObjStack: objStack withValue: topx + 1]. ^objOop! Item was changed: ----- Method: SpurMemoryManager>>queueMourner: (in category 'weakness and ephemerality') ----- queueMourner: anEphemeronOrWeakArray "Add the ephemeron to the queue and make it non-ephemeral, to avoid subsequent firing. Alas this means that other ephemerons on the same object not identified in this sccavenge or GC will not fire until later. But that's life." self assert: ((self isNonImmediate: anEphemeronOrWeakArray) and: [(self formatOf: anEphemeronOrWeakArray) = self ephemeronFormat or: [(self formatOf: anEphemeronOrWeakArray) = self weakArrayFormat]]). + self deny: (self is: anEphemeronOrWeakArray onObjStack: mournQueue). - self deny: (mournQueue ~= nilObj - and: [self is: anEphemeronOrWeakArray onObjStack: mournQueue]). self ensureRoomOnObjStackAt: MournQueueRootIndex. + self push: anEphemeronOrWeakArray onObjStack: mournQueue! - self push: anEphemeronOrWeakArray onObjStack: mournQueue. - (self formatOf: anEphemeronOrWeakArray) = self ephemeronFormat ifTrue: - [self setFormatOf: anEphemeronOrWeakArray to: self nonIndexablePointerFormat]! Item was changed: ----- Method: StackInterpreter>>fireEphemeron: (in category 'finalization') ----- fireEphemeron: ephemeron <option: #SpurObjectMemory> + objectMemory queueMourner: ephemeron.. + self setFormatOf: ephemeron to: self nonIndexablePointerFormat. - objectMemory queueMourner: ephemeron. self signalFinalization: ephemeron! |
Free forum by Nabble | Edit this page |