[Vm-dev] Problem with Proxies, objects and MethoDict

Mariano Martinez Peck marianopeck at gmail.com
Wed Sep 29 12:03:14 UTC 2010

On Wed, Sep 29, 2010 at 3:42 AM, Eliot Miranda <eliot.miranda at gmail.com>wrote:

> On Tue, Sep 28, 2010 at 1:29 PM, Mariano Martinez Peck <
> marianopeck at gmail.com> wrote:
>> Hi folks. I am trying to do something and I found a VM crash. Suppose I
>> want to swap out a class, do a become with a proxy (that with the DNU will
>> load the class back). In addition, I have instances of the swapped class.
>> Example of code (will crash in the last line):
>> o := MyObject new.
>> o foo: 123.
>> p := ClassProxy new.
>> p become: MyObject.
>> o == nil.
>> o foo.
>> My Object just extends Object, has an instVar 'foo',  and implements the
>> accessors.
>> ClassProxy implements:
>> become: aClass
>>     className := aClass name.
>>     aClass fileOut.
>>     super become: aClass
>> and
>> doesNotUnderstand: aMessage
>>     | reloadedClass |
>>     (FileStream fileNamed: className, '.st') fileIn.
>>     reloadedClass := Smalltalk at: className.
>>     self becomeForward: reloadedClass.
>>     ^aMessage sendTo: reloadedClass
>> So....does someone know why the crash?
> I'm not sure but here are some possible reasons...
> 1. you didn't flush the method lookup cache after doing the becomeForward:
> and the perform in sentTo: found a stale method and boom.

Thanks Eliot. I was checking the code of the become in
#primitiveArrayBecome  and it seems that in #mapPointersInObjectsFrom: self
startOfMemory to:
they do the "self flushMethodCacheFrom: memStart to: memEnd."

Anyway, I tried it with

| o p |
o := MyClass new.
o foo: 123.
p := ClassProxy new.
p become: MyClass.
MyClass flushCache.
ClassProxy flushCache.
o == nil.
Transcript show: o class name; cr.
o foo.

but same results.

Now, something interesting is that "Transcript show: o class name; cr."
prints "MyClass". Is this correct?

> 2. you became from a class with N inst vars to one with N+M inst vars and
> the methods of the new class accessed inst vars > N which are off the end of
> your instance, causing the VM to read invalid oops and boom.
My case is even more complicated. I want to become from a CLASS to an
INSTANCE. I mean, I want to become the class MyClass with AN INSTANCE of
PROXY CLASS. Then the proxy class uses te DNU to bring the other back.

Now I was thinking that maybe the proxy class should not extend from
ProtoObject but from Behavior or similar?  But I want smaller objects...I
don't want to spend instances in "uperclass methodDict format'"  since the
only thing I have to do is with DNU bring back other object.

Finally, I have a question. I tried to look at the #become but I didn't get
it... When I do a become from a class to an object for example, if there
were (normal) pointers (slots in other objects) to that class, then they are
updated and point to the other object. However, what happens with the
instances of that class?  is the class pointer in their object header
consider like a normal pointer? are those piointers updated also by the
#become?    Maybe they are not and this is why  "Transcript show: o class
name; cr."   prints "MyClass"   ?

Sorry for the newbie question...I am learning all this...



> So a) always flush the method lookup cache and b) /never/ cause the VM to
> read past an object by changing the class underneath an object such that the
> class accesses more inst vars than the instance has.
>> how can I solve it ?
>> Thanks in advance
>> Mariano
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20100929/ba2026b4/attachment.htm

More information about the Vm-dev mailing list