Sfoglia il codice sorgente

Minimize mutex usage when in single threaded mode.

gingerBill 12 ore fa
parent
commit
5ea2e1fe60
7 ha cambiato i file con 42 aggiunte e 27 eliminazioni
  1. 1 1
      src/check_decl.cpp
  2. 5 5
      src/check_expr.cpp
  3. 7 5
      src/check_stmt.cpp
  4. 25 14
      src/checker.cpp
  5. 2 2
      src/checker.hpp
  6. 1 0
      src/parser.cpp
  7. 1 0
      src/parser.hpp

+ 1 - 1
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)) {

+ 5 - 5
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;

+ 7 - 5
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);

+ 25 - 14
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);
 }
 
 

+ 2 - 2
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);
 
 

+ 1 - 0
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;
 }
 

+ 1 - 0
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) \