| author | |
| committer | |
| log | a647a88dfc6cdef66316399f10084b35f738b093 |
| tree | 8b2ea8968a6e273bf4a7b052a8bceb0eadcab1b6 |
| parent | 8f3e972da6badf6df82c88ba0c60aca7b545f62c |
| signature |
9 files changed, 118 insertions(+), 23 deletions(-)
src/all_types.hpp+7| ... | @@ -2021,6 +2021,13 @@ struct CodeGen { | ... | @@ -2021,6 +2021,13 @@ struct CodeGen { |
| 2021 | ZigType *entry_any_frame; | 2021 | ZigType *entry_any_frame; |
| 2022 | } builtin_types; | 2022 | } builtin_types; |
| 2023 | 2023 | ||
| 2024 | struct { | ||
| 2025 | ZigValue x_undefined; | ||
| 2026 | ZigValue x_void; | ||
| 2027 | ZigValue x_null; | ||
| 2028 | ZigValue x_unreachable; | ||
| 2029 | } intern_values; | ||
| 2030 | |||
| 2024 | ZigType *align_amt_type; | 2031 | ZigType *align_amt_type; |
| 2025 | ZigType *stack_trace_type; | 2032 | ZigType *stack_trace_type; |
| 2026 | ZigType *err_tag_type; | 2033 | ZigType *err_tag_type; |
src/bigint.cpp+5| ... | @@ -195,6 +195,11 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) { | ... | @@ -195,6 +195,11 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) { |
| 195 | memcpy(dest->data.digits, src->data.digits, sizeof(uint64_t) * dest->digit_count); | 195 | memcpy(dest->data.digits, src->data.digits, sizeof(uint64_t) * dest->digit_count); |
| 196 | } | 196 | } |
| 197 | 197 | ||
| 198 | void bigint_deinit(BigInt *bi) { | ||
| 199 | if (bi->digit_count > 1) | ||
| 200 | deallocate<uint64_t>(bi->data.digits, bi->digit_count); | ||
| 201 | } | ||
| 202 | |||
| 198 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) { | 203 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) { |
| 199 | float128_t zero; | 204 | float128_t zero; |
| 200 | ui32_to_f128M(0, &zero); | 205 | ui32_to_f128M(0, &zero); |
src/bigint.hpp+1| ... | @@ -34,6 +34,7 @@ void bigint_init_signed(BigInt *dest, int64_t x); | ... | @@ -34,6 +34,7 @@ void bigint_init_signed(BigInt *dest, int64_t x); |
| 34 | void bigint_init_bigint(BigInt *dest, const BigInt *src); | 34 | void bigint_init_bigint(BigInt *dest, const BigInt *src); |
| 35 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op); | 35 | void bigint_init_bigfloat(BigInt *dest, const BigFloat *op); |
| 36 | void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count, bool is_negative); | 36 | void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count, bool is_negative); |
| 37 | void bigint_deinit(BigInt *bi); | ||
| 37 | 38 | ||
| 38 | // panics if number won't fit | 39 | // panics if number won't fit |
| 39 | uint64_t bigint_as_u64(const BigInt *bigint); | 40 | uint64_t bigint_as_u64(const BigInt *bigint); |
src/codegen.cpp+28| ... | @@ -8008,6 +8008,33 @@ static void define_builtin_types(CodeGen *g) { | ... | @@ -8008,6 +8008,33 @@ static void define_builtin_types(CodeGen *g) { |
| 8008 | } | 8008 | } |
| 8009 | } | 8009 | } |
| 8010 | 8010 | ||
| 8011 | static void define_intern_values(CodeGen *g) { | ||
| 8012 | { | ||
| 8013 | auto& value = g->intern_values.x_undefined; | ||
| 8014 | value.type = g->builtin_types.entry_undef; | ||
| 8015 | value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.undefined"); | ||
| 8016 | value.special = ConstValSpecialStatic; | ||
| 8017 | } | ||
| 8018 | { | ||
| 8019 | auto& value = g->intern_values.x_void; | ||
| 8020 | value.type = g->builtin_types.entry_void; | ||
| 8021 | value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.void"); | ||
| 8022 | value.special = ConstValSpecialStatic; | ||
| 8023 | } | ||
| 8024 | { | ||
| 8025 | auto& value = g->intern_values.x_null; | ||
| 8026 | value.type = g->builtin_types.entry_null; | ||
| 8027 | value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.null"); | ||
| 8028 | value.special = ConstValSpecialStatic; | ||
| 8029 | } | ||
| 8030 | { | ||
| 8031 | auto& value = g->intern_values.x_unreachable; | ||
| 8032 | value.type = g->builtin_types.entry_unreachable; | ||
| 8033 | value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.unreachable"); | ||
| 8034 | value.special = ConstValSpecialStatic; | ||
| 8035 | } | ||
| 8036 | } | ||
| 8037 | |||
| 8011 | static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) { | 8038 | static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) { |
| 8012 | BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1); | 8039 | BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1); |
| 8013 | buf_init_from_str(&builtin_fn->name, name); | 8040 | buf_init_from_str(&builtin_fn->name, name); |
| ... | @@ -8629,6 +8656,7 @@ static void init(CodeGen *g) { | ... | @@ -8629,6 +8656,7 @@ static void init(CodeGen *g) { |
| 8629 | g->dummy_di_file = nullptr; | 8656 | g->dummy_di_file = nullptr; |
| 8630 | 8657 | ||
| 8631 | define_builtin_types(g); | 8658 | define_builtin_types(g); |
| 8659 | define_intern_values(g); | ||
| 8632 | 8660 | ||
| 8633 | IrInstruction *sentinel_instructions = allocate<IrInstruction>(2); | 8661 | IrInstruction *sentinel_instructions = allocate<IrInstruction>(2); |
| 8634 | g->invalid_instruction = &sentinel_instructions[0]; | 8662 | g->invalid_instruction = &sentinel_instructions[0]; |
src/hash_map.hpp+6-6| ... | @@ -23,10 +23,10 @@ public: | ... | @@ -23,10 +23,10 @@ public: |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | struct Entry { | 25 | struct Entry { |
| 26 | bool used; | ||
| 27 | int distance_from_start_index; | ||
| 28 | K key; | 26 | K key; |
| 29 | V value; | 27 | V value; |
| 28 | bool used; | ||
| 29 | int distance_from_start_index; | ||
| 30 | }; | 30 | }; |
| 31 | 31 | ||
| 32 | void clear() { | 32 | void clear() { |
| ... | @@ -187,10 +187,10 @@ private: | ... | @@ -187,10 +187,10 @@ private: |
| 187 | if (distance_from_start_index > _max_distance_from_start_index) | 187 | if (distance_from_start_index > _max_distance_from_start_index) |
| 188 | _max_distance_from_start_index = distance_from_start_index; | 188 | _max_distance_from_start_index = distance_from_start_index; |
| 189 | *entry = { | 189 | *entry = { |
| 190 | true, | ||
| 191 | distance_from_start_index, | ||
| 192 | key, | 190 | key, |
| 193 | value, | 191 | value, |
| 192 | true, | ||
| 193 | distance_from_start_index, | ||
| 194 | }; | 194 | }; |
| 195 | key = tmp.key; | 195 | key = tmp.key; |
| 196 | value = tmp.value; | 196 | value = tmp.value; |
| ... | @@ -208,10 +208,10 @@ private: | ... | @@ -208,10 +208,10 @@ private: |
| 208 | if (distance_from_start_index > _max_distance_from_start_index) | 208 | if (distance_from_start_index > _max_distance_from_start_index) |
| 209 | _max_distance_from_start_index = distance_from_start_index; | 209 | _max_distance_from_start_index = distance_from_start_index; |
| 210 | *entry = { | 210 | *entry = { |
| 211 | true, | ||
| 212 | distance_from_start_index, | ||
| 213 | key, | 211 | key, |
| 214 | value, | 212 | value, |
| 213 | true, | ||
| 214 | distance_from_start_index, | ||
| 215 | }; | 215 | }; |
| 216 | return; | 216 | return; |
| 217 | } | 217 | } |
src/ir.cpp+51-12| ... | @@ -1161,6 +1161,22 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no | ... | @@ -1161,6 +1161,22 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no |
| 1161 | return special_instruction; | 1161 | return special_instruction; |
| 1162 | } | 1162 | } |
| 1163 | 1163 | ||
| 1164 | template<typename T> | ||
| 1165 | static T *ir_create_instruction_noval(IrBuilder *irb, Scope *scope, AstNode *source_node) { | ||
| 1166 | const char *name = nullptr; | ||
| 1167 | #ifdef ZIG_ENABLE_MEM_PROFILE | ||
| 1168 | T *dummy = nullptr; | ||
| 1169 | name = ir_instruction_type_str(ir_instruction_id(dummy)); | ||
| 1170 | #endif | ||
| 1171 | T *special_instruction = allocate<T>(1, name); | ||
| 1172 | special_instruction->base.id = ir_instruction_id(special_instruction); | ||
| 1173 | special_instruction->base.scope = scope; | ||
| 1174 | special_instruction->base.source_node = source_node; | ||
| 1175 | special_instruction->base.debug_id = exec_next_debug_id(irb->exec); | ||
| 1176 | special_instruction->base.owner_bb = irb->current_basic_block; | ||
| 1177 | return special_instruction; | ||
| 1178 | } | ||
| 1179 | |||
| 1164 | template<typename T> | 1180 | template<typename T> |
| 1165 | static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 1181 | static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1166 | T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); | 1182 | T *special_instruction = ir_create_instruction<T>(irb, scope, source_node); |
| ... | @@ -1214,16 +1230,22 @@ static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *sou | ... | @@ -1214,16 +1230,22 @@ static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *sou |
| 1214 | } | 1230 | } |
| 1215 | 1231 | ||
| 1216 | static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 1232 | static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1217 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); | 1233 | #ifdef ZIG_ENABLE_MEM_PROFILE |
| 1218 | const_instruction->base.value->type = irb->codegen->builtin_types.entry_void; | 1234 | memprof_intern_count.x_void += 1; |
| 1219 | const_instruction->base.value->special = ConstValSpecialStatic; | 1235 | #endif |
| 1236 | IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); | ||
| 1237 | ir_instruction_append(irb->current_basic_block, &const_instruction->base); | ||
| 1238 | const_instruction->base.value = &irb->codegen->intern_values.x_void; | ||
| 1220 | return &const_instruction->base; | 1239 | return &const_instruction->base; |
| 1221 | } | 1240 | } |
| 1222 | 1241 | ||
| 1223 | static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 1242 | static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1224 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); | 1243 | #ifdef ZIG_ENABLE_MEM_PROFILE |
| 1225 | const_instruction->base.value->special = ConstValSpecialUndef; | 1244 | memprof_intern_count.x_undefined += 1; |
| 1226 | const_instruction->base.value->type = irb->codegen->builtin_types.entry_undef; | 1245 | #endif |
| 1246 | IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); | ||
| 1247 | ir_instruction_append(irb->current_basic_block, &const_instruction->base); | ||
| 1248 | const_instruction->base.value = &irb->codegen->intern_values.x_undefined; | ||
| 1227 | return &const_instruction->base; | 1249 | return &const_instruction->base; |
| 1228 | } | 1250 | } |
| 1229 | 1251 | ||
| ... | @@ -1252,9 +1274,12 @@ static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstN | ... | @@ -1252,9 +1274,12 @@ static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstN |
| 1252 | } | 1274 | } |
| 1253 | 1275 | ||
| 1254 | static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { | 1276 | static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) { |
| 1255 | IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node); | 1277 | #ifdef ZIG_ENABLE_MEM_PROFILE |
| 1256 | const_instruction->base.value->type = irb->codegen->builtin_types.entry_null; | 1278 | memprof_intern_count.x_null += 1; |
| 1257 | const_instruction->base.value->special = ConstValSpecialStatic; | 1279 | #endif |
| 1280 | IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node); | ||
| 1281 | ir_instruction_append(irb->current_basic_block, &const_instruction->base); | ||
| 1282 | const_instruction->base.value = &irb->codegen->intern_values.x_null; | ||
| 1258 | return &const_instruction->base; | 1283 | return &const_instruction->base; |
| 1259 | } | 1284 | } |
| 1260 | 1285 | ||
| ... | @@ -11113,6 +11138,12 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z | ... | @@ -11113,6 +11138,12 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z |
| 11113 | return new_instruction; | 11138 | return new_instruction; |
| 11114 | } | 11139 | } |
| 11115 | 11140 | ||
| 11141 | static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruction) { | ||
| 11142 | IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(&ira->new_irb, | ||
| 11143 | old_instruction->scope, old_instruction->source_node); | ||
| 11144 | return &const_instruction->base; | ||
| 11145 | } | ||
| 11146 | |||
| 11116 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, | 11147 | static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value, |
| 11117 | ZigType *wanted_type, CastOp cast_op) | 11148 | ZigType *wanted_type, CastOp cast_op) |
| 11118 | { | 11149 | { |
| ... | @@ -11429,13 +11460,21 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr | ... | @@ -11429,13 +11460,21 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr |
| 11429 | } | 11460 | } |
| 11430 | 11461 | ||
| 11431 | static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { | 11462 | static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 11432 | IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable); | 11463 | #ifdef ZIG_ENABLE_MEM_PROFILE |
| 11433 | result->value->special = ConstValSpecialStatic; | 11464 | memprof_intern_count.x_unreachable += 1; |
| 11465 | #endif | ||
| 11466 | IrInstruction *result = ir_const_noval(ira, source_instruction); | ||
| 11467 | result->value = &ira->codegen->intern_values.x_unreachable; | ||
| 11434 | return result; | 11468 | return result; |
| 11435 | } | 11469 | } |
| 11436 | 11470 | ||
| 11437 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { | 11471 | static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) { |
| 11438 | return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void); | 11472 | #ifdef ZIG_ENABLE_MEM_PROFILE |
| 11473 | memprof_intern_count.x_void += 1; | ||
| 11474 | #endif | ||
| 11475 | IrInstruction *result = ir_const_noval(ira, source_instruction); | ||
| 11476 | result->value = &ira->codegen->intern_values.x_void; | ||
| 11477 | return result; | ||
| 11439 | } | 11478 | } |
| 11440 | 11479 | ||
| 11441 | static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { | 11480 | static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) { |
src/memory_profiling.cpp+8-1| ... | @@ -6,6 +6,8 @@ | ... | @@ -6,6 +6,8 @@ |
| 6 | 6 | ||
| 7 | #ifdef ZIG_ENABLE_MEM_PROFILE | 7 | #ifdef ZIG_ENABLE_MEM_PROFILE |
| 8 | 8 | ||
| 9 | MemprofInternCount memprof_intern_count; | ||
| 10 | |||
| 9 | static bool str_eql_str(const char *a, const char *b) { | 11 | static bool str_eql_str(const char *a, const char *b) { |
| 10 | return strcmp(a, b) == 0; | 12 | return strcmp(a, b) == 0; |
| 11 | } | 13 | } |
| ... | @@ -29,7 +31,6 @@ ZigList<const char *> unknown_names = {}; | ... | @@ -29,7 +31,6 @@ ZigList<const char *> unknown_names = {}; |
| 29 | HashMap<const char *, CountAndSize, str_hash, str_eql_str> usage_table = {}; | 31 | HashMap<const char *, CountAndSize, str_hash, str_eql_str> usage_table = {}; |
| 30 | bool table_active = false; | 32 | bool table_active = false; |
| 31 | 33 | ||
| 32 | |||
| 33 | static const char *get_default_name(const char *name_or_null, size_t type_size) { | 34 | static const char *get_default_name(const char *name_or_null, size_t type_size) { |
| 34 | if (name_or_null != nullptr) return name_or_null; | 35 | if (name_or_null != nullptr) return name_or_null; |
| 35 | if (type_size >= unknown_names.length) { | 36 | if (type_size >= unknown_names.length) { |
| ... | @@ -134,6 +135,12 @@ void memprof_dump_stats(FILE *file) { | ... | @@ -134,6 +135,12 @@ void memprof_dump_stats(FILE *file) { |
| 134 | 135 | ||
| 135 | list.deinit(); | 136 | list.deinit(); |
| 136 | table_active = true; | 137 | table_active = true; |
| 138 | |||
| 139 | fprintf(stderr, "\n"); | ||
| 140 | fprintf(stderr, "undefined: interned %zu times\n", memprof_intern_count.x_undefined); | ||
| 141 | fprintf(stderr, "void: interned %zu times\n", memprof_intern_count.x_void); | ||
| 142 | fprintf(stderr, "null: interned %zu times\n", memprof_intern_count.x_null); | ||
| 143 | fprintf(stderr, "unreachable: interned %zu times\n", memprof_intern_count.x_unreachable); | ||
| 137 | } | 144 | } |
| 138 | 145 | ||
| 139 | #endif | 146 | #endif |
src/memory_profiling.hpp+8| ... | @@ -13,6 +13,14 @@ | ... | @@ -13,6 +13,14 @@ |
| 13 | #include <stddef.h> | 13 | #include <stddef.h> |
| 14 | #include <stdio.h> | 14 | #include <stdio.h> |
| 15 | 15 | ||
| 16 | struct MemprofInternCount { | ||
| 17 | size_t x_undefined; | ||
| 18 | size_t x_void; | ||
| 19 | size_t x_null; | ||
| 20 | size_t x_unreachable; | ||
| 21 | }; | ||
| 22 | extern MemprofInternCount memprof_intern_count; | ||
| 23 | |||
| 16 | void memprof_init(void); | 24 | void memprof_init(void); |
| 17 | 25 | ||
| 18 | void memprof_alloc(const char *name, size_t item_count, size_t type_size); | 26 | void memprof_alloc(const char *name, size_t item_count, size_t type_size); |
src/util.cpp+4-4| ... | @@ -121,18 +121,18 @@ SplitIterator memSplit(Slice<uint8_t> buffer, Slice<uint8_t> split_bytes) { | ... | @@ -121,18 +121,18 @@ SplitIterator memSplit(Slice<uint8_t> buffer, Slice<uint8_t> split_bytes) { |
| 121 | 121 | ||
| 122 | void zig_pretty_print_bytes(FILE *f, double n) { | 122 | void zig_pretty_print_bytes(FILE *f, double n) { |
| 123 | if (n > 1024.0 * 1024.0 * 1024.0) { | 123 | if (n > 1024.0 * 1024.0 * 1024.0) { |
| 124 | fprintf(f, "%.02f GiB", n / 1024.0 / 1024.0 / 1024.0); | 124 | fprintf(f, "%.03f GiB", n / 1024.0 / 1024.0 / 1024.0); |
| 125 | return; | 125 | return; |
| 126 | } | 126 | } |
| 127 | if (n > 1024.0 * 1024.0) { | 127 | if (n > 1024.0 * 1024.0) { |
| 128 | fprintf(f, "%.02f MiB", n / 1024.0 / 1024.0); | 128 | fprintf(f, "%.03f MiB", n / 1024.0 / 1024.0); |
| 129 | return; | 129 | return; |
| 130 | } | 130 | } |
| 131 | if (n > 1024.0) { | 131 | if (n > 1024.0) { |
| 132 | fprintf(f, "%.02f KiB", n / 1024.0); | 132 | fprintf(f, "%.03f KiB", n / 1024.0); |
| 133 | return; | 133 | return; |
| 134 | } | 134 | } |
| 135 | fprintf(f, "%.02f bytes", n ); | 135 | fprintf(f, "%.03f bytes", n ); |
| 136 | return; | 136 | return; |
| 137 | } | 137 | } |
| 138 | 138 |