From: Brendan Hansen Date: Fri, 21 Aug 2020 03:15:46 +0000 (-0500) Subject: Improved speed of lexer slightly; started profiling X-Git-Url: https://git.brendanfh.com/?a=commitdiff_plain;h=4558ab9bd49c8be2fa2142439da530b3e51625c2;p=onyx.git Improved speed of lexer slightly; started profiling --- diff --git a/Makefile b/Makefile index bf49f2a0..740b434b 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -RELEASE=1 +RELEASE=0 OBJ_FILES=\ build/onyxlex.o \ @@ -21,7 +21,7 @@ TARGET=./onyx ifeq ($(RELEASE), 1) FLAGS=-O2 else - FLAGS=-g + FLAGS=-g -O2 endif build/%.o: src/%.c include/bh.h diff --git a/core/math.onyx b/core/math.onyx new file mode 100644 index 00000000..8151c32d --- /dev/null +++ b/core/math.onyx @@ -0,0 +1,49 @@ +package math + +PI :: 3.14159265f; +TAU :: 6.28318330f; + +// Simple taylor series approximation of sin(t) +sin :: proc (t_: f32) -> f32 { + t := t_; + while t >= PI do t -= TAU; + while t <= -PI do t += TAU; + + res := 0.0f; + + plus_minus := 1.0f; + n := 13; + while n > 1 { + res += plus_minus; + res *= t * t / cast(f32) (n * n - n); + + plus_minus = -plus_minus; + n -= 2; + } + + res += 1.0f; + res *= t; + return res; +} + +// Simple taylor series approximation of cos(t) +cos :: proc (t_: f32) -> f32 { + t := t_; + while t >= PI do t -= TAU; + while t <= -PI do t += TAU; + + res := 0.0f; + + plus_minus := 1.0f; + n := 12; + while n > 1 { + res += plus_minus; + res *= t * t / cast(f32) (n * n - n); + + plus_minus = -plus_minus; + n -= 2; + } + + res += 1.0f; + return res; +} \ No newline at end of file diff --git a/docs/plan b/docs/plan index 50f6ee14..8bcf3262 100644 --- a/docs/plan +++ b/docs/plan @@ -187,6 +187,23 @@ HOW: [X] returning structs - This will put forward a lot of the work that will be done for multiple return values + [ ] Put type info in data section so it is runtime accessible + - type name + - size + - alignment + - struct member names + - array length + + [ ] convert to using an 'atom' like table + - All identifier tokens are given a unique atom ptr, up to string equality. + - This means identifiers can be compared using ptr comparison, instead of string comparison + - This mean no more token_toggle_end!! Woo!! + + [ ] Make the lexer much faster + - Technically it isn't slow right now + - But, profiling says we are spending 50% of the program execution time in the lexer + - That is awful + [ ] Add slices - Arrays without a size - Converted to a struct that looks like: @@ -213,12 +230,6 @@ HOW: [ ] All code paths return correct value - [ ] Put type info in data section so it is runtime accessible - - size - - alignment - - struct member names - - array length - [ ] Type parameterized structs [ ] Arrays need to be much better diff --git a/include/bh.h b/include/bh.h index 4a57248a..b0633fc4 100644 --- a/include/bh.h +++ b/include/bh.h @@ -228,16 +228,6 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc); -// MANAGED HEAP ALLOCATOR -typedef struct bh_managed_heap { - ptr* pointers; // Actually a bh_arr -} bh_managed_heap; - -void bh_managed_heap_init(bh_managed_heap* mh); -void bh_managed_heap_free(bh_managed_heap* mh); -bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh); -BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc); - // ARENA ALLOCATOR @@ -734,6 +724,16 @@ void bh_imap_clear(bh_imap* imap); +// MANAGED HEAP ALLOCATOR +typedef struct bh_managed_heap { + bh_imap ptrs; +} bh_managed_heap; + +void bh_managed_heap_init(bh_managed_heap* mh); +void bh_managed_heap_free(bh_managed_heap* mh); +bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh); +BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc); + @@ -870,17 +870,15 @@ BH_ALLOCATOR_PROC(bh_heap_allocator_proc) { // MANAGED HEAP ALLOCATOR IMPLEMENTATION void bh_managed_heap_init(bh_managed_heap* mh) { - mh->pointers = NULL; - - bh_arr_new(bh_heap_allocator(), mh->pointers, 4); + bh_imap_init(&mh->ptrs, bh_heap_allocator(), 512); } void bh_managed_heap_free(bh_managed_heap* mh) { - bh_arr_each(ptr, p, mh->pointers) { - free(*p); + bh_arr_each(bh__imap_entry, p, mh->ptrs.entries) { + free((void *) p->key); } - bh_arr_free(mh->pointers); + bh_imap_free(&mh->ptrs); } bh_allocator bh_managed_heap_allocator(bh_managed_heap* mh) { @@ -903,40 +901,17 @@ BH_ALLOCATOR_PROC(bh_managed_heap_allocator_proc) { } if (retval != NULL) - bh_arr_push(mh->pointers, retval); + bh_imap_put(&mh->ptrs, (u64) retval, 1); } break; case bh_allocator_action_resize: { - i32 replace_idx = 0; - b32 found = 0; - - bh_arr_each(ptr, p, mh->pointers) { - if (*p == prev_memory) { - found = 1; - break; - } - - replace_idx++; - } - + bh_imap_delete(&mh->ptrs, (u64) prev_memory); retval = realloc(prev_memory, size); - mh->pointers[replace_idx] = retval; + bh_imap_put(&mh->ptrs, (u64) retval, 1); } break; case bh_allocator_action_free: { - i32 free_idx = 0; - b32 found = 0; - - bh_arr_each(ptr, p, mh->pointers) { - if (*p == prev_memory) { - found = 1; - break; - } - - free_idx++; - } - - bh_arr_fastdelete(mh->pointers, free_idx); + bh_imap_delete(&mh->ptrs, (u64) prev_memory); free(prev_memory); } break; } diff --git a/onyx b/onyx index ba5c54d5..776bc764 100755 Binary files a/onyx and b/onyx differ diff --git a/src/onyxlex.c b/src/onyxlex.c index 153606e4..fdbfb8b1 100644 --- a/src/onyxlex.c +++ b/src/onyxlex.c @@ -80,23 +80,27 @@ static const char* token_type_names[] = { } #endif -static b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, TokenType type) { - i64 len = chars_match(tokenizer->curr, lit); - if (len > 0) { - if (is_word && char_is_alphanum(*(tokenizer->curr + len)) || charset_contains("_$", *(tokenizer->curr + len))) - return 0; +#define char_is_alphanum(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || ((c) >= '0' && (c) <= '9')) - tk->type = type; - tk->text = tokenizer->curr; - tk->length = len; - tk->pos.line = tokenizer->line_number; - tk->pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1; +static inline b32 token_lit(OnyxTokenizer* tokenizer, OnyxToken* tk, char* lit, b32 is_word, TokenType type) { + i64 len = 0; + char* ptr1 = tokenizer->curr; + char* ptr2 = lit; + while (*ptr2 != '\0' && *ptr1 == *ptr2) ptr1++, ptr2++, len++; + if (*ptr2 != '\0') return 0; - tokenizer->curr += len; + if (is_word && char_is_alphanum(*ptr1) || *ptr1 == '_' || *ptr1 == '$') + return 0; - return 1; - } - return 0; + tk->type = type; + tk->text = tokenizer->curr; + tk->length = len; + tk->pos.line = tokenizer->line_number; + tk->pos.column = (i32)(tokenizer->curr - tokenizer->line_start) + 1; + + tokenizer->curr += len; + + return 1; } const char* token_name(TokenType tkn_type) { @@ -148,66 +152,6 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { goto token_parsed; } - LITERAL_TOKEN("package", 1, Token_Type_Keyword_Package); - LITERAL_TOKEN("struct", 1, Token_Type_Keyword_Struct); - LITERAL_TOKEN("enum" , 1, Token_Type_Keyword_Enum); - LITERAL_TOKEN("use", 1, Token_Type_Keyword_Use); - LITERAL_TOKEN("if", 1, Token_Type_Keyword_If); - LITERAL_TOKEN("elseif", 1, Token_Type_Keyword_Elseif); - LITERAL_TOKEN("else", 1, Token_Type_Keyword_Else); - LITERAL_TOKEN("global", 1, Token_Type_Keyword_Global); - LITERAL_TOKEN("return", 1, Token_Type_Keyword_Return); - LITERAL_TOKEN("proc", 1, Token_Type_Keyword_Proc); - LITERAL_TOKEN("as", 1, Token_Type_Keyword_As); - LITERAL_TOKEN("cast", 1, Token_Type_Keyword_Cast); - LITERAL_TOKEN("while", 1, Token_Type_Keyword_While); - LITERAL_TOKEN("for", 1, Token_Type_Keyword_For); - LITERAL_TOKEN("break", 1, Token_Type_Keyword_Break); - LITERAL_TOKEN("continue", 1, Token_Type_Keyword_Continue); - LITERAL_TOKEN("sizeof", 1, Token_Type_Keyword_Sizeof); - LITERAL_TOKEN("alignof", 1, Token_Type_Keyword_Alignof); - LITERAL_TOKEN("defer", 1, Token_Type_Keyword_Defer); - LITERAL_TOKEN("do", 1, Token_Type_Keyword_Do); - LITERAL_TOKEN("true", 1, Token_Type_Literal_True); - LITERAL_TOKEN("false", 1, Token_Type_Literal_False); - LITERAL_TOKEN("->", 0, Token_Type_Right_Arrow); - LITERAL_TOKEN("<-", 0, Token_Type_Right_Arrow); - LITERAL_TOKEN("---", 0, Token_Type_Empty_Block); - LITERAL_TOKEN("|>", 0, Token_Type_Pipe); - LITERAL_TOKEN("&&", 0, Token_Type_And_And); - LITERAL_TOKEN("||", 0, Token_Type_Or_Or); - LITERAL_TOKEN(">>>=", 0, Token_Type_Sar_Equal); - LITERAL_TOKEN(">>=", 0, Token_Type_Shr_Equal); - LITERAL_TOKEN("<<=", 0, Token_Type_Shl_Equal); - LITERAL_TOKEN(">>>", 0, Token_Type_Shift_Arith_Right); - LITERAL_TOKEN(">>", 0, Token_Type_Shift_Right); - LITERAL_TOKEN("<<", 0, Token_Type_Shift_Left); - LITERAL_TOKEN("&=", 0, Token_Type_And_Equal); - LITERAL_TOKEN("|=", 0, Token_Type_Or_Equal); - LITERAL_TOKEN("^=", 0, Token_Type_Xor_Equal); - LITERAL_TOKEN("<=", 0, Token_Type_Less_Equal); - LITERAL_TOKEN(">=", 0, Token_Type_Greater_Equal); - LITERAL_TOKEN("==", 0, Token_Type_Equal_Equal); - LITERAL_TOKEN("!=", 0, Token_Type_Not_Equal); - LITERAL_TOKEN("+=", 0, Token_Type_Plus_Equal); - LITERAL_TOKEN("-=", 0, Token_Type_Minus_Equal); - LITERAL_TOKEN("*=", 0, Token_Type_Star_Equal); - LITERAL_TOKEN("/=", 0, Token_Type_Fslash_Equal); - LITERAL_TOKEN("%=", 0, Token_Type_Percent_Equal); - - // Symbols - if (char_is_alpha(*tk.text) || *tokenizer->curr == '_') { - u64 len = 0; - while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) { - len++; - INCREMENT_CURR_TOKEN(tokenizer); - } - - tk.length = len; - tk.type = Token_Type_Symbol; - goto token_parsed; - } - // String literal if (*tk.text == '"') { u64 len = 0; @@ -290,6 +234,67 @@ OnyxToken* onyx_get_token(OnyxTokenizer* tokenizer) { goto token_parsed; } + LITERAL_TOKEN("package", 1, Token_Type_Keyword_Package); + LITERAL_TOKEN("struct", 1, Token_Type_Keyword_Struct); + LITERAL_TOKEN("enum" , 1, Token_Type_Keyword_Enum); + LITERAL_TOKEN("use", 1, Token_Type_Keyword_Use); + LITERAL_TOKEN("if", 1, Token_Type_Keyword_If); + LITERAL_TOKEN("elseif", 1, Token_Type_Keyword_Elseif); + LITERAL_TOKEN("else", 1, Token_Type_Keyword_Else); + LITERAL_TOKEN("global", 1, Token_Type_Keyword_Global); + LITERAL_TOKEN("return", 1, Token_Type_Keyword_Return); + LITERAL_TOKEN("proc", 1, Token_Type_Keyword_Proc); + LITERAL_TOKEN("as", 1, Token_Type_Keyword_As); + LITERAL_TOKEN("cast", 1, Token_Type_Keyword_Cast); + LITERAL_TOKEN("while", 1, Token_Type_Keyword_While); + LITERAL_TOKEN("for", 1, Token_Type_Keyword_For); + LITERAL_TOKEN("break", 1, Token_Type_Keyword_Break); + LITERAL_TOKEN("continue", 1, Token_Type_Keyword_Continue); + LITERAL_TOKEN("sizeof", 1, Token_Type_Keyword_Sizeof); + LITERAL_TOKEN("alignof", 1, Token_Type_Keyword_Alignof); + LITERAL_TOKEN("defer", 1, Token_Type_Keyword_Defer); + LITERAL_TOKEN("do", 1, Token_Type_Keyword_Do); + LITERAL_TOKEN("true", 1, Token_Type_Literal_True); + LITERAL_TOKEN("false", 1, Token_Type_Literal_False); + LITERAL_TOKEN("->", 0, Token_Type_Right_Arrow); + LITERAL_TOKEN("<-", 0, Token_Type_Right_Arrow); + LITERAL_TOKEN("---", 0, Token_Type_Empty_Block); + LITERAL_TOKEN("|>", 0, Token_Type_Pipe); + LITERAL_TOKEN("&&", 0, Token_Type_And_And); + LITERAL_TOKEN("||", 0, Token_Type_Or_Or); + LITERAL_TOKEN(">>>=", 0, Token_Type_Sar_Equal); + LITERAL_TOKEN(">>=", 0, Token_Type_Shr_Equal); + LITERAL_TOKEN("<<=", 0, Token_Type_Shl_Equal); + LITERAL_TOKEN(">>>", 0, Token_Type_Shift_Arith_Right); + LITERAL_TOKEN(">>", 0, Token_Type_Shift_Right); + LITERAL_TOKEN("<<", 0, Token_Type_Shift_Left); + LITERAL_TOKEN("&=", 0, Token_Type_And_Equal); + LITERAL_TOKEN("|=", 0, Token_Type_Or_Equal); + LITERAL_TOKEN("^=", 0, Token_Type_Xor_Equal); + LITERAL_TOKEN("<=", 0, Token_Type_Less_Equal); + LITERAL_TOKEN(">=", 0, Token_Type_Greater_Equal); + LITERAL_TOKEN("==", 0, Token_Type_Equal_Equal); + LITERAL_TOKEN("!=", 0, Token_Type_Not_Equal); + LITERAL_TOKEN("+=", 0, Token_Type_Plus_Equal); + LITERAL_TOKEN("-=", 0, Token_Type_Minus_Equal); + LITERAL_TOKEN("*=", 0, Token_Type_Star_Equal); + LITERAL_TOKEN("/=", 0, Token_Type_Fslash_Equal); + LITERAL_TOKEN("%=", 0, Token_Type_Percent_Equal); + + // Symbols + if (char_is_alpha(*tk.text) || *tokenizer->curr == '_') { + u64 len = 0; + while (char_is_alphanum(*tokenizer->curr) || charset_contains("_$", *tokenizer->curr)) { + len++; + INCREMENT_CURR_TOKEN(tokenizer); + } + + tk.length = len; + tk.type = Token_Type_Symbol; + goto token_parsed; + } + + tk.type = (TokenType) *tokenizer->curr; INCREMENT_CURR_TOKEN(tokenizer); diff --git a/src/onyxsymres.c b/src/onyxsymres.c index d0de2ea8..ced78907 100644 --- a/src/onyxsymres.c +++ b/src/onyxsymres.c @@ -121,7 +121,7 @@ static void symres_local(AstLocal** local) { bh_arr_push(bh_arr_last(semstate.block_stack)->locals, *local); bh_arr_push(semstate.curr_function->locals, *local); - + symbol_introduce(semstate.curr_scope, (*local)->token, (AstNode *) *local); } diff --git a/src/onyxwasm.c b/src/onyxwasm.c index fe96ce89..0f635fdd 100644 --- a/src/onyxwasm.c +++ b/src/onyxwasm.c @@ -331,9 +331,9 @@ static u64 local_lookup_idx(LocalAllocator* la, u64 value) { assert(value & LOCAL_IS_WASM); u32 idx = value & 0xFFFFFFFF; - if (value & 0x100000000) idx += la->allocated[0]; - if (value & 0x200000000) idx += la->allocated[1]; - if (value & 0x400000000) idx += la->allocated[2]; + if (value & 0x100000000) idx += la->allocated[0]; + if (value & 0x200000000) idx += la->allocated[1]; + if (value & 0x400000000) idx += la->allocated[2]; return (u64) idx; } @@ -1217,11 +1217,11 @@ COMPILE_FUNC(expression, AstTyped* expr) { if (expr->type->kind == Type_Kind_Struct) { TypeStruct* st = &expr->type->Struct; - + fori (idx, 0, st->mem_count) { WIL(WI_LOCAL_GET, localidx + idx); } - + } else { WIL(WI_LOCAL_GET, localidx); } @@ -1593,7 +1593,7 @@ COMPILE_FUNC(return, AstReturn* ret) { while (i >= 0) { compile_statement(mod, &code, mod->deferred_stmts[i].stmt); i--; - } + } } if (mod->has_stack_locals) @@ -2005,7 +2005,7 @@ static void compile_file_contents(OnyxWasmModule* mod, AstFileContents* fc) { onyx_message_add(Msg_Type_File_Not_Found, fc->filename->pos, fc->filename->text); - + token_toggle_end(fc->filename); return; }