From d542e9b12296f4f2d382613f7a530e120d8733fe Mon Sep 17 00:00:00 2001 From: jordanmontt Date: Fri, 31 May 2024 16:25:57 +0200 Subject: [PATCH 1/3] First commit to add an allocator pattern --- src/Kernel-CodeModel/Behavior.class.st | 30 +++++++++++-------- src/Kernel-CodeModel/NormalAllocator.class.st | 19 ++++++++++++ src/Kernel-CodeModel/PinnedAllocator.class.st | 13 ++++++++ 3 files changed, 50 insertions(+), 12 deletions(-) create mode 100644 src/Kernel-CodeModel/NormalAllocator.class.st create mode 100644 src/Kernel-CodeModel/PinnedAllocator.class.st diff --git a/src/Kernel-CodeModel/Behavior.class.st b/src/Kernel-CodeModel/Behavior.class.st index 562fdca6e92..2557ca93251 100644 --- a/src/Kernel-CodeModel/Behavior.class.st +++ b/src/Kernel-CodeModel/Behavior.class.st @@ -374,19 +374,8 @@ Behavior >> basicIdentityHash [ { #category : 'instance creation' } Behavior >> basicNew [ - "Primitive. Answer an instance of the receiver (which is a class) with no - indexable variables. Fail if the class is indexable. Essential. See Object - documentation whatIsAPrimitive. - - If the primitive fails because space is low then the scavenger will run - before the method is activated. Check that space was low and retry - via handleFailingBasicNew if so." - - ec == #'insufficient object memory' ifTrue: - [^self handleFailingBasicNew]. - self isVariable ifTrue: [^self basicNew: 0]. - self primitiveFailed + ^ DefaultAllocator allocate: self ] { #category : 'instance creation' } @@ -1358,6 +1347,23 @@ Behavior >> printOn: aStream [ self superclass printOn: aStream ] +{ #category : 'instance creation' } +Behavior >> privateBasicNew [ + "Primitive. Answer an instance of the receiver (which is a class) with no + indexable variables. Fail if the class is indexable. Essential. See Object + documentation whatIsAPrimitive. + + If the primitive fails because space is low then the scavenger will run + before the method is activated. Check that space was low and retry + via handleFailingBasicNew if so." + + + ec == #'insufficient object memory' ifTrue: + [^self handleFailingBasicNew]. + self isVariable ifTrue: [^self basicNew: 0]. + self primitiveFailed +] + { #category : 'accessing - properties' } Behavior >> properties [ ^ ClassProperties at: self ifAbsent: nil diff --git a/src/Kernel-CodeModel/NormalAllocator.class.st b/src/Kernel-CodeModel/NormalAllocator.class.st new file mode 100644 index 00000000000..8aff2d90eb7 --- /dev/null +++ b/src/Kernel-CodeModel/NormalAllocator.class.st @@ -0,0 +1,19 @@ +Class { + #name : 'NormalAllocator', + #superclass : 'Object', + #category : 'Kernel-CodeModel-Allocators', + #package : 'Kernel-CodeModel', + #tag : 'Allocators' +} + +{ #category : 'class initialization' } +NormalAllocator class >> initialize [ + + Smalltalk globals at: #DefaultAllocator put: self new +] + +{ #category : 'instance creation' } +NormalAllocator >> allocate: aClass [ + + ^ aClass privateBasicNew +] diff --git a/src/Kernel-CodeModel/PinnedAllocator.class.st b/src/Kernel-CodeModel/PinnedAllocator.class.st new file mode 100644 index 00000000000..77302807bbe --- /dev/null +++ b/src/Kernel-CodeModel/PinnedAllocator.class.st @@ -0,0 +1,13 @@ +Class { + #name : 'PinnedAllocator', + #superclass : 'Object', + #category : 'Kernel-CodeModel-Allocators', + #package : 'Kernel-CodeModel', + #tag : 'Allocators' +} + +{ #category : 'instance creation' } +PinnedAllocator >> allocate: aClass [ + + ^ aClass basicNewPinned +] From b2ee0e2821f1e985bdadb6fdb0719062b8d933f6 Mon Sep 17 00:00:00 2001 From: jordanmontt Date: Fri, 31 May 2024 23:28:43 +0200 Subject: [PATCH 2/3] Added allocator desing with Dynamic Variables --- src/Kernel-CodeModel/Behavior.class.st | 35 +++++++++++-------- src/Kernel-CodeModel/NormalAllocator.class.st | 10 +++--- src/Kernel-CodeModel/ObjectAllocator.class.st | 13 +++++++ src/Kernel-CodeModel/PinnedAllocator.class.st | 13 ------- src/ThreadedFFI-UFFI/Behavior.extension.st | 8 +++-- src/ThreadedFFI-UFFI/PinnedAllocator.class.st | 18 ++++++++++ 6 files changed, 62 insertions(+), 35 deletions(-) create mode 100644 src/Kernel-CodeModel/ObjectAllocator.class.st delete mode 100644 src/Kernel-CodeModel/PinnedAllocator.class.st create mode 100644 src/ThreadedFFI-UFFI/PinnedAllocator.class.st diff --git a/src/Kernel-CodeModel/Behavior.class.st b/src/Kernel-CodeModel/Behavior.class.st index 2557ca93251..02294182be6 100644 --- a/src/Kernel-CodeModel/Behavior.class.st +++ b/src/Kernel-CodeModel/Behavior.class.st @@ -375,25 +375,13 @@ Behavior >> basicIdentityHash [ { #category : 'instance creation' } Behavior >> basicNew [ - ^ DefaultAllocator allocate: self + ^ ObjectAllocator value allocate: self ] { #category : 'instance creation' } Behavior >> basicNew: sizeRequested [ - "Primitive. Answer an instance of this class with the number of indexable - variables specified by the argument, sizeRequested. Fail if this class is not - indexable or if the argument is not a positive Integer, or if there is not - enough memory available. Essential. See Object documentation whatIsAPrimitive. - - If the primitive fails because space is low then the scavenger will run before the - method is activated. Check args and retry via handleFailingBasicNew: if they're OK." - - ec == #'insufficient object memory' ifTrue: - [^self handleFailingBasicNew: sizeRequested]. - self isVariable ifFalse: - [self error: self printString, ' cannot have variable sized instances']. - self primitiveFailed + ^ ObjectAllocator value allocate: self size: sizeRequested ] { #category : 'obsolete subclasses' } @@ -1364,6 +1352,25 @@ Behavior >> privateBasicNew [ self primitiveFailed ] +{ #category : 'instance creation' } +Behavior >> privateBasicNew: sizeRequested [ + "Primitive. Answer an instance of this class with the number of indexable + variables specified by the argument, sizeRequested. Fail if this class is not + indexable or if the argument is not a positive Integer, or if there is not + enough memory available. Essential. See Object documentation whatIsAPrimitive. + + If the primitive fails because space is low then the scavenger will run before the + method is activated. Check args and retry via handleFailingBasicNew: if they're OK." + + + ec == #'insufficient object memory' ifTrue: [ + ^ self handleFailingBasicNew: sizeRequested ]. + self isVariable ifFalse: [ + self error: + self printString , ' cannot have variable sized instances' ]. + self primitiveFailed +] + { #category : 'accessing - properties' } Behavior >> properties [ ^ ClassProperties at: self ifAbsent: nil diff --git a/src/Kernel-CodeModel/NormalAllocator.class.st b/src/Kernel-CodeModel/NormalAllocator.class.st index 8aff2d90eb7..3377d09584f 100644 --- a/src/Kernel-CodeModel/NormalAllocator.class.st +++ b/src/Kernel-CodeModel/NormalAllocator.class.st @@ -6,14 +6,14 @@ Class { #tag : 'Allocators' } -{ #category : 'class initialization' } -NormalAllocator class >> initialize [ +{ #category : 'instance creation' } +NormalAllocator class >> allocate: aClass [ - Smalltalk globals at: #DefaultAllocator put: self new + ^ aClass privateBasicNew ] { #category : 'instance creation' } -NormalAllocator >> allocate: aClass [ +NormalAllocator class >> allocate: aClass size: requestedSize [ - ^ aClass privateBasicNew + ^ aClass privateBasicNew: requestedSize ] diff --git a/src/Kernel-CodeModel/ObjectAllocator.class.st b/src/Kernel-CodeModel/ObjectAllocator.class.st new file mode 100644 index 00000000000..3a57c31fa30 --- /dev/null +++ b/src/Kernel-CodeModel/ObjectAllocator.class.st @@ -0,0 +1,13 @@ +Class { + #name : 'ObjectAllocator', + #superclass : 'DynamicVariable', + #category : 'Kernel-CodeModel-Allocators', + #package : 'Kernel-CodeModel', + #tag : 'Allocators' +} + +{ #category : 'accessing' } +ObjectAllocator >> default [ + + ^ NormalAllocator +] diff --git a/src/Kernel-CodeModel/PinnedAllocator.class.st b/src/Kernel-CodeModel/PinnedAllocator.class.st deleted file mode 100644 index 77302807bbe..00000000000 --- a/src/Kernel-CodeModel/PinnedAllocator.class.st +++ /dev/null @@ -1,13 +0,0 @@ -Class { - #name : 'PinnedAllocator', - #superclass : 'Object', - #category : 'Kernel-CodeModel-Allocators', - #package : 'Kernel-CodeModel', - #tag : 'Allocators' -} - -{ #category : 'instance creation' } -PinnedAllocator >> allocate: aClass [ - - ^ aClass basicNewPinned -] diff --git a/src/ThreadedFFI-UFFI/Behavior.extension.st b/src/ThreadedFFI-UFFI/Behavior.extension.st index 210219f2c2a..a639091b2e5 100644 --- a/src/ThreadedFFI-UFFI/Behavior.extension.st +++ b/src/ThreadedFFI-UFFI/Behavior.extension.st @@ -23,11 +23,13 @@ Behavior >> basicNewPinned: requestedSize [ { #category : '*ThreadedFFI-UFFI' } Behavior >> newPinned [ - ^ self basicNewPinned initialize + ^ ObjectAllocator value: PinnedAllocator during: [ self new ] ] { #category : '*ThreadedFFI-UFFI' } -Behavior >> newPinned: sizeRequested [ +Behavior >> newPinned: requestedSize [ - ^ (self basicNewPinned: sizeRequested) initialize + ^ ObjectAllocator + value: PinnedAllocator + during: [ self new: requestedSize ] ] diff --git a/src/ThreadedFFI-UFFI/PinnedAllocator.class.st b/src/ThreadedFFI-UFFI/PinnedAllocator.class.st new file mode 100644 index 00000000000..9bd077d89c2 --- /dev/null +++ b/src/ThreadedFFI-UFFI/PinnedAllocator.class.st @@ -0,0 +1,18 @@ +Class { + #name : 'PinnedAllocator', + #superclass : 'Object', + #category : 'ThreadedFFI-UFFI', + #package : 'ThreadedFFI-UFFI' +} + +{ #category : 'instance creation' } +PinnedAllocator class >> allocate: aClass [ + + ^ aClass basicNewPinned +] + +{ #category : 'instance creation' } +PinnedAllocator class >> allocate: aClass size: requestedSize [ + + ^ aClass basicNewPinned: requestedSize +] From 29f9fb74befc5dac732a18440e708049fec234bc Mon Sep 17 00:00:00 2001 From: jordanmontt Date: Mon, 3 Jun 2024 12:01:36 +0200 Subject: [PATCH 3/3] Added tenured allocator --- src/Kernel-CodeModel/Behavior.class.st | 8 +++++--- .../TenuredAllocator.class.st | 19 +++++++++++++++++++ 2 files changed, 24 insertions(+), 3 deletions(-) create mode 100644 src/Kernel-CodeModel/TenuredAllocator.class.st diff --git a/src/Kernel-CodeModel/Behavior.class.st b/src/Kernel-CodeModel/Behavior.class.st index b992da0bb00..b2b2ff85528 100644 --- a/src/Kernel-CodeModel/Behavior.class.st +++ b/src/Kernel-CodeModel/Behavior.class.st @@ -1305,15 +1305,17 @@ Behavior >> newTenured [ are made in the new space, that why the new space exists. Use this method when you know that tenuring the object is what you want." - ^ self basicNewTenured initialize + ^ ObjectAllocator value: TenuredAllocator during: [ self new ] ] { #category : 'instance creation' } -Behavior >> newTenured: sizeRequested [ +Behavior >> newTenured: requestedSize [ "Allocates the variable size object in the old space. See newTenured comment for more information." - ^ (self basicNewTenured: sizeRequested) initialize + ^ ObjectAllocator + value: TenuredAllocator + during: [ self new: requestedSize ] ] { #category : 'initialization' } diff --git a/src/Kernel-CodeModel/TenuredAllocator.class.st b/src/Kernel-CodeModel/TenuredAllocator.class.st new file mode 100644 index 00000000000..30c0f4e6df9 --- /dev/null +++ b/src/Kernel-CodeModel/TenuredAllocator.class.st @@ -0,0 +1,19 @@ +Class { + #name : 'TenuredAllocator', + #superclass : 'Object', + #category : 'Kernel-CodeModel-Allocators', + #package : 'Kernel-CodeModel', + #tag : 'Allocators' +} + +{ #category : 'instance creation' } +TenuredAllocator class >> allocate: aClass [ + + ^ aClass basicNewTenured +] + +{ #category : 'instance creation' } +TenuredAllocator class >> allocate: aClass size: requestedSize [ + + ^ aClass basicNewTenured: requestedSize +]