RubyConf 2023 - The Second Oldest Bug by Jeremy Evans

Explore the Second Oldest Bug in Ruby, its causes, and the journey to fix it, including performance optimizations and implications, showcasing the complexity of debugging and the importance of collaboration.

Key takeaways
  • Ruby’s Second Oldest Bug: Ruby’s second oldest open bug #4040, a system stack error with hash *a for large a.
  • Method Calling: Function calls can cause issues with large array splats; stack overflow errors can occur when calling methods defined in C.
  • Ruby’s VM Stack: Ruby’s virtual machine uses a stack for method calls, with limited size.
  • Arguments: Passing large array splats can cause issues; Ruby has a limit on the number of arguments it can pass.
  • Fixing the Bug: Multiple approaches to fixing the bug were taken, including creating a temporary array to hold arguments and pushing the keyword hash onto the array.
  • Performance Optimizations: Some performance improvements were made, including optimizations to method calling and eliminating the need for unnecessary copying.
  • Bug Fix and Performance Implications: The bug fix had both performance improvements and decreases, with some benchmarks showing faster and others showing slower results.
  • Apply Fixes: When deciding whether to commit fixes, an understanding of the costs and benefits is necessary.
  • Bug Class: Not a single bug, but a general class of related bugs.
  • Further Debugging: Utilize tools like GDB and Ruby’s compiler to better understand issue and create fixes.
  • Test Suites: Running test suites can help identify issues; passing a large array splat test case will also reveal bugs.
  • Approach: Creating a temporary Ruby array to store arguments, copying from argv into the array, and returning a pointer to the array can mitigate issues.
  • Method Missing Calls: Performance improvements were made by reducing the time it takes to handle method missing calls.
  • YJIT Bench: A set of general benchmarks for testing Ruby performance.
  • Stack Technology: Ruby’s stack is limited in size and can cause issues with large array splats.
  • Object Pool: Ruby objects are stored in memory on the C heap.
  • Code Complexity: Code complexity can be an issue when making changes to fix bugs, and inverse trade-offs may be necessary to balance maintainability with performance.
  • Ruby Interns: It’s okay to need help from others in fixing Ruby bugs.