diff --git a/src/ir.cpp b/src/ir.cpp index 5f50586f72..aa46b37d4f 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -14,6 +14,7 @@ #include "range_set.hpp" #include "softfloat.hpp" #include "util.hpp" +#include "mem_list.hpp" #include @@ -28,6 +29,9 @@ struct IrBuilderGen { CodeGen *codegen; IrExecutableGen *exec; IrBasicBlockGen *current_basic_block; + + // track for immediate post-analysis destruction + mem::List constants; }; struct IrAnalyze { @@ -741,6 +745,10 @@ static void ira_ref(IrAnalyze *ira) { static void ira_deref(IrAnalyze *ira) { if (ira->ref_count > 1) { ira->ref_count -= 1; + + // immediate destruction of dangling IrInstGenConst is not possible + // free tracking memory because it will never be used + ira->new_irb.constants.deinit(&heap::c_allocator); return; } assert(ira->ref_count != 0); @@ -758,6 +766,15 @@ static void ira_deref(IrAnalyze *ira) { heap::c_allocator.destroy(ira->old_irb.exec); ira->src_implicit_return_type_list.deinit(); ira->resume_stack.deinit(); + + // destroy dangling IrInstGenConst + for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) { + auto constant = ira->new_irb.constants.items[i]; + if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base)) + destroy_instruction_gen(&constant->base); + } + ira->new_irb.constants.deinit(&heap::c_allocator); + heap::c_allocator.destroy(ira); } @@ -12746,12 +12763,14 @@ static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { IrInstGen *new_instruction = &const_instruction->base; new_instruction->value->type = ty; new_instruction->value->special = ConstValSpecialStatic; + ira->new_irb.constants.append(&heap::c_allocator, const_instruction); return new_instruction; } static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { IrInstGenConst *const_instruction = ir_create_inst_noval(&ira->new_irb, old_instruction->scope, old_instruction->source_node); + ira->new_irb.constants.append(&heap::c_allocator, const_instruction); return &const_instruction->base; } diff --git a/src/mem_list.hpp b/src/mem_list.hpp index a09d4d1c8d..df82358ea9 100644 --- a/src/mem_list.hpp +++ b/src/mem_list.hpp @@ -14,11 +14,14 @@ namespace mem { template struct List { - void deinit(Allocator& allocator) { - allocator.deallocate(items, capacity); + void deinit(Allocator *allocator) { + allocator->deallocate(items, capacity); + items = nullptr; + length = 0; + capacity = 0; } - void append(Allocator& allocator, const T& item) { + void append(Allocator *allocator, const T& item) { ensure_capacity(allocator, length + 1); items[length++] = item; } @@ -57,7 +60,7 @@ struct List { return items[length - 1]; } - void resize(Allocator& allocator, size_t new_length) { + void resize(Allocator *allocator, size_t new_length) { assert(new_length != SIZE_MAX); ensure_capacity(allocator, new_length); length = new_length; @@ -67,7 +70,7 @@ struct List { length = 0; } - void ensure_capacity(Allocator& allocator, size_t new_capacity) { + void ensure_capacity(Allocator *allocator, size_t new_capacity) { if (capacity >= new_capacity) return; @@ -76,7 +79,7 @@ struct List { better_capacity = better_capacity * 5 / 2 + 8; } while (better_capacity < new_capacity); - items = allocator.reallocate_nonzero(items, capacity, better_capacity); + items = allocator->reallocate_nonzero(items, capacity, better_capacity); capacity = better_capacity; } diff --git a/src/mem_profile.cpp b/src/mem_profile.cpp index ef47c3f426..13ba57f913 100644 --- a/src/mem_profile.cpp +++ b/src/mem_profile.cpp @@ -92,7 +92,7 @@ void Profile::print_report(FILE *file) { auto entry = it.next(); if (!entry) break; - list.append(heap::bootstrap_allocator, &entry->value); + list.append(&heap::bootstrap_allocator, &entry->value); } qsort(list.items, list.length, sizeof(const Entry *), entry_compare); @@ -143,7 +143,7 @@ void Profile::print_report(FILE *file) { fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n", total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc)); - list.deinit(heap::bootstrap_allocator); + list.deinit(&heap::bootstrap_allocator); } uint32_t Profile::usage_hash(UsageKey key) {