Optimize re-serializing deserialized functions

This commit is contained in:
Joshua Suskalo 2024-10-03 11:12:37 -04:00
parent cce6c823f6
commit f752a1592a
No known key found for this signature in database
GPG key ID: 9B6BA586EFF1B9F0
2 changed files with 18 additions and 11 deletions

View file

@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file. This change
- New `coffi.mem/null` var for implementing custom types
### Performance
- Upcall functions serialized from functions returned by deserializing function pointers now use the backing function pointer directly
- Upcall and downcall classes have been changed to be memoized, meaning ASM is no longer invoked every time a function is serialized, which should drastically improve performance where functions are serialized in a hot loop
### Fixed

View file

@ -575,25 +575,31 @@
(mem/global-arena))))
(defmethod mem/serialize* ::fn
[f [_fn arg-types ret-type & {:keys [raw-fn?]}] arena]
(.upcallStub
(Linker/nativeLinker)
^MethodHandle (cond-> f
(not raw-fn?) (upcall-serde-wrapper arg-types ret-type)
:always (upcall-handle arg-types ret-type))
^FunctionDescriptor (function-descriptor arg-types ret-type)
^Arena arena
(make-array Linker$Option 0)))
[f [_fn arg-types ret-type & {:keys [raw-fn?]} :as typ] arena]
(if-let [address (::address (meta f))]
(do (assert (= typ (::type (meta f)))
"The type of a deserialized function must match the type it is re-serialized to.")
address)
(.upcallStub
(Linker/nativeLinker)
^MethodHandle (cond-> f
(not raw-fn?) (upcall-serde-wrapper arg-types ret-type)
:always (upcall-handle arg-types ret-type))
^FunctionDescriptor (function-descriptor arg-types ret-type)
^Arena arena
(make-array Linker$Option 0))))
(defmethod mem/deserialize* ::fn
[addr [_fn arg-types ret-type & {:keys [raw-fn?]}]]
[addr [_fn arg-types ret-type & {:keys [raw-fn?] :as typ}]]
(when-not (mem/null? addr)
(vary-meta
(-> ^MemorySegment addr
(downcall-handle (function-descriptor arg-types ret-type))
(downcall-fn arg-types ret-type)
(cond-> (not raw-fn?) (make-serde-wrapper arg-types ret-type)))
assoc ::address addr)))
assoc
::address addr
::type typ)))
;;; Static memory access