From 71bffd46dc9717ded66b3db353084871a11563e6 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Mon, 13 Sep 2021 01:14:17 +0100 Subject: [PATCH] Reduce size of `Type` --- src/check_builtin.cpp | 8 ++++++-- src/check_type.cpp | 12 ++++++++++-- src/types.cpp | 24 ++++++++++-------------- 3 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/check_builtin.cpp b/src/check_builtin.cpp index 1f9eea45d..4e8eed1fc 100644 --- a/src/check_builtin.cpp +++ b/src/check_builtin.cpp @@ -1943,7 +1943,7 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 soa_struct->Struct.node = operand->expr; soa_struct->Struct.soa_kind = StructSoa_Fixed; soa_struct->Struct.soa_elem = elem; - soa_struct->Struct.soa_count = count; + soa_struct->Struct.soa_count = cast(i32)count; scope = create_scope(c->info, c->scope); soa_struct->Struct.scope = scope; @@ -1976,7 +1976,11 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32 soa_struct->Struct.node = operand->expr; soa_struct->Struct.soa_kind = StructSoa_Fixed; soa_struct->Struct.soa_elem = elem; - soa_struct->Struct.soa_count = count; + if (count > I32_MAX) { + count = I32_MAX; + error(call, "Array count too large for an #soa struct, got %lld", cast(long long)count); + } + soa_struct->Struct.soa_count = cast(i32)count; scope = create_scope(c->info, old_struct->Struct.scope->parent); soa_struct->Struct.scope = scope; diff --git a/src/check_type.cpp b/src/check_type.cpp index 32a40de12..55c931ab4 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2253,7 +2253,11 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el soa_struct->Struct.node = array_typ_expr; soa_struct->Struct.soa_kind = soa_kind; soa_struct->Struct.soa_elem = elem; - soa_struct->Struct.soa_count = count; + if (count > I32_MAX) { + count = I32_MAX; + error(array_typ_expr, "Array count too large for an #soa struct, got %lld", cast(long long)count); + } + soa_struct->Struct.soa_count = cast(i32)count; scope = create_scope(ctx->info, ctx->scope, 8); soa_struct->Struct.scope = scope; @@ -2295,7 +2299,11 @@ Type *make_soa_struct_internal(CheckerContext *ctx, Ast *array_typ_expr, Ast *el soa_struct->Struct.node = array_typ_expr; soa_struct->Struct.soa_kind = soa_kind; soa_struct->Struct.soa_elem = elem; - soa_struct->Struct.soa_count = count; + if (count > I32_MAX) { + count = I32_MAX; + error(array_typ_expr, "Array count too large for an #soa struct, got %lld", cast(long long)count); + } + soa_struct->Struct.soa_count = cast(i32)count; scope = create_scope(ctx->info, old_struct->Struct.scope->parent); soa_struct->Struct.scope = scope; diff --git a/src/types.cpp b/src/types.cpp index 47a949699..570851124 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -131,7 +131,8 @@ enum StructSoaKind : u8 { struct TypeStruct { Slice fields; Slice tags; - Slice offsets; + i64 * offsets; // count == fields.count + Ast * node; Scope * scope; @@ -141,7 +142,7 @@ struct TypeStruct { Type * soa_elem; - i64 soa_count; + i32 soa_count; StructSoaKind soa_kind; bool is_polymorphic; @@ -154,8 +155,10 @@ struct TypeStruct { struct TypeUnion { Slice variants; + Ast * node; Scope * scope; + i64 variant_block_size; i64 custom_align; Type * polymorphic_params; // Type_Tuple @@ -244,7 +247,7 @@ struct TypeProc { }) \ TYPE_KIND(Tuple, struct { \ Slice variables; /* Entity_Variable */ \ - Slice offsets; \ + i64 * offsets; \ bool are_offsets_being_processed; \ bool are_offsets_set; \ bool is_packed; \ @@ -3064,9 +3067,9 @@ i64 type_align_of_internal(Type *t, TypePath *path) { return gb_clamp(next_pow2(type_size_of_internal(t, path)), 1, build_context.word_size); } -Slice type_set_offsets_of(Slice const &fields, bool is_packed, bool is_raw_union) { +i64 *type_set_offsets_of(Slice const &fields, bool is_packed, bool is_raw_union) { gbAllocator a = permanent_allocator(); - auto offsets = slice_make(a, fields.count); + auto offsets = gb_alloc_array(a, i64, fields.count); i64 curr_offset = 0; if (is_raw_union) { for_array(i, fields) { @@ -3100,7 +3103,6 @@ bool type_set_offsets(Type *t) { if (!t->Struct.are_offsets_set) { t->Struct.are_offsets_being_processed = true; t->Struct.offsets = type_set_offsets_of(t->Struct.fields, t->Struct.is_packed, t->Struct.is_raw_union); - GB_ASSERT(t->Struct.offsets.count == t->Struct.fields.count); t->Struct.are_offsets_being_processed = false; t->Struct.are_offsets_set = true; return true; @@ -3285,18 +3287,12 @@ i64 type_size_of_internal(Type *t, TypePath *path) { if (path->failure) { return FAILURE_SIZE; } - if (t->Struct.are_offsets_being_processed && t->Struct.offsets.data == nullptr) { + if (t->Struct.are_offsets_being_processed && t->Struct.offsets == nullptr) { type_path_print_illegal_cycle(path, path->path.count-1); return FAILURE_SIZE; } - if (t->Struct.are_offsets_set && t->Struct.offsets.count != t->Struct.fields.count) { - // TODO(bill, 2019-04-28): Determine exactly why the offsets length is different thatn the field length - // Are the the same at some point and then the struct length is increased? - // Why is this not handled by the type cycle checker? - t->Struct.are_offsets_set = false; - } type_set_offsets(t); - GB_ASSERT_MSG(t->Struct.offsets.count == t->Struct.fields.count, "%s", type_to_string(t)); + GB_ASSERT(t->Struct.fields.count == 0 || t->Struct.offsets != nullptr); size = t->Struct.offsets[cast(isize)count-1] + type_size_of_internal(t->Struct.fields[cast(isize)count-1]->type, path); return align_formula(size, align); }