diff --git a/cmake/vmmaker.cmake b/cmake/vmmaker.cmake index a7fbbe20ce..fb0c56f60d 100644 --- a/cmake/vmmaker.cmake +++ b/cmake/vmmaker.cmake @@ -68,7 +68,7 @@ if(GENERATE_SOURCES) message("Defining Windows VM to download for code generation") set(VMMAKER_VM ${VMMAKER_DIR}/vm/PharoConsole.exe) set(VM_URL https://files.pharo.org/vm/pharo-spur64-headless/Windows-x86_64/PharoVM-10.0.5-2757766f-Windows-x86_64-bin.zip) - set(VM_URL_HASH SHA256=e7430f753ae51fbec8b6a6105f9721cd503d13d0e4ad8069f74da0f6a32c8055) + set(VM_URL_HASH SHA256=917dbbef15b870ecf5ecf449bd6be39437985c6e3f056620e9acda60ea58e09e) elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux" AND (${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")) message("Defining Linux AARCH64 VM to download for code generation") set(VMMAKER_VM ${VMMAKER_DIR}/vm/pharo) diff --git a/smalltalksrc/VMMaker/AbstractComposedImageAccess.class.st b/smalltalksrc/VMMaker/AbstractComposedImageAccess.class.st index 388d1fc53d..d4433fd457 100644 --- a/smalltalksrc/VMMaker/AbstractComposedImageAccess.class.st +++ b/smalltalksrc/VMMaker/AbstractComposedImageAccess.class.st @@ -20,7 +20,7 @@ AbstractComposedImageAccess >> createImageDirectory: imageFileName [ self cppIf: ((self defined: #_WIN32) or: [(self defined: #_WIN64)]) ifTrue: [ self mkdir: imageFileName ] - ifFalse: [ self mkdir: imageFileName _: 0777 ] ] + ifFalse: [ self mkdir: imageFileName _: 8r777 ] ] inSmalltalk: [ imageFileName asFileReference ensureDeleteAll. imageFileName asFileReference ensureCreateDirectory ] diff --git a/smalltalksrc/VMMaker/CoInterpreter.class.st b/smalltalksrc/VMMaker/CoInterpreter.class.st index de962511cd..401e0e98e3 100644 --- a/smalltalksrc/VMMaker/CoInterpreter.class.st +++ b/smalltalksrc/VMMaker/CoInterpreter.class.st @@ -753,7 +753,7 @@ CoInterpreter >> assertValidStackedInstructionPointersIn: aStackPage line: ln [ theIP = cogit ceReturnToInterpreterPC ifTrue: [theIP := self iframeSavedIP: theFP]. self assert: (theIP >= (methodObj + (objectMemory lastPointerOf: methodObj)) - and: [theIP < (methodObj + (objectMemory numBytesOfBytes: methodObj) + objectMemory baseHeaderSize - 1)]) + and: [theIP <= (methodObj + (objectMemory numBytesOfBytes: methodObj) + objectMemory baseHeaderSize - 1)]) l: ln. prevFrameWasCogged := false]. theIP := (stackPages unsignedLongAt: theFP + FoxCallerSavedIP) asUnsignedInteger. diff --git a/smalltalksrc/VMMaker/Spur32BitMMLESimulator.class.st b/smalltalksrc/VMMaker/Spur32BitMMLESimulator.class.st index 671c6cb76f..9d328c00c5 100644 --- a/smalltalksrc/VMMaker/Spur32BitMMLESimulator.class.st +++ b/smalltalksrc/VMMaker/Spur32BitMMLESimulator.class.st @@ -83,7 +83,7 @@ Spur32BitMMLESimulator >> fetchFloatAt: floatBitsAddress into: aFloat [ aFloat at: 1 put: (self uint32AtPointer: floatBitsAddress+4) ] -{ #category : #'object access' } +{ #category : #'as yet unclassified' } Spur32BitMMLESimulator >> fetchPointer: fieldIndex ofObject: objOop [ self assert: (self isForwarded: objOop) not. self assert: (fieldIndex >= 0 and: [fieldIndex < (self numSlotsOfAny: objOop) diff --git a/smalltalksrc/VMMaker/Spur32BitMemoryManager.class.st b/smalltalksrc/VMMaker/Spur32BitMemoryManager.class.st index 7667f3def9..b34928cd65 100644 --- a/smalltalksrc/VMMaker/Spur32BitMemoryManager.class.st +++ b/smalltalksrc/VMMaker/Spur32BitMemoryManager.class.st @@ -842,7 +842,6 @@ Spur32BitMemoryManager >> setIsImmutableOf: objOop to: aBoolean [ { #category : #'header access' } Spur32BitMemoryManager >> setIsMarkedOf: objOop to: aBoolean [ self assert: (self isFreeObject: objOop) not. - self assert: (memoryMap isPermanentObject: objOop) not. self flag: #endianness. self unsignedLongAt: objOop + 4 @@ -905,7 +904,7 @@ Spur32BitMemoryManager >> shorten: objOop toIndexableSize: indexableSize [ ofObject: copy withValue: (self fetchPointer: i ofObject: objOop)]. (self isRemembered: objOop) ifTrue: - [fromOldSpaceRememberedSet doRemember: copy]. + [fromOldSpaceRememberedSet remember: copy]. self forward: objOop to: copy. ^0]. diff --git a/smalltalksrc/VMMaker/Spur64BitMMLESimulator.class.st b/smalltalksrc/VMMaker/Spur64BitMMLESimulator.class.st index 38554164dd..e99eb4e323 100644 --- a/smalltalksrc/VMMaker/Spur64BitMMLESimulator.class.st +++ b/smalltalksrc/VMMaker/Spur64BitMMLESimulator.class.st @@ -83,7 +83,7 @@ Spur64BitMMLESimulator >> fetchFloatAt: floatBitsAddress into: aFloat [ aFloat at: 1 put: (self uint32AtPointer: floatBitsAddress+4) ] -{ #category : #'object access' } +{ #category : #'as yet unclassified' } Spur64BitMMLESimulator >> fetchPointer: fieldIndex ofObject: objOop [ self assert: (self isForwarded: objOop) not. self assert: (fieldIndex >= 0 and: [fieldIndex < (self numSlotsOfAny: objOop) diff --git a/smalltalksrc/VMMaker/Spur64BitMemoryManager.class.st b/smalltalksrc/VMMaker/Spur64BitMemoryManager.class.st index efc07dd9ea..c845e664a1 100644 --- a/smalltalksrc/VMMaker/Spur64BitMemoryManager.class.st +++ b/smalltalksrc/VMMaker/Spur64BitMemoryManager.class.st @@ -973,7 +973,6 @@ Spur64BitMemoryManager >> setIsImmutableOf: objOop to: aBoolean [ { #category : #'header access' } Spur64BitMemoryManager >> setIsMarkedOf: objOop to: aBoolean [ self assert: (self isFreeObject: objOop) not. - self assert: (memoryMap isPermanentObject: objOop) not. self unsignedLongAt: objOop put: (aBoolean @@ -1036,7 +1035,7 @@ Spur64BitMemoryManager >> shorten: objOop toIndexableSize: indexableSize [ ofObject: copy withValue: (self fetchPointer: i ofObject: objOop)]. (self isRemembered: objOop) ifTrue: - [fromOldSpaceRememberedSet doRemember: copy]. + [fromOldSpaceRememberedSet remember: copy]. self forward: objOop to: copy. ^0]. diff --git a/smalltalksrc/VMMaker/SpurGenerationScavenger.class.st b/smalltalksrc/VMMaker/SpurGenerationScavenger.class.st index 2bb2d64b14..630cdd0b42 100644 --- a/smalltalksrc/VMMaker/SpurGenerationScavenger.class.st +++ b/smalltalksrc/VMMaker/SpurGenerationScavenger.class.st @@ -376,7 +376,7 @@ SpurGenerationScavenger >> copyToOldSpace: survivor bytes: bytesInObject format: [:p| | field | field := manager longAt: survivor + p. (manager isReallyYoung: field) ifTrue: - [manager getFromOldSpaceRememberedSet doRemember: newOop. + [manager getFromOldSpaceRememberedSet remember: newOop. ^newOop]]]. ^newOop ] @@ -727,7 +727,7 @@ SpurGenerationScavenger >> logTenuringPolicy [ { #category : #scavenger } SpurGenerationScavenger >> mapOopsFromPermSpace [ - | destIndex sourceIndex referrer | + | destIndex sourceIndex referrer result | @@ -738,21 +738,31 @@ SpurGenerationScavenger >> mapOopsFromPermSpace [ It has to be in the remembered set if there are references to non permanent objects. I will be compacting the rememberedSet while iterating it" - [sourceIndex < manager getFromPermSpaceRememberedSet rememberedSetSize] whileTrue: - [ referrer := manager getFromPermSpaceRememberedSet objectAt: sourceIndex. + [sourceIndex < manager getFromPermToNewSpaceRememberedSet rememberedSetSize] whileTrue: + [ referrer := manager getFromPermToNewSpaceRememberedSet objectAt: sourceIndex. self deny: (manager isEphemeron: referrer). self deny: (manager isWeakNonImm: referrer). - (self scavengeReferentsOfFromPermSpace: referrer) + result := self scavengeReferentsOfFromPermSpace: referrer. + + result = 1 ifTrue: - [manager getFromPermSpaceRememberedSet save: referrer at: destIndex. + [ + "Refers new space, we keep it" + manager getFromPermToNewSpaceRememberedSet save: referrer at: destIndex. destIndex := destIndex + 1] ifFalse: - [ manager setIsRememberedOf: referrer to: false]. + [ + "We clean the remembered set flag, it is only marking if it is maybe pointing to new objects" + manager setIsRememberedOf: referrer to: false. + "Refers to Old Space, if refers to perm space only, I do nothing. I remove it from the remembered set fromPermSpaceToNewSpace" + result = 2 ifTrue: [ + manager getFromPermToOldSpaceRememberedSet rememberWithoutMarkingAsRemembered: referrer] + ]. sourceIndex := sourceIndex + 1]. - manager getFromPermSpaceRememberedSet setRememberedSetSize: destIndex. + manager getFromPermToNewSpaceRememberedSet setRememberedSetSize: destIndex. "self assert: (manager isPermSpaceRememberedSetSane)." ] @@ -779,7 +789,8 @@ SpurGenerationScavenger >> newSpaceStart: startAddress newSpaceBytes: totalBytes eden start: futureSpace limit; limit: startAddress + totalBytes. manager getFromOldSpaceRememberedSet fudge: self rememberedSetFudge. - manager getFromPermSpaceRememberedSet fudge: self rememberedSetFudge. + manager getFromPermToOldSpaceRememberedSet fudge: self rememberedSetFudge. + manager getFromPermToNewSpaceRememberedSet fudge: self rememberedSetFudge. self assert: self futureSpace limit <= (startAddress + totalBytes). self assert: self eden start \\ manager allocationUnit @@ -865,13 +876,21 @@ SpurGenerationScavenger >> printRememberedSet [ space; shortPrintOop: oop ]. - coInterpreter print: 'From Permpace:'; cr. + coInterpreter print: 'From Permpace to OldSpace:'; cr. - manager getFromPermSpaceRememberedSet rememberedSetWithIndexDo: [ :oop :i | + manager getFromPermToOldSpaceRememberedSet rememberedSetWithIndexDo: [ :oop :i | coInterpreter printNum: i; space; - shortPrintOop: oop ] + shortPrintOop: oop ]. + + coInterpreter print: 'From Permpace to NewSpace:'; cr. + + manager getFromPermToNewSpaceRememberedSet rememberedSetWithIndexDo: [ :oop :i | + coInterpreter + printNum: i; + space; + shortPrintOop: oop ] ] { #category : #'debug support' } @@ -985,7 +1004,7 @@ SpurGenerationScavenger >> processWeaklings [ ((self processWeakSurvivor: weakObj) and: [ (manager getMemoryMap isOldObject: weakObj) and: [ (manager isRemembered: weakObj) not ] ]) ifTrue: [ - manager getFromOldSpaceRememberedSet doRemember: weakObj ]. + manager getFromOldSpaceRememberedSet remember: weakObj ]. weakCorpse := self nextCorpseOrNil: weakCorpse ]. weakList := nil ] ] @@ -1114,7 +1133,7 @@ SpurGenerationScavenger >> scavengeLoop [ ] { #category : #scavenger } -SpurGenerationScavenger >> scavengeReferentsOf: referrer additionalShouldKeepReferrerTestingBlock: shouldKeepReferrerTestingBlock [ +SpurGenerationScavenger >> scavengeReferentsOf: referrer additionalTestingBlock: additionalTestingBlock [ "scavengeReferentsOf: referrer inspects all the pointers in referrer. If any are new objects, it has them moved to FutureSurvivorSpace, and answers truth. If there are no new referents, it answers falsity. To handle @@ -1156,12 +1175,12 @@ SpurGenerationScavenger >> scavengeReferentsOf: referrer additionalShouldKeepRef [newLocation := self copyAndForward: referent. (manager isYoung: newLocation) ifTrue: [foundNewReferentOrIsWeakling := true] - ifFalse: [(shouldKeepReferrerTestingBlock value: referrer value: newLocation) ifTrue: [ foundNewReferentOrIsWeakling := true ]]]. + ifFalse: [additionalTestingBlock value: referrer value: newLocation]]. manager storePointerUnchecked: i ofMaybeForwardedObject: referrer withValue: newLocation] ifFalse: [ manager storePointerUnchecked: i ofMaybeForwardedObject: referrer withValue: referent. - (shouldKeepReferrerTestingBlock value: referrer value: referent) ifTrue: [ foundNewReferentOrIsWeakling := true ]]]]. + additionalTestingBlock value: referrer value: referent]]]. ^foundNewReferentOrIsWeakling ] @@ -1170,7 +1189,9 @@ SpurGenerationScavenger >> scavengeReferentsOfFromOldSpace: referrer [ - ^ self scavengeReferentsOf: referrer additionalShouldKeepReferrerTestingBlock: [ :aReferrer :aReferent | false ]. + ^ self + scavengeReferentsOf: referrer + additionalTestingBlock: [ :aReferrer :aReferent | "Do nothing" ]. ] { #category : #scavenger } @@ -1178,15 +1199,20 @@ SpurGenerationScavenger >> scavengeReferentsOfFromPermSpace: referrer [ - | returnValue | + | returnValue refersOldSpace | + + refersOldSpace := false. returnValue := self scavengeReferentsOf: referrer - additionalShouldKeepReferrerTestingBlock: [ :aReferrer :referent | - (manager isPermanent: referent) not - and: [ (manager isFixedKnownObject: referent) not ] ]. + additionalTestingBlock: [ :aReferrer :referent | + (refersOldSpace not and: [ (manager isFixedKnownObject: referent) not and: [ (manager isPermanent: referent) not ]]) + ifTrue: [ refersOldSpace := true ] + ]. - ^ returnValue. + returnValue ifTrue: [ ^ 1 "Refers NewSpace" ]. + refersOldSpace ifTrue: [ ^ 2 "Refers OldSpace only" ]. + ^ 3 "Refers PermSpace only" ] { #category : #scavenger } diff --git a/smalltalksrc/VMMaker/SpurMemoryManager.class.st b/smalltalksrc/VMMaker/SpurMemoryManager.class.st index c3dd7b0f06..bef16f4507 100644 --- a/smalltalksrc/VMMaker/SpurMemoryManager.class.st +++ b/smalltalksrc/VMMaker/SpurMemoryManager.class.st @@ -617,7 +617,8 @@ Class { 'unscannedEphemeronsQueueInitialSize', 'permSpaceFreeStart', 'fromOldSpaceRememberedSet', - 'fromPermSpaceRememberedSet' + 'fromPermToOldSpaceRememberedSet', + 'fromPermToNewSpaceRememberedSet' ], #classVars : [ 'BitsPerByte', @@ -635,7 +636,8 @@ Class { 'ObjStackPageSlots', 'ObjStackTopx', 'OldRememberedSetRootIndex', - 'PermRememberedSetRootIndex', + 'PermToNewRememberedSetRootIndex', + 'PermToOldRememberedSetRootIndex', 'RemapBufferSize', 'WeaklingStackRootIndex' ], @@ -738,7 +740,8 @@ SpurMemoryManager class >> declareCVarsIn: aCCodeGenerator [ aCCodeGenerator var: #memoryMap type: #'VMMemoryMap *'; var: #fromOldSpaceRememberedSet type: #'VMRememberedSet *'; - var: #fromPermSpaceRememberedSet type: #'VMRememberedSet *' + var: #fromPermToOldSpaceRememberedSet type: #'VMRememberedSet *'; + var: #fromPermToNewSpaceRememberedSet type: #'VMRememberedSet *' ] { #category : #translation } @@ -790,7 +793,8 @@ SpurMemoryManager class >> initialize [ WeaklingStackRootIndex := MarkStackRootIndex + 1. MournQueueRootIndex := MarkStackRootIndex + 2. OldRememberedSetRootIndex := MarkStackRootIndex + 3. - PermRememberedSetRootIndex := MarkStackRootIndex + 4. + PermToOldRememberedSetRootIndex := MarkStackRootIndex + 4. + PermToNewRememberedSetRootIndex := MarkStackRootIndex + 5. MarkObjectsForEnumerationPrimitives := false. @@ -1801,6 +1805,13 @@ SpurMemoryManager >> allPermSpaceObjectsDo: aBlockClosure [ currentObject := self objectAfter: currentObject limit: permSpaceFreeStart ]. ] +{ #category : #'gc - global' } +SpurMemoryManager >> allPermSpaceObjectsUnmarked [ + self allPermSpaceObjectsDo: + [:o| (self isMarked: o) ifTrue: [bogon := o. ^false]]. + ^true +] + { #category : #'weakness and ephemerality' } SpurMemoryManager >> allStrongSlotsOfWeaklingAreMarked: aWeakling [ "N.B. generateToByDoLimitExpression:negative:on: guards against (unsigned)0 - 1 going +ve" @@ -2287,6 +2298,23 @@ SpurMemoryManager >> allocatePinnedSlots: nSlots [ ^obj ] +{ #category : #initialization } +SpurMemoryManager >> allocateRememberedSetWithRootIndex: rootIndex [ + + + + + | newRememberedSet | + + newRememberedSet := self cCoerce: (self malloc: + (self sizeof: VMRememberedSet)) + to: #'VMRememberedSet *'. + + newRememberedSet rootIndex: rootIndex. + + ^ newRememberedSet +] + { #category : #allocation } SpurMemoryManager >> allocateSlots: numSlots format: formatField classIndex: classIndex [ "Allocate an object with numSlots space. If there is room beneath scavengeThreshold @@ -3392,7 +3420,7 @@ SpurMemoryManager >> checkOkayYoungReferrer: obj [ [ self print: 'remembered bit is not set in '; printHex: obj; cr. ^false ]. (self getFromOldSpaceRememberedSet isInRememberedSet: obj) ifTrue: [^true]. - (self getFromPermSpaceRememberedSet isInRememberedSet: obj) ifTrue: [^true]. + (self getFromPermToNewSpaceRememberedSet isInRememberedSet: obj) ifTrue: [^true]. self printHex: obj; print: ' has remembered bit set but is not in remembered set'; cr. @@ -3805,6 +3833,41 @@ SpurMemoryManager >> classTagForSpecialObjectsIndex: splObjIndex compactClassInd ^compactClassIndex ] +{ #category : #'perm - space' } +SpurMemoryManager >> cleanUpPermToOldSpaceRememeberedSet [ + + | destIndex sourceIndex referrer | + + + + sourceIndex := destIndex := 0. + + "We iterate the remembered set to remove the objects that no longer points to old space. + As it might have duplicates, I use the mark bit to see if I have already this object." + + self assert: self allPermSpaceObjectsUnmarked. + + [sourceIndex < self getFromPermToOldSpaceRememberedSet rememberedSetSize] whileTrue: + [ referrer := self getFromPermToOldSpaceRememberedSet objectAt: sourceIndex. + + self assert: ((self hasYoungReferents: referrer) not or:[self isRemembered: referrer]). + + ((self isMarked: referrer) not and: [self hasOldReferents: referrer]) + ifTrue:[ + self getFromPermToOldSpaceRememberedSet save: referrer at: destIndex. + self setIsMarkedOf: referrer to: true. + destIndex := destIndex + 1]. + sourceIndex := sourceIndex + 1]. + + self getFromPermToOldSpaceRememberedSet setRememberedSetSize: destIndex. + + self getFromPermToOldSpaceRememberedSet rememberedSetWithIndexDo:[ :oop :i | + self setIsMarkedOf: oop to: false ]. + + self assert: self allPermSpaceObjectsUnmarked. + +] + { #category : #'debug support' } SpurMemoryManager >> clearLeakMapAndMapAccessibleFreeSpace [ "Perform an integrity/leak check using the heapMap. Set a bit at each free chunk's header." @@ -3884,7 +3947,7 @@ SpurMemoryManager >> clone: objOop [ withValue: oop]. (hasYoung and: [(memoryMap isYoungObject: newObj) not]) ifTrue: - [self getFromOldSpaceRememberedSet doRemember: newObj]] + [self getFromOldSpaceRememberedSet remember: newObj]] ifFalse: [0 to: numSlots - 1 do: [:i| @@ -3895,7 +3958,7 @@ SpurMemoryManager >> clone: objOop [ [coInterpreter maybeFixClonedCompiledMethod: newObj. ((memoryMap isOldObject: newObj) and: [(memoryMap isYoungObject: objOop) or: [self isRemembered: objOop]]) ifTrue: - [self getFromOldSpaceRememberedSet doRemember: newObj]]]. + [self getFromOldSpaceRememberedSet remember: newObj]]]. ^newObj ] @@ -3936,7 +3999,7 @@ SpurMemoryManager >> cloneInOldSpace: objOop forPinning: forPinning [ ofObject: newObj withValue: oop]. hasYoung ifTrue: - [self getFromOldSpaceRememberedSet doRemember: newObj]] + [self getFromOldSpaceRememberedSet remember: newObj]] ifFalse: [0 to: numSlots - 1 do: [:i| @@ -3946,7 +4009,7 @@ SpurMemoryManager >> cloneInOldSpace: objOop forPinning: forPinning [ fmt >= self firstCompiledMethodFormat ifTrue: [coInterpreter maybeFixClonedCompiledMethod: newObj. ((memoryMap isYoungObject: objOop) or: [self isRemembered: objOop]) ifTrue: - [self getFromOldSpaceRememberedSet doRemember: newObj]]]. + [self getFromOldSpaceRememberedSet remember: newObj]]]. (hash := self rawHashBitsOf: objOop) ~= 0 ifTrue: [self setHashBitsOf: newObj to: hash]. (self isObjImmutable: objOop) ifTrue: @@ -4314,9 +4377,10 @@ SpurMemoryManager >> doBecome: obj1 to: obj2 copyHash: copyHashFlag [ ] { #category : #'private - perm space' } -SpurMemoryManager >> doMoveToPermSpace: objOop [ +SpurMemoryManager >> doMoveToPermSpace: objOop addToRememberedSet: shouldAddToRememberedSet [ + + | numSlots numPointerSlots fmt newObj hash refersNewSpace refersOldSpace| - | numSlots numPointerSlots fmt newObj shouldBeRememberedInPermSpace hash | numSlots := self numSlotsOf: objOop. numPointerSlots := self numPointerSlotsOf: objOop. @@ -4332,7 +4396,8 @@ SpurMemoryManager >> doMoveToPermSpace: objOop [ self primitiveFailFor: PrimErrNoMemory. ^ nil ]. - shouldBeRememberedInPermSpace := false. + refersNewSpace := false. + refersOldSpace := false. 0 to: numSlots - 1 do: [ :i | | referenced | referenced := self fetchPointer: i ofObject: objOop. @@ -4345,11 +4410,14 @@ SpurMemoryManager >> doMoveToPermSpace: objOop [ (self isForwarded: referenced) ifTrue: [ referenced := self followForwarded: referenced ]. - (shouldBeRememberedInPermSpace not - and: [ (self isFixedKnownObject: referenced) not - and: [(self getMemoryMap isYoungObject: referenced) or: [ - self getMemoryMap isOldObject: referenced ]]]) - ifTrue: [ shouldBeRememberedInPermSpace := true ]]. + "If the object already refers to new space, we don't check anymore" + (refersNewSpace not and: [(self isFixedKnownObject: referenced) not]) + ifTrue: [ + (self getMemoryMap isYoungObject: referenced) + ifTrue: [ refersNewSpace := true ] + ifFalse: [ (self getMemoryMap isOldObject: referenced) + ifTrue: [ refersOldSpace := true ] ]] + ]. "We check only if the object has not be already detected." @@ -4362,8 +4430,11 @@ SpurMemoryManager >> doMoveToPermSpace: objOop [ (self isRemembered: objOop) ifTrue: [ fromOldSpaceRememberedSet forgetObject: objOop ]. - shouldBeRememberedInPermSpace - ifTrue: [ fromPermSpaceRememberedSet doRemember: newObj ]. + shouldAddToRememberedSet + ifTrue: [ + refersNewSpace + ifTrue: [ self getFromPermToNewSpaceRememberedSet remember: newObj ] + ifFalse: [ refersOldSpace ifTrue: [ self getFromPermToOldSpaceRememberedSet rememberWithoutMarkingAsRemembered: newObj ] ]]. (hash := self rawHashBitsOf: objOop) ~= 0 ifTrue: [ self setHashBitsOf: newObj to: hash ]. @@ -4511,22 +4582,15 @@ SpurMemoryManager >> endianness [ { #category : #initialization } SpurMemoryManager >> ensureAuxiliarStructures [ - self - cCode: [ - fromOldSpaceRememberedSet isNil ifTrue: [ - fromOldSpaceRememberedSet := self - cCoerce: (self malloc: (self sizeof: VMRememberedSet)) - to: #'VMRememberedSet *'. - - fromOldSpaceRememberedSet rootIndex: OldRememberedSetRootIndex]. - - fromPermSpaceRememberedSet isNil ifTrue: [ - fromPermSpaceRememberedSet := self - cCoerce: (self malloc: (self sizeof: VMRememberedSet)) - to: #'VMRememberedSet *'. - - fromPermSpaceRememberedSet rootIndex: PermRememberedSetRootIndex]]. + self cCode: [ + fromOldSpaceRememberedSet ifNil: [ + fromOldSpaceRememberedSet := self allocateRememberedSetWithRootIndex: OldRememberedSetRootIndex ]. + fromPermToOldSpaceRememberedSet ifNil: [ + fromPermToOldSpaceRememberedSet := self allocateRememberedSetWithRootIndex: PermToOldRememberedSetRootIndex ]. + + fromPermToNewSpaceRememberedSet ifNil: [ + fromPermToNewSpaceRememberedSet := self allocateRememberedSetWithRootIndex: PermToNewRememberedSetRootIndex ] ] ] { #category : #'class table' } @@ -4727,7 +4791,9 @@ SpurMemoryManager >> expungeDuplicateAndUnmarkedClasses: expungeUnmarked [ ifFalse: [((expungeUnmarked and: [(self isMarkedOrPermanent: classOrNil) not]) or: [(self rawHashBitsOf: classOrNil) ~= classIndex]) ifTrue: - [self storePointerUnchecked: j + [ + self deny: (self isPermanent: classOrNil). + self storePointerUnchecked: j ofObject: classTablePage withValue: nilObj. "but if it is marked, it should still be in the table at its correct index." @@ -5787,12 +5853,6 @@ SpurMemoryManager >> fromOldSpaceRememberedSet [ ^ fromOldSpaceRememberedSet ] -{ #category : #accessing } -SpurMemoryManager >> fromPermSpaceRememberedSet [ - - ^ fromPermSpaceRememberedSet -] - { #category : #'gc - global' } SpurMemoryManager >> fullGC [ "Perform a full eager compacting GC. Answer the size of the largest free chunk." @@ -5843,12 +5903,21 @@ SpurMemoryManager >> getFromOldSpaceRememberedSet [ ] { #category : #accessing } -SpurMemoryManager >> getFromPermSpaceRememberedSet [ +SpurMemoryManager >> getFromPermToNewSpaceRememberedSet [ + + + + + ^ fromPermToNewSpaceRememberedSet +] + +{ #category : #accessing } +SpurMemoryManager >> getFromPermToOldSpaceRememberedSet [ - ^ fromPermSpaceRememberedSet + ^ fromPermToOldSpaceRememberedSet ] { #category : #accessing } @@ -6007,6 +6076,14 @@ SpurMemoryManager >> hasIdentityHash: objOop [ inSmalltalk: [(self rawHashBitsOf: objOop) ~= 0] ] +{ #category : #'object testing' } +SpurMemoryManager >> hasOldReferents: objOop [ + + + + ^ self hasReferents: objOop satisfying: [ :referenced | (self isFixedKnownObject: referenced) not and: [self isOld: referenced] ] +] + { #category : #'header access' } SpurMemoryManager >> hasOverflowHeader: objOop [ ^(self rawNumSlotsOf: objOop) = self numSlotsMask @@ -6025,6 +6102,25 @@ SpurMemoryManager >> hasPointerFieldsNonImm: oop [ ^self isAnyPointerFormat: (self formatOf: oop) ] +{ #category : #'object testing' } +SpurMemoryManager >> hasReferents: objOop satisfying: aCondition [ + + 0 to: (self numPointerSlotsOf: objOop) - 1 do: [ :i | + | referenced | + referenced := self fetchPointer: i ofObject: objOop. + + ((self isNonImmediate: referenced) + and: [self isInObjectMemory: referenced ]) ifTrue: [ + (self isOopForwarded: referenced) + ifTrue: [ referenced := self followForwarded: referenced. + self storePointer: i ofObject: objOop withValue: referenced ]. + + (aCondition value: referenced) + ifTrue: [ ^ true ]] ]. + + ^ false +] + { #category : #'interpreter access' } SpurMemoryManager >> hasSixtyFourBitImmediates [ "The V3 64-bit memory manager has 64-bit oops, but its SmallIntegers only have @@ -6034,12 +6130,10 @@ SpurMemoryManager >> hasSixtyFourBitImmediates [ { #category : #'object testing' } SpurMemoryManager >> hasYoungReferents: objOop [ - 0 to: (self numPointerSlotsOf: objOop) - 1 do: - [:i| | oop | - oop := self fetchPointer: i ofObject: objOop. - (self isYoung: oop) ifTrue: - [^true]]. - ^false + + + + ^ self hasReferents: objOop satisfying: [ :referenced | self isYoung: referenced ] ] { #category : #'header access' } @@ -6165,6 +6259,8 @@ SpurMemoryManager >> ifOopInvalidForBecome: oop errorCodeInto: aBlock [ (self isPinned: oop) ifTrue: [^aBlock value: PrimErrObjectIsPinned]. (self isObjImmutable: oop) ifTrue: + [^aBlock value: PrimErrNoModification]. + (memoryMap isPermanentObject: oop) ifTrue: [^aBlock value: PrimErrNoModification] ] @@ -6460,7 +6556,8 @@ SpurMemoryManager >> initialize [ "we can initialize things that are virtual in C." fromOldSpaceRememberedSet := VMRememberedSet new manager: self; rootIndex: OldRememberedSetRootIndex; yourself. - fromPermSpaceRememberedSet := VMRememberedSet new manager: self; rootIndex: PermRememberedSetRootIndex; yourself. + fromPermToOldSpaceRememberedSet := VMRememberedSet new manager: self; rootIndex: PermToOldRememberedSetRootIndex; yourself. + fromPermToNewSpaceRememberedSet := VMRememberedSet new manager: self; rootIndex: PermToNewRememberedSetRootIndex; yourself. scavenger := SpurGenerationScavenger simulatorClass new manager: self; yourself. segmentManager := SpurSegmentManager simulatorClass new manager: self; yourself. @@ -6648,9 +6745,9 @@ SpurMemoryManager >> initializeObjectMemory: bytesToShift [ self initializeNewSpaceVariables. fromOldSpaceRememberedSet initializeRememberedSetShouldStartEmpty: true. - fromPermSpaceRememberedSet initializeRememberedSetShouldStartEmpty: false. - self assert: self isPermSpaceRememberedSetSane. - + fromPermToOldSpaceRememberedSet initializeRememberedSetShouldStartEmpty: false. + fromPermToNewSpaceRememberedSet initializeRememberedSetShouldStartEmpty: true. + segmentManager checkSegments. compactor biasForGC. @@ -7557,46 +7654,48 @@ SpurMemoryManager >> isPermSpaceRememberedSetSane [ - - | numPointerSlots referenced mustBeRemembered | - - self allPermSpaceObjectsDo: [ :objOop | - numPointerSlots := self numPointerSlotsOf: objOop. - mustBeRemembered := false. - 0 to: numPointerSlots - 1 do: [ :index | - referenced := self fetchPointer: index ofObject: objOop. - (self isInObjectMemory: referenced) ifTrue: [ - (self isOopForwarded: referenced) ifTrue: [ - referenced := self followForwarded: referenced ]. + | refersNewSpace refersOldSpace isInPermToNewRememberedSet isInPermToOldRememberedSet isValid| + + isValid := true. + + self allPermSpaceObjectsDo: [ :objOop | - (((self isFixedKnownObject: referenced) not - and: [ self isNonImmediate: referenced ]) - and: [(self getMemoryMap isYoungObject: referenced) or: [ self getMemoryMap isOldObject: referenced ]]) - ifTrue: [ mustBeRemembered := true]]]. - - mustBeRemembered ifTrue: [ - (self getFromPermSpaceRememberedSet isInRememberedSet: objOop) - ifFalse: [ - self logError: 'Offending Object: %p' _: objOop. - self error: 'Object should be in remembered set'. ]. + refersNewSpace := self hasYoungReferents: objOop. + refersOldSpace := self hasOldReferents: objOop. + + isInPermToNewRememberedSet := self getFromPermToNewSpaceRememberedSet isInRememberedSet: objOop. + isInPermToOldRememberedSet := self getFromPermToOldSpaceRememberedSet isInRememberedSet: objOop. + + (isInPermToNewRememberedSet and: [ refersNewSpace or: refersOldSpace ]) + ifTrue: [ (self isRemembered: objOop) ifFalse: [ + isValid := false. self logError: 'Offending Object: %p' _: objOop. - self error: 'Object should be marked as remembered' ]] - ifFalse: [ - (self getFromPermSpaceRememberedSet isInRememberedSet: objOop) - ifTrue: [ + self error: 'Object should be marked as remembered' ]]. + + (refersNewSpace and: [ isInPermToNewRememberedSet not ]) + ifTrue: [ + isValid := false. self logError: 'Offending Object: %p' _: objOop. - self error: 'Object should not be in remembered set'. ]. - (self isRemembered: objOop) - ifTrue: [ + self error: 'Object should be in remembered set (Perm to New)' ]. + + (isInPermToNewRememberedSet and: [refersNewSpace not and: [ refersOldSpace not ]]) + ifTrue: [ + isValid := false. self logError: 'Offending Object: %p' _: objOop. - self error: 'Object should not be marked as remembered' ] - ]. + self error: 'Object should not be in remembered set (Perm to New)'. ]. + + (refersOldSpace and: [ isInPermToNewRememberedSet not and: [isInPermToOldRememberedSet not] ]) + ifTrue: [ + isValid := false. + self logError: 'Offending Object: %p' _: objOop. + self error: 'Object should not be in remembered set (Perm to Old)'. ]. + ]. - ^ true. + ^ isValid. ] { #category : #'object testing' } @@ -8407,8 +8506,10 @@ SpurMemoryManager >> markAndShouldScan: objOop [ "if markAndTrace: is to follow and eliminate forwarding pointers in its scan it cannot be handed an r-value which is forwarded." self assert: (self isForwarded: objOop) not. + (self isMarked: objOop) ifTrue: - [^false]. + [ self assert: (memoryMap isPermanentObject: objOop) not. + ^false]. "If it is a permanent object I will not mark it" (memoryMap isPermanentObject: objOop) @@ -8488,6 +8589,9 @@ SpurMemoryManager >> markAndTraceExtraRoots [ { #category : #'gc - global' } SpurMemoryManager >> markAndTraceHiddenRoots [ + + + "The hidden roots hold both the class table pages and the obj stacks, and hence need special treatment. The obj stacks must be marked specially; their pages must be marked, but only the contents of the @@ -8502,7 +8606,11 @@ SpurMemoryManager >> markAndTraceHiddenRoots [ self markAndTraceObjStack: markStack andContents: false. self markAndTraceObjStack: weaklingStack andContents: false. self markAndTraceObjStack: mournQueue andContents: true. - self markAndTraceRememberedSet: fromPermSpaceRememberedSet. + + self cleanUpPermToOldSpaceRememeberedSet. + + self markAndTraceRememberedSet: self getFromPermToOldSpaceRememberedSet. + self markAndTraceRememberedSet: self getFromPermToNewSpaceRememberedSet. self setIsMarkedOf: self nilObject to: true. self setIsMarkedOf: self trueObject to: true. @@ -8555,6 +8663,7 @@ SpurMemoryManager >> markAndTraceObjStack: stackOrNil andContents: markAndTraceC SpurMemoryManager >> markAndTraceRememberedSet: aRememberedSet [ | rememberedSetOop | + rememberedSetOop := aRememberedSet objectOop. self setIsMarkedOf: rememberedSetOop to: true. @@ -8635,7 +8744,7 @@ SpurMemoryManager >> markLoopFrom: objOop [ | key | (self isImmediate: (key := self keyOfEphemeron: objToScan)) or: [ - self isMarked: key ] ]) + self isMarkedOrPermanent: key ] ]) ifTrue: [ self numSlotsOf: objToScan ] ifFalse: [ self numStrongSlotsOfInephemeral: objToScan ]. @@ -9016,16 +9125,15 @@ SpurMemoryManager >> moveToPermSpace: objOop [ | newObj | - "Clearing the flag for all" becomeEffectsFlags := 0. - (self isValidToMoveToPermSpace: objOop) ifFalse: [ - self primitiveFailFor: PrimErrBadReceiver. - ^ nil ]. + (self isValidToMoveToPermSpace: objOop) ifFalse: [ + self primitiveFailFor: PrimErrBadReceiver. + ^ nil ]. "Clonning in permSpace" - newObj := self doMoveToPermSpace: objOop. + newObj := self doMoveToPermSpace: objOop addToRememberedSet: true. self doAfterMoveToPermSpace. @@ -9042,30 +9150,30 @@ SpurMemoryManager >> moveToPermSpaceInBulk: anArrayOop [ becomeEffectsFlags := 0. size := self numSlotsOf: anArrayOop. - - 0 to: size - 1 do: [ :index | - + + 0 to: size - 1 do: [ :index | objOop := self fetchPointer: index ofObject: anArrayOop. - - (self isValidToMoveToPermSpace: objOop) ifFalse: [ - self primitiveFailFor: PrimErrBadReceiver. - ^ nil ]]. + (self isValidToMoveToPermSpace: objOop) ifFalse: [ + self primitiveFailFor: PrimErrBadReceiver. + ^ nil ] ]. - 0 to: size - 1 do: [ :index | + + 0 to: size - 1 do: [ :index | objOop := self fetchPointer: index ofObject: anArrayOop. - (self getMemoryMap isPermanentObject: objOop) - ifFalse: [ - "Clonning in permSpace" - newObj := self doMoveToPermSpace: objOop. - newObj ifNil: [ ^ anArrayOop ]. - - self storePointer: index ofObject: anArrayOop withValue: newObj]]. + (self getMemoryMap isPermanentObject: objOop) ifFalse: [ + "Clonning in permSpace - We don't add to the remembered set, this will be done after all is moved. To minimize the size of the remembered set" + newObj := self doMoveToPermSpace: objOop addToRememberedSet: false. + newObj ifNil: [ ^ anArrayOop ]. + + self storePointer: index ofObject: anArrayOop withValue: newObj ] ]. self followForwardedObjectFields: anArrayOop toDepth: 1. + self recreateFromPermSpaceRememberedSet. - becomeEffectsFlags := BecamePointerObjectFlag + BecameActiveClassFlag bitOr: BecameCompiledMethodFlag. + becomeEffectsFlags := BecamePointerObjectFlag + BecameActiveClassFlag + bitOr: BecameCompiledMethodFlag. self doAfterMoveToPermSpace. ^ anArrayOop @@ -9941,16 +10049,21 @@ SpurMemoryManager >> pastSpaceStart [ ^pastSpaceStart ] -{ #category : #scavenger } -SpurMemoryManager >> permRememberedSetObj [ - ^self fetchPointer: PermRememberedSetRootIndex ofObject: hiddenRootsObj -] - { #category : #accessing } SpurMemoryManager >> permSpaceFreeStart [ ^ permSpaceFreeStart ] +{ #category : #scavenger } +SpurMemoryManager >> permToNewRememberedSetObj [ + ^self fetchPointer: PermToNewRememberedSetRootIndex ofObject: hiddenRootsObj +] + +{ #category : #scavenger } +SpurMemoryManager >> permToOldRememberedSetObj [ + ^self fetchPointer: PermToOldRememberedSetRootIndex ofObject: hiddenRootsObj +] + { #category : #'primitive support' } SpurMemoryManager >> pinObject: objOop [ "Attempt to pin objOop, which must not be immediate. @@ -10109,7 +10222,7 @@ SpurMemoryManager >> possibleOldObjectStoreInto: destObj [ (self isRemembered: destObj) ifFalse: [ - fromOldSpaceRememberedSet doRemember: destObj ] + fromOldSpaceRememberedSet remember: destObj ] ] { #category : #'store check' } @@ -10126,10 +10239,12 @@ SpurMemoryManager >> possiblePermObjectStoreInto: destObj value: valueObj [ (self isInObjectMemory: valueObj) ifFalse: [ ^ self ]. + (self isRemembered: destObj) + ifTrue: [ ^ self ]. + (self isPermanent: destObj) ifTrue: [ - (self isPermanent: valueObj) ifFalse: [ - (self isRemembered: destObj) ifFalse: [ - fromPermSpaceRememberedSet doRemember: destObj ] ] ] + (self getMemoryMap isPermanentObject: valueObj) ifFalse: [ + self getFromPermToNewSpaceRememberedSet remember: destObj ] ] ] { #category : #'become implementation' } @@ -11018,6 +11133,52 @@ SpurMemoryManager >> readUINT8AtPointer: aCArrayAccessor [ ^ intPtr at: 0 ] +{ #category : #'perm - space' } +SpurMemoryManager >> recreateFromPermSpaceRememberedSet [ + + self getFromPermToOldSpaceRememberedSet emptyRememberedSet. + self getFromPermToNewSpaceRememberedSet emptyRememberedSet. + + self allPermSpaceObjectsDo: [ :aPermSpaceObject | + | slotIndex referenced numPointerSlots refersNewSpace refersOldSpace | + + "We clear the bit of all remembered objects, it will be recalculated" + self setIsRememberedOf: aPermSpaceObject to: false. + numPointerSlots := self numPointerSlotsOf: aPermSpaceObject. + + refersNewSpace := false. + refersOldSpace := false. + + slotIndex := 0. + + "If the object already refers to new space, we don't check anymore" + [ refersNewSpace not and: [slotIndex < numPointerSlots] ] + whileTrue: [ + referenced := self fetchPointer: slotIndex ofObject: aPermSpaceObject. + + "We check if we have an object in the pointer slots of objOop" + ((self isNonImmediate: referenced) and: [self isInObjectMemory: referenced ]) + ifTrue: [ + (self isForwarded: referenced) + ifTrue: [ referenced := self followForwarded: referenced ]. + + + (self isFixedKnownObject: referenced) + ifFalse: [ + (self getMemoryMap isYoungObject: referenced) + ifTrue: [ refersNewSpace := true ] + ifFalse: [ (self getMemoryMap isOldObject: referenced) + ifTrue: [ refersOldSpace := true ] ]]. + ]. + slotIndex := slotIndex + 1. + ]. + + refersNewSpace + ifTrue: [ self getFromPermToNewSpaceRememberedSet remember: aPermSpaceObject ] + ifFalse: [ refersOldSpace ifTrue: [ self getFromPermToOldSpaceRememberedSet rememberWithoutMarkingAsRemembered: aPermSpaceObject ] ] + ] +] + { #category : #compaction } SpurMemoryManager >> relocateObjStackForPlanningCompactor: objStack [ "Relocate all objStack pages that comprise objStack." @@ -11097,10 +11258,10 @@ SpurMemoryManager >> rememberObjInCorrectRememberedSet: objOop [ (self isOld: objOop) ifTrue: [ - ^ fromOldSpaceRememberedSet doRemember: objOop ]. + ^ fromOldSpaceRememberedSet remember: objOop ]. (self isPermanent: objOop) ifTrue: [ - ^ fromPermSpaceRememberedSet doRemember: objOop ]. + ^ fromPermToNewSpaceRememberedSet remember: objOop ]. ^ objOop diff --git a/smalltalksrc/VMMaker/SpurPlanningCompactor.class.st b/smalltalksrc/VMMaker/SpurPlanningCompactor.class.st index d310151c39..81eff18b8e 100644 --- a/smalltalksrc/VMMaker/SpurPlanningCompactor.class.st +++ b/smalltalksrc/VMMaker/SpurPlanningCompactor.class.st @@ -61,8 +61,9 @@ Class { 'objectAfterLastMobileObject', 'savedFirstFieldsSpace', 'savedFirstFieldsSpaceNotInOldSpace', - 'firstFieldOfPermRememberedSet', - 'savedFirstFieldSpaceMaxSlots' + 'savedFirstFieldSpaceMaxSlots', + 'firstFieldOfPermToOldRememberedSet', + 'firstFieldOfPermToNewRememberedSet' ], #pools : [ 'VMBytecodeConstants' @@ -616,10 +617,15 @@ SpurPlanningCompactor >> repinRememberedSet [ manager setIsPinnedOf: manager oldRememberedSetObj to: true. manager getFromOldSpaceRememberedSet relocateRememberedSet. - manager getFromPermSpaceRememberedSet rememberedSetSize > 0 ifTrue: - [manager storePointerUnchecked: 0 ofObject: manager permRememberedSetObj withValue: firstFieldOfPermRememberedSet]. - manager setIsPinnedOf: manager permRememberedSetObj to: true. - manager getFromPermSpaceRememberedSet relocateRememberedSet + manager getFromPermToOldSpaceRememberedSet rememberedSetSize > 0 ifTrue: + [manager storePointerUnchecked: 0 ofObject: manager permToOldRememberedSetObj withValue: firstFieldOfPermToOldRememberedSet]. + manager setIsPinnedOf: manager permToOldRememberedSetObj to: true. + manager getFromPermToOldSpaceRememberedSet relocateRememberedSet. + + manager getFromPermToNewSpaceRememberedSet rememberedSetSize > 0 ifTrue: + [manager storePointerUnchecked: 0 ofObject: manager permToNewRememberedSetObj withValue: firstFieldOfPermToNewRememberedSet]. + manager setIsPinnedOf: manager permToNewRememberedSetObj to: true. + manager getFromPermToNewSpaceRememberedSet relocateRememberedSet ] { #category : #'space management' } @@ -777,8 +783,13 @@ SpurPlanningCompactor >> unpinRememberedSet [ firstFieldOfRememberedSet := manager fetchPointer: 0 ofObject: manager oldRememberedSetObj. manager setIsPinnedOf: manager oldRememberedSetObj to: false. - firstFieldOfPermRememberedSet := manager fetchPointer: 0 ofObject: manager permRememberedSetObj. - manager setIsPinnedOf: manager permRememberedSetObj to: false + firstFieldOfPermToOldRememberedSet := manager fetchPointer: 0 ofObject: manager permToOldRememberedSetObj. + manager setIsPinnedOf: manager permToOldRememberedSetObj to: false. + + firstFieldOfPermToNewRememberedSet := manager fetchPointer: 0 ofObject: manager permToNewRememberedSetObj. + manager setIsPinnedOf: manager permToNewRememberedSetObj to: false + + ] { #category : #compaction } @@ -868,6 +879,8 @@ SpurPlanningCompactor >> updatePointersInManagerHeapEntities [ "The special non-pointer objects containing pointers, which are the objStacks and the rememberedSet, must be updated manually since they will not be recognized as containing pointers in the normal sweep." + + manager relocateObjStacksForPlanningCompactor. (manager getFromOldSpaceRememberedSet rememberedSetSize > 0 @@ -875,18 +888,43 @@ SpurPlanningCompactor >> updatePointersInManagerHeapEntities [ [firstFieldOfRememberedSet := manager fetchPointer: 0 ofObject: firstFieldOfRememberedSet]. self relocateObjectsInHeapEntity: manager oldRememberedSetObj from: 1 to: manager getFromOldSpaceRememberedSet rememberedSetSize - 1. - (manager getFromPermSpaceRememberedSet rememberedSetSize > 0) ifTrue: - [self updatePointersIn: firstFieldOfPermRememberedSet ]. + "We use the mark bit to avoid duplicates... only in the remembered set" + + (manager getFromPermToOldSpaceRememberedSet rememberedSetSize > 0) ifTrue: + [(manager isMarked: firstFieldOfPermToOldRememberedSet) ifFalse: + [ self updatePointersIn: firstFieldOfPermToOldRememberedSet. + manager mark: firstFieldOfPermToOldRememberedSet ] ]. + + manager getFromPermToOldSpaceRememberedSet + rememberedSetWithIndexDo: [ :oop :index | + (manager isMarked: oop) ifFalse: + [ self updatePointersIn: oop. + manager mark: oop ]] startingAt: 1. + + (manager getFromPermToNewSpaceRememberedSet rememberedSetSize > 0) ifTrue: + [(manager isMarked: firstFieldOfPermToNewRememberedSet) ifFalse: + [ self updatePointersIn: firstFieldOfPermToNewRememberedSet. + manager mark: firstFieldOfPermToNewRememberedSet ]]. - manager getFromPermSpaceRememberedSet - rememberedSetWithIndexDo: [ :oop :index | - self updatePointersIn: oop ] startingAt: 1. + manager getFromPermToNewSpaceRememberedSet + rememberedSetWithIndexDo: [ :oop :index | + (manager isMarked: oop) ifFalse: + [ self updatePointersIn: oop. + manager mark: oop ]] startingAt: 1. + (manager getFromPermToOldSpaceRememberedSet rememberedSetSize > 0) ifTrue: + [manager setIsMarkedOf: firstFieldOfPermToOldRememberedSet to: false ]. + + (manager getFromPermToNewSpaceRememberedSet rememberedSetSize > 0) ifTrue: + [manager setIsMarkedOf: firstFieldOfPermToNewRememberedSet to: false]. + + manager getFromPermToNewSpaceRememberedSet + rememberedSetWithIndexDo: [ :oop :index | manager setIsMarkedOf: oop to: false] startingAt: 1. + + manager getFromPermToOldSpaceRememberedSet + rememberedSetWithIndexDo: [ :oop :index | manager setIsMarkedOf: oop to: false] startingAt: 1. - "Note that we /must not/ set the rememberedSetObj here since it is a slot in the hiddenRootsObj - and will be updated normally in updatePointersInInitialImmobileObjects. So do not do - (self isMobile: manager rememberedSetObj) ifTrue: - [manager rememberedSetObj: (manager fetchPointer: 0 ofObject: manager rememberedSetObj)]" + self assert: manager allPermSpaceObjectsUnmarked. ] { #category : #compaction } diff --git a/smalltalksrc/VMMaker/SpurSelectiveCompactor.class.st b/smalltalksrc/VMMaker/SpurSelectiveCompactor.class.st index fb9011fdf6..652b6728e1 100644 --- a/smalltalksrc/VMMaker/SpurSelectiveCompactor.class.st +++ b/smalltalksrc/VMMaker/SpurSelectiveCompactor.class.st @@ -99,7 +99,7 @@ SpurSelectiveCompactor >> compactSegment: segInfo freeStart: initialFreeStart se (manager isRemembered: copy) ifTrue: ["copy has the remembered bit set, but is not in the remembered table." manager setIsRememberedOf: copy to: false. - self getFromOldSpaceRememberedSet doRemember: copy]. + self getFromOldSpaceRememberedSet remember: copy]. manager forward: currentEntity to: (manager objectStartingAt: fillStart). fillStart := fillStart + bytesToCopy. self assert: (self oop: fillStart isLessThan: (segmentToFill segLimit - manager bridgeSize))]. diff --git a/smalltalksrc/VMMaker/StackInterpreter.class.st b/smalltalksrc/VMMaker/StackInterpreter.class.st index ecbef645a9..3b513a33bc 100644 --- a/smalltalksrc/VMMaker/StackInterpreter.class.st +++ b/smalltalksrc/VMMaker/StackInterpreter.class.st @@ -15212,8 +15212,8 @@ StackInterpreter >> transferTo: newProc from: sourceCode [ statProcessSwitch := statProcessSwitch + 1. self push: instructionPointer. self writeBackHeadFramePointers. - self assertValidExecutionPointe: instructionPointer r: framePointer s: stackPointer imbar: true line: #'__LINE__'. - + self assertValidExecutionPointe: instructionPointer r: framePointer s: stackPointer. + "ensureMethodIsCogged: in makeBaseFrameFor: in externalSetStackPageAndPointersForSuspendedContextOfProcess: below may do a code compaction. Nil instructionPointer to avoid it getting pushed twice." diff --git a/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st b/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st index 4a83d10f2c..1555d5515c 100644 --- a/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st +++ b/smalltalksrc/VMMaker/StackInterpreterPrimitives.class.st @@ -1683,7 +1683,19 @@ StackInterpreterPrimitives >> primitiveGetVMParameter: index [ [76] -> [^self getMethodCompilationMSecs]. [77] -> [^self getBlockCompilationCount]. [78] -> [^self getBlockCompilationMSecs]. - [79] -> [^objectMemory integerObjectOf: self getImageVersion ] } + [79] -> [^objectMemory integerObjectOf: self getImageVersion ]. + [80] -> [^objectMemory integerObjectOf: + objectMemory getFromOldSpaceRememberedSet rememberedSetSize]. + [81] -> [^objectMemory integerObjectOf: + objectMemory getFromOldSpaceRememberedSet rememberedSetLimit]. + [82] -> [^objectMemory integerObjectOf: + objectMemory getFromPermToOldSpaceRememberedSet rememberedSetSize]. + [83] -> [^objectMemory integerObjectOf: + objectMemory getFromPermToOldSpaceRememberedSet rememberedSetLimit]. + [84] -> [^objectMemory integerObjectOf: + objectMemory getFromPermToNewSpaceRememberedSet rememberedSetSize]. + [85] -> [^objectMemory integerObjectOf: + objectMemory getFromPermToNewSpaceRememberedSet rememberedSetLimit]} otherwise: [^nil] ] @@ -3964,7 +3976,7 @@ StackInterpreterPrimitives >> primitiveVMParameter [ Otherwise the *real* list is in the code: `StackInterpreterPrimitives>>#primitiveGetVMParameter:`" | paramsArraySize index | - paramsArraySize := 79. + paramsArraySize := 85. argumentCount = 0 ifTrue: [^self primitiveAllVMParameters: paramsArraySize]. argumentCount > 2 ifTrue: [^self primitiveFailFor: PrimErrBadNumArgs]. diff --git a/smalltalksrc/VMMaker/VMRememberedSet.class.st b/smalltalksrc/VMMaker/VMRememberedSet.class.st index 617ecdab4e..97e4ff6655 100644 --- a/smalltalksrc/VMMaker/VMRememberedSet.class.st +++ b/smalltalksrc/VMMaker/VMRememberedSet.class.st @@ -69,24 +69,19 @@ VMRememberedSet >> countNotNilObjects [ ^ count ] -{ #category : #'store check' } -VMRememberedSet >> doRemember: objOop [ - "Add the argument to the remembered set and set its isRemembered bit to true. - Answer the argument for the benefit of the Cogit." - - - self assert: (manager isNonImmediate: objOop). - self deny: (manager getMemoryMap isYoungObject: objOop). - self deny: (self isInRememberedSet: objOop). +{ #category : #initialization } +VMRememberedSet >> emptyRememberedSet [ + + | oldObj | - manager setIsRememberedOf: objOop to: true. - rememberedSetSize >= rememberedSetLimit ifTrue: - [self growRememberedSet]. - rememberedSetArray at: rememberedSetSize put: objOop. - self setRememberedSetSize: rememberedSetSize + 1. - rememberedSetSize >= rememberedSetRedZone ifTrue: - [manager scheduleScavenge]. - ^objOop + oldObj := self objectOop. + oldObj = manager nilObject + ifFalse: [ + manager rememberedSet: rootIndex oop: manager nilObject. + manager freeObject: oldObj ]. + + self initializeRememberedSetShouldStartEmpty: true. + ] { #category : #'store check' } @@ -137,7 +132,7 @@ VMRememberedSet >> growRememberedSet [ newObj ifNil: [newObj := manager allocatePinnedSlots: numSlots + 1024. newObj ifNil: - [(manager growOldSpaceByAtLeast: numSlots + 1024) ifNil: [self error: 'could not grow remembered set']. + [(manager growOldSpaceByAtLeast: (numSlots + 1024) * manager wordSize) ifNil: [self error: 'could not grow remembered set']. newObj := manager allocatePinnedSlots: numSlots + 1024. "cannot fail"]]. manager rememberedSet: rootIndex oop: newObj. @@ -297,12 +292,43 @@ VMRememberedSet >> relocateRememberedSet [ self rememberedSetArray: (self rememberedSetArrayPointerFromObject: self objectOop) ] +{ #category : #'store check' } +VMRememberedSet >> remember: objOop [ + "Add the argument to the remembered set and set its isRemembered bit to true. + Answer the argument for the benefit of the Cogit." + + + self deny: (self isInRememberedSet: objOop). + + manager setIsRememberedOf: objOop to: true. + + ^ self rememberWithoutMarkingAsRemembered: objOop +] + { #category : #accessing } VMRememberedSet >> rememberPreviousSize [ previousRememberedSetSize := rememberedSetSize ] +{ #category : #'store check' } +VMRememberedSet >> rememberWithoutMarkingAsRemembered: objOop [ + + + + + self assert: (manager isNonImmediate: objOop). + self deny: (manager getMemoryMap isYoungObject: objOop). + + rememberedSetSize >= rememberedSetLimit ifTrue: + [self growRememberedSet]. + rememberedSetArray at: rememberedSetSize put: objOop. + self setRememberedSetSize: rememberedSetSize + 1. + rememberedSetSize >= rememberedSetRedZone ifTrue: + [manager scheduleScavenge]. + ^objOop +] + { #category : #accessing } VMRememberedSet >> rememberedSetArray [ diff --git a/smalltalksrc/VMMakerTests/VMJitMethodTest.class.st b/smalltalksrc/VMMakerTests/VMJitMethodTest.class.st index 00a7857f62..8e27c1cdd4 100644 --- a/smalltalksrc/VMMakerTests/VMJitMethodTest.class.st +++ b/smalltalksrc/VMMakerTests/VMJitMethodTest.class.st @@ -13,7 +13,7 @@ VMJitMethodTest >> addVector: arg1 with: arg2 intoVector: arg3 [ | tmp1 tmp2 | tmp1 := 0. tmp2 := 2. - [ tmp2 == tmp1 ] whileFalse: [ + [ tmp2 == tmp1 ] whileFalse: [ arg3. tmp1 := tmp1 + 2 ]. ^ arg3 diff --git a/smalltalksrc/VMMakerTests/VMPermanentSpaceMemoryTest.class.st b/smalltalksrc/VMMakerTests/VMPermanentSpaceMemoryTest.class.st index 78cddaccd4..49cf813a85 100644 --- a/smalltalksrc/VMMakerTests/VMPermanentSpaceMemoryTest.class.st +++ b/smalltalksrc/VMMakerTests/VMPermanentSpaceMemoryTest.class.st @@ -25,6 +25,33 @@ VMPermanentSpaceMemoryTest >> testAllInstancesReturnsObjectsInPermSpace [ self assert: (memory fetchPointer: 0 ofObject: allInstances) equals: permanentObject. ] +{ #category : #'tests - allocation' } +VMPermanentSpaceMemoryTest >> testBecomingOfPermanentObjectFails [ + + | permanentObject oldObject youngReplacement arrFrom arrTo ec | + + permanentObject := self newPermanentObjectWithSlots: 1. + oldObject := self newOldSpaceObjectWithSlots: 0. + memory storePointer: 0 ofObject: permanentObject withValue: oldObject. + + memory fullGC. + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject). + + youngReplacement := self newObjectWithSlots: 2. + memory storePointer: 0 ofObject: youngReplacement withValue: oldObject. + + self keepObjectInVMVariable1: youngReplacement. + + arrFrom := self newArrayWithSlots: 1. + arrTo := self newArrayWithSlots: 1. + + memory storePointer: 0 ofObject: arrFrom withValue: permanentObject. + memory storePointer: 0 ofObject: arrTo withValue: youngReplacement. + ec := memory become: arrFrom with: arrTo twoWay: false copyHash: false. + + self deny: ec equals: PrimNoErr +] + { #category : #'test - moving' } VMPermanentSpaceMemoryTest >> testCompiledMethodWithMachineCodeIsNotRememberedWhenModified [ @@ -42,7 +69,7 @@ VMPermanentSpaceMemoryTest >> testCompiledMethodWithMachineCodeIsNotRememberedWh self deny: (memory isRemembered: permanentObject1). self deny: (memory getFromOldSpaceRememberedSet isInRememberedSet: permanentObject1). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1) ] @@ -63,7 +90,7 @@ VMPermanentSpaceMemoryTest >> testCompiledMethodWithMachineCodeIsNotRememberedWh self deny: (memory isRemembered: permanentObject1). self deny: (memory getFromOldSpaceRememberedSet isInRememberedSet: permanentObject1). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1) ] @@ -115,18 +142,20 @@ VMPermanentSpaceMemoryTest >> testMoveOldObjectInRememberedSetIsMovedFromSet [ self assert: (memory isRemembered: oldObject). self assert: (memory getFromOldSpaceRememberedSet isInRememberedSet: oldObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: oldObject). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: oldObject). permanentObject := memory moveToPermSpace: oldObject. self assert: (memory isRemembered: permanentObject). - "Old object is now a forwarder shoul not be in any remembered set" + "Old object is now a forwarder should not be in any remembered set" self deny: (memory getFromOldSpaceRememberedSet isInRememberedSet: oldObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: oldObject). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: oldObject). + self deny: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: oldObject). self deny: (memory getFromOldSpaceRememberedSet isInRememberedSet: permanentObject). - self assert: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject). ] @@ -143,7 +172,7 @@ VMPermanentSpaceMemoryTest >> testMovingAnObjectReferencingAYoungOnePutsInRememb permanentObject := memory moveToPermSpace: rootObject. self assert: (memory isRemembered: permanentObject). - self assert: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject). ] { #category : #'test - moving' } @@ -158,8 +187,9 @@ VMPermanentSpaceMemoryTest >> testMovingAnObjectReferencingAnOldOnePutsInRemembe permanentObject := memory moveToPermSpace: rootObject. - self assert: (memory isRemembered: permanentObject). - self assert: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject). + "Perm to Old objects are not set the remembered bit" + self deny: (memory isRemembered: permanentObject). + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject). ] { #category : #'test - moving' } @@ -276,6 +306,67 @@ VMPermanentSpaceMemoryTest >> testNextObjectIsReturningAGoodValue [ ] +{ #category : #'test - moving' } +VMPermanentSpaceMemoryTest >> testObjectInBothRememberedSetIsCorrectlyUpdated [ + + | oldObject1 permanentObject1 oldObject2 youngObject | + + "To force compaction" + self newOldSpaceArrayWithSlots: 2. + + self keepObjectInVMVariable1: (self newOldSpaceArrayWithSlots: 3). + + oldObject1 := self newOldSpaceObjectWithSlots: 2. + + oldObject2 := self newOldSpaceObjectWithSlots: 1. + self keepObjectInVMVariable2: oldObject2. + + youngObject := self newZeroSizedObject. + self keepObjectInVMVariable3: youngObject. + + memory storePointer: 0 ofObject: oldObject1 withValue: oldObject2. + + permanentObject1 := memory moveToPermSpace: oldObject1. + + memory storePointer: 1 ofObject: permanentObject1 withValue: youngObject. + + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject1). + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1). + + memory fullGC. + + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject1). + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1). + + self assert: (memory fetchPointer: 0 ofObject: permanentObject1) equals: self keptObjectInVMVariable2. + self assert: (memory fetchPointer: 1 ofObject: permanentObject1) equals: self keptObjectInVMVariable3. + +] + +{ #category : #'tests - allocation' } +VMPermanentSpaceMemoryTest >> testObjectReferencingOldIsAddedToCorrectRememberedSetAndThenRemoved [ + + | oldObject1 oldObject2 permObject2 | + oldObject1 := self newOldSpaceObjectWithSlots: 0. + oldObject2 := self newOldSpaceObjectWithSlots: 1. + + memory storePointer: 0 ofObject: oldObject2 withValue: oldObject1. + + permObject2 := memory moveToPermSpace: oldObject2. + + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permObject2). + + "Add again as duplicated" + memory getFromPermToOldSpaceRememberedSet rememberWithoutMarkingAsRemembered: permObject2. + + memory storePointer: 0 ofObject: permObject2 withValue: memory nilObject. + + memory fullGC. + + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permObject2). + self assert: memory getFromPermToNewSpaceRememberedSet rememberedSetSize equals: 0. +] + { #category : #'test - moving' } VMPermanentSpaceMemoryTest >> testObjectWithForwarderIsCorrectlyResolved [ @@ -294,6 +385,82 @@ VMPermanentSpaceMemoryTest >> testObjectWithForwarderIsCorrectlyResolved [ ] +{ #category : #'test - moving' } +VMPermanentSpaceMemoryTest >> testPassingObjectInBulkToPermSpaceKeepsFirstInRememberedSet [ + + | oldObject1 permanentObject1 oldObject2 array | + + oldObject1 := self newOldSpaceObjectWithSlots: 1. + oldObject2 := self newOldSpaceObjectWithSlots: 1. + memory storePointer: 0 ofObject: oldObject1 withValue: oldObject2. + + array := self newArrayWithSlots: 1. + memory storePointer: 0 ofObject: array withValue: oldObject1. + + memory moveToPermSpaceInBulk: array. + + permanentObject1 := memory fetchPointer: 0 ofObject: array. + + self deny: (memory isRemembered: permanentObject1). + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1 ). + +] + +{ #category : #'test - moving' } +VMPermanentSpaceMemoryTest >> testPassingObjectsInBulkPreservesObjectAlreadyInTheRememberedSet [ + + | oldObject1 permanentObject1 oldObject2 permanentObject2 array youngObject | + + oldObject1 := self newOldSpaceObjectWithSlots: 1. + oldObject2 := self newOldSpaceObjectWithSlots: 1. + youngObject := self newZeroSizedObject. + + memory storePointer: 0 ofObject: oldObject1 withValue: youngObject. + memory storePointer: 0 ofObject: oldObject2 withValue: youngObject. + + permanentObject1 := memory moveToPermSpace: oldObject1. + + self assert: (memory isRemembered: permanentObject1). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject1). + + array := self newArrayWithSlots: 1. + memory storePointer: 0 ofObject: array withValue: oldObject2. + + memory moveToPermSpaceInBulk: array. + + permanentObject2 := memory fetchPointer: 0 ofObject: array. + + self assert: (memory isRemembered: permanentObject1). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject1). + + self assert: (memory isRemembered: permanentObject2). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject2). + +] + +{ #category : #'test - moving' } +VMPermanentSpaceMemoryTest >> testPassingTwoObjectsInBulkToPermSpaceIsRemovedFromRememberedSet [ + + | oldObject1 permanentObject1 oldObject2 permanentObject2 array | + + oldObject1 := self newOldSpaceObjectWithSlots: 1. + oldObject2 := self newOldSpaceObjectWithSlots: 1. + memory storePointer: 0 ofObject: oldObject1 withValue: oldObject2. + + array := self newArrayWithSlots: 2. + memory storePointer: 0 ofObject: array withValue: oldObject1. + memory storePointer: 1 ofObject: array withValue: oldObject2. + + memory moveToPermSpaceInBulk: array. + + permanentObject1 := memory fetchPointer: 0 ofObject: array. + permanentObject2 := memory fetchPointer: 1 ofObject: array. + + self deny: (memory isRemembered: permanentObject1). + self deny: (memory getFromOldSpaceRememberedSet isInRememberedSet: permanentObject1). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1). +] + { #category : #'test - moving' } VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceIsRemovedFromRememberedSet [ @@ -306,11 +473,12 @@ VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceIsRemovedFromRemem permanentObject1 := memory moveToPermSpace: oldObject1. permanentObject2 := memory moveToPermSpace: oldObject2. - memory doScavenge: 1. + "The FromPermToOld Remembered set is cleaned on FullGC" + memory fullGC. self deny: (memory isRemembered: permanentObject1). self deny: (memory getFromOldSpaceRememberedSet isInRememberedSet: permanentObject1). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject1). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1). ] { #category : #'test - moving' } @@ -325,8 +493,9 @@ VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceKeepsFirstInRememb permanentObject1 := memory moveToPermSpace: oldObject1. permanentObject2 := memory moveToPermSpace: oldObject2. - self assert: (memory isRemembered: permanentObject1). - self assert: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject1 ). + "But it is not marked" + self deny: (memory isRemembered: permanentObject1). + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject1 ). ] @@ -346,7 +515,7 @@ VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceKeepsPointerToForw ] { #category : #'test - moving' } -VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceUpdatesForwarderInGC [ +VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceNotUpdatesForwarderInScanvenge [ | oldObject1 permanentObject1 oldObject2 permanentObject2 | @@ -357,13 +526,13 @@ VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceUpdatesForwarderIn permanentObject1 := memory moveToPermSpace: oldObject1. permanentObject2 := memory moveToPermSpace: oldObject2. - memory fullGC. + memory doScavenge: 1. - self assert: (memory fetchPointer: 0 ofObject: permanentObject1) equals: permanentObject2 + self deny: (memory fetchPointer: 0 ofObject: permanentObject1) equals: permanentObject2 ] { #category : #'test - moving' } -VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceUpdatesForwarderInScanvenge [ +VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceUpdatesForwarderInGC [ | oldObject1 permanentObject1 oldObject2 permanentObject2 | @@ -374,7 +543,7 @@ VMPermanentSpaceMemoryTest >> testPassingTwoObjectsToPermSpaceUpdatesForwarderIn permanentObject1 := memory moveToPermSpace: oldObject1. permanentObject2 := memory moveToPermSpace: oldObject2. - memory doScavenge: 1. + memory fullGC. self assert: (memory fetchPointer: 0 ofObject: permanentObject1) equals: permanentObject2 ] @@ -439,7 +608,7 @@ VMPermanentSpaceMemoryTest >> testPermanentObjectPointingToFalseIsNotRemembered permanentObject := memory moveToPermSpace: oldObject. self deny: (memory isRemembered: permanentObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject ). ] { #category : #'test - moving' } @@ -452,7 +621,7 @@ VMPermanentSpaceMemoryTest >> testPermanentObjectPointingToMachineCodeIsNotRemem permanentObject := memory moveToPermSpace: oldObject. self deny: (memory isRemembered: permanentObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject ). ] { #category : #'test - moving' } @@ -464,7 +633,7 @@ VMPermanentSpaceMemoryTest >> testPermanentObjectPointingToNilIsNotRemembered [ permanentObject := memory moveToPermSpace: oldObject. self deny: (memory isRemembered: permanentObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject ). ] { #category : #'test - moving' } @@ -477,7 +646,7 @@ VMPermanentSpaceMemoryTest >> testPermanentObjectPointingToTrueIsNotRemembered [ permanentObject := memory moveToPermSpace: oldObject. self deny: (memory isRemembered: permanentObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permanentObject ). ] { #category : #'test - moving' } @@ -491,14 +660,14 @@ VMPermanentSpaceMemoryTest >> testPermanentObjectPointingToYoungObjectIsRemovedW permanentObject := memory moveToPermSpace: oldObject. self assert: (memory isRemembered: permanentObject). - self assert: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject ). memory storePointer: 0 ofObject: permanentObject withValue: 16. memory doScavenge: 1. self deny: (memory isRemembered: permanentObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self deny: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject ). ] @@ -513,14 +682,14 @@ VMPermanentSpaceMemoryTest >> testPermanentObjectUpdatedToTrueIsRemovedFromRemem permanentObject := memory moveToPermSpace: oldObject. self assert: (memory isRemembered: permanentObject). - self assert: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject ). memory storePointer: 0 ofObject: permanentObject withValue: memory trueObject. memory doScavenge: 1. self deny: (memory isRemembered: permanentObject). - self deny: (memory getFromPermSpaceRememberedSet isInRememberedSet: permanentObject ). + self deny: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permanentObject ). ] diff --git a/smalltalksrc/VMMakerTests/VMPrimitiveTest.class.st b/smalltalksrc/VMMakerTests/VMPrimitiveTest.class.st index d8eed44748..c229c96b28 100644 --- a/smalltalksrc/VMMakerTests/VMPrimitiveTest.class.st +++ b/smalltalksrc/VMMakerTests/VMPrimitiveTest.class.st @@ -5097,10 +5097,10 @@ VMPrimitiveTest >> testPrimitiveVMParameterReturnsArrayOfOops [ interpreter preemptionYields: true. interpreter primitiveVMParameter. - "Check this is an array that has 79 OOP entries" + "Check this is an array that has 85 OOP entries" self assert: (memory isArray: interpreter stackTop). slots := memory numSlotsOf: interpreter stackTop. - self assert: slots equals: 79. + self assert: slots equals: 85. 0 to: slots - 1 do: [ :i | memory okayOop: (memory fetchPointer: i ofObject: interpreter stackTop) ] diff --git a/smalltalksrc/VMMakerTests/VMSpurMemoryManagerTest.class.st b/smalltalksrc/VMMakerTests/VMSpurMemoryManagerTest.class.st index 00d55b276b..8019a6749c 100644 --- a/smalltalksrc/VMMakerTests/VMSpurMemoryManagerTest.class.st +++ b/smalltalksrc/VMMakerTests/VMSpurMemoryManagerTest.class.st @@ -277,12 +277,13 @@ VMSpurMemoryManagerTest >> initializeOldSpaceForScavenger [ fetchPointer: 0 ofObject: memory hiddenRootsObject. - memory fromOldSpaceRememberedSet initializeRememberedSetShouldStartEmpty: true. - memory fromPermSpaceRememberedSet initializeRememberedSetShouldStartEmpty: true. + memory getFromOldSpaceRememberedSet initializeRememberedSetShouldStartEmpty: true. + memory getFromPermToOldSpaceRememberedSet initializeRememberedSetShouldStartEmpty: true. + memory getFromPermToNewSpaceRememberedSet initializeRememberedSetShouldStartEmpty: true. - memory getFromOldSpaceRememberedSet doRemember: + memory getFromOldSpaceRememberedSet remember: memory hiddenRootsObject. - memory getFromOldSpaceRememberedSet doRemember: firstClassTablePage. + memory getFromOldSpaceRememberedSet remember: firstClassTablePage. memory specialObjectsOop: (self newObjectWithSlots: 60). memory scavengingGCTenuringIf: 1. diff --git a/smalltalksrc/VMMakerTests/VMSpurOldSpaceGarbageCollectorTest.class.st b/smalltalksrc/VMMakerTests/VMSpurOldSpaceGarbageCollectorTest.class.st index 1d89edf344..0830123f51 100644 --- a/smalltalksrc/VMMakerTests/VMSpurOldSpaceGarbageCollectorTest.class.st +++ b/smalltalksrc/VMMakerTests/VMSpurOldSpaceGarbageCollectorTest.class.st @@ -236,9 +236,11 @@ VMSpurOldSpaceGarbageCollectorTest >> testAnOldObjectReferencedFromVMVariableSho { #category : #'tests-OldSpaceSize' } VMSpurOldSpaceGarbageCollectorTest >> testArrayOfPermanentObjectsPointingToOldObjectsIsCorrectlyMantained [ - | deltaFreeSpace arrayOfPerms objectsSize aPermObject anOldObject originalRememberedSetSize afteRememberedSetSize numberOfObjects | + | deltaFreeSpace arrayOfPerms objectsSize aPermObject anOldObject originalRememberedSetSize afteRememberedSetSize numberOfObjects originalNewRememberedSetSize afteNewRememberedSetSize | + + originalRememberedSetSize := memory bytesInObject: memory getFromPermToOldSpaceRememberedSet objectOop. + originalNewRememberedSetSize := memory bytesInObject: memory getFromPermToNewSpaceRememberedSet objectOop. - originalRememberedSetSize := memory bytesInObject: memory fromPermSpaceRememberedSet objectOop. numberOfObjects := 4096. deltaFreeSpace := self deltaFreeSpaceAfterGC: [ @@ -252,9 +254,10 @@ VMSpurOldSpaceGarbageCollectorTest >> testArrayOfPermanentObjectsPointingToOldOb memory storePointer: i ofObject: arrayOfPerms withValue: aPermObject ]. self keepObjectInVMVariable2: arrayOfPerms ]. - afteRememberedSetSize := memory bytesInObject: memory fromPermSpaceRememberedSet objectOop. + afteRememberedSetSize := memory bytesInObject: memory getFromPermToOldSpaceRememberedSet objectOop. + afteNewRememberedSetSize := memory bytesInObject: memory getFromPermToNewSpaceRememberedSet objectOop. - self assert: deltaFreeSpace equals: objectsSize + (afteRememberedSetSize - originalRememberedSetSize) + self assert: deltaFreeSpace equals: objectsSize + (afteRememberedSetSize - originalRememberedSetSize) + (afteNewRememberedSetSize - originalNewRememberedSetSize) ] { #category : #'tests-OldSpaceSize' } diff --git a/smalltalksrc/VMMakerTests/VMSpurRememberedSetTest.class.st b/smalltalksrc/VMMakerTests/VMSpurRememberedSetTest.class.st index c7fd91024d..674b31f591 100644 --- a/smalltalksrc/VMMakerTests/VMSpurRememberedSetTest.class.st +++ b/smalltalksrc/VMMakerTests/VMSpurRememberedSetTest.class.st @@ -55,9 +55,12 @@ VMSpurRememberedSetTest >> testMoveToPermSpaceObjectWithOldObjectShouldRememberP permObjectAddress := memory moveToPermSpace: oldObjectAddress. - self assert: (memory isRemembered: permObjectAddress). + self deny: (memory isRemembered: permObjectAddress). self deny: (memory isRemembered: referencedOldObjectAddress). + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permObjectAddress). + self deny: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: referencedOldObjectAddress). + ] { #category : #'tests - from perm to old' } @@ -70,12 +73,12 @@ VMSpurRememberedSetTest >> testMoveToPermSpaceObjectWithOldObjectShouldUpdateOld referencedOldObjectAddress := self newOldSpaceObjectWithSlots: 0. memory storePointer: 0 ofObject: oldObjectAddress withValue: referencedOldObjectAddress. - self assert: memory fromPermSpaceRememberedSet rememberedSetSize equals: 0. + self assert: memory getFromPermToOldSpaceRememberedSet rememberedSetSize equals: 0. permObjectAddress := memory moveToPermSpace: oldObjectAddress. - self assert: memory fromPermSpaceRememberedSet rememberedSetSize equals: 1. - self assert: (memory fromPermSpaceRememberedSet objectAt: 0) equals: permObjectAddress. + self assert: memory getFromPermToOldSpaceRememberedSet rememberedSetSize equals: 1. + self assert: (memory getFromPermToOldSpaceRememberedSet objectAt: 0) equals: permObjectAddress. ] @@ -110,7 +113,7 @@ VMSpurRememberedSetTest >> testMoveToPermSpaceRememberedObjectShouldUpdateNewRem permObjectAddress := memory moveToPermSpace: oldObjectAddress. - self assert: (memory fromPermSpaceRememberedSet objectAt: 0) equals: permObjectAddress. + self assert: (memory getFromPermToNewSpaceRememberedSet objectAt: 0) equals: permObjectAddress. ] @@ -259,8 +262,8 @@ VMSpurRememberedSetTest >> testStoreYoungAndOldObjectInPermObjectShouldRememberP "Check sets" self assert: memory fromOldSpaceRememberedSet rememberedSetSize equals: 0. - self assert: memory fromPermSpaceRememberedSet rememberedSetSize equals: 1. - self assert: (memory fromPermSpaceRememberedSet objectAt: 0) equals: permObjectAddress. + self assert: memory getFromPermToNewSpaceRememberedSet rememberedSetSize equals: 1. + self assert: (memory getFromPermToNewSpaceRememberedSet objectAt: 0) equals: permObjectAddress. ] diff --git a/smalltalksrc/VMMakerTests/VMSpurScavengerTest.class.st b/smalltalksrc/VMMakerTests/VMSpurScavengerTest.class.st index 9a51ace62e..94f56ee281 100644 --- a/smalltalksrc/VMMakerTests/VMSpurScavengerTest.class.st +++ b/smalltalksrc/VMMakerTests/VMSpurScavengerTest.class.st @@ -416,10 +416,13 @@ VMSpurScavengerTest >> testPermObjectInRemeberedSetShouldBeKeptWhenTheReferenced "Should be in the remembered set as this is clean up during the scavenge" self assert: (memory isRemembered: permObjectAddress). + self assert: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permObjectAddress). memory doScavenge: 1 "TenureByAge". - self assert: (memory isRemembered: permObjectAddress). + self deny: (memory isRemembered: permObjectAddress). + self deny: (memory getFromPermToNewSpaceRememberedSet isInRememberedSet: permObjectAddress). + self assert: (memory getFromPermToOldSpaceRememberedSet isInRememberedSet: permObjectAddress). ]