eXept Software AG Logo

Smalltalk/X Webserver

Documentation of class 'WeakArray':

Home

Documentation
www.exept.de
Everywhere
for:
[back]

Class: WeakArray


Inheritance:

   Object
   |
   +--Collection
      |
      +--SequenceableCollection
         |
         +--ArrayedCollection
            |
            +--WeakArray

Package:
stx:libbasic
Category:
Collections-Weak
Version:
rev: 1.108 date: 2023/10/06 11:54:48
user: stefan
file: WeakArray.st directory: libbasic
module: stx stc-classLibrary: libbasic

Description:


WeakArrays can be used to trace disposal of objects; in contrast to other
objects, references by WeakArrays will NOT keep an object from being
garbage collected.
Instead, whenever an object kept in a WeakArray dies, its entry is set to a SmallInteger,
and the WeakArray is informed by the storage manager. The WeakArray itself
then informs possible dependents via the dependency mechanism.

WeakArrays are used to track disposal of objects which keep external
world resources. For example, FileStreams must close their underlying
file when disposed (otherwise you could run out of OS filedescriptors).
This can be done by keeping the FileStream objects in a weakArray, and
keep a parallel array of filedescriptors. Whenever a fileStream is
freed, search both arrays for an index where the stream is set to a SmallInteger, but the
filedescriptor is non-nil. Then close that file, and nil the filedescriptor
entry. Notice, that there is a class (Registry) which does exactly this in
a more programmer friendly way.

Another application is caching of data: keep it in a weakArray, so the
data in that cache will not be unreclaimable due to being cached.
(for example, the ResourcePack class uses a WeakArray to cache recently
 used resource data for a while).

The way in which weakArrays get informed by the runtime system is via
an interrupt (DisposeInterrupt) which is first sent to the disposeHandler
(typically ObjectMemory). ObjectMemory then takes the required steps to
notify all weakArrays via the #lostPointer message.
The reason for not sending messages directly from the VM is to make it
possible to run the finalization code at lower priority or from another class.
Also, as a side effect, it is possible to delay finalization by blocking
interrupts. (thus, the actual sending of the #lostPointer message is under
control of Smalltalk code, which is modifyable).


A weakArray notifies its dependents via normal dependency notfications.


As a possible option, we could perform the weakArray scanning only in
the oldSpace reclamation code - this would remove most of the overhead,
but will lead to much longer delayed finalization .... we will see.


[instance variables:]

    dependents                  get informed via #change notifiction
                                that the weakArray has lost pointers.
                                Having the dependents here is an optimization.

[class variables:]

    RegistrationFailedSignal    raised if a weakArray cannot be
                                registered by the VM. This only happens,
                                if the VM has to resize its internal tables
                                and is running out of malloc-memory.

[memory requirements:]
    OBJ-HEADER + (size * ptr-size) + ptr-size
               + sizeof(dependents-collection)

copyright

COPYRIGHT (c) 1991 by Claus Gittinger All Rights Reserved This software is furnished under a license and may be used only in accordance with the terms of that license and with the inclusion of the above copyright notice. This software may not be provided or otherwise made available to, or used by, any other person. No title to or ownership of the software is hereby transferred.

Class protocol:

initialization
o  initialize
adjust my class flags and setup the private signal

instance creation
o  basicNew: size
return a new weakArray with size slots

queries
o  isBuiltInClass
return true if this class is known by the run-time-system.
Here, true is returned for myself, false for subclasses.


Instance protocol:

GC registration
o  registerAsWeakArray
register the receiver in the VM -
i.e. tell the VM to nil disposed entries in the receiver
and notify the disposeInterruptHandler whenever that happened.

accessing
o  at: index ifAbsent: exceptionValue
return the indexed instance variable with index, anInteger,
or exceptionValue if the index is invalid.

o  at: index ifInvalid: exceptionalValue
return the indexed instance variable with index, anInteger,
but only if still valid; otherwise return the value from exceptionalValue

o  basicAt: index
return the indexed instance variable with index, anInteger.
Reimplemented here for IGC readBarrier.
(You don't have to understand this.)

o  basicAt: index put: someObject
store someObject in the weakArray at some index.

o  validElements
answer all of my values that are neither garbage collected nor nil as an Array

add
o  addAllTo: aCollection
add all elements of the receiver that are still valid to aCollection.
Return aCollection.
Redefined here to exclude outdated elements.

copying
o  skipInstvarIndexInDeepCopy: index
a helper for deepCopy; only indices for which this method returns
false are copied in a deep copy.

copying-private
o  postCopy
the copy does not share dependencies

o  postCopyFrom: original
the copy does not share dependencies

o  postDeepCopy
the copy does not share dependencies

dependents access
o  addDependent: anObject
make the argument, anObject be a dependent of the receiver

o  dependents
return the dependents of the receiver.

o  dependents: aCollectionOrNil
set the dependents of the receiver

o  dependentsDo: aBlock
evaluate aBlock for all of my dependents

o  removeDependent: anObject
make the argument, anObject be independent of the receiver

enumerating
o  do: aBlock
evaluate the argument, aBlock for each (living) element in the collection.
- reimplemented for IGC readBarrier.
You don't have to understand this.

o  forAllDeadIndicesDo: aBlock replacingCorpsesWith: newValue
evaluate the argument, aBlock for all indices where elements have been
replaced by a SmallInteger (due to a collected object), and replace the element
with newValue.
In the current implementation, the block sees the newValue (i.e. it is
changed before the block is called); this behavior is not guaranteed
with future versions.
Be aware, that while indices are being enumerated, other
slots may change iff the garbage collector finds new garbage.

o  keysAndValuesDo: aBlock
evaluate the argument, aBlock for each element in the collection.
- reimplemented for speed.
You don't have to understand this.

o  nonNilElementsDo: aBlock
evaluate the argument, aBlock for each non-nil element (treats evacuated values as nil)

o  replaceCorpsesWith: newValue
replace all indices where elements have been replaced by a SmallInteger
(due to a collected object), with newValue.
Answer the index of the last entry that is nil or has been nilled, or 0 if there is none.
Be aware, that while indices are being enumerated, other
slots may change iff the garbage collector finds new garbage.

o  validElementsDo: aBlock
evaluate the argument, aBlock for each non-nil/non-evacuated element

notification
o  lostPointer
I lost a pointer; tell dependents.
This is sent from the finalization code in ObjectMemory.

testing
o  hasValidElements
answer true, if i contain at least one element that is neither nil nor garbage collected

o  isWeak
return true if the receiver has weak references to its elements.

o  isWeakCollection
return true, if the receiver has weak references to its elements.



ST/X 7.7.0.0; WebServer 1.702 at 20f6060372b9.unknown:8081; Tue, 10 Dec 2024 21:45:03 GMT