Skip to main content

Module protect_pool

Module protect_pool 

Source
Expand description

VECSXP-backed protection pool with generational keys.

A GC protection mechanism that stores protected SEXPs in a single R VECSXP (generic list), with slot management and generation tracking on the Rust side.

§Performance

Benchmarked at 10.1 ns/op for single insert+release. Zero R allocation per insert (unlike preserve.rs DLL which allocates a CONSXP each time). See analysis/gc-protection-benchmarks-results.md for full data.

§When to use

Use this for cross-.Call protection when:

  • You have many protected objects or frequent insert/release churn
  • You need any-order release (not LIFO)
  • You want generational safety (stale-key detection)

For temporaries within a .Call, use ProtectScope instead (7.4 ns/op, zero allocation, LIFO bulk cleanup).

For a few long-lived objects that are never released in a loop (like ExternalPtr), use R_PreserveObject directly (13 ns/op, zero Rust-side bookkeeping).

§Architecture

┌─────────────────────────────────────┐
│  R side: VECSXP (GC-traced slots)   │  ← one R_PreserveObject, ever
│  [SEXP][SEXP][NIL][SEXP][NIL][SEXP] │
└──────┬──────────────────────────────┘
       │ slot indices
┌──────┴──────────────────────────────┐
│  Rust side: Vec<u32> generations    │  ← one free list, one generation array
│  + Vec<usize> free_slots            │
└─────────────────────────────────────┘

No external dependencies for slot management. The generation counter per slot detects stale keys. Single free list for VECSXP slot reuse.

Structs§

ProtectKey
Generational key for a slot in a ProtectPool.
ProtectPool
A VECSXP-backed pool for GC protection with generational keys.

Type Aliases§

NoSendSync 🔒
Enforces !Send + !Sync (R API is not thread-safe).