Skip to content

Conversation

@mattsse
Copy link
Contributor

@mattsse mattsse commented Jun 13, 2025

Summary

This PR addresses a significant performance bottleneck in the JavaScript tracer implementation where new JS objects were created for every EVM instruction execution. The optimization introduces an object reuse pattern that dramatically reduces allocation overhead.

Changes

Core Implementation

  • Added step_object and db_object fields to JsInspector struct for reusable objects
  • Implemented create_js_object_template() methods for one-time object structure creation
  • Added update_js_object() methods for in-place data updates without recreation
  • Modified try_step() and try_fault() methods to use lazy initialization and object reuse

Performance Optimization

  • Before: 2 new JS objects created per EVM instruction (millions per transaction trace)
  • After: 2 JS objects created once per tracer instance, then updated in-place
  • Impact: Massive reduction in heap allocations and garbage collection pressure

Test Coverage

  • Added 38 comprehensive test cases covering:
    • Unit tests for template creation and object updates
    • Integration tests for JS inspector functionality
    • Performance tests verifying no object leaks
    • Equivalence tests ensuring backward compatibility

Backward Compatibility

All existing JavaScript tracer code continues to work unchanged. The original into_js_object() methods are preserved for compatibility.

Test Results

All 46 tests pass, including 8 existing tests and 38 new tests specifically for this optimization.

Type of Change

  • Performance improvement
  • New feature (object reuse pattern)
  • Breaking change
  • New tests added

mattsse added 4 commits June 13, 2025 09:38
This change eliminates the performance bottleneck in JavaScript tracing
where new objects were created for every EVM instruction execution.

Key improvements:
- Added object reuse pattern with lazy initialization for step and database objects
- Implemented create_js_object_template() and update_js_object() methods
- Modified try_step() and try_fault() to reuse objects instead of recreating
- Reduced object allocation from millions per trace to 2 per tracer instance
- Added comprehensive test suite with 38 new tests covering unit, integration, and performance scenarios

Performance impact:
- Before: 2 new JS objects created per EVM instruction (potentially millions per transaction)
- After: 2 JS objects created once per tracer instance, then updated in-place
- Expected: Significant reduction in allocation overhead and garbage collection pressure

Backward compatibility maintained - existing JavaScript tracer code works unchanged.
- Add enter_frame_object and exit_frame_object fields to JsInspector
- Implement create_js_object_template and update_js_object for CallFrame and FrameResult
- Update try_enter and try_exit to use lazy initialization and object reuse
- Add comprehensive tests for enter/exit optimization
- This completes the object reuse pattern for all JS tracer hot paths
- Replace assert_eq with assert for boolean comparisons
- Use inline format args
- Add #[allow(dead_code)] to unused into_js_object methods
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.

2 participants