[squeak-dev] The Inbox: Collections-Igor.Stasenko.370.mcz
commits at source.squeak.org
commits at source.squeak.org
Tue Sep 21 00:25:16 UTC 2010
Igor Stasenko uploaded a new version of Collections to project The Inbox:
http://source.squeak.org/inbox/Collections-Igor.Stasenko.370.mcz
==================== Summary ====================
Name: Collections-Igor.Stasenko.370
Author: Igor.Stasenko
Time: 21 September 2010, 3:24:55.541 am
UUID: c67c4335-23af-2b43-a789-0c1345a144b6
Ancestors: Collections-eem.369
- slice for a new weak finalization
=============== Diff against Collections-eem.369 ===============
Item was changed:
----- Method: WeakArray class>>finalizationProcess (in category 'private') -----
finalizationProcess
-
[true] whileTrue:
+ [ WeakFinalizationRegistry initTestPair.
+ FinalizationSemaphore wait.
- [FinalizationSemaphore wait.
FinalizationLock critical:
+ [
+ WeakFinalizationRegistry checkTestPair.
+ FinalizationDependents do:
- [FinalizationDependents do:
[:weakDependent |
weakDependent ifNotNil:
[weakDependent finalizeValues]]]
ifError:
[:msg :rcvr | rcvr error: msg].
].
!
Item was added:
+ Object subclass: #WeakFinalizationList
+ instanceVariableNames: 'first'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Collections-Weak'!
+
+ !WeakFinalizationList commentStamp: 'Igor.Stasenko 3/8/2010 21:50' prior: 0!
+ IMPORTANT!!!!!!
+
+ This class is a special object, recognized by VM.
+ Its only purpose is to
+ a) identify a special kind of objects who usually having a weak references but
+ also having an instance of me held by first non-weak fixed slot (instance variable).
+
+ b) a 'first' instance variable points to the head of a list of items, reported by VM which has weak references which became garbage during last garbage collection!
Item was added:
+ ----- Method: WeakFinalizationList>>first (in category 'accessing') -----
+ first
+ ^ first!
Item was added:
+ ----- Method: WeakFinalizationList>>swapWithNil (in category 'accessing') -----
+ swapWithNil
+
+ | head |
+ head := first.
+ first := nil.
+ ^ head!
Item was added:
+ Collection subclass: #WeakFinalizationRegistry
+ instanceVariableNames: 'list valueDictionary sema'
+ classVariableNames: 'HasNewFinalization TestItem TestList'
+ poolDictionaries: ''
+ category: 'Collections-Weak'!
+
+ !WeakFinalizationRegistry commentStamp: 'Igor.Stasenko 3/8/2010 23:04' prior: 0!
+ This kind of WeakRegistry using a new VM feature,
+ which allows a more robust finalization support.
+
+ In contrast to old implementation, it doesn't spending linear time , checking what elements became garbage.!
Item was added:
+ ----- Method: WeakFinalizationRegistry classSide>>checkTestPair (in category 'testing') -----
+ checkTestPair
+ HasNewFinalization := TestList swapWithNil notNil.!
Item was added:
+ ----- Method: WeakFinalizationRegistry classSide>>hasNewFinalization (in category 'testing') -----
+ hasNewFinalization
+ ^ HasNewFinalization == true!
Item was added:
+ ----- Method: WeakFinalizationRegistry classSide>>initTestPair (in category 'testing') -----
+ initTestPair
+ TestItem := WeakFinalizerItem new list: TestList object: Object new.
+ !
Item was added:
+ ----- Method: WeakFinalizationRegistry classSide>>initialize (in category 'class initialization') -----
+ initialize
+ TestList := WeakFinalizationList new.
+ !
Item was added:
+ ----- Method: WeakFinalizationRegistry classSide>>new (in category 'instance creation') -----
+ new
+ | registry |
+ registry := super new.
+ WeakArray addWeakDependent: registry.
+ ^registry
+ !
Item was added:
+ ----- Method: WeakFinalizationRegistry classSide>>new: (in category 'instance creation') -----
+ new: n
+ ^ self new!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>add: (in category 'adding') -----
+ add: anObject
+ "Add anObject to the receiver. Store the object as well as the associated executor."
+
+ ^self add: anObject executor: anObject executor!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>add:executor: (in category 'adding') -----
+ add: anObject executor: anExecutor
+
+ self protected: [ | finItem |
+ finItem := valueDictionary at: anObject ifAbsentPut: [
+ WeakFinalizerItem new list: list object: anObject ].
+ finItem add: anExecutor ].
+ ^ anObject
+ !
Item was added:
+ ----- Method: WeakFinalizationRegistry>>do: (in category 'enumerating') -----
+ do: aBlock
+ ^self protected: [
+ valueDictionary keysDo: aBlock.
+ ].
+ !
Item was added:
+ ----- Method: WeakFinalizationRegistry>>finalizeValues (in category 'finalization') -----
+ finalizeValues
+ "Finalize any values, which happen to stocked in our list, due to some weak references become garbage"
+
+ | finalizer |
+
+ HasNewFinalization == true ifFalse: [
+ self protected: [ valueDictionary finalizeValues ].
+ ^ self ].
+
+ self protected: [ finalizer := list swapWithNil ].
+
+ "We don't need to proted a following loop from concurrent access,
+ because at the moment we're finalizing values,
+ only we can access this list of finalizers, because valueDictionary already see them
+ as an unused slots, because they're associated with key == nil"
+
+ [ finalizer notNil ] whileTrue: [
+ | next |
+ next := finalizer next.
+ finalizer finalizeValues.
+ finalizer := next
+ ].
+ !
Item was added:
+ ----- Method: WeakFinalizationRegistry>>initialize (in category 'initialize-release') -----
+ initialize
+ valueDictionary := WeakIdentityKeyDictionary new.
+ list := WeakFinalizationList new.
+ sema := Semaphore forMutualExclusion.
+ self installFinalizer.!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>installFinalizer (in category 'initialize-release') -----
+ installFinalizer
+
+ valueDictionary finalizer: #finalizeValues!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>keys (in category 'accessing') -----
+ keys
+
+ ^ valueDictionary keys!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>postCopy (in category 'copying') -----
+ postCopy
+ "should we prohibit any attempts to copy receiver?"
+ self protected: [ | oldDict |
+ sema := Semaphore forMutualExclusion.
+ oldDict := valueDictionary.
+ list := WeakFinalizationList new.
+ valueDictionary := WeakIdentityKeyDictionary new.
+ self installFinalizer.
+
+ oldDict keysAndValuesDo: [:key :value |
+ valueDictionary at: key put: (value copyWithList: list)
+ ].
+ ]!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>printElementsOn: (in category 'printing') -----
+ printElementsOn: aStream
+ sema ifNil: [^super printElementsOn: aStream].
+ aStream nextPutAll: '(<this WeakRegistry is locked>)'!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>protected: (in category 'private') -----
+ protected: aBlock
+ "Execute aBlock protected by the accessLock"
+
+ ^ sema
+ critical: aBlock
+ ifError: [ :msg :rcvr |
+ rcvr error: msg ] !
Item was added:
+ ----- Method: WeakFinalizationRegistry>>remove:ifAbsent: (in category 'printing') -----
+ remove: oldObject ifAbsent: exceptionBlock
+ "Remove oldObject as one of the receiver's elements."
+
+ oldObject ifNil: [ ^nil ].
+ ^(self protected: [ valueDictionary removeKey: oldObject ifAbsent: nil ])
+ ifNil: [ exceptionBlock value ]!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>removeAll (in category 'printing') -----
+ removeAll
+ "See super"
+
+ self protected:[
+ valueDictionary removeAll.
+ ].!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>size (in category 'accessing') -----
+ size
+ ^ self protected: [valueDictionary slowSize]!
Item was added:
+ ----- Method: WeakFinalizationRegistry>>species (in category 'private') -----
+ species
+ ^Set!
Item was added:
+ Object weakSubclass: #WeakFinalizerItem
+ instanceVariableNames: 'list next executor'
+ classVariableNames: ''
+ poolDictionaries: ''
+ category: 'Collections-Weak'!
Item was added:
+ ----- Method: WeakFinalizerItem classSide>>new (in category 'as yet unclassified') -----
+ new
+ ^ self basicNew: 1!
Item was added:
+ ----- Method: WeakFinalizerItem>>add: (in category 'accessing') -----
+ add: newExecutor
+
+ executor
+ ifNil: [ executor := newExecutor ]
+ ifNotNil: [
+ executor hasMultipleExecutors
+ ifTrue: [ executor add: newExecutor]
+ ifFalse: [ executor := ObjectFinalizerCollection with: executor with: newExecutor ]
+ ]!
Item was added:
+ ----- Method: WeakFinalizerItem>>clear (in category 'accessing') -----
+ clear
+ list := next := nil.!
Item was added:
+ ----- Method: WeakFinalizerItem>>copyWithList: (in category 'copying') -----
+ copyWithList: aList
+
+ ^ self copy list: aList!
Item was added:
+ ----- Method: WeakFinalizerItem>>executor (in category 'accessing') -----
+ executor
+ ^ executor!
Item was added:
+ ----- Method: WeakFinalizerItem>>finalizeValues (in category 'finalizing') -----
+ finalizeValues
+ " cleanup the receiver, so it could be reused "
+ | ex |
+ ex := executor.
+ executor := nil.
+ next := nil.
+ ex finalize.!
Item was added:
+ ----- Method: WeakFinalizerItem>>list (in category 'accessing') -----
+ list
+ ^ list!
Item was added:
+ ----- Method: WeakFinalizerItem>>list: (in category 'accessing') -----
+ list: aList
+ list := aList!
Item was added:
+ ----- Method: WeakFinalizerItem>>list:object: (in category 'initialize-release') -----
+ list: weakFinalizationList object: anObject
+ self assert: (weakFinalizationList class == WeakFinalizationList).
+ list := weakFinalizationList.
+ self at: 1 put: anObject.
+ !
Item was added:
+ ----- Method: WeakFinalizerItem>>list:object:executor: (in category 'initialize-release') -----
+ list: weakFinalizationList object: anObject executor: anExecutor
+ self assert: (weakFinalizationList class == WeakFinalizationList).
+ list := weakFinalizationList.
+ self at: 1 put: anObject.
+ executor := anExecutor!
Item was added:
+ ----- Method: WeakFinalizerItem>>next (in category 'accessing') -----
+ next
+ ^ next!
Item was added:
+ ----- Method: WeakFinalizerItem>>object (in category 'accessing') -----
+ object
+ ^ self at: 1!
Item was added:
+ ----- Method: WeakFinalizerItem>>postCopy (in category 'copying') -----
+ postCopy
+ executor hasMultipleFinalizers ifTrue: [ executor := executor copy ].!
More information about the Squeak-dev
mailing list
|