From bd8bff85d6e67b293f0440b006a8bb4cfc66287c Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Mon, 27 Feb 2023 17:05:27 +0100 Subject: [PATCH] Add tracking allocator. Fix substruct issue. --- lib/std/core/allocators/tracking_allocator.c3 | 105 ++++++++++++++++++ lib/std/core/mem_array.c3 | 3 +- src/compiler/compiler_internal.h | 2 +- src/compiler/enums.h | 2 +- src/compiler/parse_global.c | 5 +- src/compiler/sema_casts.c | 2 +- src/compiler/sema_decls.c | 4 +- src/compiler/symtab.c | 2 +- 8 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 lib/std/core/allocators/tracking_allocator.c3 diff --git a/lib/std/core/allocators/tracking_allocator.c3 b/lib/std/core/allocators/tracking_allocator.c3 new file mode 100644 index 000000000..f42eec172 --- /dev/null +++ b/lib/std/core/allocators/tracking_allocator.c3 @@ -0,0 +1,105 @@ +// Copyright (c) 2021 Christoffer Lerno. All rights reserved. +// Use of this source code is governed by the MIT license +// a copy of which can be found in the LICENSE_STDLIB file. + +module std::core::mem::allocator; +import std::collections::map; + +define PtrMap = HashMap; + +// A simple tracking allocator. +// It tracks allocations using a hash map but +// is not compatible with allocators that uses mark() +struct TrackingAllocator +{ + inline Allocator allocator; + Allocator* inner_allocator; + PtrMap map; + usz mem_total; + usz allocs_total; +} + +/** + * Initialize a memory arena for use using the provided bytes. + * + * @require this != null + **/ +fn void TrackingAllocator.init(TrackingAllocator* this, Allocator* allocator) +{ + *this = { .inner_allocator = allocator, .allocator.function = &tracking_allocator_fn }; + this.map.init(.allocator = allocator); +} + +fn void TrackingAllocator.free(TrackingAllocator* this) +{ + this.map.free(); + *this = {}; +} + +/** + * @param [inout] data + * @require !alignment || math::is_power_of_2(alignment) + */ +fn void*! tracking_allocator_fn(Allocator* data, usz size, usz alignment, usz offset, void* old_pointer, AllocationKind kind) @private +{ + TrackingAllocator* this = (TrackingAllocator*)data; + void* result = this.inner_allocator.function(this.inner_allocator, size, alignment, offset, old_pointer, kind)?; + switch (kind) + { + case CALLOC: + case ALIGNED_CALLOC: + case ALLOC: + case ALIGNED_ALLOC: + this.map.set((uptr)result, size); + this.mem_total += size; + this.allocs_total++; + return result; + case REALLOC: + case ALIGNED_REALLOC: + this.map.remove((uptr)old_pointer); + this.map.set((uptr)result, size); + this.mem_total += size; + if (size > 0) this.allocs_total++; + return result; + case ALIGNED_FREE: + case FREE: + if (!old_pointer) return null; + this.map.remove((uptr)old_pointer); + return null; + case MARK: + // Unsupported + return null; + case RESET: + this.map.clear(); + return null; + } + unreachable(); +} + +fn usz TrackingAllocator.allocated(TrackingAllocator* this) +{ + usz allocated = 0; + @pool() + { + foreach (usz allocation : this.map.value_tlist()) + { + allocated += allocation; + } + }; + return allocated; +} + +fn usz TrackingAllocator.total_allocated(TrackingAllocator* this) +{ + return this.mem_total; +} + +fn usz TrackingAllocator.total_allocation_count(TrackingAllocator* this) +{ + return this.allocs_total; +} + +fn usz TrackingAllocator.allocation_count(TrackingAllocator* this) +{ + return this.map.count; +} \ No newline at end of file diff --git a/lib/std/core/mem_array.c3 b/lib/std/core/mem_array.c3 index 25cd4d5d2..fd2418d67 100644 --- a/lib/std/core/mem_array.c3 +++ b/lib/std/core/mem_array.c3 @@ -1,6 +1,7 @@ -// Copyright (c) 2021 Christoffer Lerno. All rights reserved. +// Copyright (c) 2021-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the MIT license // a copy of which can be found in the LICENSE_STDLIB file. + module std::core::mem::array; /** diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index c1e31eaa9..e0ff7fdfc 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 842d30523..697db8d4e 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index f3a02dbd9..208723cfc 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -1,7 +1,10 @@ +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. +// Use of this source code is governed by the GNU LGPLv3.0 license +// a copy of which can be found in the LICENSE file. + #include "compiler_internal.h" #include "parser_internal.h" - static Decl *parse_const_declaration(ParseContext *c, bool is_global); static inline Decl *parse_func_definition(ParseContext *c, AstId docs, bool is_interface); static inline bool parse_bitstruct_body(ParseContext *c, Decl *decl); diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 0f200157f..2ae38e313 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1618,7 +1618,7 @@ static bool cast_expr_inner(SemaContext *context, Expr *expr, Type *to_type, boo if (type_is_substruct(from)) { Type *type; - Expr *access = expr_access_inline_member(expr_copy(expr), from->decl->strukt.members[0]); + Expr *access = expr_access_inline_member(expr_copy(expr), from->decl); while (1) { type = access->type->canonical; diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 88ac7d3db..e1cbcebc4 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1,5 +1,5 @@ -// Copyright (c) 2020 Christoffer Lerno. All rights reserved. -// Use of this source code is governed by a LGPLv3.0 +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. +// Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file. #include "sema_internal.h" diff --git a/src/compiler/symtab.c b/src/compiler/symtab.c index d92f4f3e3..6abe71fcd 100644 --- a/src/compiler/symtab.c +++ b/src/compiler/symtab.c @@ -1,4 +1,4 @@ -// Copyright (c) 2019 Christoffer Lerno. All rights reserved. +// Copyright (c) 2019-2023 Christoffer Lerno. All rights reserved. // Use of this source code is governed by the GNU LGPLv3.0 license // a copy of which can be found in the LICENSE file.