2

Generational References

 3 years ago
source link: https://vale.dev/blog/generational-references
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Generational References

2.3x faster than reference counting, unoptimized!
Jan 5 2021  —  Evan Ovadia

Generational references are a new memory management technique that's easy, deterministic, and very fast.

This technique is the first ingredient in Vale's final hybrid-generational memory design, which is even faster. Our eventual goal is to be as fast as Rust, and perhaps even as fast as C++, while being safer than both. 0

This article explains how generational references work, how they compare to reference counting, and what makes it all so fast. 1

Built on Single Ownership

Recall that in Vale, an object is freed when its owning reference goes out of scope. An object always has exactly one owning reference pointing to it.

We can have as many non-owning references as we want. 2

In other languages, when a programmer frees an object and then accidentally dereferences a non-owning reference to it, it can cause memory unsafety and vulnerabilities. 3

Our goal is to detect this situation and react to it safely. 4

Generational Malloc and the Sacred Integer

Generational references use generational malloc, which is like regular malloc, except at the top of every allocation is a generation number, which tracks how many objects have previously been at this memory location.

One could also think of it as describing "I am the nth inhabitant of this memory location".

Freeing an object will increment its generation number. Nobody else ever modifies it.

Later on, we use this number to see if a particular object is still alive, explained further below.

Generational malloc would normally be an adjustment to mimalloc or jemalloc, but we can simulate it with our own genMalloc and genFree functions:

  • genFree increments the generation number, and instead of calling free 56, remembers the allocation in a free-list. There's a free-list for every size class (16b, 24b, 32b, <=48b, <=64b, <=128b, etc).
  • genMalloc pulls from a free-list if possible. If it's empty, it calls malloc and initializes the generation number to 1.

You can find our experimental implementation in genHeap.c.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK