[strongtalk] r186 committed - Allow GC Aliens to be garbage collected when no longer referenced

2 views
Skip to first unread message

codesite...@google.com

unread,
Dec 14, 2009, 6:14:42 PM12/14/09
to strongta...@googlegroups.com
Revision: 186
Author: StephenLRees
Date: Mon Dec 14 15:12:21 2009
Log: Allow GC Aliens to be garbage collected when no longer referenced
http://code.google.com/p/strongtalk/source/detail?r=186

Added:
/branches/gcc-linux/StrongtalkSource/WeakSet.dlt
/branches/gcc-linux/StrongtalkSource/WeakSetTest.dlt
Modified:
/branches/gcc-linux/StrongtalkSource/Alien.dlt
/branches/gcc-linux/StrongtalkSource/AlienClassTest.dlt
/branches/gcc-linux/StrongtalkSource/AlienWeakTable.dlt

=======================================
--- /dev/null
+++ /branches/gcc-linux/StrongtalkSource/WeakSet.dlt Mon Dec 14 15:12:21
2009
@@ -0,0 +1,55 @@
+Delta define: #WeakSet as: (
+(Class subclassOf: 'Set' instanceVariables: 'dependents <NotifyingObject>
+tableDependent <BlockDependent>
+')) !
+
+(Delta mirrorFor: #WeakSet) revision: '$Revision:$'!
+
+(Delta mirrorFor: #WeakSet) group: 'Unclassified'!
+
+(Delta mirrorFor: #WeakSet)
+comment:
+''!
+
+! (Delta mirrorFor: #WeakSet) methodsFor: 'private-accessing' !
+
+
+table: newTable <WeakArray[A|Object]>
+
+ self table isNil
+ ifFalse: [self table removeWeakDependent: tableDependent].
+ newTable addWeakDependent: tableDependent.
+ super table: newTable! !
+
+! (Delta mirrorFor: #WeakSet) methodsFor: 'private-computations' !
+
+
+newTableWithSize: tableSize <Int> ^ <WeakArray[A|Object]>
+
+ ^WeakArray[A|Object] new: tableSize! !
+
+! (Delta mirrorFor: #WeakSet) methodsFor: 'private-initialization' !
+
+
+initCapacity: cap <Int>
+
+ dependents := NotifyingObject new.
+ tableDependent := BlockDependent
+ updateBlock: [:aspect :victim |
+ self size: self size - 1.
+ dependents
+ changed: #finalize
+ with: victim].
+ super initCapacity: cap! !
+
+! (Delta mirrorFor: #WeakSet) methodsFor: 'weak dependents' !
+
+
+addWeakDependent: dependent
+
+ dependents addDependent: dependent!
+
+removeWeakDependent: dependent
+
+ dependents removeDependent: dependent! !
+
=======================================
--- /dev/null
+++ /branches/gcc-linux/StrongtalkSource/WeakSetTest.dlt Mon Dec 14
15:12:21 2009
@@ -0,0 +1,70 @@
+Delta define: #WeakSetTest as: (
+(Class subclassOf: 'TestCase' instanceVariables: '')) !
+
+(Delta mirrorFor: #WeakSetTest) revision: '$Revision:$'!
+
+(Delta mirrorFor: #WeakSetTest) group: 'Unclassified'!
+
+(Delta mirrorFor: #WeakSetTest)
+comment:
+''!
+
+! (Delta mirrorFor: #WeakSetTest) methodsFor: 'testing' !
+
+
+add: count <int> to: set <Set>
+
+ count timesRepeat: [set add: Object new]!
+
+testAddShouldAddItemToSet
+
+ | set victim finalizedObject listener dead |
+ set := WeakSet new.
+ victim := Object new.
+ set add: victim.
+ self assert: (set includes: victim).
+ listener := BlockDependent
+ updateBlock: [:aspect :obj | dead := obj].
+ set addWeakDependent: listener.
+ victim := nil.
+ VM collectGarbage.
+ Processor yield.
+ self deny: dead isNil.
+ self deny: (set includes: dead).
+ set add: dead.
+ self assert: (set includes: dead)!
+
+testRemovedWeakDependentShouldNotReceiveUpdate
+
+ | set victim finalizedObject listener dead |
+ set := WeakSet new.
+ victim := Object new.
+ set add: victim.
+ self assert: (set includes: victim).
+ listener := BlockDependent
+ updateBlock: [:aspect :obj | dead := obj].
+ set addWeakDependent: listener.
+ set removeWeakDependent: listener.
+ victim := nil.
+ VM collectGarbage.
+ Processor yield.
+ self assert: dead isNil!
+
+testShouldOnlyNotifyOncePerObjectFollowingGrowth
+
+ | set finalizedObject listener dead strong count|
+ count := 0.
+ set := WeakSet new: 4.
+ strong := Set new: 4.
+ self add: 5 to: strong.
+ set addAll: strong.
+ self assert: set size = 5.
+ listener := BlockDependent
+ updateBlock: [:aspect :obj | count := count + 1].
+ set addWeakDependent: listener.
+ strong := nil.
+ VM collectGarbage.
+ Processor yield.
+ self assert: count = 5.
+ self assert: set size = 0! !
+
=======================================
--- /branches/gcc-linux/StrongtalkSource/Alien.dlt Sun Sep 13 14:52:44 2009
+++ /branches/gcc-linux/StrongtalkSource/Alien.dlt Mon Dec 14 15:12:21 2009
@@ -120,11 +120,10 @@
newGC: size <Integer> ^<X>

| alien address |
- self unimplemented.
alien := self primitiveNew: 8.
alien size: size negated.
address := self Ccalloc: size.
- GCMallocedAliens add: alien finalizing: address.
+ self gcMallocedAliens add: alien.
^alien
addressField: address;
initialize
@@ -161,6 +160,14 @@
! (Delta mirrorFor: #Alien) classSide methodsFor: 'private - accessing' !


+gcMallocedAliens ^<WeakSet>
+
+ GCMallocedAliens isNil
+ ifTrue: [GCMallocedAliens := WeakSet new.
+ GCMallocedAliens addWeakDependent: (
+ BlockDependent updateBlock: [:aspect :alien | alien free])].
+ ^GCMallocedAliens!
+
loadedLibraries

LoadedLibraries isNil ifTrue:
=======================================
--- /branches/gcc-linux/StrongtalkSource/AlienClassTest.dlt Sun Sep 13
14:52:44 2009
+++ /branches/gcc-linux/StrongtalkSource/AlienClassTest.dlt Mon Dec 14
15:12:21 2009
@@ -78,11 +78,19 @@
self assert: alien size == TestAlien dataSize negated.
self assert: alien address == 0!

-testNewGCUnimplemented
-
- self should: [Alien newGC: 4]
- raise: Error
- withExceptionDo: [:ex| self assert: self unimplementedText = ex
messageText]!
+testNewGCShouldBeFreedAfterGC
+
+ |gcAlien weak res|
+ gcAlien := Alien newGC: 4.
+ weak := WeakSet new.
+ weak add: gcAlien.
+ weak addWeakDependent: (BlockDependent updateBlock: [:a :dead| res :=
dead]).
+ self deny: gcAlien address = 0.
+ gcAlien := nil.
+ VM collectGarbage.
+ (Delay forMilliseconds: 10) wait.
+ self deny: res isNil.
+ self assert: res address = 0!

testPrimLoadLibraryWin32

=======================================
--- /branches/gcc-linux/StrongtalkSource/AlienWeakTable.dlt Sun Dec 13
16:47:01 2009
+++ /branches/gcc-linux/StrongtalkSource/AlienWeakTable.dlt Mon Dec 14
15:12:21 2009
@@ -64,5 +64,5 @@
strongArray := Array new: 1024.
owner := anOwner.
weakArray addWeakDependent: (BlockDependent
- updateBlock: [:aspect| self finalizeValues])! !
-
+ updateBlock: [:aspect :object | self finalizeValues])! !
+
Reply all
Reply to author
Forward
0 new messages