[Vm-dev] problem with Interpreter>>#printNameOfClass:count:

Mariano Martinez Peck marianopeck at gmail.com
Mon Apr 25 15:53:18 UTC 2011


On Fri, Apr 1, 2011 at 5:51 AM, Javier Pimás <elpochodelagente at gmail.com>wrote:

>
> Hi, this method of Interpreter is used for debugging, and should print the
> name of the class passed in console:
>
> printNameOfClass: classOop count: cnt
> "Details: The count argument is used to avoid a possible infinite recursion
> if classOop is a corrupted object."
>
> cnt <= 0 ifTrue: [ ^ self print: 'bad class' ].
> (self sizeBitsOf: classOop) = (7 * self bytesPerWord) "(Metaclass
> instSize+1 * 4)"
>  ifTrue: [self printNameOfClass: (self fetchPointer: 5 "thisClass"
> ofObject: classOop)
> count: cnt - 1.
>  self print: ' class']
> ifFalse: [self printStringOf: (self fetchPointer: 6 "name" ofObject:
> classOop)]
>
> it's logic is this: if the classOop is of a normal Class instance, it
> should use the instance var number six,
>
>
which corresponds to the class' name. If not, then the classOop represents a
> Metaclass instance, and then it will fetch inst var number 5, which is the
> corresponding class, print its name, and then print 'class' to let you
> distinguish it that it is a metaclass.
>

> The problem of the method is that it determines if it's a class instance or
> a metaclass instance by looking at the size of the oop, which seems to have
> changed, at least in pharo (Metaclass instSize+1 * 4 = 36 =
> 9*bytesPerWord).
>

> The method could be fixed by changing 7 to 9 then. But it will break if
> Metaclass changes again.
>

yes


> So I have this idea: make it check if the classOop is a metaclass instance.
> Metaclass class is not a special object, but can be obtained by accessing
> any special one, like with
>
> Integer class class
>
> or directly with
>
> nil class class class (!!)
>
> then the proposed code is:
>
> printNameOfClass: classOop count: cnt "Details: The count argument is used
> to avoid a possible infinite recursion if classOop is a corrupted object." |
> metaclassClass | cnt <= 0 ifTrue: [ ^ self print: 'bad class' ].
> metaclassClass := self fetchClassOf: (self fetchClassOf: (self fetchPointer:
> ClassInteger ofObject: specialObjectsOop)). metaclassClass = (self
> fetchClassOf: classOop) "Is it a metaclass?" ifTrue: [self printNameOfClass:
> (self fetchPointer: 5 "thisClass" ofObject: classOop) count: cnt - 1. self
> print: ' class'] ifFalse: [self printStringOf: (self fetchPointer: 6 "name"
> ofObject: classOop)]
>
>

Looking at Cog, I think Eliot has already solved this problem:

printNameOfClass: classOop count: cnt
    "Details: The count argument is used to avoid a possible infinite
recursion if classOop is a corrupted object."
    <inline: false>
    (classOop = 0 or: [cnt <= 0]) ifTrue: [^self print: 'bad class'].
    ((objectMemory sizeBitsOf: classOop) = metaclassSizeBytes
      and: [metaclassSizeBytes > (thisClassIndex * BytesPerWord)])
"(Metaclass instSize * 4)"
        ifTrue: [self printNameOfClass: (objectMemory fetchPointer:
thisClassIndex ofObject: classOop) count: cnt - 1.
                self print: ' class']
        ifFalse: [self printStringOf: (objectMemory fetchPointer:
classNameIndex ofObject: classOop)]


And metaclassSizeBytes is set in a "similar" way you proposed:

StackInterpreter >> initializeExtraClassInstVarIndices
    "Initialize metaclassSizeBytes and thisClassIndex which are used in
debug printing, and
     classNameIndex which is used not only for debug printing but for
is:KindOf: & is:MemberOf:
     via classNameOf:is: (evil but a reality we have to accept)."
    | classArrayObj classArrayClass |
    classNameIndex := 6. "default"
    thisClassIndex := 5. "default"
    classArrayObj := objectMemory splObj: ClassArray.
    classArrayClass := objectMemory fetchClassOfNonInt: classArrayObj.
    metaclassSizeBytes := objectMemory sizeBitsOf: classArrayClass.
"determine actual (Metaclass instSize * 4)"
 ......


So...it is correct to assume that this is solved in Cog ?

Thanks

Mariano




>
> I'd also like to have this included too:
>
> printClassOf: oop
>  "Print the class of the oop in console"
> self printNameOfClass: (self fetchClassOf: oop) count: 5.
>
> which is simple but pretty much useful.
>
> What do you think?
>
> Regards,
>            Javier.
>
> --
> Javier Pimás
> Ciudad de Buenos Aires
>
>


-- 
Mariano
http://marianopeck.wordpress.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20110425/71cc12ce/attachment.htm


More information about the Vm-dev mailing list