Limitations
The current Swapper implementation presents some limitations, which are listed below.
Any object containing an instance of CompiledMethod will not be unloaded. (This can be overridden with certain restrictions described in CompiledMethods).
Classes are unloaded by using "lightweight" dumping replacements in a transparent manner. (An override is provided to allow dumping of specified classes as normal objects for specialized applications that require it). Lightweight here means that a compact representation is dumped for classes.
If an error occurs during loading then the entire operation is aborted. There is no partial completion of the loading operation. The position at the swapping stream is not specified when the operation is aborted.
Objects dumped by this release of the Swapper can not be loaded by previous releases.
Special care should be taken when packaging an application for run time. Because of the way in which instance variable based replacement works, and the way in which dumping replacements are implemented (instance variables such as description of ClassDescription are used), you should be aware that they cannot be removed in a runtime image. They can be nil, but they must be present. Also, the names of instance variables of a given class (instance variable instVarNames in ClassDescription) should be present and not nil at runtime so that checking can be done and proper mutation performed.
Classes such as SmallInteger, True, False, Character and UndefinedObject should not define any loading or dumping replacement. They are special classes and optimizations in the dumping and loading process do not guarantee that a replacement object will be asked for objects of these classes.
Since the Swapper is now a framework, you can redefine replacement behavior. Due to internal optimizations, by default, not all loaded objects are asked for their loading replacement. So, when you define new loading replacement methods, make sure you also perform one of the following:
Turn off loading optimization for the instance of ObjectLoader you use. You can use ObjectLoader instance method optimizeLoadingReplacement:. This forces the loader to send the message (that computes loading replacement) to all objects loaded. This makes the loading itself a bit slower, though how much slower will depend on the number of objects you are loading, since it is an extra message send per loaded object.
Define class method definesLoadingReplacement in the class that needs a loading replacement, and make it return true. Do this before dumping your objects. When dumping, the ObjectDumper recognizes instances of this class as objects that need to be processed on load, and makes sure that the ObjectLoader used, even when optimization is turned on, computes a loading replacement for instances of this class. Performance will still be optimal. Collisions of method names in the same class can be solved by the use of strategies. See The Swapper framework.
When you redefine class-based and instance-variable-based replacement, you also need to define the class methods definesClassBasedReplacement and definesInstVarReplacement respectively to return true, so that the ObjectDumper can know whether instances of this class need to be sent messages to compute a replacement. Collisions of method names in the same class can be solved by the use of strategies. See The Swapper framework.
Last modified date: 01/29/2015