Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ftype-scheme-object-pointer and related foreign-pointer extensions #897

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

mflatt
Copy link
Contributor

@mflatt mflatt commented Dec 21, 2024

An ftype pointer to a Scheme object is useful to communicate the address of an bytevector or flvector (like
object->reference-address) in the same places that ftype pointers can be used. There's a key difference between using these new pointers and constructing a pointer with the result of
object->reference-address: GC cooperation with a Scheme-object pointer ensures that the address does not go stale. Instead, the address is extracted just after moving into a context where a collection cannot occur (e.g., a foreign call without __collect_safe).

With Scheme-object pointers as a way to unify GCable and foreign references through the ftype interface, some further additions give the ftype layer flexiblity similar to the lower-level foreign-ref API, which extracts data from a reference without a declared/checked foreign representation. The ftype-any-ref and ftype-any-set! forms cover pointer access and update, and ftype-pointer is allowed as a ftype-name for a generic pointer type. In addition, type-scheme-object-pointer works as an ftype-name for a pointer to a GCable object. In the case of an (& <ftype>) argument or result, (& <ftype> ftype-pointer) can be used to accept/allocate a generic pointer record instead of a -specific pointer record, and similarly (& <ftype> ftype-scheme-object-pointer).

The key changes are fairly modest, but there are many additional changes just to expand plumbing. The most tedious change is that the internal $make-record-type function has a new argument that can turn on GC cooperation for Scheme-object ftype pointers. Most of the rest is about making foreign-call pointer arguments and results distinguish a predicate for argument checking from the rtd used to create pointer objects.

@mflatt
Copy link
Contributor Author

mflatt commented Dec 21, 2024

This change helps close a gap between the Chez Scheme and Racket FFIs. It builds on the object->reference-address approach that closed the biggest gap, and extends that to a more uniform treatment of foreign and GC_managed addresses. Concretely, a revised Racket FFI implementation using this extension is 2x to 4x as fast at many foreign-pointer operations. The improvement is because the FFI implementation doesn't have to branch between multiple ways of representing addresses, and because it doesn't have to disable interrupts to work with addresses that can change during a GC.

An ftype pointer to a Scheme object is useful to communicate the
address of an bytevector or flvector (like
`object->reference-address`) in the same places that ftype pointers
can be used. There's a key difference between using these new pointers
and constructing a pointer with the result of
`object->reference-address`: GC cooperation with a Scheme-object
pointer ensures that the address does not go stale. Instead, the
address is extracted just after moving into a context where a
collection cannot occur (e.g., a foreign call without
`__collect_safe`).

With Scheme-object pointers as a way to unify GCable and foreign
references through the ftype interface, some further additions give
the ftype layer flexiblity similar to the lower-level `foreign-ref`
API, which extracts data from a reference without a declared/checked
foreign representation. The `ftype-any-ref` and `ftype-any-set!` forms
cover pointer access and update, and `ftype-pointer` is allowed as a
ftype-name for a generic pointer type. In addition,
`type-scheme-object-pointer` works as an ftype-name for a pointer to a
GCable object. In the case of an `(& <ftype>)` argument or result,
`(& <ftype> ftype-pointer)` can be used to accept/allocate a generic
pointer record instead of a <ftype>-specific pointer record, and
similarly `(& <ftype> ftype-scheme-object-pointer)`.

The key changes are fairly modest, but there are many additional
changes just to expand plumbing. The most tedious change is that the
internal `$make-record-type` function has a new argument that can turn
on GC cooperation for Scheme-object ftype pointers. Most of the rest
is about making foreign-call pointer arguments and results distinguish
a predicate for argument checking from the rtd used to create pointer
objects.
Copy link
Contributor

@owaddell owaddell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick sweep for typos so far.

In the commit message:

  • "address of an bytevector" -> "address of a bytevector"
  • "type-scheme-object-pointer works as" -> "ftype-scheme-object-pointer works as"

s/cpprim.ss Outdated Show resolved Hide resolved
s/mkgc.ss Outdated Show resolved Hide resolved
csug/foreign.stex Outdated Show resolved Hide resolved
csug/foreign.stex Outdated Show resolved Hide resolved
csug/foreign.stex Show resolved Hide resolved
csug/foreign.stex Outdated Show resolved Hide resolved
csug/foreign.stex Outdated Show resolved Hide resolved
csug/foreign.stex Outdated Show resolved Hide resolved
csug/foreign.stex Outdated Show resolved Hide resolved
release_notes/release_notes.stex Outdated Show resolved Hide resolved
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants