Unsynchronized table which tracks wire handle to object mappings, as well as ClassNotFoundExceptions associated with deserialized objects. This class implements an exception-propagation algorithm for determining which objects should have ClassNotFoundExceptions associated with them, taking into account cycles and discontinuities (e.g., skipped fields) in the object graph.
General use of the table is as follows: during deserialization, a given object is first assigned a handle by calling the assign method. This method leaves the assigned handle in an "open" state, wherein dependencies on the exception status of other handles can be registered by calling the markDependency method, or an exception can be directly associated with the handle by calling markException. When a handle is tagged with an exception, the HandleTable assumes responsibility for propagating the exception to any other objects which depend (transitively) on the exception-tagged object.
Once all exception information/dependencies for the handle have been registered, the handle should be "closed" by calling the finish method on it. The act of finishing a handle allows the exception propagation algorithm to aggressively prune dependency links, lessening the performance/memory impact of exception tracking.
Note that the exception propagation algorithm used depends on handles being assigned/finished in LIFO order; however, for simplicity as well as memory conservation, it does not enforce this constraint.