mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Removing unused hash table functions. Removal of macro DECL_NEW. Smaller initial vector size. Remove unnecessary memclear.
This commit is contained in:
@@ -28,6 +28,7 @@ set(CMAKE_CXX_STANDARD 17)
|
||||
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -O3")
|
||||
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -gdwarf-3")
|
||||
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
AllTargetsAsmParsers
|
||||
|
||||
@@ -5,20 +5,22 @@
|
||||
#include "compiler_internal.h"
|
||||
|
||||
|
||||
Decl *decl_new_ct(DeclKind kind, TokenId span)
|
||||
{
|
||||
Decl *decl = decl_calloc();
|
||||
decl->decl_kind = kind;
|
||||
decl->span = source_span_from_token_id(span);
|
||||
return decl;
|
||||
}
|
||||
|
||||
Decl *decl_new(DeclKind decl_kind, TokenId name, Visibility visibility)
|
||||
{
|
||||
Decl *decl = decl_calloc();
|
||||
decl->decl_kind = decl_kind;
|
||||
decl->name_token = name;
|
||||
decl->span = source_span_from_token_id(name);
|
||||
if (name.index)
|
||||
{
|
||||
assert(name.index);
|
||||
decl->name = TOKSTR(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
decl->name = NULL;
|
||||
}
|
||||
decl->visibility = visibility;
|
||||
return decl;
|
||||
}
|
||||
@@ -131,7 +133,19 @@ void decl_set_external_name(Decl *decl)
|
||||
|
||||
Decl *decl_new_with_type(TokenId name, DeclKind decl_type, Visibility visibility)
|
||||
{
|
||||
Decl *decl = decl_new(decl_type, name, visibility);
|
||||
Decl *decl = decl_calloc();
|
||||
decl->decl_kind = decl_type;
|
||||
if (name.index)
|
||||
{
|
||||
decl->name_token = name;
|
||||
decl->name = TOKSTR(name);
|
||||
decl->span = source_span_from_token_id(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
decl->name = NULL;
|
||||
}
|
||||
decl->visibility = visibility;
|
||||
TypeKind kind = TYPE_POISONED;
|
||||
switch (decl_type)
|
||||
{
|
||||
@@ -371,7 +385,6 @@ Expr *expr_new(ExprKind kind, SourceSpan start)
|
||||
Expr *expr = expr_calloc();
|
||||
expr->expr_kind = kind;
|
||||
expr->span = start;
|
||||
expr->type = NULL;
|
||||
return expr;
|
||||
}
|
||||
|
||||
|
||||
@@ -374,7 +374,7 @@ void compiler_compile(void)
|
||||
|
||||
if (active_target.check_only) return;
|
||||
|
||||
void **gen_contexts = NULL;
|
||||
void **gen_contexts = VECNEW(void*, module_count);
|
||||
void (*task)(void *);
|
||||
|
||||
switch (active_target.backend)
|
||||
|
||||
@@ -200,6 +200,7 @@ typedef struct
|
||||
{
|
||||
uint32_t count;
|
||||
uint32_t capacity;
|
||||
uint32_t max_load;
|
||||
SEntry *entries;
|
||||
} STable;
|
||||
|
||||
@@ -1793,12 +1794,10 @@ bool context_set_module(Context *context, Path *path, TokenId *generic_parameter
|
||||
// --- Decl functions
|
||||
|
||||
Decl *decl_new(DeclKind decl_kind, TokenId name, Visibility visibility);
|
||||
Decl *decl_new_ct(DeclKind kind, TokenId span);
|
||||
Decl *decl_new_with_type(TokenId name, DeclKind decl_type, Visibility visibility);
|
||||
Decl *decl_new_var(TokenId name, TypeInfo *type, VarDeclKind kind, Visibility visibility);
|
||||
Decl *decl_new_generated_var(const char *name, Type *type, VarDeclKind kind, SourceSpan span);
|
||||
#define DECL_NEW(_kind, _vis) decl_new(_kind, context->lex.tok.id, _vis)
|
||||
#define DECL_NEW_WITH_TYPE(_kind, _vis) decl_new_with_type(context->lex.tok.id, _kind, _vis)
|
||||
#define DECL_NEW_VAR(_type, _kind, _vis) decl_new_var(context->lex.tok.id, _type, _kind, _vis)
|
||||
void decl_set_external_name(Decl *decl);
|
||||
const char *decl_to_name(Decl *decl);
|
||||
|
||||
@@ -1994,7 +1993,7 @@ static inline SourceSpan source_span_from_token_id(TokenId id)
|
||||
void stable_init(STable *table, uint32_t initial_size);
|
||||
void *stable_set(STable *table, const char *key, void *value);
|
||||
void *stable_get(STable *table, const char *key);
|
||||
void *stable_delete(STable *table, const char *key);
|
||||
|
||||
void stable_clear(STable *table);
|
||||
|
||||
void scratch_buffer_clear(void);
|
||||
|
||||
@@ -9,8 +9,8 @@ Context *context_create(File *file)
|
||||
{
|
||||
Context *context = CALLOCS(Context);
|
||||
context->file = file;
|
||||
stable_init(&context->local_symbols, 256);
|
||||
stable_init(&context->external_symbols, 256);
|
||||
stable_init(&context->local_symbols, 1024);
|
||||
stable_init(&context->external_symbols, 1024);
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -134,13 +134,13 @@ void context_register_external_symbol(Context *context, Decl *decl)
|
||||
|
||||
void context_register_global_decl(Context *context, Decl *decl)
|
||||
{
|
||||
assert(decl->name);
|
||||
decl->module = context->module;
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
case DECL_POISONED:
|
||||
break;
|
||||
case DECL_GENERIC:
|
||||
assert(decl->name);
|
||||
if (decl->macro_decl.type_parent)
|
||||
{
|
||||
vec_add(context->generic_methods, decl);
|
||||
@@ -153,6 +153,7 @@ void context_register_global_decl(Context *context, Decl *decl)
|
||||
decl_set_external_name(decl);
|
||||
break;
|
||||
case DECL_MACRO:
|
||||
assert(decl->name);
|
||||
if (decl->macro_decl.type_parent)
|
||||
{
|
||||
vec_add(context->macro_methods, decl);
|
||||
@@ -165,6 +166,7 @@ void context_register_global_decl(Context *context, Decl *decl)
|
||||
decl_set_external_name(decl);
|
||||
break;
|
||||
case DECL_FUNC:
|
||||
assert(decl->name);
|
||||
if (decl->func_decl.type_parent)
|
||||
{
|
||||
vec_add(context->methods, decl);
|
||||
@@ -176,6 +178,7 @@ void context_register_global_decl(Context *context, Decl *decl)
|
||||
}
|
||||
break;
|
||||
case DECL_VAR:
|
||||
assert(decl->name);
|
||||
vec_add(context->vars, decl);
|
||||
decl_set_external_name(decl);
|
||||
break;
|
||||
@@ -185,14 +188,17 @@ void context_register_global_decl(Context *context, Decl *decl)
|
||||
case DECL_TYPEDEF:
|
||||
case DECL_ERRTYPE:
|
||||
case DECL_BITSTRUCT:
|
||||
assert(decl->name);
|
||||
vec_add(context->types, decl);
|
||||
decl_set_external_name(decl);
|
||||
break;
|
||||
case DECL_DEFINE:
|
||||
assert(decl->name);
|
||||
vec_add(context->generic_defines, decl);
|
||||
decl_set_external_name(decl);
|
||||
break;
|
||||
case DECL_ENUM:
|
||||
assert(decl->name);
|
||||
vec_add(context->enums, decl);
|
||||
decl_set_external_name(decl);
|
||||
break;
|
||||
|
||||
@@ -40,7 +40,7 @@ static DesignatorElement **macro_copy_designator_list(DesignatorElement **list)
|
||||
DesignatorElement **result = NULL;
|
||||
VECEACH(list, i)
|
||||
{
|
||||
DesignatorElement *element = MALLOC(sizeof(DesignatorElement));
|
||||
DesignatorElement *element = MALLOCS(DesignatorElement);
|
||||
DesignatorElement *to_copy = list[i];
|
||||
*element = *to_copy;
|
||||
switch (to_copy->kind)
|
||||
@@ -456,7 +456,7 @@ static Attr **copy_attributes(Attr** attr_list)
|
||||
VECEACH(attr_list, i)
|
||||
{
|
||||
Attr *attribute = attr_list[i];
|
||||
Attr *copy = MALLOC(sizeof(Attr));
|
||||
Attr *copy = MALLOCS(Attr);
|
||||
*copy = *attribute;
|
||||
MACRO_COPY_EXPR(copy->expr);
|
||||
vec_add(list, copy);
|
||||
|
||||
@@ -127,9 +127,9 @@ static inline void add_generic_token(Lexer *lexer, TokenType type)
|
||||
// what amounts to a huge array.
|
||||
// Consequently these allocs are actually simultaneously
|
||||
// allocating data and putting that data in an array.
|
||||
SourceLocation *location = sourceloc_alloc();
|
||||
unsigned char *token_type = (unsigned char *)toktype_alloc();
|
||||
TokenData *data = tokdata_alloc();
|
||||
SourceLocation *location = sourceloc_calloc();
|
||||
unsigned char *token_type = (unsigned char *)toktype_calloc();
|
||||
TokenData *data = tokdata_calloc();
|
||||
token_type[0] = (unsigned char)type;
|
||||
|
||||
// Set the location.
|
||||
@@ -345,14 +345,16 @@ static inline bool scan_ident(Lexer *lexer, TokenType normal, TokenType const_to
|
||||
{
|
||||
hash = FNV1a(prefix, hash);
|
||||
}
|
||||
while (peek(lexer) == '_')
|
||||
char c;
|
||||
while ((c = peek(lexer)) == '_')
|
||||
{
|
||||
hash = FNV1a(peek(lexer), hash);
|
||||
hash = FNV1a(c, hash);
|
||||
next(lexer);
|
||||
}
|
||||
while (1)
|
||||
{
|
||||
switch (peek(lexer))
|
||||
c = peek(lexer);
|
||||
switch (c)
|
||||
{
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e':
|
||||
case 'f': case 'g': case 'h': case 'i': case 'j':
|
||||
@@ -385,7 +387,7 @@ static inline bool scan_ident(Lexer *lexer, TokenType normal, TokenType const_to
|
||||
default:
|
||||
goto EXIT;
|
||||
}
|
||||
hash = FNV1a(peek(lexer), hash);
|
||||
hash = FNV1a(c, hash);
|
||||
next(lexer);
|
||||
}
|
||||
// Allow bang!
|
||||
|
||||
@@ -137,8 +137,8 @@ static inline bool parse_top_level_block(Context *context, Decl ***decls, TokenT
|
||||
*/
|
||||
static inline Decl *parse_ct_if_top_level(Context *context)
|
||||
{
|
||||
Decl *ct = DECL_NEW(DECL_CT_IF, VISIBLE_LOCAL);
|
||||
advance_and_verify(context, TOKEN_CT_IF);
|
||||
Decl *ct = decl_new_ct(DECL_CT_IF, context->lex.prev_tok);
|
||||
ASSIGN_EXPR_ELSE(ct->ct_if_decl.expr, parse_const_paren_expr(context), poisoned_decl);
|
||||
|
||||
if (!parse_top_level_block(context, &ct->ct_if_decl.then, TOKEN_CT_ENDIF, TOKEN_CT_ELIF, TOKEN_CT_ELSE)) return poisoned_decl;
|
||||
@@ -147,7 +147,7 @@ static inline Decl *parse_ct_if_top_level(Context *context)
|
||||
while (TOKEN_IS(TOKEN_CT_ELIF))
|
||||
{
|
||||
advance_and_verify(context, TOKEN_CT_ELIF);
|
||||
Decl *ct_elif = DECL_NEW(DECL_CT_ELIF, VISIBLE_LOCAL);
|
||||
Decl *ct_elif = decl_new_ct(DECL_CT_ELIF, context->lex.prev_tok);
|
||||
ASSIGN_EXPR_ELSE(ct_elif->ct_elif_decl.expr, parse_const_paren_expr(context), poisoned_decl);
|
||||
|
||||
if (!parse_top_level_block(context, &ct_elif->ct_elif_decl.then, TOKEN_CT_ENDIF, TOKEN_CT_ELIF, TOKEN_CT_ELSE)) return poisoned_decl;
|
||||
@@ -157,7 +157,7 @@ static inline Decl *parse_ct_if_top_level(Context *context)
|
||||
if (TOKEN_IS(TOKEN_CT_ELSE))
|
||||
{
|
||||
advance_and_verify(context, TOKEN_CT_ELSE);
|
||||
Decl *ct_else = DECL_NEW(DECL_CT_ELSE, VISIBLE_LOCAL);
|
||||
Decl *ct_else = decl_new_ct(DECL_CT_ELSE, context->lex.prev_tok);
|
||||
ct_if_decl->elif = ct_else;
|
||||
if (!parse_top_level_block(context, &ct_else->ct_else_decl, TOKEN_CT_ENDIF, TOKEN_CT_ENDIF, TOKEN_CT_ENDIF)) return poisoned_decl;
|
||||
}
|
||||
@@ -179,10 +179,10 @@ static inline Decl *parse_ct_case(Context *context)
|
||||
{
|
||||
case TOKEN_CT_DEFAULT:
|
||||
advance(context);
|
||||
decl = DECL_NEW(DECL_CT_CASE, VISIBLE_LOCAL);
|
||||
decl = decl_new_ct(DECL_CT_CASE, context->lex.tok.id);
|
||||
break;
|
||||
case TOKEN_CT_CASE:
|
||||
decl = DECL_NEW(DECL_CT_CASE, VISIBLE_LOCAL);
|
||||
decl = decl_new_ct(DECL_CT_CASE, context->lex.tok.id);
|
||||
advance(context);
|
||||
ASSIGN_TYPE_ELSE(decl->ct_case_decl.type, parse_type(context), poisoned_decl);
|
||||
break;
|
||||
@@ -208,8 +208,8 @@ static inline Decl *parse_ct_case(Context *context)
|
||||
*/
|
||||
static inline Decl *parse_ct_switch_top_level(Context *context)
|
||||
{
|
||||
Decl *ct = DECL_NEW(DECL_CT_SWITCH, VISIBLE_LOCAL);
|
||||
advance_and_verify(context, TOKEN_CT_SWITCH);
|
||||
Decl *ct = decl_new_ct(DECL_CT_SWITCH, context->lex.prev_tok);
|
||||
ASSIGN_EXPR_ELSE(ct->ct_switch_decl.expr, parse_const_paren_expr(context), poisoned_decl);
|
||||
|
||||
CONSUME_OR(TOKEN_LBRACE, poisoned_decl);
|
||||
@@ -801,21 +801,25 @@ static Decl *parse_const_declaration(Context *context, Visibility visibility)
|
||||
{
|
||||
advance_and_verify(context, TOKEN_CONST);
|
||||
|
||||
Decl *decl = DECL_NEW_VAR(NULL, VARDECL_CONST, visibility);
|
||||
decl->span.loc = context->lex.prev_tok;
|
||||
SourceSpan span = { .loc = context->lex.prev_tok, .end_loc = context->lex.tok.id };
|
||||
|
||||
TypeInfo *type_info = NULL;
|
||||
|
||||
if (parse_next_is_decl(context))
|
||||
{
|
||||
ASSIGN_TYPE_ELSE(decl->var.type_info, parse_type(context), poisoned_decl);
|
||||
ASSIGN_TYPE_ELSE(type_info, parse_type(context), poisoned_decl);
|
||||
}
|
||||
decl->name = TOKSTR(context->lex.tok);
|
||||
decl->name_token = context->lex.tok.id;
|
||||
|
||||
if (!consume_const_name(context, "const")) return poisoned_decl;
|
||||
|
||||
Decl *decl = decl_new_var(context->lex.prev_tok, type_info, VARDECL_CONST, visibility);
|
||||
|
||||
CONSUME_OR(TOKEN_EQ, poisoned_decl);
|
||||
|
||||
ASSIGN_EXPR_ELSE(decl->var.init_expr, parse_initializer(context), poisoned_decl);
|
||||
|
||||
RANGE_EXTEND_PREV(decl);
|
||||
|
||||
return decl;
|
||||
}
|
||||
|
||||
@@ -1814,8 +1818,8 @@ static inline Decl *parse_error_declaration(Context *context, Visibility visibil
|
||||
decl->enums.type_info = type_info_new_base(type_iptr->canonical, decl->span);
|
||||
while (!try_consume(context, TOKEN_RBRACE))
|
||||
{
|
||||
Decl *enum_const = DECL_NEW(DECL_ERRVALUE, decl->visibility);
|
||||
const char *name = TOKSTR(context->lex.tok);
|
||||
Decl *enum_const = decl_new(DECL_ERRVALUE, context->lex.tok.id, decl->visibility);
|
||||
const char *name = enum_const->name;
|
||||
VECEACH(decl->enums.values, i)
|
||||
{
|
||||
Decl *other_constant = decl->enums.values[i];
|
||||
@@ -1906,10 +1910,11 @@ static inline Decl *parse_enum_declaration(Context *context, Visibility visibili
|
||||
{
|
||||
advance_and_verify(context, TOKEN_ENUM);
|
||||
|
||||
Decl *decl = DECL_NEW_WITH_TYPE(DECL_ENUM, visibility);
|
||||
|
||||
if (!consume_type_name(context, "enum")) return poisoned_decl;
|
||||
|
||||
Decl *decl = decl_new_with_type(context->lex.prev_tok, DECL_ENUM, visibility);
|
||||
|
||||
|
||||
TypeInfo *type = NULL;
|
||||
if (try_consume(context, TOKEN_COLON))
|
||||
{
|
||||
@@ -1921,8 +1926,8 @@ static inline Decl *parse_enum_declaration(Context *context, Visibility visibili
|
||||
decl->enums.type_info = type ? type : type_info_new_base(type_int, decl->span);
|
||||
while (!try_consume(context, TOKEN_RBRACE))
|
||||
{
|
||||
Decl *enum_const = DECL_NEW(DECL_ENUM_CONSTANT, decl->visibility);
|
||||
const char *name = TOKSTR(context->lex.tok);
|
||||
Decl *enum_const = decl_new(DECL_ENUM_CONSTANT, context->lex.tok.id, decl->visibility);
|
||||
const char *name = enum_const->name;
|
||||
VECEACH(decl->enums.values, i)
|
||||
{
|
||||
Decl *other_constant = decl->enums.values[i];
|
||||
@@ -2274,7 +2279,7 @@ Decl *parse_top_level_statement(Context *context)
|
||||
if (!check_no_visibility_before(context, visibility)) return poisoned_decl;
|
||||
{
|
||||
ASSIGN_AST_ELSE(Ast *ast, parse_ct_assert_stmt(context), poisoned_decl);
|
||||
decl = decl_new(DECL_CT_ASSERT, ast->span.loc, visibility);
|
||||
decl = decl_new_ct(DECL_CT_ASSERT, ast->span.loc);
|
||||
decl->ct_assert_decl = ast;
|
||||
if (docs)
|
||||
{
|
||||
|
||||
@@ -115,8 +115,7 @@ void expr_insert_addr(Expr *original)
|
||||
*original = *original->unary_expr.expr;
|
||||
return;
|
||||
}
|
||||
Expr *inner = expr_alloc();
|
||||
*inner = *original;
|
||||
Expr *inner = expr_copy(original);
|
||||
original->expr_kind = EXPR_UNARY;
|
||||
original->type = type_get_ptr(inner->type);
|
||||
original->unary_expr.operator = UNARYOP_ADDR;
|
||||
@@ -1324,6 +1323,7 @@ static inline bool sema_expand_call_arguments(Context *context, CalledDecl *call
|
||||
call->call_expr.arguments = actual_args;
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline bool sema_expr_analyse_call_invocation(Context *context, Expr *call, CalledDecl callee, bool *failable)
|
||||
{
|
||||
// 1. Check body arguments.
|
||||
@@ -3337,7 +3337,7 @@ static inline void sema_update_const_initializer_with_designator_struct(ConstIni
|
||||
VECEACH(elements, i)
|
||||
{
|
||||
// Create zero initializers for each of those { a: zeroinit, b: zeroinit, ... }
|
||||
ConstInitializer *element_init = MALLOC(sizeof(ConstInitializer));
|
||||
ConstInitializer *element_init = MALLOCS(ConstInitializer);
|
||||
element_init->type = type_flatten(elements[i]->type);
|
||||
element_init->kind = CONST_INIT_ZERO;
|
||||
const_inits[i] = element_init;
|
||||
@@ -3474,11 +3474,11 @@ static inline void sema_update_const_initializer_with_designator_array(ConstInit
|
||||
// Create and append:
|
||||
if (!initializer)
|
||||
{
|
||||
initializer = MALLOC(sizeof(ConstInitializer));
|
||||
initializer = MALLOCS(ConstInitializer);
|
||||
initializer->type = element_type;
|
||||
initializer->kind = CONST_INIT_ARRAY_VALUE;
|
||||
initializer->init_array_value.index = index;
|
||||
inner_value = MALLOC(sizeof(ConstInitializer));
|
||||
inner_value = MALLOCS(ConstInitializer);
|
||||
inner_value->type = element_type;
|
||||
inner_value->kind = CONST_INIT_ZERO;
|
||||
initializer->init_array_value.element = inner_value;
|
||||
@@ -3502,11 +3502,11 @@ static inline void sema_update_const_initializer_with_designator_array(ConstInit
|
||||
array_elements[i] = array_elements[i - 1];
|
||||
}
|
||||
// Then we create our new entry.
|
||||
initializer = MALLOC(sizeof(ConstInitializer));
|
||||
initializer = MALLOCS(ConstInitializer);
|
||||
initializer->type = element_type;
|
||||
initializer->kind = CONST_INIT_ARRAY_VALUE;
|
||||
initializer->init_array_value.index = index;
|
||||
inner_value = MALLOC(sizeof(ConstInitializer));
|
||||
inner_value = MALLOCS(ConstInitializer);
|
||||
inner_value->type = element_type;
|
||||
inner_value->kind = CONST_INIT_ZERO;
|
||||
initializer->init_array_value.element = inner_value;
|
||||
@@ -3606,7 +3606,7 @@ static bool sema_expr_analyse_designated_initializer(Context *context, Type *ass
|
||||
|
||||
if (expr_is_constant_eval(initializer, CONSTANT_EVAL_ANY))
|
||||
{
|
||||
ConstInitializer *const_init = MALLOC(sizeof(ConstInitializer));
|
||||
ConstInitializer *const_init = MALLOCS(ConstInitializer);
|
||||
sema_create_const_initializer(const_init, initializer);
|
||||
expr_set_as_const_list(initializer, const_init);
|
||||
return true;
|
||||
@@ -3762,7 +3762,7 @@ static inline bool sema_expr_analyse_struct_plain_initializer(Context *context,
|
||||
inits[i] = expr->const_expr.list;
|
||||
continue;
|
||||
}
|
||||
ConstInitializer *element_init = MALLOC(sizeof(ConstInitializer));
|
||||
ConstInitializer *element_init = MALLOCS(ConstInitializer);
|
||||
sema_create_const_initializer_value(element_init, expr);
|
||||
inits[i] = element_init;
|
||||
}
|
||||
@@ -3836,7 +3836,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(Context *context, T
|
||||
vec_add(inits, expr->const_expr.list);
|
||||
continue;
|
||||
}
|
||||
ConstInitializer *element_init = MALLOC(sizeof(ConstInitializer));
|
||||
ConstInitializer *element_init = MALLOCS(ConstInitializer);
|
||||
sema_create_const_initializer_value(element_init, expr);
|
||||
vec_add(inits, element_init);
|
||||
}
|
||||
|
||||
@@ -241,11 +241,6 @@ static inline SymEntry *entry_find(const char *key, uint32_t key_len, uint32_t h
|
||||
|
||||
const char *symtab_add(const char *symbol, uint32_t len, uint32_t fnv1hash, TokenType *type)
|
||||
{
|
||||
if (symtab.count >= symtab.max_count)
|
||||
{
|
||||
|
||||
FATAL_ERROR("Symtab exceeded capacity, please increase --symtab.");
|
||||
}
|
||||
SymEntry *entry = entry_find(symbol, len, fnv1hash);
|
||||
if (entry->value)
|
||||
{
|
||||
@@ -253,6 +248,10 @@ const char *symtab_add(const char *symbol, uint32_t len, uint32_t fnv1hash, Toke
|
||||
return entry->value;
|
||||
}
|
||||
|
||||
if (symtab.count >= symtab.max_count)
|
||||
{
|
||||
FATAL_ERROR("Symtab exceeded capacity, please increase --symtab.");
|
||||
}
|
||||
char *copy = MALLOC(len + 1);
|
||||
memcpy(copy, symbol, len);
|
||||
copy[len] = '\0';
|
||||
@@ -261,7 +260,7 @@ const char *symtab_add(const char *symbol, uint32_t len, uint32_t fnv1hash, Toke
|
||||
entry->hash = fnv1hash;
|
||||
entry->type = *type;
|
||||
symtab.count++;
|
||||
return entry->value;
|
||||
return copy;
|
||||
}
|
||||
|
||||
const char *symtab_find(const char *symbol, uint32_t len, uint32_t fnv1hash, TokenType *type)
|
||||
@@ -277,14 +276,10 @@ void stable_init(STable *table, uint32_t initial_size)
|
||||
assert(initial_size && "Size must be larger than 0");
|
||||
assert (is_power_of_two(initial_size) && "Must be a power of two");
|
||||
|
||||
SEntry *entries = MALLOC(initial_size * sizeof(Entry));
|
||||
for (uint32_t i = 0; i < initial_size; i++)
|
||||
{
|
||||
entries[i].key = NULL;
|
||||
entries[i].value = NULL;
|
||||
}
|
||||
SEntry *entries = CALLOC(initial_size * sizeof(Entry));
|
||||
table->count = 0;
|
||||
table->capacity = initial_size;
|
||||
table->max_load = initial_size * TABLE_MAX_LOAD;
|
||||
table->entries = entries;
|
||||
}
|
||||
|
||||
@@ -294,63 +289,56 @@ void stable_clear(STable *table)
|
||||
table->count = 0;
|
||||
}
|
||||
|
||||
#define TOMBSTONE ((void *)0x01)
|
||||
static SEntry *sentry_find(SEntry *entries, uint32_t capacity, const char *key)
|
||||
{
|
||||
uint32_t index = (uint32_t)((((uintptr_t)key) >> 2u) & (capacity - 1));
|
||||
SEntry *tombstone = NULL;
|
||||
while (1)
|
||||
{
|
||||
SEntry *entry = &entries[index];
|
||||
if (entry->key == key) return entry;
|
||||
if (entry->key == NULL)
|
||||
{
|
||||
if (entry->value != TOMBSTONE)
|
||||
{
|
||||
return tombstone ? tombstone : entry;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!tombstone) tombstone = entry;
|
||||
}
|
||||
}
|
||||
if (entry->key == key || !entry->key) return entry;
|
||||
index = (index + 1) & (capacity - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void *stable_set(STable *table, const char *key, void *value)
|
||||
{
|
||||
assert(value && "Cannot insert NULL");
|
||||
if (table->count + 1 > table->capacity * TABLE_MAX_LOAD)
|
||||
static inline void stable_resize(STable *table)
|
||||
{
|
||||
ASSERT(table->capacity < MAX_HASH_SIZE, "Table size too large, exceeded max hash size");
|
||||
|
||||
uint32_t new_capacity = table->capacity ? (table->capacity << 1u) : 16u;
|
||||
SEntry *new_data = MALLOC(new_capacity * sizeof(SEntry));
|
||||
for (uint32_t i = 0; i < new_capacity; i++)
|
||||
{
|
||||
new_data[i].key = NULL;
|
||||
new_data[i].value = NULL;
|
||||
}
|
||||
SEntry *new_data = CALLOC(new_capacity * sizeof(SEntry));
|
||||
table->count = 0;
|
||||
for (uint32_t i = 0; i < table->capacity; i++)
|
||||
uint32_t len = table->capacity;
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
{
|
||||
SEntry *entry = &table->entries[i];
|
||||
if (!entry->key) continue;
|
||||
const char *key = entry->key;
|
||||
if (!key) continue;
|
||||
table->count++;
|
||||
SEntry *dest = sentry_find(new_data, new_capacity, entry->key);
|
||||
*dest = *entry;
|
||||
SEntry *dest = sentry_find(new_data, new_capacity, key);
|
||||
dest->key = key;
|
||||
dest->value = entry->value;
|
||||
}
|
||||
table->entries = new_data;
|
||||
table->max_load = new_capacity * TABLE_MAX_LOAD;
|
||||
table->capacity = new_capacity;
|
||||
}
|
||||
void *stable_set(STable *table, const char *key, void *value)
|
||||
{
|
||||
assert(value && "Cannot insert NULL");
|
||||
if (table->count >= table->max_load) stable_resize(table);
|
||||
|
||||
SEntry *entry = sentry_find(table->entries, table->capacity, key);
|
||||
void *old = entry->value && entry->value != TOMBSTONE ? entry->value : NULL;
|
||||
void *old = entry->value;
|
||||
entry->key = key;
|
||||
entry->value = value;
|
||||
if (!old) table->count++;
|
||||
if (!old)
|
||||
{
|
||||
table->count++;
|
||||
if (table->count >= table->max_load) goto RESIZE;
|
||||
}
|
||||
return old;
|
||||
RESIZE:
|
||||
stable_resize(table);
|
||||
return old;
|
||||
}
|
||||
|
||||
@@ -362,13 +350,3 @@ void *stable_get(STable *table, const char *key)
|
||||
return entry->key == NULL ? NULL : entry->value;
|
||||
}
|
||||
|
||||
void *stable_delete(STable *table, const char *key)
|
||||
{
|
||||
if (!table->count) return NULL;
|
||||
SEntry *entry = sentry_find(table->entries, table->capacity, key);
|
||||
if (!entry->key) return NULL;
|
||||
void *value = entry->value;
|
||||
entry->key = NULL;
|
||||
entry->value = TOMBSTONE;
|
||||
return value;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ void *cmalloc(size_t size);
|
||||
void *ccalloc(size_t size, size_t elements);
|
||||
void memory_init(void);
|
||||
void memory_release();
|
||||
void *malloc_arena(size_t mem);
|
||||
void *calloc_arena(size_t mem);
|
||||
#define malloc_arena calloc_arena
|
||||
void free_arena(void);
|
||||
void print_arena_status(void);
|
||||
void run_arena_allocator_tests(void);
|
||||
@@ -47,14 +48,9 @@ void taskqueue_add(TaskQueueRef queue, Task *task);
|
||||
void taskqueue_destroy(TaskQueueRef queue);
|
||||
void taskqueue_wait_for_completion(TaskQueueRef queue);
|
||||
|
||||
static inline void *calloc_arena(size_t size)
|
||||
{
|
||||
void *ptr = malloc_arena(size);
|
||||
memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
#define MALLOC(mem) malloc_arena(mem)
|
||||
#define MALLOCS(type) malloc_arena(sizeof(type))
|
||||
#define CALLOC(mem) calloc_arena(mem)
|
||||
#define CALLOCS(type) calloc_arena(sizeof(type))
|
||||
|
||||
static inline bool is_power_of_two(uint64_t x)
|
||||
@@ -369,8 +365,7 @@ static inline VHeader_* vec_new_(size_t element_size, size_t capacity)
|
||||
{
|
||||
assert(capacity < UINT32_MAX);
|
||||
assert(element_size < UINT32_MAX / 100);
|
||||
VHeader_ *header = malloc_arena(element_size * capacity + sizeof(VHeader_));
|
||||
header->size = 0;
|
||||
VHeader_ *header = CALLOC(element_size * capacity + sizeof(VHeader_));
|
||||
header->capacity = (uint32_t)capacity;
|
||||
return header;
|
||||
}
|
||||
@@ -400,13 +395,12 @@ static inline void* expand_(void *vec, size_t element_size)
|
||||
VHeader_ *header;
|
||||
if (!vec)
|
||||
{
|
||||
header = vec_new_(element_size, 16);
|
||||
header = vec_new_(element_size, 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
header = ((VHeader_ *)vec) - 1;
|
||||
}
|
||||
header->size++;
|
||||
if (header->size == header->capacity)
|
||||
{
|
||||
VHeader_ *new_array = vec_new_(element_size, header->capacity << 1U);
|
||||
@@ -422,6 +416,7 @@ static inline void* expand_(void *vec, size_t element_size)
|
||||
header = new_array;
|
||||
new_array->capacity = header->capacity << 1U;
|
||||
}
|
||||
header->size++;
|
||||
return &(header[1]);
|
||||
}
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ void memory_release()
|
||||
}
|
||||
|
||||
// Simple bump allocator with buckets.
|
||||
void *malloc_arena(size_t mem)
|
||||
void *calloc_arena(size_t mem)
|
||||
{
|
||||
assert(mem > 0);
|
||||
// Round to multiple of 16
|
||||
@@ -53,13 +53,13 @@ void run_arena_allocator_tests(void)
|
||||
if (!was_init) memory_init();
|
||||
memory_release();
|
||||
memory_init();
|
||||
ASSERT(malloc_arena(10) != malloc_arena(10), "Expected different values...");
|
||||
ASSERT(calloc_arena(10) != calloc_arena(10), "Expected different values...");
|
||||
printf("-- Tested basic allocation - OK.\n");
|
||||
ASSERT(arena.allocated == 32, "Expected allocations rounded to next 16 bytes");
|
||||
malloc_arena(1);
|
||||
calloc_arena(1);
|
||||
ASSERT(arena.allocated == 48, "Expected allocations rounded to next 16 bytes");
|
||||
printf("-- Tested allocation alignment - OK.\n");
|
||||
ASSERT(malloc_arena(1024 * 1024) != NULL, "Expected allocation to work");
|
||||
ASSERT(calloc_arena(1024 * 1024) != NULL, "Expected allocation to work");
|
||||
free_arena();
|
||||
ASSERT(arena.allocated == 0, "Arena not freed?");
|
||||
printf("-- Test freeing arena - OK.\n");
|
||||
|
||||
@@ -8,12 +8,8 @@
|
||||
#define ARENA_DEF(name, type) \
|
||||
extern Vmem name##_arena; \
|
||||
typedef unsigned type##Id; \
|
||||
static inline type *name##_alloc(void) { return (type *)vmem_alloc(&name##_arena, sizeof(type)); } \
|
||||
static inline type *name##_calloc(void) { return (type *)vmem_alloc(&name##_arena, sizeof(type)); } \
|
||||
static inline void name##_arena_free(void) { vmem_free(&name##_arena); } \
|
||||
static inline type *name##_calloc(void) { \
|
||||
type *ptr = name##_alloc(); \
|
||||
memset(ptr, 0, sizeof(type)); \
|
||||
return ptr; } \
|
||||
static inline type *name##ptr(type ## Id id) { return ((type *)name##_arena.ptr) + id; } \
|
||||
static inline type##Id name##id(type *ptr) { return (unsigned) (ptr - ((type *)name##_arena.ptr)); } \
|
||||
static inline type *name##_copy(type *ptr) { type *x = name##_alloc(); memcpy(x, ptr, sizeof(type)); return x; }
|
||||
static inline type *name##_copy(type *ptr) { type *x = name##_calloc(); memcpy(x, ptr, sizeof(type)); return x; }
|
||||
|
||||
@@ -54,12 +54,6 @@ static inline void* mmap_allocate(Vmem *vmem, size_t to_allocate)
|
||||
}
|
||||
#endif
|
||||
void *ptr = ((uint8_t *)vmem->ptr) + vmem->allocated;
|
||||
#ifndef NDEBUG
|
||||
for (size_t i = vmem->allocated; i < allocated_after; i++)
|
||||
{
|
||||
((uint8_t *)vmem->ptr)[i] = 0xAA;
|
||||
}
|
||||
#endif
|
||||
vmem->allocated = allocated_after;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user