I repost the mail to the mailing-list since I do not see it in the 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.

- what is the invariant? 
that currentclass always point to the currently looked up class and 
newMethod is the found method?

- why lookupMethodFor: selector InDictionary: dictionary is defined in StackInterpreter but never used
only in CoInterpreter?

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);
}