Change memory layout of map to be 3 words smaller

This commit is contained in:
gingerBill
2018-08-30 19:14:10 +01:00
parent e0240c186f
commit aa542980ce
12 changed files with 114 additions and 44 deletions
+15 -2
View File
@@ -217,11 +217,22 @@ Ast *remove_type_alias_clutter(Ast *node) {
}
}
isize total_attribute_count(DeclInfo *decl) {
isize attribute_count = 0;
for_array(i, decl->attributes) {
Ast *attr = decl->attributes[i];
if (attr->kind != Ast_Attribute) continue;
attribute_count += attr->Attribute.elems.count;
}
return attribute_count;
}
void check_type_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Type *def) {
GB_ASSERT(e->type == nullptr);
DeclInfo *decl = decl_info_of_entity(e);
if (decl != nullptr && decl->attributes.count > 0) {
if (decl != nullptr && total_attribute_count(decl) > 0) {
error(decl->attributes[0], "Attributes are not allowed on type declarations");
}
@@ -290,6 +301,8 @@ void override_entity_in_scope(Entity *original_entity, Entity *new_entity) {
map_set(&found_scope->elements, hash_string(original_name), new_entity);
}
void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init, Type *named_type) {
GB_ASSERT(e->type == nullptr);
GB_ASSERT(e->kind == Entity_Constant);
@@ -380,7 +393,7 @@ void check_const_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, Ast *init,
DeclInfo *decl = decl_info_of_entity(e);
if (decl != nullptr && decl->attributes.count > 0) {
if (decl != nullptr && total_attribute_count(decl) > 0) {
error(decl->attributes[0], "Attributes are not allowed on constant value declarations");
}
}
+10 -6
View File
@@ -1008,10 +1008,14 @@ Type *determine_type_from_polymorphic(CheckerContext *ctx, Type *poly_type, Oper
return t_invalid;
}
bool is_expr_from_another_parameter(CheckerContext *ctx, Ast *expr) {
bool is_expr_from_a_parameter(CheckerContext *ctx, Ast *expr) {
if (expr == nullptr) {
return false;
}
expr = unparen_expr(expr);
if (expr->kind == Ast_SelectorExpr) {
Ast *lhs = expr->SelectorExpr.expr;
return is_expr_from_another_parameter(ctx, lhs);
return is_expr_from_a_parameter(ctx, lhs);
} else if (expr->kind == Ast_Ident) {
Operand x= {};
Entity *e = check_ident(ctx, &x, expr, nullptr, nullptr, false);
@@ -1025,7 +1029,6 @@ bool is_expr_from_another_parameter(CheckerContext *ctx, Ast *expr) {
ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type **out_type_, Ast *expr, bool allow_caller_location) {
ParameterValue param_value = {};
// gb_printf_err("HERE\n");
if (expr == nullptr) {
return param_value;
}
@@ -1071,7 +1074,7 @@ ParameterValue handle_parameter_value(CheckerContext *ctx, Type *in_type, Type *
if (e->flags & EntityFlag_Param) {
error(expr, "Default parameter cannot be another parameter");
} else {
if (is_expr_from_another_parameter(ctx, expr)) {
if (is_expr_from_a_parameter(ctx, expr)) {
error(expr, "Default parameter cannot be another parameter");
} else {
param_value.kind = ParameterValue_Value;
@@ -1689,6 +1692,7 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
CheckerContext *c = &c_;
c->curr_proc_sig = type;
c->in_proc_sig = true;
bool variadic = false;
isize variadic_index = -1;
@@ -1898,7 +1902,7 @@ void init_map_internal_types(Type *type) {
/*
struct {
hashes: [dynamic]int;
hashes: []int;
entries: [dynamic]EntryType;
}
*/
@@ -1906,7 +1910,7 @@ void init_map_internal_types(Type *type) {
Ast *dummy_node = alloc_ast_node(nullptr, Ast_Invalid);
Scope *s = create_scope(builtin_scope, a);
Type *hashes_type = alloc_type_dynamic_array(t_int);
Type *hashes_type = alloc_type_slice(t_int);
Type *entries_type = alloc_type_dynamic_array(type->Map.entry_type);
+8 -5
View File
@@ -905,11 +905,14 @@ void add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, Dec
if (e->scope != nullptr) {
Scope *scope = e->scope;
if ((scope->flags&ScopeFlag_File) && is_entity_kind_exported(e->kind)) {
AstPackage *pkg = scope->file->pkg;
GB_ASSERT(pkg->scope == scope->parent);
GB_ASSERT(c->pkg == pkg);
scope = pkg->scope;
if (scope->flags & ScopeFlag_File) {
if (is_entity_kind_exported(e->kind)) {
AstPackage *pkg = scope->file->pkg;
GB_ASSERT(pkg->scope == scope->parent);
GB_ASSERT(c->pkg == pkg);
scope = pkg->scope;
}
}
add_entity(c->checker, scope, identifier, e);
}
+1
View File
@@ -301,6 +301,7 @@ struct CheckerContext {
String proc_name;
DeclInfo * curr_proc_decl;
Type * curr_proc_sig;
bool in_proc_sig;
ForeignContext foreign_context;
gbAllocator allocator;
+5
View File
@@ -45,6 +45,7 @@ enum EntityFlag {
EntityFlag_Sret = 1<<11,
EntityFlag_BitFieldValue = 1<<12,
EntityFlag_PolyConst = 1<<13,
EntityFlag_NotExported = 1<<14,
EntityFlag_CVarArg = 1<<20,
EntityFlag_AutoCast = 1<<21,
@@ -172,6 +173,10 @@ bool is_entity_exported(Entity *e) {
return false;
}
if (e->flags & EntityFlag_NotExported) {
return false;
}
String name = e->token.string;
if (name.len == 0) {
return false;
+15 -19
View File
@@ -2768,6 +2768,7 @@ irValue *ir_emit_array_epi(irProcedure *proc, irValue *s, i32 index) {
irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
gbAllocator a = ir_allocator();
GB_ASSERT(is_type_pointer(ir_type(s)));
Type *t = base_type(type_deref(ir_type(s)));
Type *result_type = nullptr;
@@ -2808,18 +2809,18 @@ irValue *ir_emit_struct_ep(irProcedure *proc, irValue *s, i32 index) {
case 2: result_type = t_int_ptr; break;
case 3: result_type = t_allocator_ptr; break;
}
} /* else if (is_type_map(t)) {
} else if (is_type_map(t)) {
init_map_internal_types(t);
Type *itp = alloc_type_pointer(t->Map.internal_type);
s = ir_emit_load(proc, ir_emit_transmute(proc, s, itp));
s = ir_emit_transmute(proc, s, itp);
Type *gst = t->Map.generated_struct_type;
Type *gst = t->Map.internal_type;
GB_ASSERT(gst->kind == Type_Struct);
switch (index) {
case 0: result_type = alloc_type_pointer(gst->Struct.fields[0]->type); break;
case 1: result_type = alloc_type_pointer(gst->Struct.fields[1]->type); break;
}
} */else {
} else {
GB_PANIC("TODO(bill): struct_gep type: %s, %d", type_to_string(ir_type(s)), index);
}
@@ -2887,15 +2888,15 @@ irValue *ir_emit_struct_ev(irProcedure *proc, irValue *s, i32 index) {
}
break;
// case Type_Map: {
// init_map_internal_types(t);
// Type *gst = t->Map.generated_struct_type;
// switch (index) {
// case 0: result_type = gst->Struct.fields[0]->type; break;
// case 1: result_type = gst->Struct.fields[1]->type; break;
// }
// break;
// }
case Type_Map: {
init_map_internal_types(t);
Type *gst = t->Map.generated_struct_type;
switch (index) {
case 0: result_type = gst->Struct.fields[0]->type; break;
case 1: result_type = gst->Struct.fields[1]->type; break;
}
break;
}
default:
GB_PANIC("TODO(bill): struct_ev type: %s, %d", type_to_string(ir_type(s)), index);
@@ -2962,12 +2963,7 @@ irValue *ir_emit_deep_field_gep(irProcedure *proc, irValue *e, Selection sel) {
} else if (type->kind == Type_Array) {
e = ir_emit_array_epi(proc, e, index);
} else if (type->kind == Type_Map) {
e = ir_emit_struct_ep(proc, e, 1);
switch (index) {
case 0: e = ir_emit_struct_ep(proc, e, 1); break; // count
case 1: e = ir_emit_struct_ep(proc, e, 2); break; // capacity
case 2: e = ir_emit_struct_ep(proc, e, 3); break; // allocator
}
e = ir_emit_struct_ep(proc, e, index);
} else {
GB_PANIC("un-gep-able type %s", type_to_string(type));
}
+1 -1
View File
@@ -458,7 +458,7 @@ void ir_print_type(irFileBuffer *f, irModule *m, Type *t, bool in_struct) {
ir_print_encoded_local(f, name);
} else {
// TODO(bill): Is this correct behaviour?!
GB_ASSERT_MSG(name.len > 0, "%.*s %p", LIT(t->Named.name), e);
// GB_ASSERT_MSG(name.len > 0, "%.*s %p", LIT(t->Named.name), e);
// gb_printf_err("%.*s %p\n", LIT(t->Named.name), t->Named.type_name);
ir_print_type(f, m, bt);
}
+14 -1
View File
@@ -1839,13 +1839,26 @@ Selection lookup_field_with_selection(Type *type_, String field_name, bool is_ty
// `Raw_Dynamic_Array` type?
GB_ASSERT(t_allocator != nullptr);
String allocator_str = str_lit("allocator");
gb_local_persist Entity *entity__allocator = alloc_entity_field(nullptr, make_token_ident(allocator_str), t_allocator, false, 0);
gb_local_persist Entity *entity__allocator = alloc_entity_field(nullptr, make_token_ident(allocator_str), t_allocator, false, 3);
if (field_name == allocator_str) {
selection_add_index(&sel, 3);
sel.entity = entity__allocator;
return sel;
}
} else if (type->kind == Type_Map) {
// IMPORTANT TODO(bill): Should these members be available to should I only allow them with
// `Raw_Map` type?
GB_ASSERT(t_allocator != nullptr);
String allocator_str = str_lit("allocator");
gb_local_persist Entity *entity__allocator = alloc_entity_field(nullptr, make_token_ident(allocator_str), t_allocator, false, 3);
if (field_name == allocator_str) {
selection_add_index(&sel, 1);
selection_add_index(&sel, 3);
sel.entity = entity__allocator;
return sel;
}
}
return sel;