Skip to content

Add Collector supertrait over Allocator#18

Open
Ironankit525 wants to merge 1 commit intoboa-dev:mainfrom
Ironankit525:collector-trait-issue-11
Open

Add Collector supertrait over Allocator#18
Ironankit525 wants to merge 1 commit intoboa-dev:mainfrom
Ironankit525:collector-trait-issue-11

Conversation

@Ironankit525
Copy link

@Ironankit525 Ironankit525 commented Mar 1, 2026

Closes #11

What this does

Adds a Collector supertrait over allocator_api2::Allocator along with a GcAllocator wrapper that uses RefCell for interior mutability, letting third-party collections allocate through the GC.

Changes

  • oscars/Cargo.toml - added allocator-api2 dependency
    • oscars/src/collector.rs - new module with Collector trait, GcAllocator struct, and tests
    • oscars/src/lib.rs - wired collector behind mark_sweep feature
    • oscars/src/collectors/mark_sweep/mod.rs - made allocator field pub(crate)

Tests

Five new tests covering basic alloc, ZST, drop, trait bounds, and string payloads. All 37 tests pass.

Introduces a Collector trait that extends allocator_api2::Allocator,
plus a GcAllocator wrapper around MarkSweepGarbageCollector using
RefCell for interior mutability. This lets the GC be plugged into
any collection that accepts a custom allocator.

Wired behind the mark_sweep feature flag. Five tests cover basic
allocation, ZSTs, drop, string payloads, and trait-bound checks.
@Ironankit525 Ironankit525 changed the title add Collector supertrait over Allocator (closes #11) Add Collector supertrait over Allocator Mar 1, 2026
@Flamki
Copy link
Contributor

Flamki commented Mar 2, 2026

Proposed follow-up (design-first, non-overlapping with #18/#15/#21)

I want to take a narrow, reviewable slice that does not duplicate the Collector:Allocator wiring currently in flight.
Instead of touching that API shape, this proposal focuses on allocator correctness guarantees that any final design should satisfy.

Scope (proposal)

Focus area: GC-aware allocation accounting + safety invariants for allocations made through GC-facing allocators.

Goal:

Non-goals (explicitly out of scope):

  • redefining Collector trait shape,
  • replacing arena layout (bitmap/multi-pool design),
  • broad refactors across collectors.

Design note (draft)

Problem statement

As allocator integration evolves, there are two classes of memory that matter:

  1. memory tracked in collector-owned structures (arenas/pools),
  2. memory allocated externally via allocator interfaces (e.g. collection backing buffers).

If GC threshold logic only considers (1), it can under-estimate pressure and delay collection incorrectly.

Proposed model

Introduce a clear accounting split:

  • managed_bytes: bytes owned by collector-managed heaps/arenas.
  • external_bytes: bytes allocated through GC-exposed allocator paths but not physically inside managed arenas.
  • total_tracked_bytes = managed_bytes + external_bytes.

Threshold checks and OOM/collection triggers should be based on total_tracked_bytes.

Why this slice is safe to do now

  • independent from final trait/API naming,
  • useful whether final allocator bridge uses wrapper or interior mutability,
  • provides correctness guardrails that future allocator implementations can reuse.

Invariants (must hold)

  1. Accounting completeness
  • Any successful external allocation increments external_bytes by the actual allocated size.
  • Any successful deallocation decrements external_bytes by the matching size.
  • No silent path should bypass accounting updates.
  1. No underflow / no double free accounting
  • Deallocation accounting must not underflow.
  • Releasing the same logical allocation twice must be rejected or guarded (debug assert / tracked metadata).
  1. Threshold monotonicity
  • If total_tracked_bytes grows past threshold, collector trigger condition must become true.
  • If bytes are released and total drops below threshold, trigger condition may become false accordingly.
  1. Allocation-failure consistency
  • If allocation fails, counters must remain unchanged.
  • Partial failures must not leave accounting in a corrupted state.
  1. Collector-agnostic semantics
  • These invariants should hold regardless of specific collector backend, as long as it exposes allocator behavior.

Test plan (first pass)

Unit tests

  1. external_alloc_increments_accounting
  • allocate N bytes through allocator path
  • assert external_bytes += N
  • assert total_tracked_bytes updated
  1. external_dealloc_decrements_accounting
  • allocate N, then deallocate same block
  • assert net delta = 0
  1. threshold_trigger_uses_total_tracked_bytes
  • configure small threshold
  • push only external allocations over threshold
  • assert trigger condition becomes true (even if managed heap unchanged)
  1. failed_alloc_does_not_mutate_counters
  • force allocation failure path (or mock allocator)
  • assert counters unchanged
  1. dealloc_guard_against_underflow
  • attempt invalid/mismatched deallocation case
  • assert panic/error/debug-guard behavior (depending on project policy)

Integration-ish tests (minimal)

  1. vec_backing_with_gc_allocator_contributes_to_pressure (if feasible in current harness)
  • create growable structure using GC-facing allocator
  • grow capacity
  • assert pressure tracking reflects that growth

Regression test framing

  • Add at least one test that would have passed under arena-only accounting but fails with external pressure omitted.

Deliverable format

If maintainers agree, I can submit this as:

  1. a docs-first PR (note + invariants + test matrix), then
  2. a tiny follow-up implementation PR limited to accounting hooks + tests only.

@Flamki
Copy link
Contributor

Flamki commented Mar 2, 2026

Thanks for the work here. I moved my design-first follow-up proposal to #11 to avoid overlap with #18. I won’t touch #18 scope and will wait for maintainer direction on a separate, non-overlapping slice.

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.

Investigate into a way to consolidate reconcile the Allocator trait and a collection trait

2 participants