mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Add location tracking for memory allocations.
This commit is contained in:
committed by
Christoffer Lerno
parent
e31f2a03ba
commit
f39aa1a41e
@@ -86,9 +86,9 @@ struct GrowableBitSet
|
||||
* @param initial_capacity
|
||||
* @param [&inout] allocator "The allocator to use, defaults to the heap allocator"
|
||||
**/
|
||||
fn GrowableBitSet* GrowableBitSet.init_new(&self, usz initial_capacity = 1, Allocator* allocator = mem::heap())
|
||||
fn GrowableBitSet* GrowableBitSet.init_new(&self, usz initial_capacity = 1, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
self.data.init_new(initial_capacity, allocator);
|
||||
self.data.init_new(initial_capacity, allocator, env);
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,14 +22,14 @@ struct List (Printable)
|
||||
* @param initial_capacity "The initial capacity to reserve"
|
||||
* @param [&inout] allocator "The allocator to use, defaults to the heap allocator"
|
||||
**/
|
||||
fn List* List.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap())
|
||||
fn List* List.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
self.allocator = allocator;
|
||||
self.size = 0;
|
||||
if (initial_capacity > 0)
|
||||
{
|
||||
initial_capacity = math::next_power_of_2(initial_capacity);
|
||||
self.entries = allocator.alloc_aligned(Type.sizeof * initial_capacity, .alignment = Type[1].alignof)!!;
|
||||
self.entries = allocator.alloc_aligned(Type.sizeof * initial_capacity, .alignment = Type[1].alignof, .env = env)!!;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -26,13 +26,13 @@ struct HashMap
|
||||
* @require !map.allocator "Map was already initialized"
|
||||
* @require capacity < MAXIMUM_CAPACITY "Capacity cannot exceed maximum"
|
||||
**/
|
||||
fn HashMap* HashMap.init_new(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::heap())
|
||||
fn HashMap* HashMap.init_new(&map, uint capacity = DEFAULT_INITIAL_CAPACITY, float load_factor = DEFAULT_LOAD_FACTOR, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
capacity = math::next_power_of_2(capacity);
|
||||
map.allocator = allocator;
|
||||
map.load_factor = load_factor;
|
||||
map.threshold = (uint)(capacity * load_factor);
|
||||
map.table = allocator.new_zero_array(Entry*, capacity);
|
||||
map.table = allocator.new_zero_array(Entry*, capacity, .env = env);
|
||||
return map;
|
||||
}
|
||||
|
||||
@@ -62,9 +62,9 @@ fn bool HashMap.is_initialized(&map)
|
||||
* @param [&inout] allocator "The allocator to use"
|
||||
* @param [&in] other_map "The map to copy from."
|
||||
**/
|
||||
fn HashMap* HashMap.init_new_from_map(&self, HashMap* other_map, Allocator* allocator = mem::heap())
|
||||
fn HashMap* HashMap.init_new_from_map(&self, HashMap* other_map, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
self.init_new(other_map.table.len, other_map.load_factor, allocator);
|
||||
self.init_new(other_map.table.len, other_map.load_factor, allocator, env);
|
||||
self.put_all_for_create(other_map);
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -78,9 +78,9 @@ fn usz! Object.to_format(&self, Formatter* formatter) @dynamic
|
||||
}
|
||||
}
|
||||
|
||||
fn Object* new_obj(Allocator* allocator)
|
||||
fn Object* new_obj(Allocator* allocator, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
Object* o = allocator.new(Object);
|
||||
Object* o = allocator.new(Object, .env = env);
|
||||
*o = { .allocator = allocator, .type = void.typeid };
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -36,9 +36,9 @@ struct PrivatePriorityQueue (Printable)
|
||||
Heap heap;
|
||||
}
|
||||
|
||||
fn void PrivatePriorityQueue.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap()) @inline
|
||||
fn void PrivatePriorityQueue.init_new(&self, usz initial_capacity = 16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env()) @inline
|
||||
{
|
||||
self.heap.init_new(initial_capacity, allocator);
|
||||
self.heap.init_new(initial_capacity, allocator, .env = env);
|
||||
}
|
||||
|
||||
fn void PrivatePriorityQueue.init_temp(&self, usz initial_capacity = 16) @inline
|
||||
|
||||
@@ -8,10 +8,10 @@ const usz MIN_CAPACITY @private = 16;
|
||||
/**
|
||||
* @require !self.data() "String already initialized"
|
||||
**/
|
||||
fn DString DString.init_new(&self, usz capacity = MIN_CAPACITY, Allocator* allocator = mem::heap())
|
||||
fn DString DString.init_new(&self, usz capacity = MIN_CAPACITY, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
if (capacity < MIN_CAPACITY) capacity = MIN_CAPACITY;
|
||||
StringData* data = allocator.new(StringData, .end_padding = capacity);
|
||||
StringData* data = allocator.new(StringData, .end_padding = capacity, .env = env);
|
||||
data.allocator = allocator;
|
||||
data.len = 0;
|
||||
data.capacity = capacity;
|
||||
@@ -27,17 +27,17 @@ fn DString DString.init_temp(&self, usz capacity = MIN_CAPACITY)
|
||||
return *self;
|
||||
}
|
||||
|
||||
fn DString new_with_capacity(usz capacity, Allocator* allocator = mem::heap())
|
||||
fn DString new_with_capacity(usz capacity, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return DString{}.init_new(capacity, allocator);
|
||||
return DString{}.init_new(capacity, allocator, .env = env);
|
||||
}
|
||||
|
||||
fn DString temp_with_capacity(usz capacity) => new_with_capacity(capacity, mem::temp()) @inline;
|
||||
|
||||
fn DString new(String c = "", Allocator* allocator = mem::heap())
|
||||
fn DString new(String c = "", Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz len = c.len;
|
||||
StringData* data = (StringData*)new_with_capacity(len, allocator);
|
||||
StringData* data = (StringData*)new_with_capacity(len, allocator, env);
|
||||
if (len)
|
||||
{
|
||||
data.len = len;
|
||||
@@ -48,10 +48,10 @@ fn DString new(String c = "", Allocator* allocator = mem::heap())
|
||||
|
||||
fn DString temp_new(String s = "") => new(s, mem::temp()) @inline;
|
||||
|
||||
fn DString DString.new_concat(self, DString b, Allocator* allocator = mem::heap())
|
||||
fn DString DString.new_concat(self, DString b, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
DString string;
|
||||
string.init_new(self.len() + b.len(), allocator);
|
||||
string.init_new(self.len() + b.len(), allocator, env);
|
||||
string.append(self);
|
||||
string.append(b);
|
||||
return string;
|
||||
@@ -148,37 +148,37 @@ fn void DString.append_char32(&self, Char32 c)
|
||||
|
||||
fn DString DString.tcopy(&self) => self.copy(mem::temp());
|
||||
|
||||
fn DString DString.copy(self, Allocator* allocator = null)
|
||||
fn DString DString.copy(self, Allocator* allocator = null, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
if (!self)
|
||||
{
|
||||
if (allocator) return new_with_capacity(0, allocator);
|
||||
if (allocator) return new_with_capacity(0, allocator, env);
|
||||
return (DString)null;
|
||||
}
|
||||
StringData* data = self.data();
|
||||
if (!allocator) allocator = mem::heap();
|
||||
DString new_string = new_with_capacity(data.capacity, allocator);
|
||||
DString new_string = new_with_capacity(data.capacity, allocator, env);
|
||||
mem::copy((char*)new_string.data(), (char*)data, StringData.sizeof + data.len);
|
||||
return new_string;
|
||||
}
|
||||
|
||||
fn ZString DString.copy_zstr(self, Allocator* allocator = mem::heap())
|
||||
fn ZString DString.copy_zstr(self, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz str_len = self.len();
|
||||
if (!str_len)
|
||||
{
|
||||
return (ZString)allocator.calloc(1);
|
||||
return (ZString)allocator.calloc(1, env);
|
||||
}
|
||||
char* zstr = allocator.alloc(str_len + 1);
|
||||
char* zstr = allocator.alloc(str_len + 1, env);
|
||||
StringData* data = self.data();
|
||||
mem::copy(zstr, &data.chars, str_len);
|
||||
zstr[str_len] = 0;
|
||||
return (ZString)zstr;
|
||||
}
|
||||
|
||||
fn String DString.copy_str(self, Allocator* allocator = mem::heap())
|
||||
fn String DString.copy_str(self, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return (String)self.copy_zstr(allocator)[:self.len()];
|
||||
return (String)self.copy_zstr(allocator, env)[:self.len()];
|
||||
}
|
||||
|
||||
fn String DString.tcopy_str(self) => self.copy_str(mem::temp()) @inline;
|
||||
@@ -240,9 +240,9 @@ fn void DString.append_chars(&self, String str)
|
||||
data.len += other_len;
|
||||
}
|
||||
|
||||
fn Char32[] DString.copy_utf32(&self, Allocator* allocator = mem::heap())
|
||||
fn Char32[] DString.copy_utf32(&self, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return self.str_view().to_new_utf32(allocator) @inline!!;
|
||||
return self.str_view().to_new_utf32(allocator, env) @inline!!;
|
||||
}
|
||||
|
||||
fn void DString.append_string(&self, DString str)
|
||||
@@ -354,7 +354,7 @@ fn usz! DString.appendfn(&self, String format, args...) @maydiscard
|
||||
return len + 1;
|
||||
}
|
||||
|
||||
fn DString new_join(String[] s, String joiner, Allocator* allocator = mem::heap())
|
||||
fn DString new_join(String[] s, String joiner, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
if (!s.len) return (DString)null;
|
||||
usz total_size = joiner.len * s.len;
|
||||
@@ -362,7 +362,7 @@ fn DString new_join(String[] s, String joiner, Allocator* allocator = mem::heap(
|
||||
{
|
||||
total_size += str.len;
|
||||
}
|
||||
DString res = new_with_capacity(total_size, allocator);
|
||||
DString res = new_with_capacity(total_size, allocator, env);
|
||||
res.append(s[0]);
|
||||
foreach (String* &str : s[1..])
|
||||
{
|
||||
@@ -384,12 +384,12 @@ fn StringData* DString.data(self) @inline @private
|
||||
return (StringData*)self;
|
||||
}
|
||||
|
||||
fn void DString.reserve(&self, usz addition)
|
||||
fn void DString.reserve(&self, usz addition, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
StringData* data = self.data();
|
||||
if (!data)
|
||||
{
|
||||
*self = dstring::new_with_capacity(addition);
|
||||
*self = dstring::new_with_capacity(addition, .env = env);
|
||||
return;
|
||||
}
|
||||
usz len = data.len + addition;
|
||||
@@ -398,7 +398,7 @@ fn void DString.reserve(&self, usz addition)
|
||||
if (new_capacity < MIN_CAPACITY) new_capacity = MIN_CAPACITY;
|
||||
while (new_capacity < len) new_capacity *= 2;
|
||||
data.capacity = new_capacity;
|
||||
*self = (DString)data.allocator.realloc(data, StringData.sizeof + new_capacity);
|
||||
*self = (DString)data.allocator.realloc(data, StringData.sizeof + new_capacity, env);
|
||||
}
|
||||
|
||||
fn usz! DString.read_from_stream(&self, InStream* reader)
|
||||
|
||||
@@ -385,6 +385,20 @@ macro void @scoped(Allocator* allocator; @body())
|
||||
@body();
|
||||
}
|
||||
|
||||
macro void @report_heap_allocs_in_scope(;@body())
|
||||
{
|
||||
TrackingAllocator tracker;
|
||||
tracker.init(thread_allocator);
|
||||
Allocator* old_allocator = thread_allocator;
|
||||
thread_allocator = &tracker;
|
||||
defer
|
||||
{
|
||||
thread_allocator = old_allocator;
|
||||
tracker.print_report();
|
||||
tracker.free();
|
||||
}
|
||||
@body();
|
||||
}
|
||||
|
||||
macro void @stack_mem(usz $size; @body(Allocator* mem)) @builtin
|
||||
{
|
||||
@@ -494,11 +508,21 @@ fn void initialize_wasm_mem() @init(1) @private
|
||||
thread_allocator = &wasm_allocator;
|
||||
}
|
||||
|
||||
module std::core::mem @if(!env::TRACK_MEMORY);
|
||||
module std::core::mem;
|
||||
|
||||
macro @clone(value) @builtin
|
||||
|
||||
macro TrackingEnv* get_tracking_env()
|
||||
{
|
||||
return mem::heap().clone(value);
|
||||
$if env::TRACK_MEMORY:
|
||||
return &&TrackingEnv { $$FILE, $$FUNC, $$LINE };
|
||||
$else
|
||||
return null;
|
||||
$endif
|
||||
}
|
||||
|
||||
macro @clone(value, TrackingEnv* env = mem::get_tracking_env()) @builtin
|
||||
{
|
||||
return mem::heap().clone(value, env);
|
||||
}
|
||||
|
||||
macro @tclone(value) @builtin
|
||||
@@ -506,24 +530,24 @@ macro @tclone(value) @builtin
|
||||
return mem::temp().clone(value);
|
||||
}
|
||||
|
||||
fn void* malloc(usz size) @builtin @inline
|
||||
fn void* malloc(usz size, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline
|
||||
{
|
||||
return mem::heap().alloc(size);
|
||||
return mem::heap().alloc(size, env);
|
||||
}
|
||||
|
||||
fn void* tmalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline
|
||||
fn void* tmalloc(usz size, usz alignment = 0, usz offset = 0, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline
|
||||
{
|
||||
return temp().acquire(size, false, alignment, offset, null)!!;
|
||||
return temp().acquire(size, false, alignment, offset, env)!!;
|
||||
}
|
||||
|
||||
macro new($Type)
|
||||
macro new($Type, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return heap().new($Type);
|
||||
return heap().new($Type, .env = env);
|
||||
}
|
||||
|
||||
macro new_clear($Type)
|
||||
macro new_clear($Type, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return heap().new_clear($Type);
|
||||
return heap().new_clear($Type, env);
|
||||
}
|
||||
|
||||
macro new_temp($Type)
|
||||
@@ -536,9 +560,9 @@ macro new_temp_clear($Type)
|
||||
return tcalloc($Type.sizeof);
|
||||
}
|
||||
|
||||
macro new_array($Type, usz elements)
|
||||
macro new_array($Type, usz elements, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return heap().new_array($Type, elements);
|
||||
return heap().new_array($Type, elements, .env = env);
|
||||
}
|
||||
|
||||
macro temp_array($Type, usz elements)
|
||||
@@ -546,9 +570,9 @@ macro temp_array($Type, usz elements)
|
||||
return (($Type*)tmalloc($Type.sizeof * elements, $Type.alignof))[:elements];
|
||||
}
|
||||
|
||||
macro new_zero_array($Type, usz elements)
|
||||
macro new_zero_array($Type, usz elements, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return heap().new_zero_array($Type, elements);
|
||||
return heap().new_zero_array($Type, elements, env);
|
||||
}
|
||||
|
||||
macro temp_zero_array($Type, usz elements)
|
||||
@@ -556,9 +580,9 @@ macro temp_zero_array($Type, usz elements)
|
||||
return (($Type*)tcalloc($Type.sizeof * elements, $Type.alignof))[:elements];
|
||||
}
|
||||
|
||||
fn void* calloc(usz size) @builtin @inline
|
||||
fn void* calloc(usz size, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline
|
||||
{
|
||||
return heap().calloc(size);
|
||||
return heap().calloc(size, env);
|
||||
}
|
||||
|
||||
fn void* tcalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline
|
||||
@@ -566,14 +590,14 @@ fn void* tcalloc(usz size, usz alignment = 0, usz offset = 0) @builtin @inline
|
||||
return temp().acquire(size, false, alignment, offset, null)!!;
|
||||
}
|
||||
|
||||
fn void* realloc(void *ptr, usz new_size) @builtin @inline
|
||||
fn void* realloc(void *ptr, usz new_size, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline
|
||||
{
|
||||
return heap().realloc(ptr, new_size);
|
||||
return heap().realloc(ptr, new_size, env);
|
||||
}
|
||||
|
||||
fn void free(void* ptr) @builtin @inline
|
||||
fn void free(void* ptr, TrackingEnv* env = mem::get_tracking_env()) @builtin @inline
|
||||
{
|
||||
heap().free(ptr);
|
||||
heap().free(ptr, env);
|
||||
}
|
||||
|
||||
fn void* trealloc(void* ptr, usz size, usz alignment = mem::DEFAULT_MEM_ALIGNMENT) @builtin @inline
|
||||
|
||||
@@ -9,6 +9,8 @@ struct TrackingEnv
|
||||
String function;
|
||||
uint line;
|
||||
}
|
||||
|
||||
|
||||
interface Allocator
|
||||
{
|
||||
fn void reset(usz mark) @optional;
|
||||
@@ -103,116 +105,120 @@ fn usz alignment_for_allocation(usz alignment) @inline @private
|
||||
return alignment < mem::DEFAULT_MEM_ALIGNMENT ? alignment = mem::DEFAULT_MEM_ALIGNMENT : alignment;
|
||||
}
|
||||
|
||||
module std::core::mem::allocator @if(!env::TRACK_MEMORY);
|
||||
|
||||
// Allocator "functions"
|
||||
|
||||
macro void*! Allocator.alloc_checked(&self, usz size)
|
||||
macro void*! Allocator.alloc_checked(&self, usz size, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
$if env::TESTING:
|
||||
char* data = self.acquire(size, false, 0, 0, null)!;
|
||||
char* data = self.acquire(size, false, 0, 0, env)!;
|
||||
mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
return data;
|
||||
$else
|
||||
return self.acquire(size, false, 0, 0, null);
|
||||
return self.acquire(size, false, 0, 0, env);
|
||||
$endif
|
||||
}
|
||||
|
||||
macro void*! Allocator.calloc_checked(&self, usz size) => self.acquire(size, true, 0, 0, null);
|
||||
macro void*! Allocator.realloc_checked(&self, void* ptr, usz new_size) => self.resize(ptr, new_size, 0, 0, null);
|
||||
|
||||
macro Allocator.new_array(&self, $Type, usz size, usz end_padding = 0)
|
||||
macro void*! Allocator.calloc_checked(&self, usz size, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding))[:size]!!;
|
||||
return self.acquire(size, true, 0, 0, env);
|
||||
}
|
||||
macro void*! Allocator.realloc_checked(&self, void* ptr, usz new_size, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return self.resize(ptr, new_size, 0, 0, env);
|
||||
}
|
||||
|
||||
macro Allocator.new_array_checked(&self, $Type, usz size, usz end_padding = 0)
|
||||
macro Allocator.new_array(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding))[:size];
|
||||
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, env))[:size]!!;
|
||||
}
|
||||
|
||||
macro Allocator.new_zero_array(&self, $Type, usz size, usz end_padding = 0)
|
||||
macro Allocator.new_array_checked(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding))[:size]!!;
|
||||
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, env))[:size];
|
||||
}
|
||||
|
||||
macro Allocator.new_zero_array_checked(&self, $Type, usz size, usz end_padding = 0)
|
||||
macro Allocator.new_zero_array(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding))[:size];
|
||||
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, env))[:size]!!;
|
||||
}
|
||||
|
||||
macro Allocator.new(&self, $Type, usz end_padding = 0) @nodiscard
|
||||
macro Allocator.new_zero_array_checked(&self, $Type, usz size, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return ($Type*)self.alloc_checked($Type.sizeof + end_padding)!!;
|
||||
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, env))[:size];
|
||||
}
|
||||
|
||||
macro Allocator.new_checked(&self, $Type, usz end_padding = 0) @nodiscard
|
||||
macro Allocator.new(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard
|
||||
{
|
||||
return ($Type*)self.alloc_checked($Type.sizeof + end_padding);
|
||||
return ($Type*)self.alloc_checked($Type.sizeof + end_padding, env)!!;
|
||||
}
|
||||
|
||||
macro Allocator.new_clear(&self, $Type, usz end_padding = 0) @nodiscard
|
||||
macro Allocator.new_checked(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard
|
||||
{
|
||||
return ($Type*)self.calloc_checked($Type.sizeof + end_padding)!!;
|
||||
return ($Type*)self.alloc_checked($Type.sizeof + end_padding, env);
|
||||
}
|
||||
|
||||
macro Allocator.new_clear_checked(&self, $Type, usz end_padding = 0) @nodiscard
|
||||
macro Allocator.new_clear(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard
|
||||
{
|
||||
return ($Type*)self.calloc_checked($Type.sizeof + end_padding);
|
||||
return ($Type*)self.calloc_checked($Type.sizeof + end_padding, env)!!;
|
||||
}
|
||||
|
||||
macro Allocator.clone(&self, value)
|
||||
macro Allocator.new_clear_checked(&self, $Type, usz end_padding = 0, TrackingEnv* env = mem::get_tracking_env()) @nodiscard
|
||||
{
|
||||
var x = self.alloc($typeof(value));
|
||||
return ($Type*)self.calloc_checked($Type.sizeof + end_padding, env);
|
||||
}
|
||||
|
||||
macro Allocator.clone(&self, value, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
var x = self.alloc($typeof(value), env);
|
||||
*x = value;
|
||||
return x;
|
||||
}
|
||||
|
||||
macro void* Allocator.alloc(&self, usz size) @nodiscard
|
||||
macro void* Allocator.alloc(&self, usz size, TrackingEnv* env = mem::get_tracking_env()) @nodiscard
|
||||
{
|
||||
return self.alloc_checked(size)!!;
|
||||
return self.alloc_checked(size, env)!!;
|
||||
}
|
||||
macro void* Allocator.calloc(&self, usz size) @nodiscard
|
||||
macro void* Allocator.calloc(&self, usz size, TrackingEnv* env = mem::get_tracking_env()) @nodiscard
|
||||
{
|
||||
return self.acquire(size, true, 0, 0, null)!!;
|
||||
return self.acquire(size, true, 0, 0, env)!!;
|
||||
}
|
||||
macro void* Allocator.realloc(&self, void* ptr, usz new_size) @nodiscard
|
||||
macro void* Allocator.realloc(&self, void* ptr, usz new_size, TrackingEnv* env = mem::get_tracking_env()) @nodiscard
|
||||
{
|
||||
return self.resize(ptr, new_size, 0, 0, null)!!;
|
||||
return self.resize(ptr, new_size, 0, 0, env)!!;
|
||||
}
|
||||
|
||||
macro void*! Allocator.alloc_aligned(&self, usz size, usz alignment, usz offset = 0)
|
||||
macro void*! Allocator.alloc_aligned(&self, usz size, usz alignment, usz offset = 0, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
$if env::TESTING:
|
||||
char* data = self.acquire(size, false, alignment, offset, null)!;
|
||||
char* data = self.acquire(size, false, alignment, offset, env)!;
|
||||
mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
return data;
|
||||
$else
|
||||
return self.acquire(size, false, alignment, offset, null);
|
||||
return self.acquire(size, false, alignment, offset, env);
|
||||
$endif
|
||||
}
|
||||
macro void*! Allocator.calloc_aligned(&self, usz size, usz alignment, usz offset = 0)
|
||||
macro void*! Allocator.calloc_aligned(&self, usz size, usz alignment, usz offset = 0, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return self.acquire(size, true, alignment, offset, null);
|
||||
return self.acquire(size, true, alignment, offset, env);
|
||||
}
|
||||
macro void*! Allocator.realloc_aligned(&self, void* ptr, usz new_size, usz alignment = 0, usz offset = 0)
|
||||
macro void*! Allocator.realloc_aligned(&self, void* ptr, usz new_size, usz alignment = 0, usz offset = 0, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return self.resize(ptr, new_size, alignment, offset, null);
|
||||
return self.resize(ptr, new_size, alignment, offset, env);
|
||||
}
|
||||
|
||||
macro void Allocator.free(&self, void* ptr)
|
||||
macro void Allocator.free(&self, void* ptr, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
$if env::TESTING:
|
||||
if (ptr) ((char*)ptr)[0] = 0xBA;
|
||||
$endif
|
||||
self.release(ptr, false, null);
|
||||
self.release(ptr, false, env);
|
||||
}
|
||||
macro void Allocator.free_aligned(&self, void* ptr)
|
||||
macro void Allocator.free_aligned(&self, void* ptr, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
$if env::TESTING:
|
||||
if (ptr) ((char*)ptr)[0] = 0xBA;
|
||||
$endif
|
||||
self.release(ptr, true, null);
|
||||
self.release(ptr, true, env);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,194 +0,0 @@
|
||||
module std::core::mem @if(env::TRACK_MEMORY);
|
||||
|
||||
macro @clone(value, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin
|
||||
{
|
||||
return mem::heap().clone(value, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro @tclone(value, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin
|
||||
{
|
||||
return mem::temp().clone(value, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
fn void* malloc(usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline
|
||||
{
|
||||
return mem::heap().alloc(size, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
fn void* tmalloc(usz size, usz alignment = 0, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline
|
||||
{
|
||||
return temp().acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line})!!;
|
||||
}
|
||||
|
||||
macro new($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return heap().new($Type, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro new_clear($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return heap().new_clear($Type, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro new_temp($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return tmalloc($Type.sizeof, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro new_temp_clear($Type, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return tcalloc($Type.sizeof, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro new_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return heap().new_array($Type, elements, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro temp_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return (($Type*)tmalloc($Type.sizeof * elements, $Type.alignof, .file = file, .func = func, .line = line))[:elements];
|
||||
}
|
||||
|
||||
macro new_zero_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return heap().new_zero_array($Type, elements, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro temp_zero_array($Type, usz elements, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return (($Type*)tcalloc($Type.sizeof * elements, $Type.alignof, .file = file, .func = func, .line = line))[:elements];
|
||||
}
|
||||
|
||||
fn void* calloc(usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline
|
||||
{
|
||||
return heap().calloc(size, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
fn void* tcalloc(usz size, usz alignment = 0, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline
|
||||
{
|
||||
return temp().acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line})!!;
|
||||
}
|
||||
|
||||
fn void* realloc(void *ptr, usz new_size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline
|
||||
{
|
||||
return heap().realloc(ptr, new_size, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
fn void free(void* ptr, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline
|
||||
{
|
||||
heap().free(ptr, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
fn void* trealloc(void* ptr, usz size, usz alignment = mem::DEFAULT_MEM_ALIGNMENT, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @builtin @inline
|
||||
{
|
||||
return temp().resize(ptr, size, alignment, 0, .env = &&TrackingEnv{ file, func, line})!!;
|
||||
}
|
||||
|
||||
module std::core::mem::allocator @if(env::TRACK_MEMORY);
|
||||
|
||||
macro void*! Allocator.alloc_checked(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
char* data = self.acquire(size, false, 0, 0, .env = &&TrackingEnv{ file, func, line})!;
|
||||
mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
return data;
|
||||
}
|
||||
|
||||
macro void*! Allocator.calloc_checked(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return self.acquire(size, true, 0, 0, .env = &&TrackingEnv{ file, func, line});
|
||||
}
|
||||
macro void*! Allocator.realloc_checked(&self, void* ptr, usz new_size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return self.resize(ptr, new_size, 0, 0, .env = &&TrackingEnv{ file, func, line});
|
||||
}
|
||||
|
||||
macro Allocator.new_array(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size]!!;
|
||||
}
|
||||
|
||||
macro Allocator.new_array_checked(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return (($Type*)self.alloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size];
|
||||
}
|
||||
|
||||
macro Allocator.new_zero_array(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size]!!;
|
||||
}
|
||||
|
||||
macro Allocator.new_zero_array_checked(&self, $Type, usz size, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return (($Type*)self.calloc_checked($Type.sizeof * size + end_padding, .file = file, .func = func, .line = line))[:size];
|
||||
}
|
||||
|
||||
macro Allocator.new(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard
|
||||
{
|
||||
return ($Type*)self.alloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line)!!;
|
||||
}
|
||||
|
||||
macro Allocator.new_checked(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard
|
||||
{
|
||||
return ($Type*)self.alloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro Allocator.new_clear(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard
|
||||
{
|
||||
return ($Type*)self.calloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line)!!;
|
||||
}
|
||||
|
||||
macro Allocator.new_clear_checked(&self, $Type, usz end_padding = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard
|
||||
{
|
||||
return ($Type*)self.calloc_checked($Type.sizeof + end_padding, .file = file, .func = func, .line = line);
|
||||
}
|
||||
|
||||
macro Allocator.clone(&self, value, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
var x = self.alloc($typeof(value), .file = file, .func = func, .line = line);
|
||||
*x = value;
|
||||
return x;
|
||||
}
|
||||
|
||||
macro void* Allocator.alloc(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard
|
||||
{
|
||||
return self.alloc_checked(size, .file = file, .func = func, .line = line)!!;
|
||||
}
|
||||
macro void* Allocator.calloc(&self, usz size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard
|
||||
{
|
||||
return self.acquire(size, true, 0, 0, .env = &&TrackingEnv{ file, func, line})!!;
|
||||
}
|
||||
macro void* Allocator.realloc(&self, void* ptr, usz new_size, String file = $$FILE, String func = $$FUNC, uint line = $$LINE) @nodiscard
|
||||
{
|
||||
return self.resize(ptr, new_size, 0, 0, .env = &&TrackingEnv{ file, func, line})!!;
|
||||
}
|
||||
macro void*! Allocator.alloc_aligned(&self, usz size, usz alignment, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
$if env::TESTING:
|
||||
char* data = self.acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line})!;
|
||||
mem::set(data, 0xAA, size, mem::DEFAULT_MEM_ALIGNMENT);
|
||||
return data;
|
||||
$else
|
||||
return self.acquire(size, false, alignment, offset, .env = &&TrackingEnv{ file, func, line});
|
||||
$endif
|
||||
}
|
||||
macro void*! Allocator.calloc_aligned(&self, usz size, usz alignment, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return self.acquire(size, true, alignment, offset, .env = &&TrackingEnv{ file, func, line});
|
||||
}
|
||||
macro void*! Allocator.realloc_aligned(&self, void* ptr, usz new_size, usz alignment = 0, usz offset = 0, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
return self.resize(ptr, new_size, alignment, offset, .env = &&TrackingEnv{ file, func, line});
|
||||
}
|
||||
|
||||
macro void Allocator.free(&self, void* ptr, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
if (ptr) ((char*)ptr)[0] = 0xBA;
|
||||
self.release(ptr, false, .env = &&TrackingEnv{ file, func, line});
|
||||
}
|
||||
|
||||
macro void Allocator.free_aligned(&self, void* ptr, String file = $$FILE, String func = $$FUNC, uint line = $$LINE)
|
||||
{
|
||||
if (ptr) ((char*)ptr)[0] = 0xBA;
|
||||
self.release(ptr, true, .env = &&TrackingEnv{ file, func, line});
|
||||
}
|
||||
@@ -38,13 +38,13 @@ macro String tformat(String fmt, ...)
|
||||
return str.str_view();
|
||||
}
|
||||
|
||||
macro String new_format(String fmt, ..., Allocator* allocator = mem::heap())
|
||||
macro String new_format(String fmt, ..., Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
@pool(allocator)
|
||||
{
|
||||
DString str = dstring::temp_with_capacity(fmt.len + $vacount * 8);
|
||||
str.appendf(fmt, $vasplat());
|
||||
return str.copy_str(allocator);
|
||||
return str.copy_str(allocator, env);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -55,11 +55,11 @@ macro bool char_in_set(char c, String set)
|
||||
return false;
|
||||
}
|
||||
|
||||
fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap())
|
||||
fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
if (!s)
|
||||
{
|
||||
return (String)allocator.new_zero_array(char, 2)[:0];
|
||||
return (String)allocator.new_zero_array(char, 2, .env = env)[:0];
|
||||
}
|
||||
|
||||
usz total_size = joiner.len * s.len;
|
||||
@@ -76,7 +76,7 @@ fn String join_new(String[] s, String joiner, Allocator* allocator = mem::heap()
|
||||
res.append(joiner);
|
||||
res.append(*str);
|
||||
}
|
||||
return res.copy_str(allocator);
|
||||
return res.copy_str(allocator, env);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -153,11 +153,11 @@ fn String String.strip_end(string, String needle)
|
||||
* @require needle.len > 0 "The needle must be at least 1 character long"
|
||||
* @ensure return.len > 0
|
||||
**/
|
||||
fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = mem::heap())
|
||||
fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz capacity = 16;
|
||||
usz i = 0;
|
||||
String* holder = allocator.new_array(String, capacity);
|
||||
String* holder = allocator.new_array(String, capacity, .env = env);
|
||||
bool no_more = false;
|
||||
while (!no_more)
|
||||
{
|
||||
@@ -176,7 +176,7 @@ fn String[] String.split(s, String needle, usz max = 0, Allocator* allocator = m
|
||||
if (i == capacity)
|
||||
{
|
||||
capacity *= 2;
|
||||
holder = allocator.realloc(holder, String.sizeof * capacity);
|
||||
holder = allocator.realloc(holder, String.sizeof * capacity, env);
|
||||
}
|
||||
holder[i++] = res;
|
||||
}
|
||||
@@ -312,19 +312,19 @@ fn usz ZString.len(str)
|
||||
}
|
||||
|
||||
|
||||
fn ZString String.zstr_copy(s, Allocator* allocator = mem::heap())
|
||||
fn ZString String.zstr_copy(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz len = s.len;
|
||||
char* str = allocator.alloc(len + 1);
|
||||
char* str = allocator.alloc(len + 1, env);
|
||||
mem::copy(str, s.ptr, len);
|
||||
str[len] = 0;
|
||||
return (ZString)str;
|
||||
}
|
||||
|
||||
fn String String.concat(s1, String s2, Allocator* allocator = mem::heap())
|
||||
fn String String.concat(s1, String s2, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz full_len = s1.len + s2.len;
|
||||
char* str = allocator.alloc(full_len + 1);
|
||||
char* str = allocator.alloc(full_len + 1, env);
|
||||
usz s1_len = s1.len;
|
||||
mem::copy(str, s1.ptr, s1_len);
|
||||
mem::copy(str + s1_len, s2.ptr, s2.len);
|
||||
@@ -337,27 +337,27 @@ fn String String.tconcat(s1, String s2) => s1.concat(s2, mem::temp());
|
||||
|
||||
fn ZString String.zstr_tcopy(s) => s.zstr_copy(mem::temp()) @inline;
|
||||
|
||||
fn String String.copy(s, Allocator* allocator = mem::heap())
|
||||
fn String String.copy(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz len = s.len;
|
||||
char* str = allocator.alloc(len + 1);
|
||||
char* str = allocator.alloc(len + 1, env);
|
||||
mem::copy(str, s.ptr, len);
|
||||
str[len] = 0;
|
||||
return (String)str[:len];
|
||||
}
|
||||
|
||||
fn void String.free(&s, Allocator* allocator = mem::heap())
|
||||
fn void String.free(&s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
if (!s.len) return;
|
||||
allocator.free(s.ptr);
|
||||
allocator.free(s.ptr, env);
|
||||
*s = "";
|
||||
}
|
||||
|
||||
fn String String.tcopy(s) => s.copy(mem::temp()) @inline;
|
||||
|
||||
fn String ZString.copy(z, Allocator* allocator = mem::temp())
|
||||
fn String ZString.copy(z, Allocator* allocator = mem::temp(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return z.str_view().copy(allocator) @inline;
|
||||
return z.str_view().copy(allocator, env) @inline;
|
||||
}
|
||||
|
||||
fn String ZString.tcopy(z)
|
||||
@@ -371,10 +371,10 @@ fn String ZString.tcopy(z)
|
||||
* @return! UnicodeResult.INVALID_UTF8 "If the string contained an invalid UTF-8 sequence"
|
||||
* @return! AllocationFailure "If allocation of the string fails"
|
||||
**/
|
||||
fn Char16[]! String.to_new_utf16(s, Allocator* allocator = mem::heap())
|
||||
fn Char16[]! String.to_new_utf16(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz len16 = conv::utf16len_for_utf8(s);
|
||||
Char16* data = allocator.new_array_checked(Char16, len16 + 1)!;
|
||||
Char16* data = allocator.new_array_checked(Char16, len16 + 1, .env = env)!;
|
||||
conv::utf8to16_unsafe(s, data)!;
|
||||
data[len16] = 0;
|
||||
return data[:len16];
|
||||
@@ -391,9 +391,9 @@ fn Char16[]! String.to_temp_utf16(s)
|
||||
return s.to_new_utf16(mem::temp());
|
||||
}
|
||||
|
||||
fn WString! String.to_new_wstring(s, Allocator* allocator = mem::heap())
|
||||
fn WString! String.to_new_wstring(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
return (WString)s.to_new_utf16(allocator).ptr;
|
||||
return (WString)s.to_new_utf16(allocator, env).ptr;
|
||||
}
|
||||
|
||||
fn WString! String.to_temp_wstring(s)
|
||||
@@ -401,10 +401,10 @@ fn WString! String.to_temp_wstring(s)
|
||||
return (WString)s.to_temp_utf16().ptr;
|
||||
}
|
||||
|
||||
fn Char32[]! String.to_new_utf32(s, Allocator* allocator = mem::heap())
|
||||
fn Char32[]! String.to_new_utf32(s, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz codepoints = conv::utf8_codepoints(s);
|
||||
Char32* data = allocator.new_array(Char32, codepoints + 1);
|
||||
Char32* data = allocator.new_array(Char32, codepoints + 1, .env = env);
|
||||
conv::utf8to32_unsafe(s, data)!;
|
||||
data[codepoints] = 0;
|
||||
return data[:codepoints];
|
||||
@@ -449,32 +449,32 @@ fn String String.temp_ascii_to_upper(s)
|
||||
return s.new_ascii_to_upper(mem::temp());
|
||||
}
|
||||
|
||||
fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = mem::heap())
|
||||
fn String! new_from_utf32(Char32[] utf32, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz len = conv::utf8len_for_utf32(utf32);
|
||||
char* data = allocator.alloc_checked(len + 1)!;
|
||||
char* data = allocator.alloc_checked(len + 1, env)!;
|
||||
defer catch allocator.free(data);
|
||||
conv::utf32to8_unsafe(utf32, data);
|
||||
data[len] = 0;
|
||||
return (String)data[:len];
|
||||
}
|
||||
|
||||
fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = mem::heap())
|
||||
fn String! new_from_utf16(Char16[] utf16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz len = conv::utf8len_for_utf16(utf16);
|
||||
char* data = allocator.alloc_checked(len + 1)!;
|
||||
char* data = allocator.alloc_checked(len + 1, env)!;
|
||||
defer catch allocator.free(data);
|
||||
conv::utf16to8_unsafe(utf16, data)!;
|
||||
data[len] = 0;
|
||||
return (String)data[:len];
|
||||
}
|
||||
|
||||
fn String! new_from_wstring(WString wstring, Allocator* allocator = mem::heap())
|
||||
fn String! new_from_wstring(WString wstring, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
usz utf16_len;
|
||||
while (wstring[utf16_len] != 0) utf16_len++;
|
||||
Char16[] utf16 = wstring[:utf16_len];
|
||||
return new_from_utf16(utf16, allocator);
|
||||
return new_from_utf16(utf16, allocator, env);
|
||||
}
|
||||
|
||||
fn String! temp_from_wstring(WString wstring) => new_from_wstring(wstring, mem::temp()) @inline;
|
||||
|
||||
@@ -16,11 +16,11 @@ struct ByteBuffer (InStream, OutStream)
|
||||
* max_read defines how many bytes might be kept before its internal buffer is shrinked.
|
||||
* @require self.bytes.len == 0 "Buffer already initialized."
|
||||
**/
|
||||
fn ByteBuffer*! ByteBuffer.init_new(&self, usz max_read, usz initial_capacity = 16, Allocator* allocator = mem::heap())
|
||||
fn ByteBuffer*! ByteBuffer.init_new(&self, usz max_read, usz initial_capacity = 16, Allocator* allocator = mem::heap(), TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
*self = { .allocator = allocator, .max_read = max_read };
|
||||
initial_capacity = max(initial_capacity, 16);
|
||||
self.grow(initial_capacity)!;
|
||||
self.grow(initial_capacity, env)!;
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -128,10 +128,10 @@ fn usz! ByteBuffer.available(&self) @inline @dynamic
|
||||
return self.write_idx - self.read_idx;
|
||||
}
|
||||
|
||||
fn void! ByteBuffer.grow(&self, usz n)
|
||||
fn void! ByteBuffer.grow(&self, usz n, TrackingEnv* env = mem::get_tracking_env())
|
||||
{
|
||||
n = math::next_power_of_2(n);
|
||||
char* p = self.allocator.realloc_aligned(self.bytes, n, .alignment = char.alignof)!;
|
||||
char* p = self.allocator.realloc_aligned(self.bytes, n, .alignment = char.alignof, .env = env)!;
|
||||
self.bytes = p[:n];
|
||||
}
|
||||
|
||||
|
||||
@@ -1305,7 +1305,7 @@ INLINE bool sema_call_expand_arguments(SemaContext *context, CalledDecl *callee,
|
||||
SemaContext *new_context = context_transform_for_eval(context, &default_context, param->unit);
|
||||
bool success;
|
||||
SCOPE_START
|
||||
new_context->original_inline_line = context->original_inline_line ? context->original_inline_line : init_expr->span.row;
|
||||
new_context->original_inline_line = context->original_inline_line ? context->original_inline_line : call->span.row;
|
||||
success = sema_analyse_expr_rhs(new_context, param->type, arg, true, no_match_ref);
|
||||
SCOPE_END;
|
||||
sema_context_destroy(&default_context);
|
||||
@@ -6783,9 +6783,19 @@ static inline bool sema_expr_analyse_compiler_const(SemaContext *context, Expr *
|
||||
expr_rewrite_to_string(expr, date_get());
|
||||
return true;
|
||||
case BUILTIN_DEF_FILE:
|
||||
if (context->call_env.current_function)
|
||||
{
|
||||
expr_rewrite_to_string(expr, context->call_env.current_function->unit->file->name);
|
||||
return true;
|
||||
}
|
||||
expr_rewrite_to_string(expr, context->compilation_unit->file->name);
|
||||
return true;
|
||||
case BUILTIN_DEF_FILEPATH:
|
||||
if (context->call_env.current_function)
|
||||
{
|
||||
expr_rewrite_to_string(expr, context->call_env.current_function->unit->file->full_path);
|
||||
return true;
|
||||
}
|
||||
expr_rewrite_to_string(expr, context->compilation_unit->file->full_path);
|
||||
return true;
|
||||
case BUILTIN_DEF_MODULE:
|
||||
|
||||
@@ -3028,6 +3028,7 @@ bool sema_analyse_function_body(SemaContext *context, Decl *func)
|
||||
Signature *signature = &func->func_decl.signature;
|
||||
FunctionPrototype *prototype = func->type->function.prototype;
|
||||
assert(prototype);
|
||||
context->original_inline_line = 0;
|
||||
context->call_env = (CallEnv) {
|
||||
.current_function = func,
|
||||
.kind = CALL_ENV_FUNCTION,
|
||||
|
||||
@@ -1 +1 @@
|
||||
#define COMPILER_VERSION "0.4.698"
|
||||
#define COMPILER_VERSION "0.4.699"
|
||||
|
||||
@@ -332,7 +332,7 @@ if.then7: ; preds = %if.exit4
|
||||
%15 = getelementptr inbounds %Doc, ptr %literal9, i32 0, i32 0
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %literal10, ptr align 8 @.__const.5, i32 8, i1 false)
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value, ptr align 8 %literal10, i32 8, i1 false)
|
||||
%16 = call ptr @std.core.mem.malloc(i64 8) #3
|
||||
%16 = call ptr @std.core.mem.malloc(i64 8, ptr null) #3
|
||||
store ptr %16, ptr %temp, align 8
|
||||
%17 = load ptr, ptr %temp, align 8
|
||||
%not = icmp eq ptr %17, null
|
||||
@@ -371,7 +371,7 @@ if.then16: ; preds = %if.exit13
|
||||
store ptr null, ptr %literal20, align 8
|
||||
%26 = getelementptr inbounds %Head, ptr %literal20, i32 0, i32 0
|
||||
store %"char[]" zeroinitializer, ptr %value22, align 8
|
||||
%27 = call ptr @std.core.mem.malloc(i64 16) #3
|
||||
%27 = call ptr @std.core.mem.malloc(i64 16, ptr null) #3
|
||||
store ptr %27, ptr %temp23, align 8
|
||||
%28 = load ptr, ptr %temp23, align 8
|
||||
%not24 = icmp eq ptr %28, null
|
||||
@@ -394,7 +394,7 @@ noerr_block28: ; preds = %if.exit26
|
||||
%31 = load ptr, ptr %temp23, align 8
|
||||
store ptr %31, ptr %26, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value29, ptr align 8 %literal20, i32 8, i1 false)
|
||||
%32 = call ptr @std.core.mem.malloc(i64 8) #3
|
||||
%32 = call ptr @std.core.mem.malloc(i64 8, ptr null) #3
|
||||
store ptr %32, ptr %temp30, align 8
|
||||
%33 = load ptr, ptr %temp30, align 8
|
||||
%not31 = icmp eq ptr %33, null
|
||||
@@ -430,7 +430,7 @@ if.exit36: ; preds = %if.exit13
|
||||
store i64 %sext, ptr %len, align 8
|
||||
%42 = load i64, ptr %len, align 8
|
||||
%add = add i64 %42, 1
|
||||
%43 = call ptr @std.core.mem.malloc(i64 %add) #3
|
||||
%43 = call ptr @std.core.mem.malloc(i64 %add, ptr null) #3
|
||||
store ptr %43, ptr %str, align 8
|
||||
%44 = load ptr, ptr %str, align 8
|
||||
%not37 = icmp eq ptr %44, null
|
||||
@@ -461,7 +461,7 @@ if.exit39: ; preds = %if.exit36
|
||||
%57 = insertvalue %"char[]" undef, ptr %ptroffset47, 0
|
||||
%58 = insertvalue %"char[]" %57, i64 %size, 1
|
||||
store %"char[]" %58, ptr %value48, align 8
|
||||
%59 = call ptr @std.core.mem.malloc(i64 16) #3
|
||||
%59 = call ptr @std.core.mem.malloc(i64 16, ptr null) #3
|
||||
store ptr %59, ptr %temp49, align 8
|
||||
%60 = load ptr, ptr %temp49, align 8
|
||||
%not50 = icmp eq ptr %60, null
|
||||
@@ -484,7 +484,7 @@ noerr_block54: ; preds = %if.exit52
|
||||
%63 = load ptr, ptr %temp49, align 8
|
||||
store ptr %63, ptr %53, align 8
|
||||
call void @llvm.memcpy.p0.p0.i32(ptr align 8 %value55, ptr align 8 %literal45, i32 8, i1 false)
|
||||
%64 = call ptr @std.core.mem.malloc(i64 8) #3
|
||||
%64 = call ptr @std.core.mem.malloc(i64 8, ptr null) #3
|
||||
store ptr %64, ptr %temp56, align 8
|
||||
%65 = load ptr, ptr %temp56, align 8
|
||||
%not57 = icmp eq ptr %65, null
|
||||
|
||||
@@ -66,7 +66,7 @@ entry:
|
||||
%lo = load i64, ptr %3, align 8
|
||||
%4 = getelementptr inbounds { i64, ptr }, ptr %allocator, i32 0, i32 1
|
||||
%hi = load ptr, ptr %4, align 8
|
||||
%5 = call ptr @std.core.dstring.new_with_capacity(i64 128, i64 %lo, ptr %hi)
|
||||
%5 = call ptr @std.core.dstring.new_with_capacity(i64 128, i64 %lo, ptr %hi, ptr null)
|
||||
store ptr %5, ptr %s, align 8
|
||||
%6 = getelementptr inbounds %Foo, ptr %0, i32 0, i32 0
|
||||
%7 = insertvalue %"any*" undef, ptr %6, 0
|
||||
@@ -133,7 +133,7 @@ entry:
|
||||
call void @llvm.memset.p0.i64(ptr align 8 %map, i8 0, i64 48, i1 false)
|
||||
%lo = load i64, ptr @std.core.mem.thread_allocator, align 8
|
||||
%hi = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
|
||||
%0 = call ptr @"std.collections.map$int$test.Foo$.HashMap.init_new"(ptr %map, i32 16, float 7.500000e-01, i64 %lo, ptr %hi)
|
||||
%0 = call ptr @"std.collections.map$int$test.Foo$.HashMap.init_new"(ptr %map, i32 16, float 7.500000e-01, i64 %lo, ptr %hi, ptr null)
|
||||
%1 = getelementptr inbounds %HashMap, ptr %map, i32 0, i32 2
|
||||
%2 = insertvalue %"any*" undef, ptr %1, 0
|
||||
%3 = insertvalue %"any*" %2, i64 ptrtoint (ptr @"$ct.uint" to i64), 1
|
||||
@@ -213,7 +213,7 @@ after_check14: ; preds = %entry, %after_check
|
||||
call void @llvm.memset.p0.i64(ptr align 8 %map2, i8 0, i64 48, i1 false)
|
||||
%lo33 = load i64, ptr @std.core.mem.thread_allocator, align 8
|
||||
%hi34 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
|
||||
%48 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map2, i32 16, float 7.500000e-01, i64 %lo33, ptr %hi34)
|
||||
%48 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map2, i32 16, float 7.500000e-01, i64 %lo33, ptr %hi34, ptr null)
|
||||
%49 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map2, i32 4, double 1.300000e+00)
|
||||
%50 = call i8 @"std.collections.map$int$double$.HashMap.has_value"(ptr %map2, double 1.300000e+00)
|
||||
store i8 %50, ptr %taddr36, align 1
|
||||
@@ -266,7 +266,7 @@ if.exit: ; preds = %if.then, %after_che
|
||||
call void @llvm.memset.p0.i64(ptr align 8 %map3, i8 0, i64 48, i1 false)
|
||||
%lo59 = load i64, ptr @std.core.mem.thread_allocator, align 8
|
||||
%hi60 = load ptr, ptr getelementptr inbounds ({ i64, ptr }, ptr @std.core.mem.thread_allocator, i32 0, i32 1), align 8
|
||||
%76 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map3, i32 16, float 7.500000e-01, i64 %lo59, ptr %hi60)
|
||||
%76 = call ptr @"std.collections.map$int$double$.HashMap.init_new"(ptr %map3, i32 16, float 7.500000e-01, i64 %lo59, ptr %hi60, ptr null)
|
||||
%77 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 5, double 3.200000e+00)
|
||||
%78 = call i8 @"std.collections.map$int$double$.HashMap.set"(ptr %map3, i32 7, double 5.200000e+00)
|
||||
%lo62 = load i64, ptr @std.core.mem.thread_allocator, align 8
|
||||
|
||||
Reference in New Issue
Block a user