Skip to content

Instantly share code, notes, and snippets.

@thejoshwolfe
Created September 2, 2016 17:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thejoshwolfe/8329b7ce04cdfdd1feb9db59f43c6552 to your computer and use it in GitHub Desktop.
Save thejoshwolfe/8329b7ce04cdfdd1feb9db59f43c6552 to your computer and use it in GitHub Desktop.
pub struct AllocatorVtable {
allocFn: fn (self: &Allocator, n: usize) -> %[]u8,
reallocFn: fn (self: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8,
freeFn: fn (self: &Allocator, mem: []u8),
}
pub struct Allocator {
vtable: &AllocatorVtable,
}
struct SpaceSavingAllocator {
@attribute("first_element") parent: Allocator,
state: SomeStateStuff,
fn init(self: &Self) {
self.parent = Allocator{
.vtable = &space_saving_allocator_vtable,
};
}
fn alloc(almostSelf: &Allocator, n: usize) -> %[]u8 {
const self = (&Self)(almostSelf);
...
}
fn realloc(almostSelf: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8 {
const self = (&Self)(almostSelf);
...
}
fn free(almostSelf: &Allocator, mem: []u8) {
const self = (&Self)(almostSelf);
...
}
}
// a constant global vtable shared among all SpaceSavingAllocator instances
// saves space and provides security by preventing these pointers from changing.
const space_saving_allocator_vtable = AllocatorVtable{
.allocFn = SpaceSavingAllocator.alloc,
.reallocFn = SpaceSavingAllocator.realloc,
.freeFn = SpaceSavingAllocator.free,
};
struct CacheFriendlyAllocator {
@attribute("first_element") parent: Allocator,
// embed the vtable in the object
vtable: AllocatorVtable,
state: SomeStateStuff,
fn init(self: &Self) {
self.parent = Allocator{
// point to ourself
.vtable = &self.vtable,
};
self.vtable = AllocatorVtable{
.allocFn = CacheFriendlyAllocator.alloc,
.reallocFn = CacheFriendlyAllocator.realloc,
.freeFn = CacheFriendlyAllocator.free,
};
}
fn alloc(almostSelf: &Allocator, n: usize) -> %[]u8 {
const self = (&Self)(almostSelf);
...
}
fn realloc(almostSelf: &Allocator, old_mem: []u8, new_size: usize) -> %[]u8 {
const self = (&Self)(almostSelf);
...
}
fn free(almostSelf: &Allocator, mem: []u8) {
const self = (&Self)(almostSelf);
...
}
}
fn testAllocator(allocator: &Allocator) {
var blob = allocator.allocFn(10);
blob = allocator.reallocFn(blob, 20);
allocator.freeFn(blob);
}
@attribute("test")
fn testMain() {
{
var allocatorImpl: SpaceSavingAllocator = undefined;
allocatorImpl.init();
testAllocator(&allocatorImpl.parent);
}
{
var allocatorImpl: CacheFriendlyAllocator = undefined;
allocatorImpl.init();
testAllocator(&allocatorImpl.parent);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment