How to access Interpreter code from plugin?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

How to access Interpreter code from plugin?

Mariano Martinez Peck
 
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



Reply | Threaded
Open this post in threaded view
|

Re: How to access Interpreter code from plugin?

Mariano Martinez Peck
 


On Wed, Oct 13, 2010 at 5:11 PM, Mariano Martinez Peck <[hidden email]> wrote:
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


Maybe this is not possible. But even with this:

traceObjectUsage: rcvr
    "rcvr markAsUsed "
   

I have the bad access :(


 
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




Reply | Threaded
Open this post in threaded view
|

Re: How to access Interpreter code from plugin?

Igor Stasenko
In reply to this post by Mariano Martinez Peck
 
Hi, Mariano.

I don't understand, why you need to dive into specific primitive(s),
while you can simply place a hook before entering any primitive and
mark all objects, which passed as parameters
(receiver & args) as 'used', and then call primitive function?


--
Best regards,
Igor Stasenko AKA sig.
Reply | Threaded
Open this post in threaded view
|

Re: How to access Interpreter code from plugin?

Mariano Martinez Peck
 


On Wed, Oct 13, 2010 at 6:31 PM, Igor Stasenko <[hidden email]> wrote:

Hi, Mariano.

I don't understand, why you need to dive into specific primitive(s),
while you can simply place a hook before entering any primitive

is there a way to do this in a genera way or I need to do it manually for each primitive?

 
and
mark all objects, which passed as parameters
(receiver & args) as 'used', and then call primitive function?


The problem is that not all of them are "used" in all primitives. Just as an example, #bytecodeNew:

bytecodePrimNew

    messageSelector := self specialSelector: 28.
    argumentCount := 0.
    self normalSend.

I don't want to trace the receiver there, but it is really not used there. I will trace it in #normalSend.
Or sometimes a primitive fails because one of the arguments is more than 32bits or because it is not smallInteger or whatever...I don't want to mark them as used just for being a parameter. I want to mark them when they are really used by the VM.

I want to avoid as much as overhead as possible.

Right now I put the tracing in #normalSend, but then I modifed some bytecodes like those for #class or #== since they were not going throught normal send.

Thanks

Mariano
Reply | Threaded
Open this post in threaded view
|

Re: How to access Interpreter code from plugin?

Andreas.Raab
 
On 10/13/2010 9:52 AM, Mariano Martinez Peck wrote:

> On Wed, Oct 13, 2010 at 6:31 PM, Igor Stasenko <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>
>     Hi, Mariano.
>
>     I don't understand, why you need to dive into specific primitive(s),
>     while you can simply place a hook before entering any primitive
>
>
> is there a way to do this in a genera way or I need to do it manually
> for each primitive?

FWIW, it's questions like these that make people wonder if you've done
your homework. The precise question is answered on page 620 of the blue
book.

Cheers,
   - Andreas

>     and
>     mark all objects, which passed as parameters
>     (receiver & args) as 'used', and then call primitive function?
>
>
> The problem is that not all of them are "used" in all primitives. Just
> as an example, #bytecodeNew:
>
> bytecodePrimNew
>
>      messageSelector := self specialSelector: 28.
>      argumentCount := 0.
>      self normalSend.
>
> I don't want to trace the receiver there, but it is really not used
> there. I will trace it in #normalSend.
> Or sometimes a primitive fails because one of the arguments is more than
> 32bits or because it is not smallInteger or whatever...I don't want to
> mark them as used just for being a parameter. I want to mark them when
> they are really used by the VM.
>
> I want to avoid as much as overhead as possible.
>
> Right now I put the tracing in #normalSend, but then I modifed some
> bytecodes like those for #class or #== since they were not going
> throught normal send.
>
> Thanks
>
> Mariano
Reply | Threaded
Open this post in threaded view
|

Re: How to access Interpreter code from plugin?

Mariano Martinez Peck
 


On Wed, Oct 13, 2010 at 7:27 PM, Andreas Raab <[hidden email]> wrote:

On 10/13/2010 9:52 AM, Mariano Martinez Peck wrote:
On Wed, Oct 13, 2010 at 6:31 PM, Igor Stasenko <[hidden email]
<mailto:[hidden email]>> wrote:


   Hi, Mariano.

   I don't understand, why you need to dive into specific primitive(s),
   while you can simply place a hook before entering any primitive


is there a way to do this in a genera way or I need to do it manually
for each primitive?

FWIW, it's questions like these that make people wonder if you've done your homework.

Is it so hard to answer in a ploite way??

If you read my first line of the email says "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. "

is it really hard to understand and simply answer page 620 ?

Anyway, those were not my original questions.

Thanks

Mariano

 
The precise question is answered on page 620 of the blue book.

Cheers,
 - Andreas


   and
   mark all objects, which passed as parameters
   (receiver & args) as 'used', and then call primitive function?


The problem is that not all of them are "used" in all primitives. Just
as an example, #bytecodeNew:

bytecodePrimNew

    messageSelector := self specialSelector: 28.
    argumentCount := 0.
    self normalSend.

I don't want to trace the receiver there, but it is really not used
there. I will trace it in #normalSend.
Or sometimes a primitive fails because one of the arguments is more than
32bits or because it is not smallInteger or whatever...I don't want to
mark them as used just for being a parameter. I want to mark them when
they are really used by the VM.

I want to avoid as much as overhead as possible.

Right now I put the tracing in #normalSend, but then I modifed some
bytecodes like those for #class or #== since they were not going
throught normal send.

Thanks

Mariano

Reply | Threaded
Open this post in threaded view
|

Re: How to access Interpreter code from plugin?

Andreas.Raab
 
On 10/13/2010 10:44 AM, Mariano Martinez Peck wrote:

> On Wed, Oct 13, 2010 at 7:27 PM, Andreas Raab <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>
>     On 10/13/2010 9:52 AM, Mariano Martinez Peck wrote:
>
>         On Wed, Oct 13, 2010 at 6:31 PM, Igor Stasenko
>         <[hidden email] <mailto:[hidden email]>
>         <mailto:[hidden email] <mailto:[hidden email]>>> wrote:
>
>
>             Hi, Mariano.
>
>             I don't understand, why you need to dive into specific
>         primitive(s),
>             while you can simply place a hook before entering any primitive
>
>
>         is there a way to do this in a genera way or I need to do it
>         manually
>         for each primitive?
>
>
>     FWIW, it's questions like these that make people wonder if you've
>     done your homework.
>
>
> Is it so hard to answer in a ploite way??

I apologize if my response seemed impolite. I'm actually trying to help
you. It's futile to attempt what you're trying to do without spending
some time reading the blue book, reading the chapter in the Nublu book,
and playing with the interpreter and the simulator. The questions you
are asking are often so basic that they *are* actually covered in the
available documentation.

> If you read my first line of the email says "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. "
>
> is it really hard to understand and simply answer page 620 ?

Please read this, it might explain a few things:

http://www.catb.org/esr/faqs/smart-questions.html

Cheers,
   - Andreas

>
> Anyway, those were not my original questions.
>
> Thanks
>
> Mariano
>
>     The precise question is answered on page 620 of the blue book.
>
>     Cheers,
>       - Andreas
>
>
>             and
>             mark all objects, which passed as parameters
>             (receiver & args) as 'used', and then call primitive function?
>
>
>         The problem is that not all of them are "used" in all
>         primitives. Just
>         as an example, #bytecodeNew:
>
>         bytecodePrimNew
>
>              messageSelector := self specialSelector: 28.
>              argumentCount := 0.
>              self normalSend.
>
>         I don't want to trace the receiver there, but it is really not used
>         there. I will trace it in #normalSend.
>         Or sometimes a primitive fails because one of the arguments is
>         more than
>         32bits or because it is not smallInteger or whatever...I don't
>         want to
>         mark them as used just for being a parameter. I want to mark
>         them when
>         they are really used by the VM.
>
>         I want to avoid as much as overhead as possible.
>
>         Right now I put the tracing in #normalSend, but then I modifed some
>         bytecodes like those for #class or #== since they were not going
>         throught normal send.
>
>         Thanks
>
>         Mariano
>
>
Reply | Threaded
Open this post in threaded view
|

Re: How to access Interpreter code from plugin?

Igor Stasenko
In reply to this post by Mariano Martinez Peck

On 13 October 2010 19:52, Mariano Martinez Peck <[hidden email]> wrote:

>
>
>
> On Wed, Oct 13, 2010 at 6:31 PM, Igor Stasenko <[hidden email]> wrote:
>>
>> Hi, Mariano.
>>
>> I don't understand, why you need to dive into specific primitive(s),
>> while you can simply place a hook before entering any primitive
>
> is there a way to do this in a genera way or I need to do it manually for each primitive?
>
>
>>
>> and
>> mark all objects, which passed as parameters
>> (receiver & args) as 'used', and then call primitive function?
>>
>
> The problem is that not all of them are "used" in all primitives. Just as an example, #bytecodeNew:
>
> bytecodePrimNew
>
>     messageSelector := self specialSelector: 28.
>     argumentCount := 0.
>     self normalSend.
>
> I don't want to trace the receiver there, but it is really not used there. I will trace it in #normalSend.
> Or sometimes a primitive fails because one of the arguments is more than 32bits or because it is not smallInteger or whatever...I don't want to mark them as used just for being a parameter. I want to mark them when they are really used by the VM.
>
> I want to avoid as much as overhead as possible.
>
> Right now I put the tracing in #normalSend, but then I modifed some bytecodes like those for #class or #== since they were not going throught normal send.
>

I don't know, what you put into 'userful' or 'used' objects.
At any moment of time, if you stop VM and look at current context, all
objects which directly reachable from it is 'userful'.
In this way, you can mark everything it meets during interpreting as
'used', and then simply do GC,
so, any 'used' objects which will become garbage will be of no
interest to you as well.

> Thanks
>
> Mariano
>
>



--
Best regards,
Igor Stasenko AKA sig.