good afternoon;
it appears that, where a field from a foreign structure is a pointer, when its value is extracted, the foreign pointer value requires allocation on the heap. is there some declaration combination which causes the foreign pointer to be allocated on the stack.
for example, in the case below, the only space used is that to marshal the arguments to %compare-quad. as insignificant as it may seem, for sustained use, the effect is to require frequent collection of the equivalent of the full heap, which brings with it promotion issues. it would be beneficial to cause the lhs-quad and rhs-quad values to be on the stack. is there some means to do that?
as is evident, this particular case involves sbcl, but - as far as cffi is concerned, the question is general.
—
(cffi:defcstruct #.(swig-lispify "MDB_val" 'classname) (#.(swig-lispify "mv_size" 'slotname) :pointer) (#.(swig-lispify "mv_data" 'slotname) :pointer))
(declaim (type (function (SB-SYS:SYSTEM-AREA-POINTER SB-SYS:SYSTEM-AREA-POINTER) fixnum) %compare-quad))
(cffi:defcallback %compare-keys :int ((lhs :pointer) (rhs :pointer)) (%compare-lmdb-keys lhs rhs))
(defun %compare-lmdb-keys (lhs rhs) (declare (type SB-SYS:SYSTEM-AREA-POINTER lhs rhs) (optimize (speed 3) (safety 0) (space 3))) (let ((lhs-quad (cffi:foreign-slot-value lhs '(:struct liblmdb:val) 'liblmdb:mv-data)) (rhs-quad (cffi:foreign-slot-value rhs '(:struct liblmdb:val) 'liblmdb:mv-data))) (declare (dynamic-extent lhs-quad rhs-quad)) (%compare-quad lhs-quad rhs-quad)))
(defun %compare-quad (lhs rhs) (declare (dynamic-extent lhs rhs) (optimize (speed 3) (safety 0))) (if (eql lhs rhs) 0 (loop for i below 4 for lhs_i = (cffi:mem-aref lhs 'term-id i) for rhs_i = (cffi:mem-aref rhs 'term-id i) if (< lhs_i rhs_i) return -1 if (> lhs_i rhs_i) return 1 finally (return 0))))
--- james anderson | james@dydra.com | http://dydra.com