Modifying MethodContext?

Stephen Pair spair at advantive.com
Tue Jul 24 13:47:48 UTC 2001


Andreas,

>> I need to add an instance variable to MethodContext.
>No. You don't. Not unless you're trying to modify the execution of
contexts (e.g., the VM aspect of it). Adding "instance variables" can be
done in a much simpler and less intrusive way.

Yes, I do.  ;)  I am trying to modify the execution of contexts (the VM
aspect).  I need an additional slot for what I'm trying to do.  Perhaps
it would help to explain what I'm doing...maybe there is a better way.

I'm creating a "forwarder" capability.  In Squeak, due to the direct
mapped memory model, a become: operation, under certain circumstances
(large image, object in old space) can take a very long time (a half
second or more).  Therefore, for certain applications, using become is
not appropriate.

The application that I have in mind is mapping external objects (they
may be in a database of some sort, or in another image).  With an object
table based memory model, you have the option of employing a design that
uses proxies, which morph themselves into the real object when sent a
message.  Without the object table, you cannot employ this design (if
you want reasonable performance), and the alternatives are pretty ugly.

All of this fits into a mult-level transaction service that I've been
working on for Squeak (it employs a copy on write scheme, object
locking, reduced conflict classes, modified tools to allow working in
the context of a transaction, etc).  This modification isn't need by the
transaction service itself, but rather with one of the primary uses of
the transaction service, the mapping of external objects...I should have
version 0.1 of the transaction service a few days after I determine
whether this forwarding scheme is going to fly or not.

So far, I have the forwarder working this way...it's a class (called
Forwarder), which is a subclass of nil and understands nothing (and I
mean nothing).  On the class side, I have a couple of primitives to set
and get the first slot of any Forwarder instance (they wont work as
instance methods...keep reading).  The first slot contains the
"forwardee."

Now, when a message is sent to an instance of a Forwarder, the VM
detects this, and changes the receiver to that of the object contained
in its first slot.  Method lookup and execution then occurs on this new
receiver.  This has the nice benefit of not creating any context for the
Forwarder in the context stack (therefore it doesn't show up in the
debugger).

What I have described so far is what I've got working...what follows is
what's left to do.  

To complete the forwarder, we must ensure that all references to self in
the methods of a forwardee object are actually referring back to the
instance of the forwarder.  But, for instance variable access and such,
we still need to refer to the forwardee (thus the need for an additional
slot in MethodContext).  All messages sent to self in the forwardee
methods will get routed back through the forwarder, but more
importantly, any references to self are actually to the forwarder (thus,
references to the forwardee can be controlled).

Why?  You've probably figured out where I'm going with this by now, but
just to re-iterate...basically, with this capability, we effectively add
back to Squeak on of the major benefits lost in a direct mapped memory
model...the ability to reference objects indirectly.  With the
forwarder, we can now create proxy objects, such that when the real
object is materialized, we can change the forwardee slot in its
forwarder to the real object, avoiding a become, yet not needing to know
in advance the real object's class, size, or anything.

Later, I may try and add a bytecode for doing a "delegated send" that
would allow any object to send a message to another object, and have all
references to self lead back to the delegator...but I don't know yet if
it will work for that case.

So...how do I add an instance variable to MethodContext and step an
image from one format to another?  

(I've worked through every conceivable way to achieve these ends without
modifying the VM and all options lead to a design which would impose
rules on the developer using the service...for instance, writing code
like "self realSelf" and overriding all methods in the parent class by
recompiling them on the subclass, etc...therefore, I would like to try a
VM based approach...what's there to lose except a little time).

Cheers,
Stephen







More information about the Squeak-dev mailing list