[Vm-dev] Re: [Pharo-project] Fwd: A question about lookup and message reification

Eliot Miranda eliot.miranda at gmail.com
Wed Feb 13 20:11:11 UTC 2013


Hi Stef,

On Wed, Feb 13, 2013 at 11:40 AM, Stéphane Ducasse <
stephane.ducasse at inria.fr> wrote:

> I repost the mail to the mailing-list since I do not see it in the vm-dev
>

did you post to vm-dev?


>
> Stef
>
>
> Hi
>
> I was reading the following method in the VM code and I have a couple of
> questions:
>
> - I do not understand why lookupMethodInClass: may return a class. I was
> thinking that it would return a method.
>
>
It doesn't matter what it returns as it's return value is always ignored.
 It assigns to newMethod.  I suspect it returns currentClass because a) the
return type was always sqInt because Slang didn't support void functions,
and b) currentClass is a value in hand so probably in a register and hence
cheap to return.


> - what is the invariant?
> that currentclass always point to the currently looked up class and
> newMethod is the found method?
>
>
The input arguments are messageSelector, argumentCount and its argument,
class.  The VM suffers somewhat from being cluttered with global variables,
which is I think a legacy of the blue-book specification (the Smalltalk
code that was used to implement Interpreter in VMMaker) being derived from
the Alto and Dorado implementations in microcode.  It would be nicer if
there were fewer variables, but e.g. supplying argumentCount as a parameter
throughout all the message handling routines can be difficult, especially
when things like perform: and MNU change the argumentCount during message
send.

- why lookupMethodFor: selector InDictionary: dictionary is defined in
> StackInterpreter but never used
> only in CoInterpreter?
>
>
Well, it belongs in StackInterpreter and could be used in the other lookup
methods.  I was probably considering rewriting the other lookup routines to
use  lookupMethodFor: InDictionary: but didn't get round to it.


> Thanks
>
>
> lookupMethodInClass: class
> | currentClass dictionary found |
> <inline: false>
> self assert: class ~= objectMemory nilObject.
> currentClass := class.
> [currentClass ~= objectMemory nilObject]
> whileTrue:
> [dictionary := objectMemory fetchPointer: MethodDictionaryIndex ofObject:
> currentClass.
>
> *** trick with the cannotInterpret ***
> dictionary = objectMemory nilObject ifTrue:
> ["MethodDict pointer is nil (hopefully due a swapped out stub)
> -- raise exception #cannotInterpret:."
> self createActualMessageTo: class.
> messageSelector := objectMemory splObj: SelectorCannotInterpret.
> self sendBreak: messageSelector + BaseHeaderSize
> point: (objectMemory lengthOf: messageSelector)
> receiver: nil.
> ^self lookupMethodInClass: (self superclassOf: currentClass)].
> *** trick with the cannotInterpret end ***
>
> found := self lookupMethodInDictionary: dictionary.
> found ifTrue: [^currentClass].
> ^^^^^^^^^^^^^^^^^^^^^^^^^
>
> currentClass := self superclassOf: currentClass].
>
> "Could not find #doesNotUnderstand: -- unrecoverable error."
> messageSelector = (objectMemory splObj: SelectorDoesNotUnderstand) ifTrue:
> [self error: 'Recursive not understood error encountered'].
>
> "Cound not find a normal message -- raise exception #doesNotUnderstand:"
> self createActualMessageTo: class.
> messageSelector := objectMemory splObj: SelectorDoesNotUnderstand.
> self sendBreak: messageSelector + BaseHeaderSize
> point: (objectMemory lengthOf: messageSelector)
> receiver: nil.
> ^self lookupMethodInClass: class
>
>
> if (found) {
> return currentClass;
> }
>
>
> static sqInt
> lookupMethodInClass(sqInt class)
> {
> // StackInterpreter>>#lookupMethodInClass:   DECL_MAYBE_SQ_GLOBAL_STRUCT
>     sqInt currentClass;
>     sqInt dictionary;
>     sqInt found;
>     sqInt header;
>     sqInt index;
>     sqInt length;
>     sqInt mask;
>     sqInt methodArray;
>     sqInt nextSelector;
>     sqInt sz;
>     sqInt wrapAround;
>
> assert(class != (nilObject()));
> currentClass = class;
> while (currentClass != GIV(nilObj)) {
> dictionary = longAt((currentClass + BaseHeaderSize) +
> (MethodDictionaryIndex << ShiftForWord));
> if (dictionary == GIV(nilObj)) {
>
> /* ifTrue: */
>
> createActualMessageTo(class);
> GIV(messageSelector) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) +
> (SelectorCannotInterpret << ShiftForWord));
> sendBreakpointreceiver(GIV(messageSelector) + BaseHeaderSize,
> lengthOf(GIV(messageSelector)), null);
> return lookupMethodInClass(longAt((currentClass + BaseHeaderSize) +
> (SuperclassIndex << ShiftForWord)));
> }
> /* begin lookupMethodInDictionary: */
> /* begin fetchWordLengthOf: */
> /* begin sizeBitsOf: */
> header = longAt(dictionary);
> sz = ((header & TypeMask) == HeaderTypeSizeAndClass
> ? (longAt(dictionary - (BytesPerWord * 2))) & LongSizeMask
> : header & SizeMask);
> length = ((usqInt) (sz - BaseHeaderSize)) >> ShiftForWord;
> mask = (length - SelectorStart) - 1;
>
> /* messageSelector */
>
> index = SelectorStart + (mask & (((GIV(messageSelector) & 1)
> ? (GIV(messageSelector) >> 1)
> : (((usqInt) (longAt(GIV(messageSelector)))) >> HashBitsOffset) &
> HashMaskUnshifted)));
> wrapAround = 0;
> while (1) {
> nextSelector = longAt((dictionary + BaseHeaderSize) + (index <<
> ShiftForWord));
> if (nextSelector == GIV(nilObj)) {
> found = 0;
> goto l1;
> }
> if (nextSelector == GIV(messageSelector)) {
> methodArray = longAt((dictionary + BaseHeaderSize) + (MethodArrayIndex <<
> ShiftForWord));
> GIV(newMethod) = longAt((methodArray + BaseHeaderSize) + ((index -
> SelectorStart) << ShiftForWord));
> found = 1;
> goto l1;
> }
> index += 1;
> if (index == length) {
> if (wrapAround) {
> found = 0;
> goto l1;
> }
> wrapAround = 1;
> index = SelectorStart;
> }
> }
> found = 0;
> l1: /* end lookupMethodInDictionary: */;
> if (found) {
> return currentClass;
> }
> currentClass = longAt((currentClass + BaseHeaderSize) + (SuperclassIndex
> << ShiftForWord));
> }
> if (GIV(messageSelector) == (longAt((GIV(specialObjectsOop) +
> BaseHeaderSize) + (SelectorDoesNotUnderstand << ShiftForWord)))) {
> error("Recursive not understood error encountered");
> }
> createActualMessageTo(class);
> GIV(messageSelector) = longAt((GIV(specialObjectsOop) + BaseHeaderSize) +
> (SelectorDoesNotUnderstand << ShiftForWord));
> sendBreakpointreceiver(GIV(messageSelector) + BaseHeaderSize,
> lengthOf(GIV(messageSelector)), null);
> return lookupMethodInClass(class);
> }
>
>
>
>
>
>


-- 
best,
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20130213/0ae1ceb2/attachment-0001.htm


More information about the Vm-dev mailing list