Skip to content
  • Yorick Peterse's avatar
    Fix various GC bugs and improve GC performance · 347ade20
    Yorick Peterse authored
    This fixes various Immix related bugs and makes some improvements to the
    collector's performance.
    
    Bug fixes
    ---------
    
    The following bugs have been fixed:
    
    1. Evacuating required one or more fragmented blocks, which were set
       based on histogram statistics. These statistics were only populated
       when there were one or more fragmented blocks. This resulted in
       evacuating never happening.
    
       Evacuating now happens if the previous collection increased the
       allocation threshold.
    
    2. The fragmentation status of a block was never cleared after a
       collection. This could result in an increase of fragmentation if the
       collector statistics deemed evacuating to not be needed.
    
    3. The remembered set using a HashSet meant that updating forward
       pointers in the remembered set would result in duplicate entries, as
       the hash codes would be different.
    
    4. Objects promoted to the mature generation would not be remembered if
       they contained any young pointers not promoted. We now trace mature
       objects to check if they need to be remembered, instead of always
       remembering them; drastically reducing the size of the remembered
       set.
    
    Improvements
    ------------
    
    1. The index to the eden space has been changed to a u8, allowing us to
       add some additional fields without growing the size of a Bucket.
    
    2. We no longer update line maps of mature blocks when performing a
       young collection. This is not needed in a young collection.
    
    3. We now use a chunked list for the remembered set and an additional
       object bit to prevent duplicate entries. This makes the remembered
       set more memory efficient, and removes the need for hashing. This
       does require the use of a 64-bits architecture, but Inko never really
       officially supported 32-bits anyway.
    
    4. Objects with a single hole are not taken into account when
       calculating fragmentation statuses. This way we don't overestimate
       the number of free lines as much, reducing the amount of evacuating
       objects.
    
    5. Messages are now copied into a process' local heap directly, instead
       of being copied into a separate mailbox heap. This reduces memory
       needed when sending messages, overall memory usage, and quite
       drastically simplifies the mailbox and garbage collection
       implementation. Access to the mailbox is synchronised using a
       spinlock, which is fast enough to be used by a mutator.
    
    6. Various garbage collection timers (e.g. the time spent preparing a
       collection) that weren't very useful have been removed.
    
    7. Parallel tracing performance has been improved by tracing objects in
       parallel, instead of only processing stack frames in parallel. When
       moving of objects is not needed this can significantly reduce garbage
       collection timings.
    
    8. The INKO_CONCURRENCY variable has been replaced with separate
       variables, as greater control is needed over some of the thread pool
       settings.
    
    9. GC timings can now be printed when setting INKO_PRINT_GC_TIMINGS to
       "true". This is an internal option and will only stick around until
       we have a better way of aggregating and presenting VM/GC statistics.
    
    10. Updating of garbage collection statistics at the end of a collection
        has been improved a bit, removing the need for counting the total
        number of blocks separately. The performance improvement of this is
        minor, but it does clean up the code quite a bit.
    347ade20