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 ].! |
Free forum by Nabble | Edit this page |