mirror of
https://github.com/odin-lang/Odin.git
synced 2026-10-15 08:42:05 -04:00
Cache type layouts and union constantability, build nested constants once, create debug files lazily
This commit is contained in:
1 parent
3a45aaa539
commit
29106aaa1e
8 files changed
+168
-84
No files matched your search
+27
-8
@@ -188,6 +188,7 @@ struct TypeUnion {
|
||||
bool is_polymorphic;
|
||||
bool is_poly_specialized;
|
||||
UnionTypeKind kind;
|
||||
std::atomic<u8> constantable; // 0 unknown, 1 false, 2 true
|
||||
};
|
||||
|
||||
struct TypeProc {
|
||||
@@ -417,6 +418,9 @@ gb_internal Type *base_type(Type *t);
|
||||
gb_internal Type *alloc_type_multi_pointer(Type *elem);
|
||||
gb_internal void wait_for_record_signal(Wait_Signal *signal, Futex *checking_thread);
|
||||
|
||||
// set once checking is done; until then a type may still be incomplete or part of an illegal cycle
|
||||
gb_global std::atomic<bool> global_types_are_complete;
|
||||
|
||||
gb_internal u32 type_info_flags_of_type(Type *type) {
|
||||
if (type == nullptr) {
|
||||
return 0;
|
||||
@@ -2787,16 +2791,25 @@ gb_internal bool is_type_union_constantable(Type *type) {
|
||||
Type *bt = base_type(type);
|
||||
GB_ASSERT(bt->kind == Type_Union);
|
||||
|
||||
if (bt->Union.variants.count == 0) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (Type *v : bt->Union.variants) {
|
||||
if (!is_type_constant_type_for_unions(v)) {
|
||||
return false;
|
||||
bool use_cache = global_types_are_complete.load(std::memory_order_relaxed);
|
||||
if (use_cache) {
|
||||
u8 cached = bt->Union.constantable.load(std::memory_order_relaxed);
|
||||
if (cached != 0) {
|
||||
return cached == 2;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
bool res = true;
|
||||
for (Type *v : bt->Union.variants) {
|
||||
if (!is_type_constant_type_for_unions(v)) {
|
||||
res = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (use_cache) {
|
||||
bt->Union.constantable.store(res ? 2 : 1, std::memory_order_relaxed);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
gb_internal bool is_type_raw_union_constantable(Type *type) {
|
||||
@@ -4389,6 +4402,9 @@ gb_internal i64 type_size_of_struct_pretend_is_packed(Type *ot) {
|
||||
|
||||
|
||||
gb_internal i64 type_size_of(Type *t) {
|
||||
if (t != nullptr && t->kind == Type_Named && global_types_are_complete.load(std::memory_order_relaxed)) {
|
||||
t = base_type(t);
|
||||
}
|
||||
if (t == nullptr) {
|
||||
return 0;
|
||||
}
|
||||
@@ -4431,6 +4447,9 @@ gb_internal i64 type_size_of(Type *t) {
|
||||
}
|
||||
|
||||
gb_internal i64 type_align_of(Type *t) {
|
||||
if (t != nullptr && t->kind == Type_Named && global_types_are_complete.load(std::memory_order_relaxed)) {
|
||||
t = base_type(t);
|
||||
}
|
||||
if (t == nullptr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user