73 Therefore, be prepared, that the watcher mechanism will vanish in the |
73 Therefore, be prepared, that the watcher mechanism will vanish in the |
74 future. |
74 future. |
75 " |
75 " |
76 ! ! |
76 ! ! |
77 |
77 |
|
78 !WeakArray class methodsFor:'initialization'! |
|
79 |
|
80 initialize |
|
81 "setup the private signal" |
|
82 |
|
83 RegistrationFailedSignal isNil ifTrue:[ |
|
84 Object initialize. |
|
85 |
|
86 RegistrationFailedSignal := Object errorSignal newSignalMayProceed:true. |
|
87 RegistrationFailedSignal nameClass:self message:#registrationFailedSignal. |
|
88 RegistrationFailedSignal notifierString:'weakArray registration failed'. |
|
89 ] |
|
90 ! ! |
|
91 |
78 !WeakArray class methodsFor:'instance creation'! |
92 !WeakArray class methodsFor:'instance creation'! |
79 |
93 |
80 new:size |
94 new:size |
81 "return a new weakArray with size slots" |
95 "return a new weakArray with size slots" |
82 |
96 |
83 |newArray| |
|
84 |
|
85 "This is a kludge: I would like to set WEAK-flag in the classes |
97 "This is a kludge: I would like to set WEAK-flag in the classes |
86 initialize method, but no order of class-init is defined ... |
98 initialize method, but no order of class-init is defined (yet) ... |
87 Therefore it could happen, that a WeakArray is used by other |
99 Therefore it could happen, that a WeakArray is used by other |
88 class inits BEFORE this initialize is evaluated. To avoid this, |
100 class inits BEFORE this initialize is evaluated. To avoid this, |
89 the WEAK bit in the class is set when the first WeakArray is |
101 the WEAK bit in the class is set here, when the first WeakArray is |
90 created." |
102 created." |
91 |
103 |
92 self flags:(Behavior flagWeakPointers). |
104 self flags:(Behavior flagWeakPointers). |
93 ObjectMemory disposeInterruptHandler:self. |
105 ObjectMemory disposeInterruptHandler:self. |
94 |
106 |
95 newArray := self basicNew:size. |
107 ^ (self basicNew:size) registerAsWeakArray |
|
108 ! ! |
|
109 |
|
110 !WeakArray methodsFor:'GC registration'! |
|
111 |
|
112 registerAsWeakArray |
|
113 "register the receiver in the VM - |
|
114 i.e. tell the VM to nil disposed entries in the receiver |
|
115 and notify the disposeInterruptHandler whenever that happened." |
|
116 |
|
117 |ok| |
96 %{ |
118 %{ |
97 OBJ ok; |
|
98 OBJ __addShadowObject(); |
119 OBJ __addShadowObject(); |
99 |
120 |
100 ok = __addShadowObject(newArray, 0); |
121 ok = __addShadowObject(self, 0); |
101 if (ok == false) { |
122 if (ok == false) { |
102 /* |
123 /* |
103 * this happens when too many shadow objects are |
124 * this happens when too many shadow objects are |
104 * already there, collect garbage to get rid of |
125 * already there, collect garbage to get rid of |
105 * obsolete ones, and try again. |
126 * obsolete ones, and try again. |
106 * since a full collect is expensive, we try |
127 * since a full collect is expensive, we try |
107 * a scavenge first, doing a full collect only if |
128 * a scavenge first, doing a full collect only if |
108 * that does not help. |
129 * that does not help. |
109 */ |
130 */ |
110 nonTenuringScavenge(__context); |
131 nonTenuringScavenge(__context); |
111 ok = __addShadowObject(newArray, 0); |
132 ok = __addShadowObject(self, 0); |
112 if (ok == false) { |
133 if (ok == false) { |
113 /* try more ... */ |
134 /* try more ... */ |
114 scavenge(__context); |
135 scavenge(__context); |
115 ok = __addShadowObject(newArray, 0); |
136 ok = __addShadowObject(self, 0); |
116 if (ok == false) { |
137 if (ok == false) { |
117 /* hard stuff - need full collect */ |
138 /* hard stuff - need full collect */ |
118 __garbageCollect(__context); |
139 __garbageCollect(__context); |
119 ok = __addShadowObject(newArray, 0); |
140 ok = __addShadowObject(self, 0); |
120 if (ok == false) { |
141 if (ok == false) { |
121 /* mhmh - it seems that there are really many shadow |
142 /* mhmh - it seems that there are really many shadow |
122 objects around - force creation */ |
143 objects around - force creation */ |
123 ok = __addShadowObject(newArray, 1); |
144 ok = __addShadowObject(self, 1); |
124 if (ok == false) { |
145 if (ok == false) { |
125 /* no chance - something must be wrong */ |
146 /* no chance - something must be wrong */ |
126 newArray = nil; |
|
127 } |
147 } |
128 } |
148 } |
129 } |
149 } |
130 } |
150 } |
131 } |
151 } |
132 %} |
152 %}. |
133 . |
153 ok ifFalse:[ |
134 ^ newArray |
154 ^ RegistrationFailedSignal raiseRequestWith:self |
|
155 ] |
135 ! ! |
156 ! ! |
136 |
157 |
137 !WeakArray class methodsFor:'dispose handling'! |
158 !WeakArray class methodsFor:'dispose handling'! |
138 |
159 |
139 allShadowObjectsDo:aBlock |
160 allShadowObjectsDo:aBlock |