#flushCache with MethoWrappers in CogVM

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

#flushCache with MethoWrappers in CogVM

Mariano Martinez Peck
 
Hi Eliot. I am implementing some kind of MethodWrappes/ObjectsAsMethod, whihc basically use the #run:with:in trick.
My question is that I am not sure how to implement #flushCache in my wrappers. This method is called by MethodDictionary>>#at:put:  when I want to put back the original CompiledMethod.

MyClass methodDict at: #foo put: MyWrapper withMethod: (MyClass>>#foo).
...
MyClass methodDict at: #foo put:  wrapper wrappedMethod
->  here it sends #flushCache to my wrapper instance.

In the StandardVM, I realised that at that moment, there is an entry in the cache that has selector: #foo, method:  my wrapped instance, class: MyClass, etc...

So, to flush this, I have to options:

MyWrappers>>flushCache
self wrappedMethod selector flushCache

or....

MyWrappers>>flushCache
  <primitive: 116>

this is because "self" will be found in the entry as "method" in the cache table...

So, first, are my assumptions correct?

Now, in cog I am not sure if both solutions are still valid. If I see CoInterpreterPrimitives>> primitiveFlushCacheByMethod

you do at the end:

(self methodHasCogMethod: oldMethod) ifTrue:
        [cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]

and

methodHasCogMethod: aMethodOop
    <api>
    self assert: (objectMemory isNonIntegerObject: aMethodOop).
    ^self isCogMethodReference: (self rawHeaderOf: aMethodOop)


So, it is not safe if the method is something different than a compiled method.

Is that correct? should I flush the cache entering by selector instead?  which is the safe way to clean the cache in this case?

thanks

Mariano
Reply | Threaded
Open this post in threaded view
|

Re: #flushCache with MethoWrappers in CogVM

Mariano Martinez Peck
 
Anyone? I am having Cog crashed and I think it is related to this...



On Wed, Mar 16, 2011 at 11:20 AM, Mariano Martinez Peck <[hidden email]> wrote:
Hi Eliot. I am implementing some kind of MethodWrappes/ObjectsAsMethod, whihc basically use the #run:with:in trick.
My question is that I am not sure how to implement #flushCache in my wrappers. This method is called by MethodDictionary>>#at:put:  when I want to put back the original CompiledMethod.

MyClass methodDict at: #foo put: MyWrapper withMethod: (MyClass>>#foo).
...
MyClass methodDict at: #foo put:  wrapper wrappedMethod
->  here it sends #flushCache to my wrapper instance.

In the StandardVM, I realised that at that moment, there is an entry in the cache that has selector: #foo, method:  my wrapped instance, class: MyClass, etc...

So, to flush this, I have to options:

MyWrappers>>flushCache
self wrappedMethod selector flushCache

or....

MyWrappers>>flushCache
  <primitive: 116>

this is because "self" will be found in the entry as "method" in the cache table...

So, first, are my assumptions correct?

Now, in cog I am not sure if both solutions are still valid. If I see CoInterpreterPrimitives>> primitiveFlushCacheByMethod

you do at the end:

(self methodHasCogMethod: oldMethod) ifTrue:
        [cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]

and

methodHasCogMethod: aMethodOop
    <api>
    self assert: (objectMemory isNonIntegerObject: aMethodOop).
    ^self isCogMethodReference: (self rawHeaderOf: aMethodOop)


So, it is not safe if the method is something different than a compiled method.

Is that correct? should I flush the cache entering by selector instead?  which is the safe way to clean the cache in this case?

thanks

Mariano

Reply | Threaded
Open this post in threaded view
|

Re: #flushCache with MethoWrappers in CogVM

Eliot Miranda-2
In reply to this post by Mariano Martinez Peck
 
Hi Mariano,

    VMMaker-oscog.52 is uploading:

primitiveFlushCacheByMethod
"The receiver is a compiledMethod.  Clear all entries in the method lookup cache that
refer to this method, presumably because it has been redefined, overridden or removed.
Override to flush appropriate machine code caches also."
| probe oldMethod primIdx |
oldMethod := self stackTop.
probe := 0.
1 to: MethodCacheEntries do:
[:i |
(methodCache at: probe + MethodCacheMethod) = oldMethod ifTrue:
[methodCache at: probe + MethodCacheSelector put: 0].
probe := probe + MethodCacheEntrySize].
(objectMemory isOopCompiledMethod: oldMethod) ifTrue:
[primIdx := self primitiveIndexOf: oldMethod.
primIdx = PrimitiveExternalCallIndex ifTrue:
["It's primitiveExternalCall"
self flushExternalPrimitiveOf: oldMethod].
(self methodHasCogMethod: oldMethod) ifTrue:
[cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]]

On Wed, Mar 16, 2011 at 3:20 AM, Mariano Martinez Peck <[hidden email]> wrote:
 
Hi Eliot. I am implementing some kind of MethodWrappes/ObjectsAsMethod, whihc basically use the #run:with:in trick.
My question is that I am not sure how to implement #flushCache in my wrappers. This method is called by MethodDictionary>>#at:put:  when I want to put back the original CompiledMethod.

MyClass methodDict at: #foo put: MyWrapper withMethod: (MyClass>>#foo).
...
MyClass methodDict at: #foo put:  wrapper wrappedMethod
->  here it sends #flushCache to my wrapper instance.

In the StandardVM, I realised that at that moment, there is an entry in the cache that has selector: #foo, method:  my wrapped instance, class: MyClass, etc...

So, to flush this, I have to options:

MyWrappers>>flushCache
self wrappedMethod selector flushCache

or....

MyWrappers>>flushCache
  <primitive: 116>

this is because "self" will be found in the entry as "method" in the cache table...

So, first, are my assumptions correct?

Now, in cog I am not sure if both solutions are still valid. If I see CoInterpreterPrimitives>> primitiveFlushCacheByMethod

you do at the end:

(self methodHasCogMethod: oldMethod) ifTrue:
        [cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]

and

methodHasCogMethod: aMethodOop
    <api>
    self assert: (objectMemory isNonIntegerObject: aMethodOop).
    ^self isCogMethodReference: (self rawHeaderOf: aMethodOop)


So, it is not safe if the method is something different than a compiled method.

Is that correct? should I flush the cache entering by selector instead?  which is the safe way to clean the cache in this case?

thanks

Mariano



CoInterpreterPrimitives-primitiveFlushCacheByMethod.st (1K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: #flushCache with MethoWrappers in CogVM

Mariano Martinez Peck
 
Thanks Eliot. So I assume that the correcet way to implement #flushCache  in my object as method is this:

MyObjectAsMethod>>flushCache
  <primitive: 116>


thanks Eliot

Mariano

On Sun, Mar 20, 2011 at 5:32 PM, Eliot Miranda <[hidden email]> wrote:
 
Hi Mariano,

    VMMaker-oscog.52 is uploading:

primitiveFlushCacheByMethod
"The receiver is a compiledMethod.  Clear all entries in the method lookup cache that
refer to this method, presumably because it has been redefined, overridden or removed.
Override to flush appropriate machine code caches also."
| probe oldMethod primIdx |
oldMethod := self stackTop.
probe := 0.
1 to: MethodCacheEntries do:
[:i |
(methodCache at: probe + MethodCacheMethod) = oldMethod ifTrue:
[methodCache at: probe + MethodCacheSelector put: 0].
probe := probe + MethodCacheEntrySize].
(objectMemory isOopCompiledMethod: oldMethod) ifTrue:
[primIdx := self primitiveIndexOf: oldMethod.
primIdx = PrimitiveExternalCallIndex ifTrue:
["It's primitiveExternalCall"
self flushExternalPrimitiveOf: oldMethod].
(self methodHasCogMethod: oldMethod) ifTrue:
[cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]]

On Wed, Mar 16, 2011 at 3:20 AM, Mariano Martinez Peck <[hidden email]> wrote:
 
Hi Eliot. I am implementing some kind of MethodWrappes/ObjectsAsMethod, whihc basically use the #run:with:in trick.
My question is that I am not sure how to implement #flushCache in my wrappers. This method is called by MethodDictionary>>#at:put:  when I want to put back the original CompiledMethod.

MyClass methodDict at: #foo put: MyWrapper withMethod: (MyClass>>#foo).
...
MyClass methodDict at: #foo put:  wrapper wrappedMethod
->  here it sends #flushCache to my wrapper instance.

In the StandardVM, I realised that at that moment, there is an entry in the cache that has selector: #foo, method:  my wrapped instance, class: MyClass, etc...

So, to flush this, I have to options:

MyWrappers>>flushCache
self wrappedMethod selector flushCache

or....

MyWrappers>>flushCache
  <primitive: 116>

this is because "self" will be found in the entry as "method" in the cache table...

So, first, are my assumptions correct?

Now, in cog I am not sure if both solutions are still valid. If I see CoInterpreterPrimitives>> primitiveFlushCacheByMethod

you do at the end:

(self methodHasCogMethod: oldMethod) ifTrue:
        [cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]

and

methodHasCogMethod: aMethodOop
    <api>
    self assert: (objectMemory isNonIntegerObject: aMethodOop).
    ^self isCogMethodReference: (self rawHeaderOf: aMethodOop)


So, it is not safe if the method is something different than a compiled method.

Is that correct? should I flush the cache entering by selector instead?  which is the safe way to clean the cache in this case?

thanks

Mariano




Reply | Threaded
Open this post in threaded view
|

Re: #flushCache with MethoWrappers in CogVM

Eliot Miranda-2
 


On Sun, Mar 20, 2011 at 9:52 AM, Mariano Martinez Peck <[hidden email]> wrote:
Thanks Eliot. So I assume that the correcet way to implement #flushCache  in my object as method is this:

MyObjectAsMethod>>flushCache
  <primitive: 116>

Sure.  ANother way would be something like

Object methods
flushCache
    self primFlushCacheIfSelector.
    self primFlushCacheIfMethod

primFlushCacheIfSelector
    <primitive: 119>
    ^nil

primFlushCacheIfMethod
    <primitive: 116>

But I would be tempted to define a new prim, primFlushIfSelectorAndMethod if I were going to go that route long-term, e.g.

Object methods
flushCache
    "Flush method lookup caches for the receiver whether it functions as a selector or a method."
    <primitive: 215>
    "OIf the primitive fails it probably isn't supported; fall back on the older slower prims"
    self primFlushCacheIfSelector.
    self primFlushCacheIfMethod

 


thanks Eliot

Mariano

On Sun, Mar 20, 2011 at 5:32 PM, Eliot Miranda <[hidden email]> wrote:
 
Hi Mariano,

    VMMaker-oscog.52 is uploading:

primitiveFlushCacheByMethod
"The receiver is a compiledMethod.  Clear all entries in the method lookup cache that
refer to this method, presumably because it has been redefined, overridden or removed.
Override to flush appropriate machine code caches also."
| probe oldMethod primIdx |
oldMethod := self stackTop.
probe := 0.
1 to: MethodCacheEntries do:
[:i |
(methodCache at: probe + MethodCacheMethod) = oldMethod ifTrue:
[methodCache at: probe + MethodCacheSelector put: 0].
probe := probe + MethodCacheEntrySize].
(objectMemory isOopCompiledMethod: oldMethod) ifTrue:
[primIdx := self primitiveIndexOf: oldMethod.
primIdx = PrimitiveExternalCallIndex ifTrue:
["It's primitiveExternalCall"
self flushExternalPrimitiveOf: oldMethod].
(self methodHasCogMethod: oldMethod) ifTrue:
[cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]]

On Wed, Mar 16, 2011 at 3:20 AM, Mariano Martinez Peck <[hidden email]> wrote:
 
Hi Eliot. I am implementing some kind of MethodWrappes/ObjectsAsMethod, whihc basically use the #run:with:in trick.
My question is that I am not sure how to implement #flushCache in my wrappers. This method is called by MethodDictionary>>#at:put:  when I want to put back the original CompiledMethod.

MyClass methodDict at: #foo put: MyWrapper withMethod: (MyClass>>#foo).
...
MyClass methodDict at: #foo put:  wrapper wrappedMethod
->  here it sends #flushCache to my wrapper instance.

In the StandardVM, I realised that at that moment, there is an entry in the cache that has selector: #foo, method:  my wrapped instance, class: MyClass, etc...

So, to flush this, I have to options:

MyWrappers>>flushCache
self wrappedMethod selector flushCache

or....

MyWrappers>>flushCache
  <primitive: 116>

this is because "self" will be found in the entry as "method" in the cache table...

So, first, are my assumptions correct?

Now, in cog I am not sure if both solutions are still valid. If I see CoInterpreterPrimitives>> primitiveFlushCacheByMethod

you do at the end:

(self methodHasCogMethod: oldMethod) ifTrue:
        [cogit unlinkSendsTo: (self cogMethodOf: oldMethod)]

and

methodHasCogMethod: aMethodOop
    <api>
    self assert: (objectMemory isNonIntegerObject: aMethodOop).
    ^self isCogMethodReference: (self rawHeaderOf: aMethodOop)


So, it is not safe if the method is something different than a compiled method.

Is that correct? should I flush the cache entering by selector instead?  which is the safe way to clean the cache in this case?

thanks

Mariano