| author | |
| committer | |
| log | 416a547cdb8dbbf3d2e7ce32132f0a25f2a8607e |
| tree | f73bfab6414e9e35ae5f1d104b31274b774415ff |
| parent | 26b2e5fda86fe5424ebf86924d294d8dbb972eb6 |
| parent | 770631cc79a655bc5e21184ca15bdb6192e905de |
| signature |
stage1: free more heap after analysis3 files changed, 30 insertions(+), 8 deletions(-)
src/ir.cpp+19| ... | ... | @@ -14,6 +14,7 @@ |
| 14 | 14 | #include "range_set.hpp" |
| 15 | 15 | #include "softfloat.hpp" |
| 16 | 16 | #include "util.hpp" |
| 17 | #include "mem_list.hpp" | |
| 17 | 18 | |
| 18 | 19 | #include <errno.h> |
| 19 | 20 | |
| ... | ... | @@ -28,6 +29,9 @@ struct IrBuilderGen { |
| 28 | 29 | CodeGen *codegen; |
| 29 | 30 | IrExecutableGen *exec; |
| 30 | 31 | IrBasicBlockGen *current_basic_block; |
| 32 | ||
| 33 | // track for immediate post-analysis destruction | |
| 34 | mem::List<IrInstGenConst *> constants; | |
| 31 | 35 | }; |
| 32 | 36 | |
| 33 | 37 | struct IrAnalyze { |
| ... | ... | @@ -725,6 +729,10 @@ static void ira_ref(IrAnalyze *ira) { |
| 725 | 729 | static void ira_deref(IrAnalyze *ira) { |
| 726 | 730 | if (ira->ref_count > 1) { |
| 727 | 731 | ira->ref_count -= 1; |
| 732 | ||
| 733 | // immediate destruction of dangling IrInstGenConst is not possible | |
| 734 | // free tracking memory because it will never be used | |
| 735 | ira->new_irb.constants.deinit(&heap::c_allocator); | |
| 728 | 736 | return; |
| 729 | 737 | } |
| 730 | 738 | assert(ira->ref_count != 0); |
| ... | ... | @@ -742,6 +750,15 @@ static void ira_deref(IrAnalyze *ira) { |
| 742 | 750 | heap::c_allocator.destroy(ira->old_irb.exec); |
| 743 | 751 | ira->src_implicit_return_type_list.deinit(); |
| 744 | 752 | ira->resume_stack.deinit(); |
| 753 | ||
| 754 | // destroy dangling IrInstGenConst | |
| 755 | for (size_t i = 0; i < ira->new_irb.constants.length; i += 1) { | |
| 756 | auto constant = ira->new_irb.constants.items[i]; | |
| 757 | if (constant->base.base.ref_count == 0 && !ir_inst_gen_has_side_effects(&constant->base)) | |
| 758 | destroy_instruction_gen(&constant->base); | |
| 759 | } | |
| 760 | ira->new_irb.constants.deinit(&heap::c_allocator); | |
| 761 | ||
| 745 | 762 | heap::c_allocator.destroy(ira); |
| 746 | 763 | } |
| 747 | 764 | |
| ... | ... | @@ -12493,12 +12510,14 @@ static IrInstGen *ir_const(IrAnalyze *ira, IrInst *inst, ZigType *ty) { |
| 12493 | 12510 | IrInstGen *new_instruction = &const_instruction->base; |
| 12494 | 12511 | new_instruction->value->type = ty; |
| 12495 | 12512 | new_instruction->value->special = ConstValSpecialStatic; |
| 12513 | ira->new_irb.constants.append(&heap::c_allocator, const_instruction); | |
| 12496 | 12514 | return new_instruction; |
| 12497 | 12515 | } |
| 12498 | 12516 | |
| 12499 | 12517 | static IrInstGen *ir_const_noval(IrAnalyze *ira, IrInst *old_instruction) { |
| 12500 | 12518 | IrInstGenConst *const_instruction = ir_create_inst_noval<IrInstGenConst>(&ira->new_irb, |
| 12501 | 12519 | old_instruction->scope, old_instruction->source_node); |
| 12520 | ira->new_irb.constants.append(&heap::c_allocator, const_instruction); | |
| 12502 | 12521 | return &const_instruction->base; |
| 12503 | 12522 | } |
| 12504 | 12523 |
src/mem_list.hpp+9-6| ... | ... | @@ -14,11 +14,14 @@ namespace mem { |
| 14 | 14 | |
| 15 | 15 | template<typename T> |
| 16 | 16 | struct List { |
| 17 | void deinit(Allocator& allocator) { | |
| 18 | allocator.deallocate<T>(items, capacity); | |
| 17 | void deinit(Allocator *allocator) { | |
| 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 | 25 | ensure_capacity(allocator, length + 1); |
| 23 | 26 | items[length++] = item; |
| 24 | 27 | } |
| ... | ... | @@ -57,7 +60,7 @@ struct List { |
| 57 | 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 | 64 | assert(new_length != SIZE_MAX); |
| 62 | 65 | ensure_capacity(allocator, new_length); |
| 63 | 66 | length = new_length; |
| ... | ... | @@ -67,7 +70,7 @@ struct List { |
| 67 | 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 | 74 | if (capacity >= new_capacity) |
| 72 | 75 | return; |
| 73 | 76 | |
| ... | ... | @@ -76,7 +79,7 @@ struct List { |
| 76 | 79 | better_capacity = better_capacity * 5 / 2 + 8; |
| 77 | 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 | 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 | 92 | auto entry = it.next(); |
| 93 | 93 | if (!entry) |
| 94 | 94 | break; |
| 95 | list.append(heap::bootstrap_allocator, &entry->value); | |
| 95 | list.append(&heap::bootstrap_allocator, &entry->value); | |
| 96 | 96 | } |
| 97 | 97 | |
| 98 | 98 | qsort(list.items, list.length, sizeof(const Entry *), entry_compare); |
| ... | ... | @@ -143,7 +143,7 @@ void Profile::print_report(FILE *file) { |
| 143 | 143 | fprintf(file, "\n Total calls alloc: %zu, dealloc: %zu, remain: %zu\n", |
| 144 | 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 | 149 | uint32_t Profile::usage_hash(UsageKey key) { |