This change introduces pool_save and pool_restore functions to allow
for the reuse of memory regions within the memory pool. The udiv
function is updated to use this mechanism, improving memory efficiency.
Co-authored-by: Gemini <gemini@google.com>
Remove unused .active member from mpz_pool_t structure and clean up
related code:
- Remove .active field from mpz_pool struct
- Remove .active checks from pool_alloc function
- Remove unused WITH_SCOPED_POOL macro
- Clean up extra whitespace
Simplifies pool structure and removes dead code while maintaining
full functionality.
Co-authored-by: Claude <noreply@anthropic.com>
Replace all heap-only contexts with pool-backed contexts for improved
memory allocation efficiency. Each function now declares local pool
storage to enable stack-based allocation for temporary operations.
Co-authored-by: Claude <noreply@anthropic.com>
Replace explicit pool management with unified mpz_init_temp approach:
- Remove ~120 lines of complex manual pool allocation logic
- Replace with simple mpz_init_temp calls with size estimation
- Remove unused mpz_init_pool function
- Maintain identical functionality with much cleaner code
The function now uses automatic pool/heap management through the
context architecture, eliminating manual memory handling complexity.
Co-authored-by: Claude <noreply@anthropic.com>
Convert key temporary variables to use pool-preferred allocation for better
performance and reduced heap pressure:
- Barrett reduction: q1, q2, q3, r1, r2 with appropriate size estimates
- Modular exponentiation: temp and mu variables in mpz_powm and mpz_powm_i
- GCD: temp_a and temp_b variables in binary GCD algorithm
- LCM: all temporary variables with proper size estimation
Includes smart size estimation based on input operand sizes for optimal
pool utilization while maintaining correctness.
Co-authored-by: Claude <noreply@anthropic.com>
Remove forward declarations for functions where definitions appear before usage:
- mpz_mul_sliding_window
- mpz_realloc, mpz_clear, mpz_move
Keep necessary forward declarations for Barrett reduction functions that are
used before their definitions.
Co-authored-by: Claude <noreply@anthropic.com>
Convert mpz_mul_sliding_window from legacy MPZ_UNIFIED_BINARY_OP_INT macro to
new strategy using mpz_init_temp/mpz_init_auto pattern. Inline core function
and remove unused legacy macros and functions for cleaner implementation.
Co-authored-by: Claude <noreply@anthropic.com>
Removed unused helper macros that are no longer needed after context
architecture migration:
- MPZ_TMP_INIT/MPZ_TMP_CLEAR: temporary variable management
- MPZ_POOL_ALLOC: basic pool allocation with return fallback
- MPZ_POOL_CLEANUP: pool memory cleanup
Co-authored-by: Claude <noreply@anthropic.com>
Converted multiplication and power operations to use the *_auto API:
- mpz_mul: now uses mpz_init_auto for result parameter, eliminating workspace
- bint_mul: simplified by removing redundant mpz_init call
- mrb_bint_mul_ii: simplified by removing redundant mpz_init call
- mrb_bint_pow: simplified by removing redundant mpz_init call
- mpz_pow: complete rewrite to use *_auto API, eliminating temporary variables
Key improvements:
- mpz_mul no longer needs separate workspace variable 'w'
- Fixed memory initialization issue by using mrb_calloc instead of mrb_malloc
- mpz_pow now uses temp variables that self-initialize via mpz_mul
- Power operations (2**100) now work correctly
This completes Phase 3 of the simplified API migration.
Co-authored-by: Claude <noreply@anthropic.com>
Simplified several Ruby bigint operations by removing redundant mpz_init calls:
- mrb_bint_add_n: mpz_add now handles initialization internally
- mrb_bint_sub_n: mpz_sub now handles initialization internally
- mrb_bint_add_ii: mpz_add now handles initialization internally
- mrb_bint_sub_ii: mpz_sub now handles initialization internally
These changes demonstrate the benefit of the *_auto API - operations that
previously required separate init + operation calls now work with just
the operation call, as the simplified functions handle memory allocation
automatically.
Co-authored-by: Claude <noreply@anthropic.com>
Replace complex MPZ_UNIFIED_BINARY_OP macro with clean mpz_init_auto API.
Inline mpz_add_core logic directly into mpz_add for better performance.
Key changes:
- Add mpz_init_auto() for heap allocation with size hint
- Add mpz_init_temp_auto() for pool-preferred allocation
- Convert mpz_add to use mpz_init_auto() (5 lines -> 2 lines + inlined logic)
- Inline mpz_add_core into mpz_add (eliminates function call overhead)
- Remove unused mpz_add_core function
Benefits:
- Dramatic code simplification (no complex macros)
- Better performance (no function call overhead, better compiler optimization)
- Cleaner memory management (automatic heap allocation with size hint)
- All edge cases verified working (zero operands, mixed signs, large numbers)
Foundation for converting remaining operations to simplified API.
Co-authored-by: Claude <noreply@anthropic.com>
Create unified operation macros that automatically handle pool-first-then-heap
allocation strategy, eliminating code duplication between memory management approaches.
Key changes:
- Fix MPZ_UNIFIED_BINARY_OP and MPZ_UNIFIED_UNARY_OP macro parameters to use ctx
- Add MPZ_UNIFIED_BINARY_OP_INT variant for functions returning int values
- Convert mpz_add to use unified MPZ_UNIFIED_BINARY_OP macro (20+ lines -> 4 lines)
- Convert mpz_mul_sliding_window to use MPZ_UNIFIED_BINARY_OP_INT macro
- Eliminate manual WITH_SCOPED_POOL and MPZ_POOL_ALLOC_GOTO duplication
Benefits:
- Consistent pool-first-then-heap pattern across all operations
- Reduced code duplication (~40 lines eliminated)
- Single place to optimize memory allocation strategy
- Automatic pool optimization without manual fallback logic
All arithmetic operations verified working with unified memory management.
Co-authored-by: Claude <noreply@anthropic.com>
Systematically convert mpz functions from mrb_state parameters to unified
mpz_ctx_t context parameters containing both mrb_state and optional pool.
Key changes:
- Convert 40+ core mpz functions to use mpz_ctx_t *ctx parameters
- Unify mpz_init to eliminate code duplication with mpz_init_pool
- Update public interface functions to create contexts when calling core mpz functions
- Convert pool management functions and macros to use context architecture
- Fix all context parameter passing (by reference vs by value) issues
This establishes the foundation for pool-safe operations throughout the
mruby-bigint library while maintaining backward compatibility.
Co-authored-by: Claude <noreply@anthropic.com>
Remove allocation tracking code (g_alloc_stats) and debug functions
that were used for pool performance analysis. This cleanup removes:
- allocation_stats_t struct and g_alloc_stats global variable
- pool hit/miss tracking calls in pool_alloc()
- malloc/bytes tracking in mpz_init_pool() and mpz_realloc()
- mrb_bint_pool_stats() and mrb_bint_reset_pool_stats() debug functions
The pool functionality remains intact, just without the debugging overhead.
Co-authored-by: Claude <noreply@anthropic.com>
Cleaned up comments that referenced non-existent *_pool functions:
- "extracted from uadd/uadd_pool duplication" → "for unsigned operands"
- "extracted from usub/usub_pool duplication" → "for unsigned operands"
- "extracted from udiv/udiv_pool duplication" → (simplified)
These functions were eliminated in previous refactoring commits.
Co-authored-by: Claude <noreply@anthropic.com>
Simplified pool initialization from 4 lines to 2 using C99 designated
initializers:
Before:
mpz_pool_t pool_storage = {0};
pool_storage.capacity = BIGINT_POOL_DEFAULT_SIZE;
pool_storage.active = 1;
mpz_pool_t *pool = &pool_storage;
After:
mpz_pool_t pool_storage = {.capacity = BIGINT_POOL_DEFAULT_SIZE, .active = 1};
mpz_pool_t *pool = &pool_storage;
Applied to both WITH_SCOPED_POOL macro and manual pool management
patterns. This makes pool initialization more readable and concise.
Co-authored-by: Claude <noreply@anthropic.com>
Simplified udiv structure from 3 functions to 2 by eliminating udiv_pool
and integrating pool allocation directly into main udiv function:
- Removed udiv_pool function (~170 lines) and forward declaration
- Unified edge case handling and normalization in single location
- Pool allocation tried first for medium operands (4-64 limbs)
- Automatic heap fallback when pool allocation fails
- Manual pool management instead of problematic macros
- All tests pass (1713 OK, 0 KO)
This establishes the pattern for pool-aware complex functions.
Co-authored-by: Claude <noreply@anthropic.com>
Added #ifdef MRB_DEBUG conditional include for mruby/hash.h to support
debug functions that use hash operations. This enables pool statistics
and debugging functionality when MRB_DEBUG is defined without affecting
production builds.
Co-authored-by: Claude <noreply@anthropic.com>
EOF < /dev/null
Simplified function names by removing unnecessary "_core" suffix from
functions that only have one version:
- uadd_core → uadd
- usub_core → usub
Co-authored-by: Claude <noreply@anthropic.com>
EOF < /dev/null
Removed final unused pool function mpz_set_pool (17 lines) which was
no longer referenced after pool function elimination. Build now
compiles without unused function warnings.
Co-authored-by: Claude <noreply@anthropic.com>
Removed mpz_sqrt_pool function (203 lines) and its forward declaration
to eliminate code duplication. mpz_sqrt now uses heap allocation only.
Pool support should be restored in future using unified approach.
Co-authored-by: Claude <noreply@anthropic.com>
Removed unused functions: uadd, uadd_pool, usub, usub_pool,
mpz_div_2exp_pool, mpz_mul_2exp_pool, mpz_mul_int_pool, mpz_sub_pool.
These were no longer needed after pool/non-pool unification.
Co-authored-by: Claude <noreply@anthropic.com>
Removed mpz_gcd_pool function (299 lines) and its forward declaration
to eliminate code duplication. mpz_gcd now uses heap allocation only.
Pool support should be restored in future using unified approach.
Co-authored-by: Claude <noreply@anthropic.com>
- Created mpz_mul_sliding_window_core() containing pure multiplication algorithm
- Unified mpz_mul_sliding_window() with pool-first-then-heap approach
- Eliminated mpz_mul_sliding_window_pool() function (84+ lines removed)
- Simplified mpz_mul() algorithm hierarchy to use single sliding window function
- Updated all callers in powm operations
- All tests pass, maintaining performance with cleaner architecture
Co-authored-by: Claude <noreply@anthropic.com>
- Created mpz_add_core() function containing the pure signed addition algorithm
- Refactored mpz_add() to use unified pool-first-then-heap approach
- Eliminated mpz_add_pool() function (88 lines of duplicated code removed)
- Updated all callers to use unified mpz_add()
- All tests pass, maintaining full functionality with single implementation
Co-authored-by: Claude <noreply@anthropic.com>
Added MPZ_UNIFIED_BINARY_OP and MPZ_UNIFIED_UNARY_OP macros that automatically
try pool allocation first, then fall back to heap allocation, using existing
*_core functions. This provides a clean foundation for eliminating all pool
vs non-pool function pairs.
Co-authored-by: Claude <noreply@anthropic.com>
Comparison operations don't need memory allocation, so there's no
difference between pool and non-pool versions. This eliminates
unnecessary code duplication.
Co-authored-by: Claude <noreply@anthropic.com>
The function doesn't use the pool parameter and operates on pre-allocated
memory, so mpz_abs_copy is a more accurate name. This eliminates code
duplication by making mpz_abs use mpz_abs_copy internally.
Co-authored-by: Claude <noreply@anthropic.com>
Extract multi-limb subtraction algorithm from usub() and usub_pool()
into shared usub_core() helper function. Both functions now use the
same core subtraction logic with borrow propagation, eliminating
duplicated algorithm code.
Benefits:
- Eliminates ~14 lines of duplicated subtraction algorithm code
- Single source of truth for multi-limb subtraction with borrow handling
- Reduces maintenance burden for future optimizations
- Maintains all existing functionality and performance
Co-authored-by: Claude <noreply@anthropic.com>
Extract multi-limb addition algorithm from uadd() and uadd_pool() into
shared uadd_core() helper function. Both functions now use the same
core addition logic with carry propagation, eliminating duplication
and ensuring consistent behavior.
Benefits:
- Eliminates ~13 lines of duplicated addition algorithm code
- Single source of truth for multi-limb addition with carry handling
- Reduces maintenance burden for future optimizations
- Maintains all existing functionality and performance
Co-authored-by: Claude <noreply@anthropic.com>
Extract Knuth Algorithm D implementation from udiv() and udiv_pool()
into shared udiv_core() helper function. Both functions now use the
same ~100-line core division algorithm, eliminating genuine code
duplication and ensuring fixes only need to be applied once.
Benefits:
- Eliminates ~150 lines of duplicated complex algorithm code
- Single source of truth for critical division logic
- Reduces maintenance burden for future bug fixes
- Maintains all existing functionality and performance
Co-authored-by: Claude <noreply@anthropic.com>
Add spaces around * operators in division functions for consistent
code formatting and improved readability.
Co-authored-by: Claude <noreply@anthropic.com>
Introduces `str_prefix_p` and `str_suffix_p` helper functions to
centralize the logic for checking string prefixes and suffixes.
`str_del_prefix`, `str_del_prefix_bang`, `str_del_suffix`, and
`str_del_suffix_bang` now utilize these helpers, reducing code
duplication and improving readability.
Co-authored-by: Gemini <gemini@google.com>
Introduces `ary_get_array_args` to centralize the argument parsing logic for
set operations, reducing code duplication in `ary_subtract_internal`,
`ary_union_internal`, and `ary_intersection_internal`. Also fixes a bug in
`ary_union_internal` where converted arguments were not being used.
Co-authored-by: Gemini <gemini@google.com>
Introduces `ary_update_hash_set` to centralize the logic for adding array
elements to a hash set. This helper is now used by `ary_to_hash_set`,
`ary_subtract_internal`, and `ary_intersection_internal`, reducing code
duplication.
Co-authored-by: Gemini <gemini@google.com>
Introduce comprehensive helper macros for pool memory operations:
- MPZ_POOL_ALLOC/MPZ_POOL_ALLOC_GOTO: allocation with automatic fallback
- MPZ_POOL_CLEANUP: safe cleanup with null pointer checks
- MPZ_POOL_VERIFY/MPZ_POOL_VERIFY_2/3/4/6: memory verification helpers
These macros eliminate ~30 repetitive code patterns across pool-based
functions, improving maintainability and reducing the chance of errors
in memory management logic.
Co-authored-by: Claude <noreply@anthropic.com>
This removes code duplication by making ary_compact call
ary_compact_bang on a duplicated array, centralizing the compaction
logic. It also reorders the functions to remove the need for a forward
declaration.
Co-authored-by: Gemini <gemini@google.com>
This removes code duplication by making ary_uniq call ary_uniq_bang on a
duplicated array, centralizing the uniqueness logic.
Co-authored-by: Gemini <gemini@google.com>
Replace inconsistent 'scoped' terminology with unified 'pool' naming:
- mpz_scoped_pool_t -> mpz_pool_t
- All function names: *_scoped -> *_pool
- Updated comments and documentation
This cleanup improves code readability and maintains consistent
terminology throughout the memory pool system.
Co-authored-by: Claude <noreply@anthropic.com>
Implements stack-based memory pools for GCD calculation using binary
GCD algorithm with Lehmer acceleration. Manages 8+ temporary variables
entirely in pool memory including complex transformation matrices.
Co-authored-by: Claude <noreply@anthropic.com>
Implements stack-based memory pools for six major bigint operations:
addition, subtraction, multiplication, division, square root, and
modular exponentiation. Provides 61% pool utilization with significant
heap allocation reduction (~1.4MB savings per 500 operations) while
maintaining full API compatibility and graceful fallback mechanisms.
Co-authored-by: Claude <noreply@anthropic.com>
Add stack-based memory pools to reduce heap allocations and improve
memory efficiency for bigint operations in memory-constrained
environments.
Features:
- Pool-based addition (mpz_add_scoped with uadd_scoped/usub_scoped)
- Pool-based multiplication (mpz_mul_sliding_window_scoped)
- Pool-based division (udiv_scoped with manual bit-shifting)
- Pool-based square root (mpz_sqrt_scoped with Newton-Raphson)
- Automatic fallback to traditional algorithms when pools unavailable
- 512-limb pool capacity (2-4KB stack allocation per operation)
- Algorithm selection for 4-128 limb operands (optimal memory benefit range)
Memory benefits:
- 65% pool utilization across benchmark operations
- ~2.4MB heap allocation reduction per 1000 operations
- 39-65 fewer malloc/free calls per pool-based operation
- Zero memory leaks through automatic pool cleanup
- Reduced heap fragmentation in long-running programs
- Better cache locality with stack-based intermediate calculations
Technical implementation:
- Scoped pool structure with automatic lifecycle management
- Custom pool-aware allocation and cleanup functions
- Manual bit-shifting to avoid mpz_move conflicts with pool memory
- Comprehensive error handling and graceful degradation
- Full backward compatibility with existing API
Performance characteristics:
- Prioritizes memory efficiency over raw speed (aligns with mruby design)
- Slight performance overhead acceptable for memory-constrained use cases
- Measurable memory benefits scale with operation frequency and program duration
Co-authored-by: Claude <noreply@anthropic.com>