Skip to content

Conversation

@andrewrk
Copy link
Member

@andrewrk andrewrk commented Aug 8, 2020

std.GeneralPurposeAllocator is now available. It is a function that
takes a configuration struct (with default field values) and returns an
allocator. There is a detailed description of this allocator in the
doc comments at the top of the new file.

The main feature of this allocator is that it is safe. It
prevents double-free, use-after-free, and detects leaks.

Some deprecation compile errors are removed.

The Allocator interface gains old_align as a new parameter to
resizeFn. This is useful to quickly look up allocations.

std.heap.page_allocator is improved to use mmap address hints to avoid
obtaining the same virtual address pages when unmapping and mapping
pages. The new general purpose allocator uses the page allocator as its
backing allocator by default.

std.testing.allocator is replaced with usage of this new allocator,
which does leak checking, and so the LeakCheckAllocator is retired.

stage1 is improved so that the @typeInfo of a pointer has a lazy value
for the alignment of the child type, to avoid false dependency loops
when dealing with pointers to async function frames.

The std.mem.Allocator interface is refactored to be in its own file.

std.Mutex now exposes the dummy mutex with std.mutex.Dummy.

This allocator is great for debug mode, however it needs some work to
have better performance in release modes. The next step will be setting
up a series of tests in ziglang/gotta-go-fast and then making
improvements to the implementation.

`std.GeneralPurposeAllocator` is now available. It is a function that
takes a configuration struct (with default field values) and returns an
allocator. There is a detailed description of this allocator in the
doc comments at the top of the new file.

The main feature of this allocator is that it is *safe*. It
prevents double-free, use-after-free, and detects leaks.

Some deprecation compile errors are removed.

The Allocator interface gains `old_align` as a new parameter to
`resizeFn`. This is useful to quickly look up allocations.

`std.heap.page_allocator` is improved to use mmap address hints to avoid
obtaining the same virtual address pages when unmapping and mapping
pages. The new general purpose allocator uses the page allocator as its
backing allocator by default.

`std.testing.allocator` is replaced with usage of this new allocator,
which does leak checking, and so the LeakCheckAllocator is retired.

stage1 is improved so that the `@typeInfo` of a pointer has a lazy value
for the alignment of the child type, to avoid false dependency loops
when dealing with pointers to async function frames.

The `std.mem.Allocator` interface is refactored to be in its own file.

`std.Mutex` now exposes the dummy mutex with `std.Mutex.Dummy`.

This allocator is great for debug mode, however it needs some work to
have better performance in release modes. The next step will be setting
up a series of tests in ziglang/gotta-go-fast and then making
improvements to the implementation.
 * std.Mutex API is improved to not have init() deinit(). This API is
   designed to support static initialization and does not require any
   resource cleanup. This also happens to work around some kind of
   stage1 behavior that wasn't letting the new allocator mutex code
   get compiled.
 * the general purpose allocator now returns a bool from deinit()
   which tells if there were any leaks. This value is used by the test
   runner to fail the tests if there are any.
 * self-hosted compiler is updated to use the general purpose allocator
   when not linking against libc.
@andrewrk andrewrk added breaking Implementing this issue could cause existing code to no longer compile or have different behavior. enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library. labels Aug 8, 2020

pub const Error = std.mem.Allocator.Error;

const small_bucket_count = math.log2(page_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be configurable.

free,
};

fn up_to_nearest_power_of_2(comptime T: type, n: T) T {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use math.ceilPowerOfTwo

// * stack_trace_addresses: [N]usize, // traces_per_slot for every allocation

const BucketHeader = struct {
prev: *BucketHeader,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be a std.LinkedList?

andrewrk added 10 commits August 8, 2020 00:34
The high level Allocator interface API functions will now do a
`@returnAddress()` so that stack traces captured by allocator
implementations have a return address that does not include the
Allocator overhead functions. This makes `4` a more reasonable default
for how many stack frames to capture.
This makes `@returnAddress()` return 0 for WebAssembly (when not using
the Emscripten OS) and avoids trying to capture stack traces for the
general purpose allocator on that target.
Sadly, trying to collect stack frames goes into an infinite loop on
mips. This sets the default number of stack frames to collect to 0 on
mips.
We don't pass no-omit-frame-pointer in release safe by default, so it
also makes sense to not try to collect stack trace frames by default in
release safe mode.
The tests are cleverly testing some alignment stuff, but were getting
thwarted by Windows choosing to allocate 64K aligned pages.
return power;
}

fn hash_addr(addr: usize) u32 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AutoHashMap should be better, especially now that it has a fastpath for easy to hash keys.

As pointed out by Sahnvour, AutoHashMap is both more convenient and will
have better performance in this case.
@andrewrk andrewrk merged commit 069a6f2 into master Aug 9, 2020
@andrewrk andrewrk deleted the general-purpose-allocator branch August 9, 2020 00:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Implementing this issue could cause existing code to no longer compile or have different behavior. enhancement Solving this issue will likely involve adding new logic or components to the codebase. standard library This issue involves writing Zig code for the standard library.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants