diff --git a/core/runtime/dynamic_map_internal.odin b/core/runtime/dynamic_map_internal.odin index 007df4365..65f883c7c 100644 --- a/core/runtime/dynamic_map_internal.odin +++ b/core/runtime/dynamic_map_internal.odin @@ -665,7 +665,8 @@ map_get :: proc "contextless" (m: $T/map[$K]$V, key: K) -> (stored_key: K, store } } -__dynamic_map_get_with_hash :: proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, key: rawptr) -> (ptr: rawptr) { +// IMPORTANT: USED WITHIN THE COMPILER +__dynamic_map_get :: proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, h: Map_Hash, key: rawptr) -> (ptr: rawptr) { if m.len == 0 { return nil } @@ -687,28 +688,24 @@ __dynamic_map_get_with_hash :: proc "contextless" (#no_alias m: ^Raw_Map, #no_al } } -// IMPORTANT: USED WITHIN THE COMPILER -__dynamic_map_get :: proc "contextless" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, key: rawptr) -> (ptr: rawptr) { - if m.len == 0 { - return nil +__dynamic_map_check_grow :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, loc := #caller_location) -> Allocator_Error { + if m.len + 1 >= map_resize_threshold(m^) { + return map_grow_dynamic(m, info, loc) } - h := info.key_hasher(key, 0) - return __dynamic_map_get_with_hash(m, info, h, key) + return nil } // IMPORTANT: USED WITHIN THE COMPILER __dynamic_map_set :: proc "odin" (#no_alias m: ^Raw_Map, #no_alias info: ^Map_Info, key, value: rawptr, loc := #caller_location) -> rawptr { hash := info.key_hasher(key, 0) - if found := __dynamic_map_get_with_hash(m, info, hash, key); found != nil { + if found := __dynamic_map_get(m, info, hash, key); found != nil { intrinsics.mem_copy_non_overlapping(found, value, info.vs.size_of_type) return found } - if m.len + 1 >= map_resize_threshold(m^) { - if err := map_grow_dynamic(m, info, loc); err != nil { - return nil - } + if __dynamic_map_check_grow(m, info, loc) != nil { + return nil } result := map_insert_hash_dynamic(m, info, hash, uintptr(key), uintptr(value)) diff --git a/src/checker.cpp b/src/checker.cpp index d48b37b26..0c23f2627 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -927,8 +927,8 @@ void init_universal(void) { Type *hasher_args[2] = {t_rawptr, t_uintptr}; t_hasher_proc = alloc_type_proc_from_types(hasher_args, 2, t_uintptr, false, ProcCC_Contextless); - Type *map_get_args[2] = {/*map*/t_rawptr, /*key*/t_rawptr}; - t_map_get_proc = alloc_type_proc_from_types(map_get_args, 2, t_rawptr, false, ProcCC_Contextless); + Type *map_get_args[3] = {/*map*/t_rawptr, /*hash*/t_uintptr, /*key*/t_rawptr}; + t_map_get_proc = alloc_type_proc_from_types(map_get_args, 3, t_rawptr, false, ProcCC_Contextless); } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index ee3d36896..f0a123e5e 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -498,16 +498,18 @@ lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { LLVMValueRef x = LLVMGetParam(p->value, 0); LLVMValueRef y = LLVMGetParam(p->value, 1); + LLVMValueRef z = LLVMGetParam(p->value, 2); lbValue map_ptr = {x, t_rawptr}; - lbValue key_ptr = {y, t_rawptr}; + lbValue h = {y, t_uintptr}; + lbValue key_ptr = {z, t_rawptr}; lb_add_proc_attribute_at_index(p, 1+0, "nonnull"); lb_add_proc_attribute_at_index(p, 1+0, "noalias"); lb_add_proc_attribute_at_index(p, 1+0, "readonly"); - lb_add_proc_attribute_at_index(p, 1+1, "nonnull"); - lb_add_proc_attribute_at_index(p, 1+1, "noalias"); - lb_add_proc_attribute_at_index(p, 1+1, "readonly"); + lb_add_proc_attribute_at_index(p, 1+2, "nonnull"); + lb_add_proc_attribute_at_index(p, 1+2, "noalias"); + lb_add_proc_attribute_at_index(p, 1+2, "readonly"); lbBlock *loop_block = lb_create_block(p, "loop"); lbBlock *hash_block = lb_create_block(p, "hash"); @@ -529,7 +531,6 @@ lbValue lb_map_get_proc_for_type(lbModule *m, Type *type) { key_ptr = lb_emit_conv(p, key_ptr, alloc_type_pointer(type->Map.key)); lbValue key = lb_emit_load(p, key_ptr); - lbValue h = lb_gen_map_key_hash(p, key, type->Map.key, nullptr); lbAddr pos = lb_add_local_generated(p, t_uintptr, false); lbAddr distance = lb_add_local_generated(p, t_uintptr, true); lbValue capacity = lb_map_cap(p, map); @@ -785,23 +786,24 @@ lbValue lb_internal_dynamic_map_get_ptr(lbProcedure *p, lbValue const &map_ptr, GB_ASSERT(map_type->kind == Type_Map); lbValue ptr = {}; - - lbValue key_ptr = lb_address_from_load_or_generate_local(p, key); - key_ptr = lb_emit_conv(p, key_ptr, t_rawptr); + lbValue key_ptr = {}; + lbValue hash = lb_gen_map_key_hash(p, key, map_type->Map.key, &key_ptr); if (build_context.use_static_map_calls) { lbValue map_get_proc = lb_map_get_proc_for_type(p->module, map_type); - auto args = array_make(permanent_allocator(), 2); + auto args = array_make(permanent_allocator(), 3); args[0] = lb_emit_conv(p, map_ptr, t_rawptr); - args[1] = key_ptr; + args[1] = hash; + args[2] = key_ptr; ptr = lb_emit_call(p, map_get_proc, args); } else { - auto args = array_make(permanent_allocator(), 3); + auto args = array_make(permanent_allocator(), 4); args[0] = lb_emit_transmute(p, map_ptr, t_raw_map_ptr); args[1] = lb_gen_map_info_ptr(p->module, map_type); - args[2] = key_ptr; + args[2] = hash; + args[3] = key_ptr; ptr = lb_emit_runtime_call(p, "__dynamic_map_get", args); }