Skip to content

Commit

Permalink
- Making it work in Windows the memory map.
Browse files Browse the repository at this point in the history
- Extracting Segment Allocation
- Fixing the rounding up to support allocation granularity
  • Loading branch information
tesonep committed Apr 8, 2022
1 parent 342b82d commit 2c5abc1
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 51 deletions.
25 changes: 17 additions & 8 deletions smalltalksrc/VMMaker/AbstractComposedImageAccess.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,7 @@ AbstractComposedImageAccess >> createImageDirectory: imageFileName [
AbstractComposedImageAccess >> existSegment: segmentIndex inImage: imageFileName [

<var: #buffer declareC: 'char buffer[255]'>
<var: #sb declareC: 'struct stat sb'>
| buffer fileName sb |
self simulationOnly: [
buffer := nil.
sb := nil ].
| buffer fileName |

fileName := self
segmentFileName: segmentIndex
Expand All @@ -41,9 +37,8 @@ AbstractComposedImageAccess >> existSegment: segmentIndex inImage: imageFileName
into: buffer
bufferSize: 255.

^ self
cCode: [ (self stat: fileName _: (self addressOf: sb)) = 0]
inSmalltalk: [ fileName asFileReference exists ]
^ self fileExists: fileName

]

{ #category : #'as yet unclassified' }
Expand All @@ -53,6 +48,20 @@ AbstractComposedImageAccess >> fieldFormat [
^ '\t#%s : %lld'.
]

{ #category : #'file operations' }
AbstractComposedImageAccess >> fileExists: fileName [

| sb |

<inline: false>
<var: #fileName type: 'char *'>
<var: #sb type: 'struct stat'>

^ self
cCode: [ (self stat: fileName _: (self addressOf: sb)) = 0]
inSmalltalk: [ fileName asFileReference exists ]
]

{ #category : #'file primitives' }
AbstractComposedImageAccess >> fscanf: file _: format _: varHolder [

Expand Down
3 changes: 3 additions & 0 deletions smalltalksrc/VMMaker/ComposedImageReader.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,9 @@ ComposedImageReader >> readPermanentSpaceFromImageFile: imageFileName header: aH
<var: #permSpaceMetadata type: #ComposedMetadataStruct>

| newBase permSpaceMetadata oldBase dataSize bytesRead |

(self fileExists: (self permSpaceMetadataFileNameInImage: imageFileName))
ifFalse: [ ^ 0 ].

permSpaceMetadata := self readPermanentSpaceMetadataFromImage: imageFileName.
oldBase := permSpaceMetadata startAddress.
Expand Down
18 changes: 1 addition & 17 deletions smalltalksrc/VMMaker/SpurMemoryManager.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -4549,6 +4549,7 @@ SpurMemoryManager >> ensureMemoryMap [
cCode: [ memoryMap := self cCoerce: (self malloc: (self sizeof: VMMemoryMap)) to: #'VMMemoryMap *']
inSmalltalk: [
memoryMap := VMMemoryMap new.
memoryMap objectMemory: self.
memoryMap memoryManager: memoryManager ].
memoryMap initializeMemoryMap.
Expand Down Expand Up @@ -11478,23 +11479,6 @@ SpurMemoryManager >> splObj: index put: anObject [
self storePointer: index ofObject: specialObjectsOop withValue: anObject
]
{ #category : #'simulation only' }
SpurMemoryManager >> sqAllocateMemorySegmentOfSize: segmentSize Above: minAddress AllocatedSizeInto: allocSizePtrOrBlock [
<doNotGenerate>
"Simulate heap growth by growing memory by segmentSize."
| start |
self assert: segmentSize \\ memoryManager wordSize = 0.
start := memoryManager allocate: segmentSize desiredPosition: minAddress.
self assert: start >= minAddress.
allocSizePtrOrBlock value: segmentSize.
^ start.
]
{ #category : #'simulation only' }
SpurMemoryManager >> sqDeallocateMemorySegmentAt: startAddress OfSize: ammount [
"This is a nop in the simulator, except for SpurPlanningCompactor which may
Expand Down
15 changes: 8 additions & 7 deletions smalltalksrc/VMMaker/SpurPlanningCompactor.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -1037,15 +1037,16 @@ SpurPlanningCompactor >> useFreeChunkForSavedFirstFieldsSpace: highestSuitableFr
SpurPlanningCompactor >> useSegmentForSavedFirstFieldsSpace: spaceEstimate [
"Attempt to allocate a memory segment large enough to hold the savedFirstFieldsSpace.
Invoked when neither eden nor a large free chunk are found to be big enough for the job."
| roundedSize allocatedSize |
| roundedSize allocatedSize segAddress |
<var: #segAddress type: #'void *'>
roundedSize := spaceEstimate + 1023 // 1024 * 1024.
(manager "sent to the manager so that the simulator can increase memory to simulate a new segment"
sqAllocateMemorySegmentOfSize: roundedSize
Above: (manager segmentManager firstGapOfSizeAtLeast: roundedSize)
AllocatedSizeInto: (self cCode: [self addressOf: allocatedSize]
inSmalltalk: [[:sz| allocatedSize := sz]])) ifNotNil:
[:segAddress|
manager getMemoryMap
allocateSegmentOfSize: roundedSize
minAddress: (manager segmentManager firstGapOfSizeAtLeast: roundedSize)
resultsIn: [ :address :aSize | allocatedSize := aSize. segAddress := address ].
segAddress ifNotNil: [
savedFirstFieldsSpace
start: segAddress asUnsignedIntegerPtr;
limit: segAddress asUnsignedIntegerPtr + allocatedSize.
Expand Down
15 changes: 8 additions & 7 deletions smalltalksrc/VMMaker/SpurSegmentManager.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -82,18 +82,19 @@ SpurSegmentManager class >> isNonArgumentImplicitReceiverVariableName: instVarNa
SpurSegmentManager >> addSegmentOfSize: ammount [
<returnTypeC: #'SpurSegmentInfo *'>
<inline: false>
| allocatedSize |
| allocatedSize segAddress |
<var: #newSeg type: #'SpurSegmentInfo *'>
<var: #segAddress type: #'void *'>
<var: #allocatedSize type: #'usqInt'>
self cCode: [] inSmalltalk: [segments ifNil: [^nil]]. "bootstrap"

(manager "sent to the manager so that the simulator can increase memory to simulate a new segment"
sqAllocateMemorySegmentOfSize: ammount
Above: (self firstGapOfSizeAtLeast: ammount)
AllocatedSizeInto: (self cCode: [self addressOf: allocatedSize]
inSmalltalk: [[:sz| allocatedSize := sz]])) ifNotNil:
[:segAddress| | newSegIndex newSeg |
manager getMemoryMap
allocateSegmentOfSize: ammount
minAddress: (self firstGapOfSizeAtLeast: ammount)
resultsIn: [ :address :aSize | allocatedSize := aSize. segAddress := address ].

segAddress ifNotNil:
[| newSegIndex newSeg |
newSegIndex := self insertSegmentFor: segAddress asUnsignedIntegerPtr.
"Simulation insertion code duplicates entries if newSegIndex ~= numSegments - 1"
self cCode: '' inSmalltalk: [segments at: newSegIndex put: SpurSegmentInfo new].
Expand Down
67 changes: 55 additions & 12 deletions smalltalksrc/VMMaker/VMMemoryMap.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,19 @@ Class {
'stackPagesStart',
'stackPagesEnd',
'initialPermSpaceSize',
'minPermSpaceSize'
'minPermSpaceSize',
'objectMemory'
],
#pools : [
'VMBasicConstants'
],
#category : #'VMMaker-Memory'
}

{ #category : #translation }
VMMemoryMap class >> filteredInstVarNames [

^ super filteredInstVarNames copyWithoutAll: #(memoryManager memoryMapConfiguration)
^ super filteredInstVarNames copyWithoutAll: #(memoryManager memoryMapConfiguration objectMemory)
]

{ #category : #translation }
Expand Down Expand Up @@ -107,7 +111,7 @@ VMMemoryMap >> allocateNewObjectsSpace [

| newSpaceSizeToAllocate |

newSpaceSizeToAllocate := self initialNewSpaceSize + self allocationReserve.
newSpaceSizeToAllocate := self roundToAllocationSize: self initialNewSpaceSize + self allocationReserve.

self newSpaceStart: (self allocateMemory: newSpaceSizeToAllocate BaseAddress: memoryMapConfiguration newSpaceInitialAddress).

Expand All @@ -121,7 +125,7 @@ VMMemoryMap >> allocateOldObjectsSpace [

| sizeToAllocate |

sizeToAllocate := self initialOldSpaceSize + self initialHeadroom.
sizeToAllocate := self roundToAllocationSize: self initialOldSpaceSize + self initialHeadroom.

self oldSpaceStart: (self allocateMemory: sizeToAllocate BaseAddress: memoryMapConfiguration oldSpaceInitialAddress).

Expand All @@ -134,7 +138,7 @@ VMMemoryMap >> allocateOldObjectsSpace [
VMMemoryMap >> allocatePermObjectsSpace [

| minSize |
minSize := self roundToPageSize: (minPermSpaceSize max: initialPermSpaceSize).
minSize := self roundToAllocationSize: (minPermSpaceSize max: initialPermSpaceSize).

minSize = 0 ifTrue: [ ^ self ].

Expand All @@ -144,7 +148,23 @@ VMMemoryMap >> allocatePermObjectsSpace [

self permSpaceStart ifNil: [ self insufficientMemoryAvailableError ].

self permSpaceEnd: self permSpaceStart + minSize
self permSpaceEnd: self permSpaceStart + minSize.
objectMemory setPermSpaceFreeStart: self permSpaceStart
]

{ #category : #allocating }
VMMemoryMap >> allocateSegmentOfSize: ammount minAddress: minAddress resultsIn: blockWithAddressAndSegSize [

| sizeToRequest segmentAddress |

<inline:true>
<var: #sizeToRequest type:'size_t'>
<var: #segmentAddress type:'void *'>

sizeToRequest := self roundToAllocationSize: ammount.
segmentAddress := self allocateMemory: sizeToRequest BaseAddress: minAddress.

blockWithAddressAndSegSize value: segmentAddress value: sizeToRequest.
]

{ #category : #allocating }
Expand All @@ -153,16 +173,27 @@ VMMemoryMap >> allocateStackPages: initialStackSize [
<inline: false>
<returnTypeC: #void>

self stackPagesStart: (self allocateMemory: initialStackSize BaseAddress: memoryMapConfiguration stackPagesInitialAddress).
| sizeToRequest |
sizeToRequest := self roundToAllocationSize: initialStackSize.

self stackPagesStart: (self allocateMemory: sizeToRequest BaseAddress: memoryMapConfiguration stackPagesInitialAddress).

self stackPagesStart ifNil: [ self insufficientMemoryAvailableError ].

self stackPagesEnd: self stackPagesStart + initialStackSize.
self stackPagesEnd: self stackPagesStart + sizeToRequest.

self memset: self stackPagesStart _: 0 _: initialStackSize.
self memset: self stackPagesStart _: 0 _: sizeToRequest.

]

{ #category : #utils }
VMMemoryMap >> allocationGranularity [

"In windows we have an allocation granularity. Maybe we have to get it from the system.
https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/ns-sysinfoapi-system_info"
self cppIf: WIN32 ifTrue: [ ^ 64 * 1024 ] ifFalse: [ ^ 0 ]
]

{ #category : #accessing }
VMMemoryMap >> allocationReserve [
^ allocationReserve
Expand Down Expand Up @@ -235,6 +266,9 @@ VMMemoryMap >> ensureAtLeastPermSpaceOf: requestedSize [
{ #category : #allocating }
VMMemoryMap >> extendPermObjectsSpace [

self permSpaceStart = 0
ifTrue: [ ^ self ensureAtLeastPermSpaceOf: 10 * 1024 * 1024 ].

^ self extendPermObjectsSpaceBy: 10 * 1024 * 1024
]

Expand All @@ -243,7 +277,7 @@ VMMemoryMap >> extendPermObjectsSpaceBy: aSize [

| requestedSize extendedAddress |

requestedSize := self roundToPageSize: aSize.
requestedSize := self roundToAllocationSize: aSize.

extendedAddress := self
allocateMemory: requestedSize
Expand Down Expand Up @@ -428,6 +462,13 @@ VMMemoryMap >> newSpaceStart: anObject [
newSpaceStart := anObject
]

{ #category : #accessing }
VMMemoryMap >> objectMemory: aValue [

<doNotGenerate>
objectMemory := aValue
]

{ #category : #accessing }
VMMemoryMap >> oldSpaceEnd [
^ oldSpaceEnd
Expand Down Expand Up @@ -475,10 +516,12 @@ VMMemoryMap >> permSpaceStart: anInteger [
]

{ #category : #utils }
VMMemoryMap >> roundToPageSize: anInteger [
VMMemoryMap >> roundToAllocationSize: anInteger [

<inline: false>

"First we round up to Page Size, and then we calculate the min with the platform granularity"

| pageSize pageMask rounded |

pageSize := self getpagesize.
Expand All @@ -488,7 +531,7 @@ VMMemoryMap >> roundToPageSize: anInteger [

rounded < anInteger ifTrue: [ rounded := rounded + pageSize ].

^ rounded
^ rounded max: self allocationGranularity
]

{ #category : #initialization }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ VMMemoryMapConfigurationFor64Bits >> newSpaceInitialAddress [
{ #category : #'initial addresses' }
VMMemoryMapConfigurationFor64Bits >> oldSpaceInitialAddress [

self cppIf: WIN32 ifTrue: [ ^ 16r4C0000000 "19GB" ].

^ 16r10000000000 "1024GB"
]

Expand Down

0 comments on commit 2c5abc1

Please sign in to comment.