Delete old hashmap implementation

This commit is contained in:
David Gonzalez Martin 2024-04-25 18:43:26 -06:00
parent 0a50781ba4
commit 5539f1e904
3 changed files with 331 additions and 227 deletions

View File

@ -19,7 +19,7 @@ const PinnedArray = library.PinnedArray;
const UnpinnedArray = library.UnpinnedArray;
const BlockList = library.BlockList;
const MyAllocator = library.MyAllocator;
const MyHashMap = library.MyHashMap;
const PinnedHashMap = library.PinnedHashMap;
const span = library.span;
const format_int = library.format_int;
const my_hash = library.my_hash;
@ -130,6 +130,24 @@ pub fn compileBuildExecutable(context: *const Context, arguments: []const []cons
.node_buffer = try PinnedArray(Node).init_with_default_granularity(),
.node_lists = try PinnedArray([]const Node.Index).init_with_default_granularity(),
.data_to_emit = try PinnedArray(*Debug.Declaration.Global).init_with_default_granularity(),
.file_token_offsets = try PinnedHashMap(Token.Range, Debug.File.Index).init(std.mem.page_size),
.file_map = try PinnedHashMap([]const u8, Debug.File.Index).init(std.mem.page_size),
.identifiers = try PinnedHashMap(u32, []const u8).init(std.mem.page_size),
.string_literal_values = try PinnedHashMap(u32, [:0]const u8).init(std.mem.page_size),
.string_literal_globals = try PinnedHashMap(u32, *Debug.Declaration.Global).init(std.mem.page_size),
.optionals = try PinnedHashMap(Type.Index, Type.Index).init(std.mem.page_size),
.pointers = try PinnedHashMap(Type.Pointer, Type.Index).init(std.mem.page_size),
.slices = try PinnedHashMap(Type.Slice, Type.Index).init(std.mem.page_size),
.arrays = try PinnedHashMap(Type.Array, Type.Index).init(std.mem.page_size),
.integers = try PinnedHashMap(Type.Integer, Type.Index).init(std.mem.page_size),
.error_unions = try PinnedHashMap(Type.Error.Union.Descriptor, Type.Index).init(std.mem.page_size),
.two_structs = try PinnedHashMap([2]Type.Index, Type.Index).init(std.mem.page_size),
.fields_array = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.name_functions = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.external_functions = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.type_declarations = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.test_functions = try PinnedHashMap(*Debug.Declaration.Global, *Debug.Declaration.Global).init(std.mem.page_size),
.code_to_emit = try PinnedHashMap(Function.Definition.Index, *Debug.Declaration.Global).init(std.mem.page_size),
};
try unit.compile(context);
@ -2941,7 +2959,7 @@ pub fn buildExecutable(context: *const Context, arguments: []const []const u8, o
if (i + 1 != arguments.len) {
i += 1;
c_source_files.appendSliceAssumeCapacity( arguments[i..]);
c_source_files.appendSliceAssumeCapacity(arguments[i..]);
i = arguments.len;
} else {
reportUnterminatedArgumentError(current_argument);
@ -3026,6 +3044,24 @@ pub fn buildExecutable(context: *const Context, arguments: []const []const u8, o
.node_buffer = try PinnedArray(Node).init_with_default_granularity(),
.node_lists = try PinnedArray([]const Node.Index).init_with_default_granularity(),
.data_to_emit = try PinnedArray(*Debug.Declaration.Global).init_with_default_granularity(),
.file_token_offsets = try PinnedHashMap(Token.Range, Debug.File.Index).init(std.mem.page_size),
.file_map = try PinnedHashMap([]const u8, Debug.File.Index).init(std.mem.page_size),
.identifiers = try PinnedHashMap(u32, []const u8).init(std.mem.page_size),
.string_literal_values = try PinnedHashMap(u32, [:0]const u8).init(std.mem.page_size),
.string_literal_globals = try PinnedHashMap(u32, *Debug.Declaration.Global).init(std.mem.page_size),
.optionals = try PinnedHashMap(Type.Index, Type.Index).init(std.mem.page_size),
.pointers = try PinnedHashMap(Type.Pointer, Type.Index).init(std.mem.page_size),
.slices = try PinnedHashMap(Type.Slice, Type.Index).init(std.mem.page_size),
.arrays = try PinnedHashMap(Type.Array, Type.Index).init(std.mem.page_size),
.integers = try PinnedHashMap(Type.Integer, Type.Index).init(std.mem.page_size),
.error_unions = try PinnedHashMap(Type.Error.Union.Descriptor, Type.Index).init(std.mem.page_size),
.two_structs = try PinnedHashMap([2]Type.Index, Type.Index).init(std.mem.page_size),
.fields_array = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.name_functions = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.external_functions = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.type_declarations = try PinnedHashMap(Type.Index, *Debug.Declaration.Global).init(std.mem.page_size),
.test_functions = try PinnedHashMap(*Debug.Declaration.Global, *Debug.Declaration.Global).init(std.mem.page_size),
.code_to_emit = try PinnedHashMap(Function.Definition.Index, *Debug.Declaration.Global).init(std.mem.page_size),
};
try unit.compile(context);
@ -3052,10 +3088,10 @@ pub const Package = struct {
directory: Directory,
/// Relative to the package main directory
source_path: []const u8,
dependencies: MyHashMap([]const u8, *Package) = .{},
dependencies: PinnedHashMap([]const u8, *Package),
fn addDependency(package: *Package, allocator: *MyAllocator, package_name: []const u8, new_dependency: *Package) !void {
try package.dependencies.put_no_clobber(allocator, package_name, new_dependency);
fn addDependency(package: *Package, package_name: []const u8, new_dependency: *Package) !void {
try package.dependencies.put_no_clobber(package_name, new_dependency);
}
};
@ -3298,6 +3334,7 @@ const _usize: Type.Index = .u64;
const _ssize: Type.Index = .s64;
fn serialize_comptime_parameters(unit: *Unit, context: *const Context, original_declaration: *Debug.Declaration, parameters: []const V.Comptime) !u32 {
_ = context; // autofix
var name = BoundedArray(u8, 4096){};
const original_name = unit.getIdentifier(original_declaration.name);
name.appendSliceAssumeCapacity(original_name);
@ -3339,7 +3376,7 @@ fn serialize_comptime_parameters(unit: *Unit, context: *const Context, original_
const hash = my_hash(name.slice());
// Don't allocate memory if not necessary
if (unit.identifiers.get(hash) == null) {
try unit.identifiers.put_no_clobber(context.my_allocator, hash, name.slice());
try unit.identifiers.put_no_clobber(hash, name.slice());
}
return hash;
@ -3364,7 +3401,7 @@ pub const Type = union(enum) {
pub const Polymorphic = struct {
parameters: []const Token.Index,
instantiations: MyHashMap(u32, *Debug.Declaration.Global) = .{},
instantiations: PinnedHashMap(u32, *Debug.Declaration.Global),
node: Node.Index,
pub fn get_instantiation(polymorphic: *Polymorphic, types: []const V.Comptime) ?*Debug.Declaration.Global {
@ -3395,7 +3432,7 @@ pub const Type = union(enum) {
const new_declaration = unit.global_declarations.get(new_declaration_index);
const parameter_hash = hash(parameters);
try polymorphic.instantiations.put_no_clobber(context.my_allocator, parameter_hash, new_declaration);
try polymorphic.instantiations.put_no_clobber(parameter_hash, new_declaration);
}
fn hash(types: []const V.Comptime) u32 {
@ -3735,7 +3772,7 @@ pub const Instruction = union(enum) {
pub const max_value_count = 32;
const Value = struct{
const Value = struct {
value: V,
basic_block: BasicBlock.Index,
};
@ -4111,7 +4148,7 @@ pub fn joinPath(context: *const Context, a: []const u8, b: []const u8) ![]const
pub const PolymorphicFunction = struct {
parameters: []const ComptimeParameterDeclaration,
instantiations: MyHashMap(u32, *Debug.Declaration.Global) = .{},
instantiations: PinnedHashMap(u32, *Debug.Declaration.Global),
node: Node.Index,
is_member_call: bool,
@ -4150,7 +4187,7 @@ pub const PolymorphicFunction = struct {
const new_declaration = unit.global_declarations.get(new_declaration_index);
const parameter_hash = hash(parameters);
try polymorphic_function.instantiations.put_no_clobber(context.my_allocator, parameter_hash, new_declaration);
try polymorphic_function.instantiations.put_no_clobber(parameter_hash, new_declaration);
return new_declaration;
}
@ -4298,7 +4335,7 @@ pub const Debug = struct {
};
pub const Scope = struct {
declarations: MyHashMap(u32, *Declaration) = .{},
declarations: PinnedHashMap(u32, *Declaration),
parent: ?*Scope = null,
file: File.Index,
line: u32,
@ -4314,7 +4351,7 @@ pub const Debug = struct {
pub const Local = struct {
scope: Scope,
local_declaration_map: MyHashMap(*Debug.Declaration.Local, Instruction.Index) = .{},
local_declaration_map: PinnedHashMap(*Debug.Declaration.Local, Instruction.Index),
};
pub const Global = struct {
@ -4324,8 +4361,8 @@ pub const Debug = struct {
pub const Function = struct {
scope: Scope,
argument_map: MyHashMap(*Debug.Declaration.Argument, Instruction.Index) = .{},
// comptime_parameters: MyHashMap(*Debug.Declaration.Argument,
argument_map: PinnedHashMap(*Debug.Declaration.Argument, Instruction.Index),
// comptime_parameters: PinnedArray(*Debug.Declaration.Argument,
};
fn lookupDeclaration(s: *Scope, name: u32, look_in_parent_scopes: bool) ?Lookup {
@ -4565,7 +4602,7 @@ pub const Builder = struct {
const error_union_type_index = try unit.types.append(context.my_allocator, .{
.@"struct" = error_union_struct_index,
});
try unit.error_unions.put_no_clobber(context.my_allocator, error_union, error_union_type_index);
try unit.error_unions.put_no_clobber(error_union, error_union_type_index);
return error_union_type_index;
}
@ -4597,7 +4634,7 @@ pub const Builder = struct {
} else {
const string_name = try join_name(context, "__anon_str_", possible_id, 10);
const identifier = try unit.processIdentifier(context, string_name);
try unit.string_literal_values.put_no_clobber(context.my_allocator, hash, string);
try unit.string_literal_values.put_no_clobber(hash, string);
const string_global_index = try unit.global_declarations.append(context.my_allocator, .{
.declaration = .{
@ -4637,7 +4674,7 @@ pub const Builder = struct {
const string_global = unit.global_declarations.get(string_global_index);
try unit.string_literal_globals.put_no_clobber(context.my_allocator, hash, string_global);
try unit.string_literal_globals.put_no_clobber(hash, string_global);
_ = unit.data_to_emit.append(string_global);
@ -5177,7 +5214,9 @@ pub const Builder = struct {
.kind = .function,
.local = true,
.level = builder.current_scope.level + 1,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
.argument_map = try PinnedHashMap(*Debug.Declaration.Argument, Instruction.Index).init(std.mem.page_size),
},
.type = function_type_index,
.body = .null,
@ -5212,7 +5251,7 @@ pub const Builder = struct {
comptime assert(@TypeOf(argument_declaration_index) == Debug.Declaration.Argument.Index);
const argument = unit.argument_declarations.get(argument_declaration_index);
try builder.current_scope.declarations.put_no_clobber(context.my_allocator, argument_name_hash, &argument.declaration);
try builder.current_scope.declarations.put_no_clobber(argument_name_hash, &argument.declaration);
const entry_block = try builder.newBasicBlock(unit, context);
const exit_block = try builder.newBasicBlock(unit, context);
@ -5327,8 +5366,8 @@ pub const Builder = struct {
const global = unit.global_declarations.get(global_index);
try unit.code_to_emit.put_no_clobber(context.my_allocator, function_definition_index, global);
try unit.name_functions.put_no_clobber(context.my_allocator, type_index, global);
try unit.code_to_emit.put_no_clobber(function_definition_index, global);
try unit.name_functions.put_no_clobber(type_index, global);
return global;
}
@ -5383,7 +5422,7 @@ pub const Builder = struct {
const global_declaration = unit.global_declarations.get(global_declaration_index);
_ = unit.data_to_emit.append(global_declaration);
try unit.fields_array.put_no_clobber(context.my_allocator, container_type_index, global_declaration);
try unit.fields_array.put_no_clobber(container_type_index, global_declaration);
return global_declaration;
},
@ -5807,13 +5846,13 @@ pub const Builder = struct {
const function_definition_global = polymorphic_function.instantiations.values()[0];
assert(function_definition_global.initial_value == .function_definition);
try unit.code_to_emit.put_no_clobber(context.my_allocator, function_definition_global.initial_value.function_definition, function_definition_global);
try unit.code_to_emit.put_no_clobber(function_definition_global.initial_value.function_definition, function_definition_global);
return function_definition_global;
},
.function_definition => |function_definition_index| {
switch (unit.getNode(declaration_node_index).id) {
.function_definition => try unit.code_to_emit.put_no_clobber(context.my_allocator, function_definition_index, global_declaration),
.function_definition => try unit.code_to_emit.put_no_clobber(function_definition_index, global_declaration),
else => {
const actual_function_declaration = unit.code_to_emit.get(function_definition_index).?;
global_declaration.initial_value = .{
@ -5824,7 +5863,7 @@ pub const Builder = struct {
},
.function_declaration => |function_type| {
switch (unit.getNode(declaration_node_index).id) {
.function_prototype => try unit.external_functions.put_no_clobber(context.my_allocator, function_type, global_declaration),
.function_prototype => try unit.external_functions.put_no_clobber(function_type, global_declaration),
else => {
const actual_function_declaration = unit.external_functions.get(function_type).?;
global_declaration.initial_value = .{
@ -5841,7 +5880,7 @@ pub const Builder = struct {
unreachable;
}
},
else => unit.type_declarations.put(context.my_allocator, type_index, global_declaration) catch {
else => unit.type_declarations.put(type_index, global_declaration) catch {
assert(unit.type_declarations.get(type_index).? == global_declaration);
},
}
@ -5856,7 +5895,7 @@ pub const Builder = struct {
.polymorphic_function => |*polymorphic_function| {
const instantiation_value = try builder.resolveComptimeValue(unit, context, Type.Expect.none, global_declaration.attributes, polymorphic_function.node, global_declaration, .right, new_parameters, maybe_member_value, polymorphic_argument_nodes);
const instantiation_global = instantiation_value.global;
try unit.code_to_emit.put(context.my_allocator, instantiation_global.initial_value.function_definition, instantiation_global);
try unit.code_to_emit.put(instantiation_global.initial_value.function_definition, instantiation_global);
return instantiation_global;
},
@ -7274,6 +7313,7 @@ pub const Builder = struct {
.local = false,
.level = builder.current_scope.level + 1,
.parent = &unit.scope.scope,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
},
.id = std.math.maxInt(u32),
@ -7482,7 +7522,7 @@ pub const Builder = struct {
});
const comptime_parameter = unit.global_declarations.get(comptime_parameter_index);
try builder.current_scope.declarations.put_no_clobber(context.my_allocator, name_hash, &comptime_parameter.declaration);
try builder.current_scope.declarations.put_no_clobber(name_hash, &comptime_parameter.declaration);
},
else => |t| @panic(@tagName(t)),
},
@ -7591,7 +7631,7 @@ pub const Builder = struct {
comptime assert(@TypeOf(argument_declaration_index) == Debug.Declaration.Argument.Index);
const argument = unit.argument_declarations.get(argument_declaration_index);
try builder.current_scope.declarations.put_no_clobber(context.my_allocator, argument_name_hash, &argument.declaration);
try builder.current_scope.declarations.put_no_clobber(argument_name_hash, &argument.declaration);
}
fn classify_argument_type_aarch64(builder: *Builder, unit: *Unit, context: *const Context, type_index: Type.Index) Function.AbiInfo {
@ -8482,6 +8522,7 @@ pub const Builder = struct {
.level = builder.current_scope.level + 1,
.local = false,
.file = builder.current_file,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
},
.options = .{},
@ -8572,7 +8613,7 @@ pub const Builder = struct {
.attributes = .{},
});
const global_declaration = unit.global_declarations.get(global_declaration_index);
try struct_type.kind.@"struct".scope.scope.declarations.put_no_clobber(context.my_allocator, hash, &global_declaration.declaration);
try struct_type.kind.@"struct".scope.scope.declarations.put_no_clobber(hash, &global_declaration.declaration);
}
const polymorphic_type_index = switch (parameter_types.len > 0) {
@ -8585,6 +8626,7 @@ pub const Builder = struct {
break :param heap_parameter_types;
},
.node = container_node_index,
.instantiations = try PinnedHashMap(u32, *Debug.Declaration.Global).init(std.mem.page_size),
},
});
const polymorphic_type = &unit.types.get(polymorphic_type_index).polymorphic;
@ -8648,6 +8690,7 @@ pub const Builder = struct {
.level = builder.current_scope.level + 1,
.local = false,
.file = builder.current_file,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
},
},
@ -8694,6 +8737,7 @@ pub const Builder = struct {
.level = builder.current_scope.level + 1,
.local = false,
.file = builder.current_file,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
},
},
@ -8853,7 +8897,7 @@ pub const Builder = struct {
});
const global_declaration = unit.global_declarations.get(global_declaration_index);
try builder.current_scope.declarations.put_no_clobber(context.my_allocator, identifier_hash, &global_declaration.declaration);
try builder.current_scope.declarations.put_no_clobber(identifier_hash, &global_declaration.declaration);
},
else => unreachable,
}
@ -9078,15 +9122,15 @@ pub const Builder = struct {
const test_global = unit.global_declarations.get(test_global_index);
try scope.scope.declarations.put_no_clobber(context.my_allocator, name_hash, &test_global.declaration);
try scope.scope.declarations.put_no_clobber(name_hash, &test_global.declaration);
try unit.test_functions.put_no_clobber(context.my_allocator, test_name_global, test_global);
try unit.test_functions.put_no_clobber(test_name_global, test_global);
try unit.code_to_emit.put_no_clobber(context.my_allocator, comptime_value.function_definition, test_global);
try unit.code_to_emit.put_no_clobber(comptime_value.function_definition, test_global);
}
}
for (builder.current_scope.declarations.values()) |declaration|{
for (builder.current_scope.declarations.values()) |declaration| {
const global_declaration: *Debug.Declaration.Global = @fieldParentPtr("declaration", declaration);
if (global_declaration.attributes.contains(.@"export")) {
const result = try builder.referenceGlobalDeclaration(unit, context, &scope.scope, declaration, .{}, &.{}, null, &.{});
@ -9175,7 +9219,9 @@ pub const Builder = struct {
.local = true,
.level = builder.current_scope.level + 1,
.file = builder.current_file,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
.argument_map = try PinnedHashMap(*Debug.Declaration.Argument, Instruction.Index).init(std.mem.page_size),
},
.has_debug_info = true,
});
@ -9498,7 +9544,7 @@ pub const Builder = struct {
// else => |t| @panic(@tagName(t)),
};
try function.scope.argument_map.put_no_clobber(context.my_allocator, argument_declaration, stack);
try function.scope.argument_map.put_no_clobber(argument_declaration, stack);
const debug_declare_argument = try unit.instructions.append(context.my_allocator, .{
.debug_declare_argument = .{
@ -9672,6 +9718,7 @@ pub const Builder = struct {
.node = function_node_index,
.parameters = comptime_parameter_declarations,
.is_member_call = is_member_call,
.instantiations = try PinnedHashMap(u32, *Debug.Declaration.Global).init(std.mem.page_size),
};
_ = try polymorphic_function.add_instantiation(unit, context, comptime_parameter_instantiations, maybe_global orelse unreachable, current_function);
return V.Comptime{
@ -9909,6 +9956,7 @@ pub const Builder = struct {
.local = false,
.level = builder.current_scope.level + 1,
.parent = builder.current_scope,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
},
.fields = try DynamicBoundedArray(Type.Error.Field.Index).init(context.arena, @intCast(nodes.len)),
@ -10989,7 +11037,7 @@ pub const Builder = struct {
.insert_value = .{
.expression = .{
.value = .{
.@"comptime" = .@"undefined",
.@"comptime" = .undefined,
},
.type = destination_type_index,
},
@ -14225,14 +14273,14 @@ pub const Builder = struct {
const local_declaration = unit.local_declarations.get(declaration_index);
assert(builder.current_scope.kind == .block);
try builder.current_scope.declarations.put_no_clobber(context.my_allocator, identifier_hash, &local_declaration.declaration);
try builder.current_scope.declarations.put_no_clobber(identifier_hash, &local_declaration.declaration);
if (emit) {
const stack = try builder.createStackVariable(unit, context, declaration_type, null);
assert(builder.current_scope.kind == .block);
const local_scope: *Debug.Scope.Local = @fieldParentPtr("scope", builder.current_scope);
try local_scope.local_declaration_map.put_no_clobber(context.my_allocator, local_declaration, stack);
try local_scope.local_declaration_map.put_no_clobber(local_declaration, stack);
const debug_declare_local = try unit.instructions.append(context.my_allocator, .{
.debug_declare_local_variable = .{
@ -14276,7 +14324,9 @@ pub const Builder = struct {
.level = builder.current_scope.level + 1,
.local = builder.current_scope.local,
.file = builder.current_file,
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
.local_declaration_map = try PinnedHashMap(*Debug.Declaration.Local, Instruction.Index).init(std.mem.page_size),
},
});
@ -16933,28 +16983,27 @@ pub const Unit = struct {
constant_arrays: V.Comptime.ConstantArray.List = .{},
constant_slices: V.Comptime.ConstantSlice.List = .{},
error_fields: Type.Error.Field.List = .{},
file_token_offsets: MyHashMap(Token.Range, Debug.File.Index) = .{},
file_map: MyHashMap([]const u8, Debug.File.Index) = .{},
identifiers: MyHashMap(u32, []const u8) = .{},
string_literal_values: MyHashMap(u32, [:0]const u8) = .{},
string_literal_globals: MyHashMap(u32, *Debug.Declaration.Global) = .{},
file_token_offsets: PinnedHashMap(Token.Range, Debug.File.Index),
file_map: PinnedHashMap([]const u8, Debug.File.Index),
identifiers: PinnedHashMap(u32, []const u8),
string_literal_values: PinnedHashMap(u32, [:0]const u8),
string_literal_globals: PinnedHashMap(u32, *Debug.Declaration.Global),
optionals: MyHashMap(Type.Index, Type.Index) = .{},
pointers: MyHashMap(Type.Pointer, Type.Index) = .{},
slices: MyHashMap(Type.Slice, Type.Index) = .{},
arrays: MyHashMap(Type.Array, Type.Index) = .{},
integers: MyHashMap(Type.Integer, Type.Index) = .{},
error_unions: MyHashMap(Type.Error.Union.Descriptor, Type.Index) = .{},
two_structs: MyHashMap([2]Type.Index, Type.Index) = .{},
fields_array: MyHashMap(Type.Index, *Debug.Declaration.Global) = .{},
name_functions: MyHashMap(Type.Index, *Debug.Declaration.Global) = .{},
error_count: u32 = 0,
optionals: PinnedHashMap(Type.Index, Type.Index),
pointers: PinnedHashMap(Type.Pointer, Type.Index),
slices: PinnedHashMap(Type.Slice, Type.Index),
arrays: PinnedHashMap(Type.Array, Type.Index),
integers: PinnedHashMap(Type.Integer, Type.Index),
error_unions: PinnedHashMap(Type.Error.Union.Descriptor, Type.Index),
two_structs: PinnedHashMap([2]Type.Index, Type.Index),
fields_array: PinnedHashMap(Type.Index, *Debug.Declaration.Global),
name_functions: PinnedHashMap(Type.Index, *Debug.Declaration.Global),
code_to_emit: MyHashMap(Function.Definition.Index, *Debug.Declaration.Global) = .{},
external_functions: PinnedHashMap(Type.Index, *Debug.Declaration.Global),
type_declarations: PinnedHashMap(Type.Index, *Debug.Declaration.Global),
test_functions: PinnedHashMap(*Debug.Declaration.Global, *Debug.Declaration.Global),
code_to_emit: PinnedHashMap(Function.Definition.Index, *Debug.Declaration.Global),
data_to_emit: PinnedArray(*Debug.Declaration.Global),
external_functions: MyHashMap(Type.Index, *Debug.Declaration.Global) = .{},
type_declarations: MyHashMap(Type.Index, *Debug.Declaration.Global) = .{},
test_functions: MyHashMap(*Debug.Declaration.Global, *Debug.Declaration.Global) = .{},
scope: Debug.Scope.Global = .{
.scope = .{
.file = .null,
@ -16963,6 +17012,13 @@ pub const Unit = struct {
.column = 0,
.level = 0,
.local = false,
.declarations = .{
.key_pointer = undefined,
.value_pointer = undefined,
.length = 0,
.granularity = 0,
.committed = 0,
},
},
},
root_package: *Package = undefined,
@ -16975,6 +17031,7 @@ pub const Unit = struct {
discard_identifiers: usize = 0,
anon_i: usize = 0,
anon_arr: usize = 0,
error_count: u32 = 0,
fn dumpInstruction(instruction_index: Instruction.Index) !void {
try write(.ir, "%");
@ -17309,7 +17366,7 @@ pub const Unit = struct {
.@"struct" = optional_struct_index,
});
try unit.optionals.put_no_clobber(context.my_allocator, element_type, optional_type_index);
try unit.optionals.put_no_clobber(element_type, optional_type_index);
return optional_type_index;
}
@ -17322,7 +17379,7 @@ pub const Unit = struct {
const type_index = try unit.types.append(context.my_allocator, .{
.pointer = pointer,
});
try unit.pointers.put_no_clobber(context.my_allocator, pointer, type_index);
try unit.pointers.put_no_clobber(pointer, type_index);
return type_index;
}
@ -17335,7 +17392,7 @@ pub const Unit = struct {
const type_index = try unit.types.append(context.my_allocator, .{
.slice = slice,
});
try unit.slices.put_no_clobber(context.my_allocator, slice, type_index);
try unit.slices.put_no_clobber(slice, type_index);
return type_index;
}
@ -17349,7 +17406,7 @@ pub const Unit = struct {
const array_type = try unit.types.append(context.my_allocator, .{
.array = array,
});
try unit.arrays.put_no_clobber(context.my_allocator, array, array_type);
try unit.arrays.put_no_clobber(array, array_type);
return array_type;
}
@ -17381,7 +17438,7 @@ pub const Unit = struct {
const type_index = try unit.types.append(context.my_allocator, .{
.integer = integer,
});
try unit.integers.put_no_clobber(context.my_allocator, integer, type_index);
try unit.integers.put_no_clobber(integer, type_index);
return type_index;
}
},
@ -17391,9 +17448,10 @@ pub const Unit = struct {
}
fn processIdentifier(unit: *Unit, context: *const Context, string: []const u8) !u32 {
_ = context; // autofix
const hash = my_hash(string);
if (unit.identifiers.get_pointer(hash) == null) {
try unit.identifiers.put_no_clobber(context.my_allocator, hash, string);
try unit.identifiers.put_no_clobber(hash, string);
}
return hash;
}
@ -17434,7 +17492,7 @@ pub const Unit = struct {
fixed_string.len += 1;
fixed_string[zero_index] = 0;
const string = fixed_string[0 .. zero_index :0];
const string = fixed_string[0..zero_index :0];
return string;
}
@ -17508,7 +17566,7 @@ pub const Unit = struct {
file.lexer = try lexer.analyze(file.source_code, &unit.token_buffer);
assert(file.status == .loaded_into_memory);
file.status = .lexed;
try unit.file_token_offsets.put_no_clobber(context.my_allocator, .{
try unit.file_token_offsets.put_no_clobber(.{
.start = file.lexer.offset,
.count = file.lexer.count,
}, file_index);
@ -17582,18 +17640,21 @@ pub const Unit = struct {
const file_index = try unit.files.append(context.my_allocator, Debug.File{
.relative_path = relative_path,
.package = package,
.scope = .{ .scope = .{
.scope = .{
.scope = .{
.file = .null,
.kind = .file,
.line = 0,
.column = 0,
.local = false,
.level = 1,
} },
.declarations = try PinnedHashMap(u32, *Debug.Declaration).init(std.mem.page_size),
},
},
});
// logln(.compilation, .new_file, "Adding file #{}: {s}\n", .{ file_index, full_path });
try unit.file_map.put_no_clobber(context.my_allocator, full_path, file_index);
try unit.file_map.put_no_clobber(full_path, file_index);
return .{
.index = file_index,
@ -17642,6 +17703,7 @@ pub const Unit = struct {
.path = main_package_absolute_directory_path,
},
.source_path = try context.my_allocator.duplicate_bytes(std.fs.path.basename(unit.descriptor.main_package_path)),
.dependencies = try PinnedHashMap([]const u8, *Package).init(std.mem.page_size),
};
break :blk result;
};
@ -17655,6 +17717,7 @@ pub const Unit = struct {
.path = directory_path,
},
.source_path = "test_runner.nat",
.dependencies = try PinnedHashMap([]const u8, *Package).init(std.mem.page_size),
};
unit.main_package = main_package;
@ -17689,9 +17752,10 @@ pub const Unit = struct {
.handle = try std.fs.openDirAbsolute(package_descriptor.directory_path, .{}),
},
.source_path = try std.mem.concat(context.allocator, u8, &.{ package_descriptor.name, ".nat" }),
.dependencies = try PinnedHashMap([]const u8, *Package).init(std.mem.page_size),
};
try unit.root_package.addDependency(context.my_allocator, package_descriptor.name, package);
try unit.root_package.addDependency(package_descriptor.name, package);
package_ptr.* = package;
}
@ -17763,7 +17827,7 @@ pub const Unit = struct {
.@"struct" = two_struct,
});
try unit.two_structs.put_no_clobber(context.my_allocator, types, type_index);
try unit.two_structs.put_no_clobber(types, type_index);
return type_index;
}
@ -17838,7 +17902,7 @@ pub const Token = struct {
length: u32,
id: Token.Id,
pub const Buffer = struct{
pub const Buffer = struct {
line_offsets: PinnedArray(u32) = .{},
tokens: PinnedArray(Token) = .{},
};

View File

@ -6,10 +6,11 @@ const write = Compilation.write;
// const log = Compilation.log;
// const logln = Compilation.logln;
const Module = Compilation.Module;
const data_structures = @import("../library.zig");
const BoundedArray = data_structures.BoundedArray;
const MyHashMap = data_structures.MyHashMap;
const PinnedArray = data_structures.PinnedArray;
const library = @import("../library.zig");
const BoundedArray = library.BoundedArray;
const PinnedHashMap = library.PinnedHashMap;
const PinnedArray = library.PinnedArray;
const format_int = library.format_int;
pub const bindings = @import("llvm_bindings.zig");
@ -28,23 +29,23 @@ pub const LLVM = struct {
module: *LLVM.Module,
builder: *LLVM.Builder,
debug_info_builder: *LLVM.DebugInfo.Builder,
debug_info_file_map: MyHashMap(Compilation.Debug.File.Index, *LLVM.DebugInfo.File) = .{},
debug_type_map: MyHashMap(Compilation.Type.Index, *LLVM.DebugInfo.Type) = .{},
type_name_map: MyHashMap(Compilation.Type.Index, []const u8) = .{},
type_map: MyHashMap(Compilation.Type.Index, *LLVM.Type) = .{},
function_declaration_map: MyHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function) = .{},
function_definition_map: MyHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function) = .{},
llvm_instruction_map: MyHashMap(Compilation.Instruction.Index, *LLVM.Value) = .{},
llvm_value_map: MyHashMap(Compilation.V, *LLVM.Value) = .{},
llvm_block_map: MyHashMap(Compilation.BasicBlock.Index, *LLVM.Value.BasicBlock) = .{},
llvm_external_functions: MyHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function) = .{},
global_variable_map: MyHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.GlobalVariable) = .{},
scope_map: MyHashMap(*Compilation.Debug.Scope, *LLVM.DebugInfo.Scope) = .{},
debug_info_file_map: PinnedHashMap(Compilation.Debug.File.Index, *LLVM.DebugInfo.File),
debug_type_map: PinnedHashMap(Compilation.Type.Index, *LLVM.DebugInfo.Type),
type_name_map: PinnedHashMap(Compilation.Type.Index, []const u8),
type_map: PinnedHashMap(Compilation.Type.Index, *LLVM.Type),
function_declaration_map: PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function),
function_definition_map: PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function),
llvm_instruction_map: PinnedHashMap(Compilation.Instruction.Index, *LLVM.Value),
llvm_value_map: PinnedHashMap(Compilation.V, *LLVM.Value),
llvm_block_map: PinnedHashMap(Compilation.BasicBlock.Index, *LLVM.Value.BasicBlock),
llvm_external_functions: PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function),
global_variable_map: PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.GlobalVariable),
scope_map: PinnedHashMap(*Compilation.Debug.Scope, *LLVM.DebugInfo.Scope),
argument_allocas: PinnedHashMap(Compilation.Instruction.Index, *LLVM.Value),
pointer_type: ?*LLVM.Type.Pointer = null,
function: *LLVM.Value.Constant.Function = undefined,
exit_block: *LLVM.Value.BasicBlock = undefined,
sema_function: *Compilation.Debug.Declaration.Global = undefined,
argument_allocas: MyHashMap(Compilation.Instruction.Index, *LLVM.Value) = .{},
return_phi_node: ?*LLVM.Value.Instruction.PhiNode = null,
scope: *LLVM.DebugInfo.Scope = undefined,
file: *LLVM.DebugInfo.File = undefined,
@ -1333,7 +1334,7 @@ pub const LLVM = struct {
else => |t| @panic(@tagName(t)),
};
try llvm.type_map.put_no_clobber(context.my_allocator, type_index, llvm_type);
try llvm.type_map.put_no_clobber(type_index, llvm_type);
return llvm_type;
}
@ -1349,7 +1350,7 @@ pub const LLVM = struct {
const filename = std.fs.path.basename(full_path);
const directory = full_path[0 .. full_path.len - filename.len];
const debug_file = llvm.debug_info_builder.createFile(filename.ptr, filename.len, directory.ptr, directory.len) orelse unreachable;
try llvm.debug_info_file_map.put_no_clobber(context.my_allocator, sema_file_index, debug_file);
try llvm.debug_info_file_map.put_no_clobber(sema_file_index, debug_file);
return debug_file;
}
}
@ -1360,7 +1361,7 @@ pub const LLVM = struct {
} else {
if (unit.type_declarations.get(sema_type_index)) |global_declaration| {
const result = unit.getIdentifier(global_declaration.declaration.name);
try llvm.type_name_map.put_no_clobber(context.my_allocator, sema_type_index, result);
try llvm.type_name_map.put_no_clobber(sema_type_index, result);
return result;
} else {
const sema_type = unit.types.get(sema_type_index);
@ -1369,7 +1370,7 @@ pub const LLVM = struct {
.integer => |integer| switch (integer.kind) {
.materialized_int => b: {
var buffer: [65]u8 = undefined;
const format = data_structures.format_int(&buffer, integer.bit_count, 10, false);
const format = format_int(&buffer, integer.bit_count, 10, false);
const slice_ptr = format.ptr - 1;
const slice = slice_ptr[0 .. format.len + 1];
slice[0] = switch (integer.signedness) {
@ -1410,7 +1411,7 @@ pub const LLVM = struct {
.array => |array| b: {
name.appendAssumeCapacity('[');
var buffer: [65]u8 = undefined;
const array_count = data_structures.format_int(&buffer, array.count, 10, false);
const array_count = format_int(&buffer, array.count, 10, false);
name.appendSliceAssumeCapacity(array_count);
name.appendAssumeCapacity(']');
const element_type_name = try llvm.renderTypeName(unit, context, array.type);
@ -1424,8 +1425,7 @@ pub const LLVM = struct {
else => |t| @panic(@tagName(t)),
};
try llvm.type_name_map.put(context.my_allocator, sema_type_index, if (name.len > 0) b: {
try llvm.type_name_map.put(sema_type_index, if (name.len > 0) b: {
const new_name = try context.arena.new_array(u8, name.len);
@memcpy(new_name, result);
break :b new_name;
@ -1533,7 +1533,7 @@ pub const LLVM = struct {
.forward_declaration = null,
});
try llvm.debug_type_map.put_no_clobber(context.my_allocator, sema_type_index, struct_type.toType());
try llvm.debug_type_map.put_no_clobber(sema_type_index, struct_type.toType());
var field_types = BoundedArray(*LLVM.DebugInfo.Type, 512){};
bit_size = 0;
@ -1842,7 +1842,7 @@ pub const LLVM = struct {
else => |t| @panic(@tagName(t)),
};
try llvm.debug_type_map.put(context.my_allocator, sema_type_index, result);
try llvm.debug_type_map.put(sema_type_index, result);
assert(@intFromPtr(result) != 0xaaaa_aaaa_aaaa_aaaa);
return result;
@ -1863,7 +1863,7 @@ pub const LLVM = struct {
if (gep.is_struct and gep.index.type != .u32) unreachable;
const gep_name = unit.getIdentifier(gep.name);
const get_element_pointer = llvm.builder.createGEP(base_type, pointer, indices.ptr, indices.len, gep_name.ptr, gep_name.len, in_bounds) orelse unreachable;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, get_element_pointer);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, get_element_pointer);
return get_element_pointer;
}
@ -2047,7 +2047,7 @@ pub const LLVM = struct {
basic_block_node.* = .{
.data = basic_block_index,
};
try llvm.llvm_block_map.put_no_clobber(context.my_allocator, basic_block_index, basic_block);
try llvm.llvm_block_map.put_no_clobber(basic_block_index, basic_block);
return basic_block_node;
}
@ -2287,8 +2287,8 @@ pub const LLVM = struct {
});
switch (declaration.initial_value) {
.function_declaration => try llvm.function_declaration_map.put_no_clobber(context.my_allocator, declaration, function),
.function_definition => try llvm.function_definition_map.put_no_clobber(context.my_allocator, declaration, function),
.function_declaration => try llvm.function_declaration_map.put_no_clobber(declaration, function),
.function_definition => try llvm.function_definition_map.put_no_clobber(declaration, function),
else => unreachable,
}
@ -2360,7 +2360,7 @@ pub const LLVM = struct {
const function_definition = unit.function_definitions.get(function_definition_index);
const scope = subprogram.toLocalScope().toScope();
try llvm.scope_map.put_no_clobber(context.my_allocator, &function_definition.scope.scope, scope);
try llvm.scope_map.put_no_clobber(&function_definition.scope.scope, scope);
},
.function_declaration => {},
else => |t| @panic(@tagName(t)),
@ -2368,7 +2368,7 @@ pub const LLVM = struct {
}
switch (declaration.initial_value) {
.function_declaration => try llvm.llvm_external_functions.put_no_clobber(context.my_allocator, declaration, function),
.function_declaration => try llvm.llvm_external_functions.put_no_clobber(declaration, function),
.function_definition => {},
else => |t| @panic(@tagName(t)),
}
@ -2419,6 +2419,19 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.inreg = llvm_context.getAttributeFromEnum(.InReg, 0),
.@"noalias" = llvm_context.getAttributeFromEnum(.NoAlias, 0),
},
.debug_info_file_map = try PinnedHashMap(Compilation.Debug.File.Index, *LLVM.DebugInfo.File).init(std.mem.page_size),
.debug_type_map = try PinnedHashMap(Compilation.Type.Index, *LLVM.DebugInfo.Type).init(std.mem.page_size),
.type_name_map = try PinnedHashMap(Compilation.Type.Index, []const u8).init(std.mem.page_size),
.type_map = try PinnedHashMap(Compilation.Type.Index, *LLVM.Type).init(std.mem.page_size),
.function_declaration_map = try PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function).init(std.mem.page_size),
.function_definition_map = try PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function).init(std.mem.page_size),
.llvm_instruction_map = try PinnedHashMap(Compilation.Instruction.Index, *LLVM.Value).init(std.mem.page_size),
.llvm_value_map = try PinnedHashMap(Compilation.V, *LLVM.Value).init(std.mem.page_size),
.llvm_block_map = try PinnedHashMap(Compilation.BasicBlock.Index, *LLVM.Value.BasicBlock).init(std.mem.page_size),
.llvm_external_functions = try PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.Function).init(std.mem.page_size),
.global_variable_map = try PinnedHashMap(*Compilation.Debug.Declaration.Global, *LLVM.Value.Constant.GlobalVariable).init(std.mem.page_size),
.scope_map = try PinnedHashMap(*Compilation.Debug.Scope, *LLVM.DebugInfo.Scope).init(std.mem.page_size),
.argument_allocas = try PinnedHashMap(Compilation.Instruction.Index, *LLVM.Value).init(std.mem.page_size),
};
if (unit.descriptor.generate_debug_information) {
@ -2442,7 +2455,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const compile_unit = llvm.debug_info_builder.createCompileUnit(LLVM.DebugInfo.Language.c, debug_info_file, producer, producer.len, is_optimized, flags, flags.len, runtime_version, splitname, splitname.len, debug_info_kind, DWOId, split_debug_inlining, debug_info_for_profiling, name_table_kind, ranges_base_address, sysroot, sysroot.len, sdk, sdk.len) orelse unreachable;
llvm.scope = compile_unit.toScope();
try llvm.scope_map.put_no_clobber(context.my_allocator, &unit.scope.scope, llvm.scope);
try llvm.scope_map.put_no_clobber(&unit.scope.scope, llvm.scope);
}
for (unit.external_functions.values()) |external_function_declaration| {
@ -2469,7 +2482,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.string_literal => |hash| {
const string_literal = unit.string_literal_values.get(hash).?;
const global_variable = llvm.builder.createGlobalString(string_literal.ptr, string_literal.len, name.ptr, name.len, address_space, llvm.module) orelse unreachable;
try llvm.global_variable_map.put_no_clobber(context.my_allocator, global_declaration, global_variable);
try llvm.global_variable_map.put_no_clobber(global_declaration, global_variable);
},
else => {
const global_type = try llvm.getType(unit, context, global_declaration.declaration.type);
@ -2485,7 +2498,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const thread_local_mode = LLVM.ThreadLocalMode.not_thread_local;
const externally_initialized = false;
const global_variable = llvm.module.addGlobalVariable(global_type, constant, linkage, initializer, name.ptr, name.len, null, thread_local_mode, address_space, externally_initialized) orelse return LLVM.Value.Error.constant_int;
try llvm.global_variable_map.put_no_clobber(context.my_allocator, global_declaration, global_variable);
try llvm.global_variable_map.put_no_clobber(global_declaration, global_variable);
},
}
@ -2513,7 +2526,11 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
global_variable.setInitializer(constant_initializer);
}
var phis = try PinnedHashMap(Compilation.Instruction.Index, *LLVM.Value.Instruction.PhiNode).init(0x1000);
for (llvm.function_definition_map.keys(), llvm.function_definition_map.values()) |function_declaration, function| {
phis.clear();
const function_definition_index = function_declaration.getFunctionDefinitionIndex();
const function_definition = unit.function_definitions.get(function_definition_index);
llvm.function = function;
@ -2528,15 +2545,13 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
llvm.scope = subprogram.toLocalScope().toScope();
}
var alloca_map = MyHashMap(Compilation.Instruction.Index, *LLVM.Value){};
var alloca_map = try PinnedHashMap(Compilation.Instruction.Index, *LLVM.Value).init(std.mem.page_size);
var block_command_list = BasicBlockList{};
const entry_block_node = try llvm.createBasicBlock(context, function_definition.basic_blocks.pointer[0], "fn_entry");
block_command_list.append(entry_block_node);
var phis = MyHashMap(Compilation.Instruction.Index, *LLVM.Value.Instruction.PhiNode){};
while (block_command_list.len != 0) {
const block_node = block_command_list.first orelse unreachable;
const basic_block_index = block_node.data;
@ -2557,7 +2572,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
assert(@intFromEnum(push_scope.old.kind) >= @intFromEnum(Compilation.Debug.Scope.Kind.function));
const lexical_block = llvm.debug_info_builder.createLexicalBlock(old_scope, llvm.file, push_scope.new.line + 1, push_scope.new.column + 1) orelse unreachable;
try llvm.scope_map.put_no_clobber(context.my_allocator, push_scope.new, lexical_block.toScope());
try llvm.scope_map.put_no_clobber(push_scope.new, lexical_block.toScope());
llvm.scope = lexical_block.toScope();
}
},
@ -2616,7 +2631,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
},
.number_literal => |literal| {
var buffer: [65]u8 = undefined;
const number_literal = data_structures.format_int(&buffer, literal, 16, false);
const number_literal = format_int(&buffer, literal, 16, false);
const slice_ptr = number_literal.ptr - 4;
const literal_slice = slice_ptr[0 .. number_literal.len + 4];
literal_slice[0] = '$';
@ -2632,7 +2647,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
} else {
const value = try llvm.emitLeftValue(unit, context, sema_value);
var buffer: [65]u8 = undefined;
const operand_number = data_structures.format_int(&buffer, operand_values.len, 16, false);
const operand_number = format_int(&buffer, operand_values.len, 16, false);
const slice_ptr = operand_number.ptr - 2;
const operand_slice = slice_ptr[0 .. operand_number.len + 2];
operand_slice[0] = '$';
@ -2676,7 +2691,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const inline_assembly = LLVM.Value.InlineAssembly.get(function_type, &assembly_statements.buffer, assembly_statements.len, &constraints.buffer, constraints.len, has_side_effects, is_align_stack, dialect, can_throw) orelse return LLVM.Value.Error.inline_assembly;
const call = llvm.builder.createCall(function_type, inline_assembly.toValue(), &operand_values.buffer, operand_values.len, "", "".len, null) orelse return LLVM.Value.Instruction.Error.call;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, call.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, call.toValue());
},
.stack_slot => |stack_slot| {
// const stack_slot_type = unit.types.get(stack_slot.type);
@ -2685,8 +2700,8 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const type_alignment = unit.types.get(stack_slot.type).getAbiAlignment(unit);
const alloca_array_size = null;
const declaration_alloca = llvm.builder.createAlloca(declaration_type, address_space, alloca_array_size, "", "".len, type_alignment) orelse return LLVM.Value.Instruction.Error.alloca;
try alloca_map.put_no_clobber(context.my_allocator, instruction_index, declaration_alloca.toValue());
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, declaration_alloca.toValue());
try alloca_map.put_no_clobber(instruction_index, declaration_alloca.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, declaration_alloca.toValue());
},
.store => |store| {
const right = try llvm.emitRightValue(unit, context, store.source);
@ -2706,7 +2721,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const cast_type = LLVM.Value.Instruction.Cast.Type.int_to_pointer;
const cast_name = @tagName(cast_type);
const cast_instruction = llvm.builder.createCast(cast_type, value, value.getType(), cast_name.ptr, cast_name.len) orelse return LLVM.Value.Instruction.Error.cast;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, cast_instruction);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, cast_instruction);
},
.array_bitcast_to_integer => unreachable,
// TODO: Poke metadata
@ -2724,27 +2739,27 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.pointer_source_type_to_destination_type,
.pointer_none_terminated_to_zero,
=> {
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, value);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, value);
},
.sign_extend => {
const sign_extend = llvm.builder.createCast(.sign_extend, value, dest_type, "sign_extend", "sign_extend".len) orelse return LLVM.Value.Instruction.Error.cast;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, sign_extend);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, sign_extend);
},
.zero_extend => {
const zero_extend = llvm.builder.createCast(.zero_extend, value, dest_type, "zero_extend", "zero_extend".len) orelse return LLVM.Value.Instruction.Error.cast;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, zero_extend);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, zero_extend);
},
.bitcast => {
const bitcast = llvm.builder.createCast(.bitcast, value, dest_type, "bitcast", "bitcast".len) orelse return LLVM.Value.Instruction.Error.cast;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, bitcast);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, bitcast);
},
.pointer_to_int => {
const pointer_to_int = llvm.builder.createCast(.pointer_to_int, value, dest_type, "pointer_to_int", "pointer_to_int".len) orelse return LLVM.Value.Instruction.Error.cast;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, pointer_to_int);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, pointer_to_int);
},
.truncate => {
const truncate = llvm.builder.createCast(.truncate, value, dest_type, "truncate", "truncate".len) orelse return LLVM.Value.Instruction.Error.cast;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, truncate);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, truncate);
},
.error_union_type_int_to_pointer, .error_union_type_upcast, .error_union_type_downcast => unreachable,
}
@ -2761,7 +2776,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
},
else => |t| @panic(@tagName(t)),
};
try llvm.llvm_value_map.put_no_clobber(context.my_allocator, load.value, value);
try llvm.llvm_value_map.put_no_clobber(load.value, value);
break :blk value;
};
@ -2771,7 +2786,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const value_type = try llvm.getType(unit, context, load.type);
const is_volatile = false;
const load_i = llvm.builder.createLoad(value_type, value, is_volatile, "", "".len, alignment) orelse return LLVM.Value.Instruction.Error.load;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, load_i.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, load_i.toValue());
},
.integer_binary_operation => |binary_operation| {
assert(binary_operation.left.type == binary_operation.right.type);
@ -2810,7 +2825,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
},
else => unreachable,
};
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, instruction);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, instruction);
},
.call => |sema_call| {
var argument_buffer: [32]*LLVM.Value = undefined;
@ -2861,7 +2876,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
else => |t| @panic(@tagName(t)),
};
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, call.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, call.toValue());
try llvm.setCallOrFunctionAttributes(unit, context, function_prototype, .{
.call = call,
@ -2918,14 +2933,14 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
};
const call_to_asm = llvm.builder.createCall(function_type, inline_asm.toValue(), syscall_arguments.ptr, syscall_arguments.len, "syscall", "syscall".len, null) orelse return LLVM.Value.Instruction.Error.call;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, call_to_asm.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, call_to_asm.toValue());
},
.@"unreachable" => {
_ = llvm.builder.createUnreachable() orelse return LLVM.Value.Instruction.Error.@"unreachable";
},
.abi_argument => |argument_index| {
const argument = llvm.function.getArgument(argument_index) orelse unreachable;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, argument.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, argument.toValue());
},
.debug_declare_argument => |debug_declare| {
if (generate_debug_information) {
@ -3024,7 +3039,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const value = try llvm.emitRightValue(unit, context, insert_value.new_value);
const indices = [1]c_uint{insert_value.index};
const instruction = llvm.builder.createInsertValue(aggregate, value, &indices, indices.len, "", "".len) orelse unreachable;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, instruction);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, instruction);
},
.extract_value => |extract_value| {
switch (unit.types.get(extract_value.expression.type).*) {
@ -3037,7 +3052,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
assert(!aggregate.getType().isPointer());
const indices = [1]c_uint{extract_value.index};
const instruction = llvm.builder.createExtractValue(aggregate, &indices, indices.len, "", "".len) orelse unreachable;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, instruction);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, instruction);
},
.integer_compare => |integer_compare| {
assert(integer_compare.left.type == integer_compare.right.type);
@ -3057,7 +3072,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
.signed_greater_equal => .sge,
};
const icmp = llvm.builder.createICmp(comparison_id, left, right, "", "".len) orelse unreachable;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, icmp);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, icmp);
},
.jump => |jump| {
const target_block = if (llvm.llvm_block_map.get(jump.to)) |target_block| target_block else blk: {
@ -3070,7 +3085,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
};
const br = llvm.builder.createBranch(target_block) orelse unreachable;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, br.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, br.toValue());
},
.branch => |branch| {
const taken_node = try llvm.createBasicBlock(context, branch.taken, "taken_block");
@ -3087,7 +3102,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const branch_weights = null;
const unpredictable = null;
const br = llvm.builder.createConditionalBranch(condition, taken_block, not_taken_block, branch_weights, unpredictable) orelse unreachable;
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, br.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, br.toValue());
},
.phi => |phi| {
const phi_type = try llvm.getType(unit, context, phi.type);
@ -3095,9 +3110,9 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const phi_name = "phi";
const phi_node = llvm.builder.createPhi(phi_type, reserved_value_count, phi_name, phi_name.len) orelse unreachable;
try phis.put_no_clobber(context.my_allocator, instruction_index, phi_node);
try phis.put_no_clobber(instruction_index, phi_node);
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, phi_node.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, phi_node.toValue());
},
.umin => |umin| {
const intrinsic_type = try llvm.getType(unit, context, umin.type);
@ -3106,7 +3121,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const right = try llvm.emitRightValue(unit, context, umin.right);
const arguments = [_]*LLVM.Value{ left, right };
const intrinsic_call = try llvm.callIntrinsic("llvm.umin", &parameter_types, &arguments);
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, intrinsic_call);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, intrinsic_call);
},
.get_element_pointer => {
_ = try llvm.createGEP(unit, context, instruction_index);
@ -3115,7 +3130,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const parameter_types: []const *LLVM.Type = &.{};
const parameter_values: []const *LLVM.Value = &.{};
const intrinsic_call = try llvm.callIntrinsic("llvm.trap", parameter_types, parameter_values);
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, intrinsic_call);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, intrinsic_call);
},
.add_overflow => |add_overflow| {
const intrinsic_type = try llvm.getType(unit, context, add_overflow.type);
@ -3124,7 +3139,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const right = try llvm.emitRightValue(unit, context, add_overflow.right);
const arguments = [_]*LLVM.Value{ left, right };
const intrinsic_call = try llvm.callIntrinsic("llvm.sadd.with.overflow", &parameter_types, &arguments);
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, intrinsic_call);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, intrinsic_call);
},
.trailing_zeroes => |v| {
const intrinsic_type = try llvm.getType(unit, context, v.type);
@ -3133,7 +3148,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const is_poison = llvm.context.getConstantInt(1, 0, false) orelse unreachable;
const arguments = [_]*LLVM.Value{ value, is_poison.toValue() };
const intrinsic_call = try llvm.callIntrinsic("llvm.cttz", &parameter_types, &arguments);
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, intrinsic_call);
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, intrinsic_call);
},
.@"switch" => |switch_expression| {
const condition = try llvm.emitRightValue(unit, context, switch_expression.condition);
@ -3165,7 +3180,7 @@ pub fn codegen(unit: *Compilation.Unit, context: *const Compilation.Context) !vo
const branch_weights = null;
const unpredictable = null;
const switch_instruction = llvm.builder.createSwitch(condition, else_block, &condition_array.buffer, &basic_block_array.buffer, condition_array.len, branch_weights, unpredictable);
try llvm.llvm_instruction_map.put_no_clobber(context.my_allocator, instruction_index, switch_instruction.toValue());
try llvm.llvm_instruction_map.put_no_clobber(instruction_index, switch_instruction.toValue());
},
.memcpy => |memcpy| {
const destination = try llvm.emitLeftValue(unit, context, memcpy.destination);

View File

@ -11,13 +11,13 @@ pub fn assert(ok: bool) void {
pub const Allocator = std.mem.Allocator;
pub const BoundedArray = std.BoundedArray;
pub const Arena = struct{
pub const Arena = struct {
position: u64,
commit_position: u64,
alignment: u64,
size: u64,
pub const Temporary = struct{
pub const Temporary = struct {
arena: *Arena,
position: u64,
};
@ -71,7 +71,7 @@ pub const Arena = struct{
}
}
pub inline fn new(arena: *Arena, comptime T: type) !*T{
pub inline fn new(arena: *Arena, comptime T: type) !*T {
const result: *T = @ptrCast(@alignCast(try arena.allocate(@sizeOf(T))));
return result;
}
@ -83,7 +83,7 @@ pub const Arena = struct{
};
pub fn DynamicBoundedArray(comptime T: type) type {
return struct{
return struct {
pointer: [*]T = @constCast((&[_]T{}).ptr),
length: u32 = 0,
capacity: u32 = 0,
@ -114,7 +114,7 @@ pub fn DynamicBoundedArray(comptime T: type) type {
array.length += count;
}
pub fn slice(array: *Array) []T{
pub fn slice(array: *Array) []T {
return array.pointer[0..array.length];
}
};
@ -123,24 +123,26 @@ pub fn DynamicBoundedArray(comptime T: type) type {
const pinned_array_page_size = 2 * 1024 * 1024;
const pinned_array_max_size = std.math.maxInt(u32) - pinned_array_page_size;
const pinned_array_default_granularity = pinned_array_page_size;
/// This must be used with big arrays
// This must be used with big arrays, which are not resizeable (can't be cleared)
pub fn PinnedArray(comptime T: type) type {
return struct{
return struct {
pointer: [*]T = @constCast((&[_]T{}).ptr),
length: u32 = 0,
granularity: u32 = 0,
pub const Index = enum(u32){
pub const Index = enum(u32) {
null = 0xffff_ffff,
_,
};
const Array = @This();
pub fn const_slice(array: *const Array) []const T{
pub fn const_slice(array: *const Array) []const T {
return array.pointer[0..array.length];
}
pub fn slice(array: *Array) []T{
pub fn slice(array: *Array) []T {
return array.pointer[0..array.length];
}
@ -155,14 +157,15 @@ pub fn PinnedArray(comptime T: type) type {
return array.get_unchecked(i);
}
pub fn get_index(array: *Array, item: *T) Index{
pub fn get_index(array: *Array, item: *T) Index {
const many_item: [*]T = @ptrCast(item);
const result = @intFromPtr(many_item) - @intFromPtr(array.pointer);
assert(result < pinned_array_max_size);
return @enumFromInt(@divExact(result, @sizeOf(T)));
}
pub fn init(granularity: u32) !Array{
pub fn init(granularity: u32) !Array {
assert(granularity & 0xfff == 0);
const raw_ptr = try reserve(pinned_array_max_size);
try commit(raw_ptr, granularity);
return Array{
@ -172,30 +175,30 @@ pub fn PinnedArray(comptime T: type) type {
};
}
pub fn init_with_default_granularity() !Array{
pub fn init_with_default_granularity() !Array {
return try Array.init(pinned_array_default_granularity);
}
pub fn append(array: *Array, item: T) *T {
if (((array.length + 1) * @sizeOf(T)) & (array.granularity - 1) == 0) {
const length: u64 = array.length;
assert((length + 1) * @sizeOf(T) <= pinned_array_max_size);
pub fn ensure_capacity(array: *Array, additional: u32) void {
const length = array.length;
const size = length * @sizeOf(T);
const granularity_aligned_size = align_forward(size, array.granularity);
const new_size = size + additional * @sizeOf(T);
if (granularity_aligned_size < new_size) {
assert((length + additional) * @sizeOf(T) <= pinned_array_max_size);
const new_granularity_aligned_size = align_forward(new_size, array.granularity);
const ptr: [*]u8 = @ptrCast(array.pointer);
commit(ptr + ((length + 1) * @sizeOf(T)), array.granularity) catch unreachable;
commit(ptr + granularity_aligned_size, new_granularity_aligned_size - granularity_aligned_size) catch unreachable;
}
}
pub fn append(array: *Array, item: T) *T {
array.ensure_capacity(1);
return array.append_with_capacity(item);
}
pub fn append_slice(array: *Array, items: []const T) void {
const count: u32 = @intCast(items.len);
if (((array.length + count) * @sizeOf(T)) & (array.granularity - 1) == 0) {
const length: u64 = array.length;
assert((length + count) * @sizeOf(T) <= pinned_array_max_size);
const ptr: [*]u8 = @ptrCast(array.pointer);
commit(ptr + ((length + count) * @sizeOf(T)), array.granularity) catch unreachable;
}
array.ensure_capacity(@intCast(items.len));
array.append_slice_with_capacity(items);
}
@ -218,7 +221,7 @@ pub fn PinnedArray(comptime T: type) type {
};
}
pub fn reserve(size: u64) ![*]u8{
pub fn reserve(size: u64) ![*]u8 {
return switch (os) {
.linux, .macos => (try std.posix.mmap(null, size, std.posix.PROT.NONE, .{
.ANONYMOUS = true,
@ -229,7 +232,7 @@ pub fn reserve(size: u64) ![*]u8{
};
}
pub fn commit(bytes: [*]u8, size: u64) !void{
pub fn commit(bytes: [*]u8, size: u64) !void {
const slice = bytes[0..size];
return switch (os) {
.linux, .macos => try std.posix.mprotect(@alignCast(slice), std.posix.PROT.WRITE | std.posix.PROT.READ),
@ -445,41 +448,37 @@ const MapResult = struct {
capacity: IndexType,
};
fn ensure_capacity_hashmap(allocator: *MyAllocator, current_capacity: IndexType, desired_capacity: IndexType, key_pointer: [*]u8, value_pointer: [*]u8, length: IndexType, key_size: IndexType, key_alignment: u16, value_size: IndexType, value_alignment: u16) !MapResult {
var new_capacity = @max(current_capacity, initial_item_count);
while (new_capacity < desired_capacity) {
new_capacity *= factor;
}
const pinned_hash_map_page_size = 2 * 1024 * 1024;
const pinned_hash_map_max_size = std.math.maxInt(u32) - pinned_hash_map_page_size;
const pinned_hash_map_default_granularity = pinned_hash_map_page_size;
if (new_capacity > current_capacity) {
const old_key_slice = key_pointer[0 .. length * key_size];
const old_value_slice = value_pointer[0 .. length * value_size];
const new_key_slice = try allocator.reallocate(old_key_slice, new_capacity * key_size, key_alignment);
const new_value_slice = try allocator.reallocate(old_value_slice, new_capacity * value_size, value_alignment);
return .{
.key_pointer = new_key_slice.ptr,
.value_pointer = new_value_slice.ptr,
.capacity = new_capacity,
};
} else {
return .{
.capacity = current_capacity,
.key_pointer = key_pointer,
.value_pointer = value_pointer,
};
}
}
pub fn MyHashMap(comptime K: type, comptime V: type) type {
// const K = []const u8;
pub fn PinnedHashMap(comptime K: type, comptime V: type) type {
return struct {
key_pointer: [*]K = undefined,
value_pointer: [*]V = undefined,
length: IndexType = 0,
capacity: IndexType = 0,
key_pointer: [*]K,
value_pointer: [*]V,
length: u32,
granularity: u32,
committed: u32,
pub fn get_pointer(map: *@This(), key: K) ?*V {
const Map = @This();
pub fn init(granularity: u32) !Map {
assert(granularity & 0xfff == 0);
const key_raw_pointer = try reserve(pinned_hash_map_max_size);
try commit(key_raw_pointer, granularity);
const value_raw_pointer = try reserve(pinned_hash_map_max_size);
try commit(value_raw_pointer, granularity);
return Map{
.key_pointer = @alignCast(@ptrCast(key_raw_pointer)),
.value_pointer = @alignCast(@ptrCast(value_raw_pointer)),
.length = 0,
.granularity = granularity,
.committed = 1,
};
}
pub fn get_pointer(map: *Map, key: K) ?*V {
for (map.keys(), 0..) |k, i| {
const is_equal = switch (@typeInfo(K)) {
.Pointer => |pointer| switch (pointer.size) {
@ -506,20 +505,20 @@ pub fn MyHashMap(comptime K: type, comptime V: type) type {
}
}
pub fn put(map: *@This(), allocator: *MyAllocator, key: K, value: V) !void {
if (map.get_pointer(key)) |value_ptr| {
value_ptr.* = value;
pub fn put(map: *@This(), key: K, value: V) !void {
if (map.get_pointer(key)) |value_pointer| {
value_pointer.* = value;
} else {
const len = map.length;
try map.ensure_capacity(allocator, len + 1);
map.ensure_capacity(len + 1);
map.put_at_with_capacity(len, key, value);
}
}
pub fn put_no_clobber(map: *@This(), allocator: *MyAllocator, key: K, value: V) !void {
pub fn put_no_clobber(map: *@This(), key: K, value: V) !void {
assert(map.get_pointer(key) == null);
const len = map.length;
try map.ensure_capacity(allocator, len + 1);
map.ensure_capacity(len + 1);
map.put_at_with_capacity(len, key, value);
}
@ -530,11 +529,33 @@ pub fn MyHashMap(comptime K: type, comptime V: type) type {
map.value_pointer[index] = value;
}
pub fn ensure_capacity(map: *@This(), allocator: *MyAllocator, desired_capacity: IndexType) !void {
const result = try ensure_capacity_hashmap(allocator, map.capacity, desired_capacity, @ptrCast(map.key_pointer), @ptrCast(map.value_pointer), map.length, @sizeOf(K), @alignOf(K), @sizeOf(V), @alignOf(V));
map.capacity = result.capacity;
map.key_pointer = @ptrCast(@alignCast(result.key_pointer));
map.value_pointer = @ptrCast(@alignCast(result.value_pointer));
fn ensure_capacity(map: *Map, additional: u32) void {
const length = map.length;
assert((length + additional) * @sizeOf(K) <= pinned_array_max_size);
{
const key_size = length * @sizeOf(K);
const key_granularity_aligned_size = align_forward(key_size, map.granularity);
const key_new_size = key_size + additional * @sizeOf(K);
if (key_granularity_aligned_size < key_new_size) {
const new_key_granularity_aligned_size = align_forward(key_new_size, map.granularity);
const key_pointer: [*]u8 = @ptrCast(map.key_pointer);
commit(key_pointer + key_granularity_aligned_size, new_key_granularity_aligned_size - key_granularity_aligned_size) catch unreachable;
}
}
{
const value_size = length * @sizeOf(V);
const value_granularity_aligned_size = align_forward(value_size, map.granularity);
const value_new_size = value_size + additional * @sizeOf(K);
if (value_granularity_aligned_size < value_new_size) {
const new_value_granularity_aligned_size = align_forward(value_new_size, map.granularity);
const value_pointer: [*]u8 = @ptrCast(map.value_pointer);
commit(value_pointer + value_granularity_aligned_size, new_value_granularity_aligned_size - value_granularity_aligned_size) catch unreachable;
}
}
}
pub fn keys(map: *@This()) []K {
@ -544,6 +565,10 @@ pub fn MyHashMap(comptime K: type, comptime V: type) type {
pub fn values(map: *@This()) []V {
return map.value_pointer[0..map.length];
}
pub fn clear(map: *Map) void {
map.length = 0;
}
};
}