| author | |
| committer | |
| log | 770631cc79a655bc5e21184ca15bdb6192e905de |
| tree | 9d9952d5e25df9891217a99f2d0f9aff2ef14caf |
| parent | e381a42de9c0f0c5439a926b0ac99026a0373f49 |
| signature |
- immediately free dangling IrInstGenConst after analysis
- fixup mem::List params `&Allocator` → `*Allocator`3 files changed, 30 insertions(+), 8 deletions(-)
src/ir.cpp+19| ... | @@ -14,6 +14,7 @@ | ... | @@ -14,6 +14,7 @@ |
| 14 | #include "range_set.hpp" | 14 | #include "range_set.hpp" |
| 15 | #include "softfloat.hpp" | 15 | #include "softfloat.hpp" |
| 16 | #include "util.hpp" | 16 | #include "util.hpp" |
| 17 | #include "mem_list.hpp" | ||
| 17 | 18 | ||
| 18 | #include <errno.h> | 19 | #include <errno.h> |
| 19 | 20 | ||
| ... | @@ -28,6 +29,9 @@ struct IrBuilderGen { | ... | @@ -28,6 +29,9 @@ struct IrBuilderGen { |
| 28 | CodeGen *codegen; | 29 | CodeGen *codegen; |
| 29 | IrExecutableGen *exec; | 30 | IrExecutableGen *exec; |
| 30 | IrBasicBlockGen *current_basic_block; | 31 | IrBasicBlockGen *current_basic_block; |
| 32 | |||
| 33 | // track for immediate post-analysis destruction | ||
| 34 | mem::List<IrInstGenConst *> constants; | ||
| 31 | }; | 35 | }; |
| 32 | 36 | ||
| 33 | struct IrAnalyze { | 37 | struct IrAnalyze { |
| ... | @@ -741,6 +745,10 @@ static void ira_ref(IrAnalyze *ira) { | ... | @@ -741,6 +745,10 @@ static void ira_ref(IrAnalyze *ira) { |
| 741 | static void ira_deref(IrAnalyze *ira) { | 745 | static void ira_deref(IrAnalyze *ira) { |
| 742 | if (ira->ref_count > 1) { | 746 | if (ira->ref_count > 1) { |
| 743 | ira->ref_count -= 1; | 747 | ira->ref_count -= 1; |
| 748 | |||
| 749 | // immediate destruction of dangling IrInstGenConst is not possible | ||
| 750 | // free tracking memory because it will never be used | ||
| 751 | ira->new_irb.constants.deinit(&heap::c_allocator); | ||
| 744 | return; | 752 | return; |
| 745 | } | 753 | } |
| 746 | assert(ira->ref_count != 0); | 754 | assert(ira->ref_count != 0); |
| ... | @@ -758,6 +766,15 @@ static void ira_deref(IrAnalyze *ira) { | ... | @@ -758,6 +766,15 @@ static void ira_deref(IrAnalyze *ira) { |
| 758 | heap::c_allocator.destroy(ira->old_irb.exec); | 766 | heap::c_allocator.destroy(ira->old_irb.exec); |
| 759 | ira->src_implicit_return_type_list.deinit(); | 767 | ira->src_implicit_return_type_list.deinit(); |
| 760 | ira->resume_stack.deinit(); | 768 | ira->resume_stack.deinit(); |
| 769 | |||
| 770 | // destroy dangling IrInstGenConst | ||
| 771 | for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) { | ||
| 772 | auto constant = ira->new_irb.constants.items[i]; | ||
| 773 | if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base)) | ||
| 774 | destroy_instruction_gen(&constant->base); | ||
| 775 | } | ||
| 776 | ira->new_irb.constants.deinit(&heap::c_allocator); | ||
| 777 | |||
| 761 | heap::c_allocator.destroy(ira); | 778 | heap::c_allocator.destroy(ira); |
| 762 | } | 779 | } |
| 763 | 780 | ||
| ... | @@ -12746,12 +12763,14 @@ static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { | ... | @@ -12746,12 +12763,14 @@ static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { |
| 12746 | IrInstGen *new_instruction = &const_instruction->base; | 12763 | IrInstGen *new_instruction = &const_instruction->base; |
| 12747 | new_instruction->value->type = ty; | 12764 | new_instruction->value->type = ty; |
| 12748 | new_instruction->value->special = ConstValSpecialStatic; | 12765 | new_instruction->value->special = ConstValSpecialStatic; |
| 12766 | ira->new_irb.constants.append(&heap::c_allocator, const_instruction); | ||
| 12749 | return new_instruction; | 12767 | return new_instruction; |
| 12750 | } | 12768 | } |
| 12751 | 12769 | ||
| 12752 | static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { | 12770 | static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { |
| 12753 | IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, | 12771 | IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, |
| 12754 | old_instruction->scope, old_instruction->source_node); | 12772 | old_instruction->scope, old_instruction->source_node); |
| 12773 | ira->new_irb.constants.append(&heap::c_allocator, const_instruction); | ||
| 12755 | return &const_instruction->base; | 12774 | return &const_instruction->base; |
| 12756 | } | 12775 | } |
| 12757 | 12776 |
src/mem_list.hpp+9-6| ... | @@ -14,11 +14,14 @@ namespace mem { | ... | @@ -14,11 +14,14 @@ namespace mem { |
| 14 | 14 | ||
| 15 | template<typename T> | 15 | template<typename T> |
| 16 | struct List { | 16 | struct List { |
| 17 | void deinit(Allocator& allocator) { | 17 | void deinit(Allocator *allocator) { |
| 18 | allocator.deallocate<T>(items, capacity); | 18 | allocator->deallocate<T>(items, capacity); |
| 19 | items = nullptr; | ||
| 20 | length = 0; | ||
| 21 | capacity = 0; | ||
| 19 | } | 22 | } |
| 20 | 23 | ||
| 21 | void append(Allocator& allocator, const T& item) { | 24 | void append(Allocator *allocator, const T& item) { |
| 22 | ensure_capacity(allocator, length + 1); | 25 | ensure_capacity(allocator, length + 1); |
| 23 | items[length++] = item; | 26 | items[length++] = item; |
| 24 | } | 27 | } |
| ... | @@ -57,7 +60,7 @@ struct List { | ... | @@ -57,7 +60,7 @@ struct List { |
| 57 | return items[length - 1]; | 60 | return items[length - 1]; |
| 58 | } | 61 | } |
| 59 | 62 | ||
| 60 | void resize(Allocator& allocator, size_t new_length) { | 63 | void resize(Allocator *allocator, size_t new_length) { |
| 61 | assert(new_length != SIZE_MAX); | 64 | assert(new_length != SIZE_MAX); |
| 62 | ensure_capacity(allocator, new_length); | 65 | ensure_capacity(allocator, new_length); |
| 63 | length = new_length; | 66 | length = new_length; |
| ... | @@ -67,7 +70,7 @@ struct List { | ... | @@ -67,7 +70,7 @@ struct List { |
| 67 | length = 0; | 70 | length = 0; |
| 68 | } | 71 | } |
| 69 | 72 | ||
| 70 | void ensure_capacity(Allocator& allocator, size_t new_capacity) { | 73 | void ensure_capacity(Allocator *allocator, size_t new_capacity) { |
| 71 | if (capacity >= new_capacity) | 74 | if (capacity >= new_capacity) |
| 72 | return; | 75 | return; |
| 73 | 76 | ||
| ... | @@ -76,7 +79,7 @@ struct List { | ... | @@ -76,7 +79,7 @@ struct List { |
| 76 | better_capacity = better_capacity * 5 / 2 + 8; | 79 | better_capacity = better_capacity * 5 / 2 + 8; |
| 77 | } while (better_capacity < new_capacity); | 80 | } while (better_capacity < new_capacity); |
| 78 | 81 | ||
| 79 | items = allocator.reallocate_nonzero<T>(items, capacity, better_capacity); | 82 | items = allocator->reallocate_nonzero<T>(items, capacity, better_capacity); |
| 80 | capacity = better_capacity; | 83 | capacity = better_capacity; |
| 81 | } | 84 | } |
| 82 | 85 |
src/mem_profile.cpp+2-2| ... | @@ -92,7 +92,7 @@ void Profile::print_report(FILE *file) { | ... | @@ -92,7 +92,7 @@ void Profile::print_report(FILE *file) { |
| 92 | auto entry = it.next(); | 92 | auto entry = it.next(); |
| 93 | if (!entry) | 93 | if (!entry) |
| 94 | break; | 94 | break; |
| 95 | list.append(heap::bootstrap_allocator, &entry->value); | 95 | list.append(&heap::bootstrap_allocator, &entry->value); |
| 96 | } | 96 | } |
| 97 | 97 | ||
| 98 | qsort(list.items, list.length, sizeof(const Entry *), entry_compare); | 98 | qsort(list.items, list.length, sizeof(const Entry *), entry_compare); |
| ... | @@ -143,7 +143,7 @@ void Profile::print_report(FILE *file) { | ... | @@ -143,7 +143,7 @@ void Profile::print_report(FILE *file) { |
| 143 | fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n", | 143 | fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n", |
| 144 | total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc)); | 144 | total_calls_alloc, total_calls_dealloc, (total_calls_alloc - total_calls_dealloc)); |
| 145 | 145 | ||
| 146 | list.deinit(heap::bootstrap_allocator); | 146 | list.deinit(&heap::bootstrap_allocator); |
| 147 | } | 147 | } |
| 148 | 148 | ||
| 149 | uint32_t Profile::usage_hash(UsageKey key) { | 149 | uint32_t Profile::usage_hash(UsageKey key) { |