GemTalk / PharoGemStoneFFI

GemStone GCI access via Pharo FFI
MIT License
1 stars 3 forks source link

Enable caching of callout methods #13

Open martinmcclure opened 1 year ago

martinmcclure commented 1 year ago

Alistair Grant says:

In FFICalloutAPI>>function:library Norm wrote:

"Norm Green: Disable replacing our FFI compiled method for GCI libraries, otherwise the moduleNameOrLibrary arg is ignored after the first invocation   and Pharo caches the function pointer in the new compile method.
    This becomes a problem when we change GCI versions and the wrong GCI library is called!
    If there's a better way to do this I'd love to know about it."
    ( '*libgci*' match: moduleNameOrLibrary asFFILibrary libraryName)
        ifFalse:[
            sender methodClass methodDict at: sender selector put: ffiMethod.   
            FFIMethodRegistry uniqueInstance registerMethod: ffiMethod .
        ].

This prevents the ffi callout method from being cached, causing the ffi method to be recompiled on every execution. (If you want some entertainment, try commenting out the entire code block quoted above, evaluateFFIMethodRegistry resetAll and see how fast GT is :-)). Instead, why not reset the methods when the library is changed? GciInterface can keep track of the version that is being used and when it changes do something similar to:

'GemStoneFFI' asPackage classes do: [ :cls |
    cls methods do: [ :cm |
        (cm hasProperty: #ffiNonCompiledMethod) ifTrue:
            [ cm methodClass methodDict
                at: cm selector
                put: (cm propertyAt: #ffiNonCompiledMethod) ] ] ].

This will mean that FFICalloutAPI>>function:library doesn't need to be changed and the common case of doing quite a bit with one version will be faster. When I tried the above reset snippet on my PC the execution time came back as 0 (< 1ms).