Hi. Sorry if the question is newbie. I am still reading the blue book, so in case this is explained there I would just appreciate a link to it.
The problem is the following: I have implemented some functionality in Interpreter to trace objects usage. I have modified all bytecodes and different primitives and now I am almost sure I am covering all the "methods sends". Now, I have a problem with bitOr: and bitAnd: for example.
If I do 9999999999999999 bitOr: 8888888888888888888 I would like to trace both intances of LargePositiveInteger as used.
LargePositiveInteger >> bitOr: bitOr: anInteger "Primitive. Answer an Integer whose bits are the logical OR of the receiver's bits and those of the argument. Fail if the receiver or argument is greater than 32 bits. See Object documentation whatIsAPrimitive." <primitive: 15> ^ super bitOr: anInteger
So...clearly, this will fail since both obects are more than 32 bits. So....we will do ^ super bitOr: anInteger
bitOr: n "Answer an Integer whose bits are the logical OR of the receiver's bits
and those of the argument, n." | norm | <primitive: 'primDigitBitOr' module:'LargeIntegers'> norm := n normalize. ^ self digitLogic: norm op: #bitOr: length: (self digitLength max: norm digitLength)
So...it will call the primDigitBitOr in the plugin LargeIntegers
In Interpreter I put an instVar for example to flag if I need to trace or not, and several helpers and primitives methods. The "main" method is:
Interpreter >> traceObjectUsage: rcvr ((self isIntegerObject: rcvr) not and: [hasToTrace]) ifTrue: [ self internalTurnOnUsedBit: rcvr. ]
Now, the problem is, how can I trace that 8888888888888888888 was used??? 9999999999999999 is used, because at least one it goes trough the #normalSend
Two options:
1) In the fail of Interprter >> primitiveBitOr: I check if the class is LargePositiveInteger, I mark it. I don't like this solution because actually I "think" it will be used, but this is just because of the implemetnation on bitOr: in the image. Maybe it changes, I don't know.
2) Ttry to trace this in the LargeInteger plugin. I would like this idea, but I found several problems:
2.a) It is ok that I cannot access/send messages to Interpreter from plugins? It seems I am only allowed to do to InterpreterPlugin. But, I don't want to duplicate all my code from Interpreter to InterpreterProxy. 2.b) So my idea was to do something like this:
InterpreterProxy >> traceObjectUsage: anObject anObject markAsUsed
And Object >> markAsUsed will just be a primitive that actually calls #traceObjectUsage
Trying to do that, I failed because sqVirtualMachine.h was not generated automatically, thus such struct didn't understand traceObjectUsage. For that, I added by hand to sqVirtualMachine.h something like this:
#if VM_PROXY_MINOR > 8 sqInt (*traceObjectUsage)(sqInt oop); #endif
With this it compiles, but when trying to run (actually in the start) the image I get a bad access error.
2.c) why is not sqVirtualMemory, or let's say, InterpreterProxy methods not automatically generated with VMMaker? I am doing something wrong ?
2.d) I saw there are more than one sqVirtualMemory. One in "/platforms/Cross/vm" and another one in "/platforms/Cross/plugins/IA32ABI/sqVirtualMachine.h" . After testin a little, it seems in my case it is using the second one. Why we have 2? and why it is using the second one ?
Ok, thanks for any help you can give me and sorry for so many (and probably newbie) questions.
Best regards,
mariano