The Inbox: Collections-Igor.Stasenko.370.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Collections-Igor.Stasenko.370.mcz

commits-2
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 ].!