• Stars
    star
    1,018
  • Rank 45,203 (Top 0.9 %)
  • Language
    Rust
  • License
    Apache License 2.0
  • Created almost 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

A fast bump allocation arena for Rust

bumpalo

A fast bump allocation arena for Rust.

Build Status

Bump Allocation

Bump allocation is a fast, but limited approach to allocation. We have a chunk of memory, and we maintain a pointer within that memory. Whenever we allocate an object, we do a quick check that we have enough capacity left in our chunk to allocate the object and then update the pointer by the object's size. That's it!

The disadvantage of bump allocation is that there is no general way to deallocate individual objects or reclaim the memory region for a no-longer-in-use object.

These trade offs make bump allocation well-suited for phase-oriented allocations. That is, a group of objects that will all be allocated during the same program phase, used, and then can all be deallocated together as a group.

Deallocation en Masse, but no Drop

To deallocate all the objects in the arena at once, we can simply reset the bump pointer back to the start of the arena's memory chunk. This makes mass deallocation extremely fast, but allocated objects' Drop implementations are not invoked.

However: bumpalo::boxed::Box<T> can be used to wrap T values allocated in the Bump arena, and calls T's Drop implementation when the Box<T> wrapper goes out of scope. This is similar to how std::boxed::Box works, except without deallocating its backing memory.

What happens when the memory chunk is full?

This implementation will allocate a new memory chunk from the global allocator and then start bump allocating into this new memory chunk.

Example

use bumpalo::Bump;
use std::u64;

struct Doggo {
    cuteness: u64,
    age: u8,
    scritches_required: bool,
}

// Create a new arena to bump allocate into.
let bump = Bump::new();

// Allocate values into the arena.
let scooter = bump.alloc(Doggo {
    cuteness: u64::max_value(),
    age: 8,
    scritches_required: true,
});

// Exclusive, mutable references to the just-allocated value are returned.
assert!(scooter.scritches_required);
scooter.age += 1;

Collections

When the "collections" cargo feature is enabled, a fork of some of the std library's collections are available in the collections module. These collection types are modified to allocate their space inside bumpalo::Bump arenas.

#[cfg(feature = "collections")]
{
    use bumpalo::{Bump, collections::Vec};

    // Create a new bump arena.
    let bump = Bump::new();

    // Create a vector of integers whose storage is backed by the bump arena. The
    // vector cannot outlive its backing arena, and this property is enforced with
    // Rust's lifetime rules.
    let mut v = Vec::new_in(&bump);

    // Push a bunch of integers onto `v`!
    for i in 0..100 {
        v.push(i);
    }
}

Eventually all std collection types will be parameterized by an allocator and we can remove this collections module and use the std versions.

For unstable, nightly-only support for custom allocators in std, see the allocator_api section below.

bumpalo::boxed::Box

When the "boxed" cargo feature is enabled, a fork of std::boxed::Box is available in the boxed module. This Box type is modified to allocate its space inside bumpalo::Bump arenas.

A Box<T> runs T's drop implementation when the Box<T> is dropped. You can use this to work around the fact that Bump does not drop values allocated in its space itself.

#[cfg(feature = "boxed")]
{
    use bumpalo::{Bump, boxed::Box};
    use std::sync::atomic::{AtomicUsize, Ordering};

    static NUM_DROPPED: AtomicUsize = AtomicUsize::new(0);

    struct CountDrops;

    impl Drop for CountDrops {
        fn drop(&mut self) {
            NUM_DROPPED.fetch_add(1, Ordering::SeqCst);
        }
    }

    // Create a new bump arena.
    let bump = Bump::new();

    // Create a `CountDrops` inside the bump arena.
    let mut c = Box::new_in(CountDrops, &bump);

    // No `CountDrops` have been dropped yet.
    assert_eq!(NUM_DROPPED.load(Ordering::SeqCst), 0);

    // Drop our `Box<CountDrops>`.
    drop(c);

    // Its `Drop` implementation was run, and so `NUM_DROPS` has been
    // incremented.
    assert_eq!(NUM_DROPPED.load(Ordering::SeqCst), 1);
}

#![no_std] Support

Bumpalo is a no_std crate. It depends only on the alloc and core crates.

Thread support

The Bump is !Sync, which makes it hard to use in certain situations around threads β€’ for example in rayon.

The bumpalo-herd crate provides a pool of Bump allocators for use in such situations.

Nightly Rust allocator_api Support

The unstable, nightly-only Rust allocator_api feature defines an Allocator trait and exposes custom allocators for std types. Bumpalo has a matching allocator_api cargo feature to enable implementing Allocator and using Bump with std collections. Note that, as feature(allocator_api) is unstable and only in nightly Rust, Bumpalo's matching allocator_api cargo feature should be considered unstable, and will not follow the semver conventions that the rest of the crate does.

First, enable the allocator_api feature in your Cargo.toml:

[dependencies]
bumpalo = { version = "3.9", features = ["allocator_api"] }

Next, enable the allocator_api nightly Rust feature in your src/lib.rs or src/main.rs:

#![feature(allocator_api)]

Finally, use std collections with Bump, so that their internal heap allocations are made within the given bump arena:

use bumpalo::Bump;

// Create a new bump arena.
let bump = Bump::new();

// Create a `Vec` whose elements are allocated within the bump arena.
let mut v = Vec::new_in(&bump);
v.push(0);
v.push(1);
v.push(2);

Using the Allocator API on Stable Rust

You can enable the allocator_api2 Cargo feature and bumpalo will use the allocator_api2 crate to implement the unstable nightlyAllocator API on stable Rust. This means that bumpalo::Bump will be usable with any collection that is generic over allocator_api2::Allocator.

Minimum Supported Rust Version (MSRV)

This crate is guaranteed to compile on stable Rust 1.63 and up. It might compile with older versions but that may change in any new patch release.

We reserve the right to increment the MSRV on minor releases, however we will strive to only do it deliberately and for good reasons.

More Repositories

1

dodrio

A fast, bump-allocated virtual DOM library for Rust and WebAssembly.
Rust
1,236
star
2

wu.js

wu.js is a JavaScript library providing higher order functions for ES6 iterators.
JavaScript
864
star
3

generational-arena

A safe arena allocator that allows deletion without suffering from the ABA problem by using generational indices.
Rust
611
star
4

state_machine_future

Easily create type-safe `Future`s from state machines β€” without the boilerplate.
Rust
322
star
5

github-api

Javascript bindings for the Github API.
JavaScript
170
star
6

glob-to-regexp

Convert a glob to a regular expression
JavaScript
145
star
7

operational-transformation

JavaScript implementation of Operational Transformation
JavaScript
141
star
8

oxischeme

A Scheme implementation, in Rust.
Rust
128
star
9

id-arena

A simple, id-based arena
Rust
88
star
10

bacon-rajan-cc

Rust
86
star
11

mach

A rust interface to the Mach 3.0 kernel that underlies OSX.
Rust
80
star
12

bindgen-tutorial-bzip2-sys

A tutorial/example crate for generating C/C++ bindings on-the-fly with libbindgen
Rust
75
star
13

inlinable_string

An owned, grow-able UTF-8 string that stores small strings inline and avoids heap-allocation.
Rust
69
star
14

intrusive_splay_tree

An intrusive splay tree implementation that is no-std compatible and free from allocation and moves
Rust
65
star
15

synth-loop-free-prog

Synthesis of Loop-free Programs in Rust
Rust
62
star
16

fart

fitzgen's art
Rust
61
star
17

peepmatic

A DSL and compiler for generating peephole optimizers for Cranelift
Rust
59
star
18

scrapmetal

Scrap Your Rust Boilerplate
Rust
55
star
19

operational-transformation-example

Example app using Operational Transformation
JavaScript
51
star
20

wasm-smith

A WebAssembly test case generator
44
star
21

source-map-mappings

Parse the `mappings` field in source maps
Rust
39
star
22

chronos

Avoids JavaScript timer congestion
JavaScript
38
star
23

wasm-nm

List the symbols within a wasm file
Rust
38
star
24

associative-cache

A generic, fixed-size, associative cache
Rust
35
star
25

fast-bernoulli

Efficient sampling with uniform probability
Rust
32
star
26

zoolander

Pure Python DSL for CSS.
Python
28
star
27

django-wysiwyg-forms

WYSIWYG form editor/creator django app
JavaScript
25
star
28

winliner

The WebAssembly Indirect Call Inliner
Rust
25
star
29

minisynth-rs

Program synthesis is possible in Rust
Rust
24
star
30

derive_is_enum_variant

Automatically derives `is_dog` and `is_cat` methods for `enum Pet { Dog, Cat }`.
Rust
22
star
31

tempest

Tempest jQuery Templating Plugin
JavaScript
22
star
32

pfds-js

Purely Functional Data Structures in JS
JavaScript
22
star
33

histo

Histograms with a configurable number of buckets, and a terminal-friendly Display.
Rust
21
star
34

one-page-wasm

Rust
21
star
35

shuffling-allocator

Rust
20
star
36

rpn-js

A reverse polish notation --> JavaScript compiler demoing source maps
JavaScript
19
star
37

bugzilla-todos

Bugzilla todo list of reviews, flag requests, and bugs to fix
JavaScript
19
star
38

dwprod

Rust
16
star
39

tryparenscript.com

The code behind TryParenScript.com
JavaScript
16
star
40

is_executable

Is there an executable file at the given path?
Rust
15
star
41

rent_to_own

A wrapper type for optionally giving up ownership of the underlying value.
Rust
12
star
42

noodles

Asynchronous, non-blocking, continuation-passing-style versions of the common higher order functions in `Array.prototype`.
JavaScript
12
star
43

rust-conf-2019

Flatulence, Crystals, and Happy Little Accidents
JavaScript
11
star
44

life

John Conway's Game of Life (in Erlang)
Erlang
10
star
45

peeking_take_while

Rust
9
star
46

bufrng

An RNG that generates "random" numbers copied from a given buffer
Rust
9
star
47

wasm-summit-2021

Stuff related to my Wasm Summit 2021 talk
Rust
9
star
48

geotoy

Polygons in Contact + Glium
Rust
9
star
49

preduce

A parallel, language agnostic, automatic test case reducer
Rust
8
star
50

erl-ot

Simple example of Operational Transformation in Erlang
Erlang
8
star
51

longest-increasing-subsequence

A crate for finding a longest increasing subsequence of some input
Rust
8
star
52

cl-pattern-matching

Erlang/Haskell style pattern matching macros for Common Lisp.
Common Lisp
7
star
53

parenscript-narwhal

Integrates ParenScript with Narwhal and provides a ParenScript REPL.
JavaScript
7
star
54

reform

A Narwhal module for working with HTML forms, similar to Django's forms.
JavaScript
7
star
55

ada-scheme

Following along with Peter Michaux's Scheme from Scratch series (http://peter.michaux.ca/articles/scheme-from-scratch-introduction) in Ada
6
star
56

wasm-debugging-capabilities

Collecting requirements for WebAssembly debugging capabilities
HTML
6
star
57

couchdb-io

Io library for working with CouchDB (not yet implemented)
Io
5
star
58

cool-rs

Rust
5
star
59

souper-ir

A library for manipulating Souper IR
Rust
4
star
60

canvas-tool

experimental canvas tool; WORK IN PROGRESS
JavaScript
4
star
61

code-size-benchmarks

Rust and WebAssembly code size micro benchmarks
Rust
4
star
62

dodrio-todomvc-wasm-instantiation

Rust
4
star
63

clife

Conway's life, in Rust.
Rust
3
star
64

class_views

Class based views for django
Python
3
star
65

Blimp

A very simple django blogging app for my site. Blog + Simple = Blimp?
Python
2
star
66

mxr

Search the Mozilla Cross Reference from the command line
Python
2
star
67

tokio-timeit-middleware

Rust
2
star
68

tasks

A demo app I used for my presentation on server side JS.
JavaScript
2
star
69

kahn

A build tool for AMD-style Common JS projects
JavaScript
2
star
70

boffo

Boffo
Erlang
2
star
71

pineapple

Not quite sure yet
JavaScript
2
star
72

mach_o_sys

Bindings to the OSX mach-o system library
Rust
2
star
73

dateformat

A port of Steven Levithan's dateFormat to CommonJS.
JavaScript
2
star
74

mcmc-maze-solver

Rust
2
star
75

protolith

Just for exploratory fun, I decided to see what it takes to write a prototypical object system in Lisp.
Common Lisp
2
star
76

strace.js

Trace JS native calls
JavaScript
2
star
77

mini-meta-git

Very simple, lightweight git repository authentication and management (because gitosis just gets in my way).
2
star
78

tron

An online implementation of Tron, but you play with code instead of keys. Built with Wu.js, WebSockets, and Node.
JavaScript
2
star
79

aossoa

A crate providing a macro to abstract and automate SoA vs AoS
Rust
1
star
80

powereddit

Make reddit better.
JavaScript
1
star
81

servo-trace-dump

JS and CSS for Servo's HTML timelines
HTML
1
star
82

reharm

Prolog
1
star
83

pybeasttree

Library for parsing/consuming BEAST tree files
Python
1
star
84

django-query-analyzer

Analyzer of django query
Python
1
star
85

rust-words

Learning Rust. Read words from stdin and then print each unique word out in order and how many times it was found.
Rust
1
star
86

breakpoint-rs

Set breakpoints with the `breakpoint!()` macro.
Rust
1
star
87

ocean-noise

Makes soothing ocean noises.
JavaScript
1
star
88

bender

Create robust user interfaces with finite state machines.
JavaScript
1
star
89

hippocampus

A Lisp dialect targetting JavaScript
JavaScript
1
star
90

magritte

My just-for-fun Lisp in progress
Common Lisp
1
star
91

loader

A smart, parallel client-side Javascript loader written in ParenScript
Common Lisp
1
star
92

learn-your-scales

Flashcard-style webapp for learning musical scales!
JavaScript
1
star
93

music-thang

JavaScript
1
star
94

what-the-ffi-python-example

Rust
1
star
95

bang-bang-con-west-2020

Writing Programs! That Write Other Programs!!
HTML
1
star
96

pancakes

Still a WIP
Rust
1
star
97

reader-submit-to-hn

Greasemonkey script to add a link for submitting articles to Hacker News from Google Reader.
JavaScript
1
star