mirror of
https://github.com/odin-lang/Odin.git
synced 2026-06-04 01:34:39 +00:00
Minimize mutex usage when in single threaded mode.
This commit is contained in:
@@ -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)) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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) \
|
||||
|
||||
Reference in New Issue
Block a user