becomeForward makes corrupted objects

Tim Rowledge tim at sumeru.stanford.edu
Tue Nov 30 01:48:32 UTC 2004


Hokay, after some head-scratching, debugging and experimenting I have
an explanation of why 'a become a' will blow the VM, why 'a
forwardBecome a' is ok and a plausible fix.

The key problem is that building the forwarding blocks used (along with
the compaction phase of the garbage collector) is not idempotent - the
first time it is done for an object _corrupts_ that object and stores
restoration info in the forwarding block. That's how the compaction
works. However, refer to the same object in a become so that you need
to build another forwarding block and you're violatin' th'law, boy. You
end up with the poor object owning a forwarding block with a completely
evil set of bits. When it comes to the compacting code's turn to do its
job the excrement impacts the rotating impeller since insted of a nice
object header word it stumbles over a mangled pointer with extra fries,
err, flags.

So now we can see why 'a become 'a fails - two forwarding blocks for one
object, and why 'a forwardBecome a' is ok - only one block is built
per forwared object. Note that we will also get into trouble if any
attempt is made to do
{a.b} become {b.a}
because of two forwarding blocks for both a & b. Likewise, expect
problems with
{a. a} becomeForward {b. c}.
I doubt anyone would deliberately write either case but code using the
become facility might easily end up doing so; for example ImageSegment
loading seems to often do 'a becomeForward a' type mutations. If it
happens that an object is refered to twice in that process, ka-boom.

The initial VM fix for the failure of 'a become a' was to fail the prim
but that stopped SqueakMap from loading because of the ImageSegment
issue mentioned above. My revised suggestion works somewhat better and
simply skips the a=>a pairs in the become prim loop. This means that
there is some time 'wasted' in such cases but at least it is cpu time
and not frustrated user time. The fix DOES NOT prevent problems such as
{a. a} becomeForward {b. c}.
which I strongly think would be better caught upfront in the image. In
general I don't see any meaningful reason to allow things like
{a.b} become {b.a}

tim
--
Tim Rowledge, tim at sumeru.stanford.edu, http://sumeru.stanford.edu/tim
Strange OpCodes: JSP: Jump on Sexy Programmer



More information about the Squeak-dev mailing list