aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <gingerBill@users.noreply.github.com>2025-09-10 21:41:52 +0100
committergingerBill <gingerBill@users.noreply.github.com>2025-09-10 21:41:52 +0100
commit5ea2e1fe60872c5d2b20e180a1514a082b6513e4 (patch)
tree8c5586843ff240e1c926dce3e17158b08446c958 /src
parent992cad101c495e9a0c96a46c0eb50f6a59c7e68f (diff)
Minimize mutex usage when in single threaded mode.
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp2
-rw-r--r--src/check_expr.cpp10
-rw-r--r--src/check_stmt.cpp12
-rw-r--r--src/checker.cpp39
-rw-r--r--src/checker.hpp4
-rw-r--r--src/parser.cpp1
-rw-r--r--src/parser.hpp1
7 files changed, 42 insertions, 27 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 58e4f0120..8fbcb5e40 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -948,7 +948,7 @@ gb_internal Entity *init_entity_foreign_library(CheckerContext *ctx, Entity *e)
error(ident, "foreign library names must be an identifier");
} else {
String name = ident->Ident.token.string;
- Entity *found = scope_lookup(ctx->scope, name);
+ Entity *found = scope_lookup(ctx->scope, name, ident->Ident.hash);
if (found == nullptr) {
if (is_blank_ident(name)) {
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index abfd11485..d2505c047 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -1738,7 +1738,7 @@ gb_internal Entity *check_ident(CheckerContext *c, Operand *o, Ast *n, Type *nam
o->expr = n;
String name = n->Ident.token.string;
- Entity *e = scope_lookup(c->scope, name);
+ Entity *e = scope_lookup(c->scope, name, n->Ident.hash);
if (e == nullptr) {
if (is_blank_ident(name)) {
error(n, "'_' cannot be used as a value");
@@ -5361,7 +5361,7 @@ gb_internal Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *
}
} else */if (node->kind == Ast_Ident) {
String name = node->Ident.token.string;
- return scope_lookup(c->scope, name);
+ return scope_lookup(c->scope, name, node->Ident.hash);
} else if (!ident_only) if (node->kind == Ast_SelectorExpr) {
ast_node(se, SelectorExpr, node);
if (se->token.kind == Token_ArrowRight) {
@@ -5383,7 +5383,7 @@ gb_internal Entity *check_entity_from_ident_or_selector(CheckerContext *c, Ast *
if (op_expr->kind == Ast_Ident) {
String op_name = op_expr->Ident.token.string;
- Entity *e = scope_lookup(c->scope, op_name);
+ Entity *e = scope_lookup(c->scope, op_name, op_expr->Ident.hash);
if (e == nullptr) {
return nullptr;
}
@@ -5480,7 +5480,7 @@ gb_internal Entity *check_selector(CheckerContext *c, Operand *operand, Ast *nod
if (op_expr->kind == Ast_Ident) {
String op_name = op_expr->Ident.token.string;
- Entity *e = scope_lookup(c->scope, op_name);
+ Entity *e = scope_lookup(c->scope, op_name, op_expr->Ident.hash);
add_entity_use(c, op_expr, e);
expr_entity = e;
@@ -5903,7 +5903,7 @@ gb_internal bool check_identifier_exists(Scope *s, Ast *node, bool nested = fals
return true;
}
} else {
- Entity *e = scope_lookup(s, name);
+ Entity *e = scope_lookup(s, name, i->hash);
if (e != nullptr) {
if (out_scope) *out_scope = e->scope;
return true;
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index ba9c08fed..62cfc256a 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -484,7 +484,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
}
if (ident_node != nullptr) {
ast_node(i, Ident, ident_node);
- e = scope_lookup(ctx->scope, i->token.string);
+ e = scope_lookup(ctx->scope, i->token.string, i->hash);
if (e != nullptr && e->kind == Entity_Variable) {
used = (e->flags & EntityFlag_Used) != 0; // NOTE(bill): Make backup just in case
}
@@ -1812,8 +1812,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
error(node, "Iteration over a bit_set of an enum is not allowed runtime type information (RTTI) has been disallowed");
}
if (rs->vals.count == 1 && rs->vals[0] && rs->vals[0]->kind == Ast_Ident) {
- String name = rs->vals[0]->Ident.token.string;
- Entity *found = scope_lookup(ctx->scope, name);
+ AstIdent *ident = &rs->vals[0]->Ident;
+ String name = ident->token.string;
+ Entity *found = scope_lookup(ctx->scope, name, ident->hash);
if (found && are_types_identical(found->type, t->BitSet.elem)) {
ERROR_BLOCK();
gbString s = expr_to_string(expr);
@@ -1857,8 +1858,9 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
error(node, "#reverse for is not supported for map types, as maps are unordered");
}
if (rs->vals.count == 1 && rs->vals[0] && rs->vals[0]->kind == Ast_Ident) {
- String name = rs->vals[0]->Ident.token.string;
- Entity *found = scope_lookup(ctx->scope, name);
+ AstIdent *ident = &rs->vals[0]->Ident;
+ String name = ident->token.string;
+ Entity *found = scope_lookup(ctx->scope, name, ident->hash);
if (found && are_types_identical(found->type, t->Map.key)) {
ERROR_BLOCK();
gbString s = expr_to_string(expr);
diff --git a/src/checker.cpp b/src/checker.cpp
index eb334e147..7da3948dc 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -380,16 +380,25 @@ gb_internal Entity *scope_lookup_current(Scope *s, String const &name) {
}
-gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_) {
+gb_global std::atomic<bool> in_single_threaded_checker_stage;
+
+gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **scope_, Entity **entity_, u32 hash) {
+ bool is_single_threaded = in_single_threaded_checker_stage.load(std::memory_order_relaxed);
if (scope != nullptr) {
bool gone_thru_proc = false;
bool gone_thru_package = false;
- StringHashKey key = string_hash_string(name);
+ StringHashKey key = {};
+ if (hash) {
+ key.hash = hash;
+ key.string = name;
+ } else {
+ key = string_hash_string(name);
+ }
for (Scope *s = scope; s != nullptr; s = s->parent) {
Entity **found = nullptr;
- rw_mutex_shared_lock(&s->mutex);
+ if (!is_single_threaded) rw_mutex_shared_lock(&s->mutex);
found = string_map_get(&s->elements, key);
- rw_mutex_shared_unlock(&s->mutex);
+ if (!is_single_threaded) rw_mutex_shared_unlock(&s->mutex);
if (found) {
Entity *e = *found;
if (gone_thru_proc) {
@@ -424,9 +433,9 @@ gb_internal void scope_lookup_parent(Scope *scope, String const &name, Scope **s
if (scope_) *scope_ = nullptr;
}
-gb_internal Entity *scope_lookup(Scope *s, String const &name) {
+gb_internal Entity *scope_lookup(Scope *s, String const &name, u32 hash) {
Entity *entity = nullptr;
- scope_lookup_parent(s, name, nullptr, &entity);
+ scope_lookup_parent(s, name, nullptr, &entity, hash);
return entity;
}
@@ -507,11 +516,9 @@ end:;
return result;
}
-gb_global bool in_single_threaded_checker_stage = false;
-
gb_internal Entity *scope_insert(Scope *s, Entity *entity) {
String name = entity->token.string;
- if (in_single_threaded_checker_stage) {
+ if (in_single_threaded_checker_stage.load(std::memory_order_relaxed)) {
return scope_insert_with_name_no_mutex(s, name, entity);
} else {
return scope_insert_with_name(s, name, entity);
@@ -853,9 +860,13 @@ gb_internal void check_scope_usage(Checker *c, Scope *scope, u64 vet_flags) {
gb_internal void add_dependency(CheckerInfo *info, DeclInfo *d, Entity *e) {
- rw_mutex_lock(&d->deps_mutex);
- ptr_set_add(&d->deps, e);
- rw_mutex_unlock(&d->deps_mutex);
+ if (in_single_threaded_checker_stage.load(std::memory_order_relaxed)) {
+ ptr_set_add(&d->deps, e);
+ } else {
+ rw_mutex_lock(&d->deps_mutex);
+ ptr_set_add(&d->deps, e);
+ rw_mutex_unlock(&d->deps_mutex);
+ }
}
gb_internal void add_type_info_dependency(CheckerInfo *info, DeclInfo *d, Type *type) {
if (d == nullptr || type == nullptr) {
@@ -4958,7 +4969,7 @@ gb_internal void check_single_global_entity(Checker *c, Entity *e, DeclInfo *d)
}
gb_internal void check_all_global_entities(Checker *c) {
- in_single_threaded_checker_stage = true;
+ in_single_threaded_checker_stage.store(true, std::memory_order_relaxed);
// NOTE(bill): This must be single threaded
// Don't bother trying
@@ -4980,7 +4991,7 @@ gb_internal void check_all_global_entities(Checker *c) {
}
}
- in_single_threaded_checker_stage = false;
+ in_single_threaded_checker_stage.store(false, std::memory_order_relaxed);
}
diff --git a/src/checker.hpp b/src/checker.hpp
index 968988962..68779c280 100644
--- a/src/checker.hpp
+++ b/src/checker.hpp
@@ -623,8 +623,8 @@ gb_internal Entity *entity_of_node(Ast *expr);
gb_internal Entity *scope_lookup_current(Scope *s, String const &name);
-gb_internal Entity *scope_lookup (Scope *s, String const &name);
-gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_);
+gb_internal Entity *scope_lookup (Scope *s, String const &name, u32 hash=0);
+gb_internal void scope_lookup_parent (Scope *s, String const &name, Scope **scope_, Entity **entity_, u32 hash=0);
gb_internal Entity *scope_insert (Scope *s, Entity *entity);
diff --git a/src/parser.cpp b/src/parser.cpp
index a7006dd39..a32494c05 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -750,6 +750,7 @@ gb_internal Ast *ast_matrix_index_expr(AstFile *f, Ast *expr, Token open, Token
gb_internal Ast *ast_ident(AstFile *f, Token token) {
Ast *result = alloc_ast_node(f, Ast_Ident);
result->Ident.token = token;
+ result->Ident.hash = string_hash(token.string);
return result;
}
diff --git a/src/parser.hpp b/src/parser.hpp
index d2dd22667..56447df43 100644
--- a/src/parser.hpp
+++ b/src/parser.hpp
@@ -396,6 +396,7 @@ struct AstSplitArgs {
AST_KIND(Ident, "identifier", struct { \
Token token; \
Entity *entity; \
+ u32 hash; \
}) \
AST_KIND(Implicit, "implicit", Token) \
AST_KIND(Uninit, "uninitialized value", Token) \