Skip to content

[Perf] - can we remove usage of GcRefCell in the inline_cache? #5399

Description

@jasonwilliams

Describe the bug
When running the "Richards" test, a high proportion of cache misses are coming from the inline cache.
Image

This is because the IC goes through a GcRefCell borrow to get entries:

pub(crate) entries: GcRefCell<ArrayVec<CacheEntry, PIC_CAPACITY>>,

When these are borrowed here, its nearly always a cache miss.

We have 2 options.

  1. As the hot path is through the some branch the mutable borrow isn't even needed, as thats only used when a weakShape has been collected, so most of these calls don't even need a mutable borrow, a shared one should be fine and offer less over head.

A quick fix could be something like this:

 pub(crate) fn get(&self, shape: &Shape) -> Option<(Shape, Slot)> {
      if self.megamorphic.get() { return None; }

      let entries = self.entries.borrow();   // shared borrow — no write to borrow flag
      let shape_addr = shape.to_addr_usize();

      for (i, entry) in entries.iter().enumerate() {
          if let Some(upgraded) = entry.shape.upgrade() {
              if upgraded.to_addr_usize() == shape_addr {
                  return Some((upgraded, entry.slot));
              }
          } else {
              // stale entry found — drop shared borrow, take exclusive, clean up
              drop(entries);
              let mut entries = self.entries.borrow_mut();
              entries.swap_remove(i);
              return None;  // shape didn't match anyway (it was stale)
          }
      }
      None
  }

2: Do we need to wrap in GcRefCell at all? CacheEntry only holds a weakShape, so probably doesn't require the wrapping in GcRefCell as by its very nature a weakShape wouldn't keep the value alive anyway. Could we just swap this to a Cell and have this still work?

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions