diff options
| author | Michael Dusan <michael.dusan@gmail.com> | 2020-02-10 21:08:08 -0500 |
|---|---|---|
| committer | Michael Dusan <michael.dusan@gmail.com> | 2020-02-10 21:08:08 -0500 |
| commit | edb210905dcbe666fa5222bceacd2e5bdb16bb89 (patch) | |
| tree | 984aec0e5bad756daf426855c54bae3c42c73eca /src/mem_list.hpp | |
| parent | 1cdefeb10b7496126bbb7d00709235abfee56a4a (diff) | |
| download | zig-edb210905dcbe666fa5222bceacd2e5bdb16bb89.tar.gz zig-edb210905dcbe666fa5222bceacd2e5bdb16bb89.zip | |
stage1: memory/report overhaul
- split util_base.hpp from util.hpp
- new namespaces: `mem` and `heap`
- new `mem::Allocator` interface
- new `heap::CAllocator` impl with global `heap::c_allocator`
- new `heap::ArenaAllocator` impl
- new `mem::TypeInfo` extracts names without RTTI
- name extraction is enabled w/ ZIG_ENABLE_MEM_PROFILE=1
- new `mem::List` takes explicit `Allocator&` parameter
- new `mem::HashMap` takes explicit `Allocator&` parameter
- add Codegen.pass1_arena and use for all `ZigValue` allocs
- deinit Codegen.pass1_arena early in `zig_llvm_emit_output()`
Diffstat (limited to 'src/mem_list.hpp')
| -rw-r--r-- | src/mem_list.hpp | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/src/mem_list.hpp b/src/mem_list.hpp new file mode 100644 index 0000000000..a09d4d1c8d --- /dev/null +++ b/src/mem_list.hpp @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2015 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_MEM_LIST_HPP +#define ZIG_MEM_LIST_HPP + +#include "mem.hpp" + +namespace mem { + +template<typename T> +struct List { + void deinit(Allocator& allocator) { + allocator.deallocate<T>(items, capacity); + } + + void append(Allocator& allocator, const T& item) { + ensure_capacity(allocator, length + 1); + items[length++] = item; + } + + // remember that the pointer to this item is invalid after you + // modify the length of the list + const T & at(size_t index) const { + assert(index != SIZE_MAX); + assert(index < length); + return items[index]; + } + + T & at(size_t index) { + assert(index != SIZE_MAX); + assert(index < length); + return items[index]; + } + + T pop() { + assert(length >= 1); + return items[--length]; + } + + T *add_one() { + resize(length + 1); + return &last(); + } + + const T & last() const { + assert(length >= 1); + return items[length - 1]; + } + + T & last() { + assert(length >= 1); + return items[length - 1]; + } + + void resize(Allocator& allocator, size_t new_length) { + assert(new_length != SIZE_MAX); + ensure_capacity(allocator, new_length); + length = new_length; + } + + void clear() { + length = 0; + } + + void ensure_capacity(Allocator& allocator, size_t new_capacity) { + if (capacity >= new_capacity) + return; + + size_t better_capacity = capacity; + do { + better_capacity = better_capacity * 5 / 2 + 8; + } while (better_capacity < new_capacity); + + items = allocator.reallocate_nonzero<T>(items, capacity, better_capacity); + capacity = better_capacity; + } + + T swap_remove(size_t index) { + if (length - 1 == index) return pop(); + + assert(index != SIZE_MAX); + assert(index < length); + + T old_item = items[index]; + items[index] = pop(); + return old_item; + } + + T *items{nullptr}; + size_t length{0}; + size_t capacity{0}; +}; + +} // namespace mem + +#endif |
