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 |
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. |
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:
|
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:
|
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: 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
|
Free forum by Nabble | Edit this page |