Skip to content

Commit

Permalink
Handling allocate of chunks in the middle of the memory map.
Browse files Browse the repository at this point in the history
Testing and handling GC
  • Loading branch information
tesonep committed Mar 29, 2022
1 parent 1bca761 commit 8996fcf
Show file tree
Hide file tree
Showing 12 changed files with 122 additions and 74 deletions.
57 changes: 43 additions & 14 deletions smalltalksrc/Slang/SlangMemoryManager.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,17 @@ Class {
#name : #SlangMemoryManager,
#superclass : #Object,
#instVars : [
'nextAvailableAddress',
'memoryMap',
'wordSize'
'wordSize',
'initialAddress'
],
#category : #'Slang-Simulation'
}

{ #category : #allocating }
SlangMemoryManager >> allocate: desiredSize [

^ self allocate: desiredSize desiredPosition: nextAvailableAddress
^ self allocate: desiredSize desiredPosition: initialAddress
]

{ #category : #allocating }
Expand All @@ -21,16 +21,12 @@ SlangMemoryManager >> allocate: desiredSize desiredPosition: desiredPos [
| allocatedAddress newMemoryRegion allocatedSize newMemory desiredPosition |
"Allocate chunks multiple of 4KB, as they are required by the machine code simulator"

allocatedSize := (desiredSize / 4096) ceiling * 4096.
allocatedSize := self roundUpToPageSize: desiredSize.
desiredPosition := self roundUpToPageSize: desiredPos.

desiredPosition := (desiredPos / 4096) ceiling * 4096.
self checkIsRegionAddress: desiredPosition.

self assert: desiredPosition \\ 4096 = 0.

allocatedAddress := desiredPosition max: nextAvailableAddress.
self assert: allocatedAddress \\ 4096 = 0.

nextAvailableAddress := desiredPosition + allocatedSize.
allocatedAddress := self findHoleBiggerThan: allocatedSize from: desiredPosition.

"Warrantee that memory regions do not move, for simulation purposes with the FFI"
newMemory := ByteArray new: allocatedSize.
Expand Down Expand Up @@ -67,6 +63,20 @@ SlangMemoryManager >> copyFrom: start to: end [
to: end - region start + 1
]

{ #category : #allocating }
SlangMemoryManager >> findHoleBiggerThan: desiredSize from: desiredPosition [

| foundPosition |
self assert: desiredSize >= self pageSize.

foundPosition := desiredPosition.

[ self wholeAt: foundPosition fits: desiredSize ]
whileFalse: [ foundPosition := foundPosition + desiredSize ].

^ foundPosition
]

{ #category : #allocating }
SlangMemoryManager >> free: address [

Expand All @@ -77,14 +87,14 @@ SlangMemoryManager >> free: address [
{ #category : #accessing }
SlangMemoryManager >> initialAddress: anInteger [

nextAvailableAddress := anInteger
initialAddress := anInteger
]

{ #category : #allocating }
SlangMemoryManager >> initialize [

super initialize.
nextAvailableAddress := 4*1024.
initialAddress := 4*1024.
memoryMap := Dictionary new
]

Expand Down Expand Up @@ -124,6 +134,12 @@ SlangMemoryManager >> longAt: address put: aWordSizedValue [
^ self writeSignedInteger: aWordSizedValue at: address size: self wordSize
]

{ #category : #utils }
SlangMemoryManager >> pageSize [

^ 4096
]

{ #category : #'memory-access' }
SlangMemoryManager >> readIntegerAt: address size: size signed: aBoolean [

Expand Down Expand Up @@ -191,11 +207,17 @@ SlangMemoryManager >> regionsDo: aFullBlockClosure [
{ #category : #allocating }
SlangMemoryManager >> registerNewRegion: newMemoryRegion size: desiredSize address: allocatedAddress [

allocatedAddress to: allocatedAddress + desiredSize by: 4096 do: [
allocatedAddress to: allocatedAddress + desiredSize by: self pageSize do: [
:pageAddress | "Index regions by the high bits of the address"
memoryMap at: pageAddress >> 12 put: newMemoryRegion ]
]

{ #category : #utils }
SlangMemoryManager >> roundUpToPageSize: desiredSize [

^ (desiredSize / self pageSize) ceiling * self pageSize
]

{ #category : #'memory-access' }
SlangMemoryManager >> unsignedByteAt: anInteger [

Expand Down Expand Up @@ -256,6 +278,13 @@ SlangMemoryManager >> unsignedShortAt: anAddress put: aValue [
^ self writeUnsignedInteger: aValue at: anAddress size: 2
]

{ #category : #allocating }
SlangMemoryManager >> wholeAt: foundPosition fits: desiredSize [

^ (foundPosition to: (foundPosition + desiredSize) by: self pageSize)
allSatisfy: [ :position | self checkIsRegionAddress: position. (memoryMap includesKey: position >> 12) not ]
]

{ #category : #accessing }
SlangMemoryManager >> wordSize [

Expand Down
13 changes: 0 additions & 13 deletions smalltalksrc/VMMaker/Spur32BitMMLECoSimulator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -333,19 +333,6 @@ Spur32BitMMLECoSimulator >> setFree: o [
super setFree: o
]

{ #category : #'header access' }
Spur32BitMMLECoSimulator >> setIsMarkedOf: objOop to: aBoolean [
"objOop = 16rB26020 ifTrue: [self halt]."
super setIsMarkedOf: objOop to: aBoolean.
"(aBoolean
and: [(self isContextNonImm: objOop)
and: [(coInterpreter
checkIsStillMarriedContext: objOop
currentFP: coInterpreter framePointer)
and: [(coInterpreter stackPages stackPageFor: (coInterpreter frameOfMarriedContext: objOop)) trace = 0]]]) ifTrue:
[self halt]"
]

{ #category : #'memory access' }
Spur32BitMMLECoSimulator >> shortAt: byteAddress [
"Return the half-word at byteAddress which must be even."
Expand Down
15 changes: 0 additions & 15 deletions smalltalksrc/VMMaker/Spur32BitMMLESimulator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -347,21 +347,6 @@ Spur32BitMMLESimulator >> scavengingGCTenuringIf: tenuringCriterion [
^super scavengingGCTenuringIf: tenuringCriterion
]

{ #category : #'header access' }
Spur32BitMMLESimulator >> setIsMarkedOf: objOop to: aBoolean [
"objOop = 16rB26020 ifTrue: [self halt]."
"(#(16r1971D0 16r196EE0 16r197048 16r197148) includes: objOop) ifTrue:
[self halt]."
super setIsMarkedOf: objOop to: aBoolean.
"(aBoolean
and: [(self isContextNonImm: objOop)
and: [(coInterpreter
checkIsStillMarriedContext: objOop
currentFP: coInterpreter framePointer)
and: [(coInterpreter stackPages stackPageFor: (coInterpreter frameOfMarriedContext: objOop)) trace = 0]]]) ifTrue:
[self halt]"
]

{ #category : #'memory access' }
Spur32BitMMLESimulator >> shortAt: byteAddress [
"Return the half-word at byteAddress which must be even."
Expand Down
2 changes: 2 additions & 0 deletions smalltalksrc/VMMaker/Spur32BitMemoryManager.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -850,6 +850,8 @@ Spur32BitMemoryManager >> setIsImmutableOf: objOop to: aBoolean [
{ #category : #'header access' }
Spur32BitMemoryManager >> setIsMarkedOf: objOop to: aBoolean [
self assert: (self isFreeObject: objOop) not.
self assert: (self isPermanentObject: objOop) not.

self flag: #endianness.
self longAt: objOop + 4
put: (aBoolean
Expand Down
13 changes: 0 additions & 13 deletions smalltalksrc/VMMaker/Spur64BitMMLECoSimulator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -324,19 +324,6 @@ Spur64BitMMLECoSimulator >> setFree: o [
super setFree: o
]

{ #category : #'header access' }
Spur64BitMMLECoSimulator >> setIsMarkedOf: objOop to: aBoolean [
"objOop = 16rB26020 ifTrue: [self halt]."
super setIsMarkedOf: objOop to: aBoolean.
"(aBoolean
and: [(self isContextNonImm: objOop)
and: [(coInterpreter
checkIsStillMarriedContext: objOop
currentFP: coInterpreter framePointer)
and: [(coInterpreter stackPages stackPageFor: (coInterpreter frameOfMarriedContext: objOop)) trace = 0]]]) ifTrue:
[self halt]"
]

{ #category : #'memory access' }
Spur64BitMMLECoSimulator >> shortAt: byteAddress [
"Return the half-word at byteAddress which must be even."
Expand Down
15 changes: 0 additions & 15 deletions smalltalksrc/VMMaker/Spur64BitMMLESimulator.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -341,21 +341,6 @@ Spur64BitMMLESimulator >> scavengingGCTenuringIf: tenuringCriterion [
^super scavengingGCTenuringIf: tenuringCriterion
]

{ #category : #'header access' }
Spur64BitMMLESimulator >> setIsMarkedOf: objOop to: aBoolean [
"objOop = 16rB26020 ifTrue: [self halt]."
"(#(16r1971D0 16r196EE0 16r197048 16r197148) includes: objOop) ifTrue:
[self halt]."
super setIsMarkedOf: objOop to: aBoolean.
"(aBoolean
and: [(self isContextNonImm: objOop)
and: [(coInterpreter
checkIsStillMarriedContext: objOop
currentFP: coInterpreter framePointer)
and: [(coInterpreter stackPages stackPageFor: (coInterpreter frameOfMarriedContext: objOop)) trace = 0]]]) ifTrue:
[self halt]"
]

{ #category : #'memory access' }
Spur64BitMMLESimulator >> shortAt: byteAddress [
"Return the half-word at byteAddress which must be even."
Expand Down
2 changes: 2 additions & 0 deletions smalltalksrc/VMMaker/Spur64BitMemoryManager.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -978,6 +978,8 @@ Spur64BitMemoryManager >> setIsImmutableOf: objOop to: aBoolean [
{ #category : #'header access' }
Spur64BitMemoryManager >> setIsMarkedOf: objOop to: aBoolean [
self assert: (self isFreeObject: objOop) not.
self assert: (self isPermanentObject: objOop) not.

self longAt: objOop
put: (aBoolean
ifTrue: [(self longAt: objOop) bitOr: 1 << self markedBitFullShift]
Expand Down
2 changes: 2 additions & 0 deletions smalltalksrc/VMMaker/SpurGenerationScavenger.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -1075,6 +1075,8 @@ SpurGenerationScavenger >> remember: objOop [
self deny: (manager isYoungObject: objOop).
self deny: (manager isRemembered: objOop).
self deny: (self isInRememberedSet: objOop).
self deny: (manager isPermanentObject: objOop).

manager setIsRememberedOf: objOop to: true.
rememberedSetSize >= rememberedSetLimit ifTrue:
[self growRememberedSet].
Expand Down
17 changes: 13 additions & 4 deletions smalltalksrc/VMMaker/SpurMemoryManager.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -1998,11 +1998,15 @@ SpurMemoryManager >> allocateMemoryOfSize: memoryBytes newSpaceSize: newSpaceByt
manager: self;
yourself.
permSpaceSize > 0
permSpaceSize isZero
ifTrue: [
memoryMap permSpaceStart: (self allocateMemoryOfSize: permSpaceSize initialAddress: 16r10000000).
memoryMap permSpaceEnd: memoryMap permSpaceStart + permSpaceSize.
permSpaceFreeStart := memoryMap permSpaceStart ]
memoryMap permSpaceStart: 16r10000000.
memoryMap permSpaceEnd: 16r10000000]
ifFalse: [
memoryMap permSpaceStart: (self allocateMemoryOfSize: permSpaceSize initialAddress: 16r10000000).
memoryMap permSpaceEnd: memoryMap permSpaceStart + permSpaceSize ].
permSpaceFreeStart := memoryMap permSpaceStart
]
Expand Down Expand Up @@ -8152,6 +8156,11 @@ SpurMemoryManager >> markAndShouldScan: objOop [
self assert: (self isForwarded: objOop) not.
(self isMarked: objOop) ifTrue:
[^false].
"If it is a permanent object I will not visit it"
(self isPermanentObject: objOop)
ifTrue: [ ^false ].
self setIsMarkedOf: objOop to: true.
format := self formatOf: objOop.
(self isPureBitsFormat: format) ifTrue: "avoid pushing non-pointer objects on the markStack."
Expand Down
18 changes: 18 additions & 0 deletions smalltalksrc/VMMaker/VMMemoryMap.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,21 @@ VMMemoryMap >> allocateOldObjectsSpace [
self setOldSpaceEnd: self oldSpaceStart + sizeToAllocate
]

{ #category : #allocating }
VMMemoryMap >> allocatePermObjectsSpace [

| permSpaceSize |
permSpaceSize := 10*1024*1024.

self permSpaceStart: (self
allocateMemory: permSpaceSize
BaseAddress: memoryMapConfiguration permSpaceInitialAddress).

self permSpaceStart ifNil: [ self insufficientMemoryAvailableError ].

self permSpaceEnd: self permSpaceStart + permSpaceSize
]

{ #category : #accessing }
VMMemoryMap >> allocationReserve [
^ allocationReserve
Expand Down Expand Up @@ -262,13 +277,16 @@ VMMemoryMap >> permSpaceStart [
{ #category : #accessing }
VMMemoryMap >> permSpaceStart: anInteger [

self assert: anInteger > oldSpaceEnd.
permSpaceStart := anInteger
]

{ #category : #initialization }
VMMemoryMap >> setOldSpaceEnd: anInteger [

oldSpaceEnd := anInteger.
self assert: (permSpaceStart isNil or: [anInteger < permSpaceStart]).

]

{ #category : #accessing }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,9 @@ VMMemoryMapConfigurationFor32Bits >> oldSpaceInitialAddress [

^ 16r40000000 "(1024 MB)"
]

{ #category : #'initial addresses' }
VMMemoryMapConfigurationFor32Bits >> permSpaceInitialAddress [

^ 16r80000000 "(2048 MB)"
]
36 changes: 36 additions & 0 deletions smalltalksrc/VMMakerTests/VMPermanentSpaceTest.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,42 @@ VMPermanentSpaceTest >> setUp [



]

{ #category : #'instance creation' }
VMPermanentSpaceTest >> testMarkingNewSpaceDoesNotMarkPermSpace [

| permanentObject newObject |

permanentObject := self newPermanentByteObjectOfSize: 14.
newObject := self newObjectWithSlots: 1.
self keepObjectInVMVariable1: newObject.

self assert: (memory isYoungObject: newObject).

memory storePointer: 0 ofObject: newObject withValue: permanentObject.

memory doScavenge: 1 "TenureByAge".

self deny: (memory isMarked: permanentObject)
]

{ #category : #'instance creation' }
VMPermanentSpaceTest >> testMarkingOldSpaceDoesNotMarkPermSpace [

| permanentObject oldObject |

permanentObject := self newPermanentByteObjectOfSize: 14.
oldObject := self newOldSpaceObjectWithSlots: 1.
self keepObjectInVMVariable1: oldObject.

self assert: (memory isOldObject: oldObject).

memory storePointer: 0 ofObject: oldObject withValue: permanentObject.

memory fullGC.

self deny: (memory isMarked: permanentObject)
]

{ #category : #'instance creation' }
Expand Down

0 comments on commit 8996fcf

Please sign in to comment.