From 917cddaf9024493618c77890cd242f251e935df7 Mon Sep 17 00:00:00 2001 From: Ore Richard Muyiwa Date: Fri, 4 Jun 2021 09:04:15 +0100 Subject: [PATCH] Fixed multiple cache misses. --- birdy.mk | 3 ++- src/b_string.c | 24 +++++++----------------- src/bird.c | 11 ++++++----- src/common.h | 5 +++++ src/compiler.c | 45 +++++++++++++++++++++++---------------------- src/memory.c | 2 +- src/object.c | 6 ++---- src/pathinfo.c | 8 +++++--- src/standard/http.c | 6 +++--- src/util.c | 22 ++++++++++++++++++---- src/value.c | 2 +- src/vm.c | 14 ++++++++------ 12 files changed, 81 insertions(+), 67 deletions(-) diff --git a/birdy.mk b/birdy.mk index 51954d89..327258c8 100644 --- a/birdy.mk +++ b/birdy.mk @@ -96,7 +96,8 @@ endif # Mode configuration. ifeq ($(MODE),debug) - CFLAGS += -O0 -DDEBUG -g +# CFLAGS += -O0 -DDEBUG -g + CFLAGS += -O0 -DDEBUG -g -fsanitize=address BUILD_DIR := build/debug else CFLAGS += -O3 -flto diff --git a/src/b_string.c b/src/b_string.c index f60b0594..aea7114f 100644 --- a/src/b_string.c +++ b/src/b_string.c @@ -461,8 +461,7 @@ DECLARE_STRING_METHOD(ends_with) { int difference = string->length - substr->length; - RETURN_BOOL( - memcmp(substr->chars, string->chars + difference, substr->length) == 0); + RETURN_BOOL(memcmp(substr->chars, string->chars + difference, substr->length) == 0); } DECLARE_STRING_METHOD(count) { @@ -657,11 +656,8 @@ DECLARE_STRING_METHOD(match) { for (int i = 0; i < (int)name_count; i++) { int n = (tab_ptr[0] << 8) | tab_ptr[1]; - char *_key = malloc(sizeof(char)); - memset(_key, 0, sizeof(char)); - - char *_val = malloc(sizeof(char)); - memset(_val, 0, sizeof(char)); + char *_key = malloc(0); + char *_val = malloc(0); sprintf(_key, "%*s", name_entry_size - 3, tab_ptr + 2); sprintf(_val, "%*s", (int)(o_vector[2 * n + 1] - o_vector[2 * n]), @@ -783,11 +779,8 @@ DECLARE_STRING_METHOD(matches) { for (i = 0; i < (int)name_count; i++) { int n = (tab_ptr[0] << 8) | tab_ptr[1]; - char *_key = malloc(sizeof(char)); - memset(_key, 0, sizeof(char)); - - char *_val = malloc(sizeof(char)); - memset(_val, 0, sizeof(char)); + char *_key = malloc(0); + char *_val = malloc(0); sprintf(_key, "%*s", name_entry_size - 3, tab_ptr + 2); sprintf(_val, "%*s", (int)(o_vector[2 * n + 1] - o_vector[2 * n]), @@ -904,11 +897,8 @@ DECLARE_STRING_METHOD(matches) { for (i = 0; i < (int)name_count; i++) { int n = (tab_ptr[0] << 8) | tab_ptr[1]; - char *_key = malloc(sizeof(char)); - memset(_key, 0, sizeof(char)); - - char *_val = malloc(sizeof(char)); - memset(_val, 0, sizeof(char)); + char *_key = malloc(0); + char *_val = malloc(0); sprintf(_key, "%*s", name_entry_size - 3, tab_ptr + 2); sprintf(_val, "%*s", (int)(o_vector[2 * n + 1] - o_vector[2 * n]), diff --git a/src/bird.c b/src/bird.c index b63e4d0f..8550c5a5 100644 --- a/src/bird.c +++ b/src/bird.c @@ -44,7 +44,7 @@ static void repl(b_vm *vm) { printf("%s, (Build time = %s, %s)\n", COMPILER, __DATE__, __TIME__); printf("Type \"exit()\" to quit, \"help()\" or \"credits()\" for more information\n"); - char *source = (char *) malloc(sizeof(char)); + char *source = (char *) calloc(1, sizeof(char)); int current_line = 0; int brace_count = 0, paren_count = 0, bracket_count = 0, single_quote_count = 0, double_quote_count = 0; @@ -133,6 +133,7 @@ static void repl(b_vm *vm) { } source = append_strings(source, line); + free(line); if (line_length > 0) { source = append_strings(source, "\n"); } @@ -153,7 +154,7 @@ static void run_file(b_vm *vm, const char *file) { char *source = read_file(file); if (source == NULL) { fprintf(stderr, "(Bird):\n Launch aborted for %s\n Reason: %s\n", file, strerror(errno)); - exit(74); + exit(EXIT_FAILURE); } b_ptr_result result = interpret(vm, source, file); @@ -162,9 +163,9 @@ static void run_file(b_vm *vm, const char *file) { fflush(stdout); if (result == PTR_COMPILE_ERR) - exit(65); + exit(EXIT_COMPILE); if (result == PTR_RUNTIME_ERR) - exit(70); + exit(EXIT_RUNTIME); } void show_usage(char *argv[]) { @@ -228,5 +229,5 @@ int main(int argc, char *argv[]) { } free_vm(vm); - return 0; + return EXIT_SUCCESS; } \ No newline at end of file diff --git a/src/common.h b/src/common.h index fda74210..c383c9d6 100644 --- a/src/common.h +++ b/src/common.h @@ -74,4 +74,9 @@ #define BIRD_VERSION_STRING "0.0.1" #define BVM_VERSION "0.0.1" + +#define EXIT_COMPILE 10 +#define EXIT_RUNTIME 10 +#define EXIT_TERMINAL 12 + #endif diff --git a/src/compiler.c b/src/compiler.c index 09483048..f33966a2 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -394,10 +394,8 @@ static int identifier_constant(b_parser *p, b_token *name) { OBJ_VAL(copy_string(p->vm, name->start, name->length))); } -static bool identifiers_equal(b_token *a, b_token *b) { - if (a->length != b->length) - return false; - return memcmp(a->start, b->start, a->length) == 0; +static inline bool identifiers_equal(b_token *a, b_token *b) { + return a->length == b->length && memcmp(a->start, b->start, a->length) == 0; } static int resolve_local(b_parser *p, b_compiler *compiler, b_token *name) { @@ -569,7 +567,8 @@ static void discard_local(b_parser *p, int depth) { } static void end_loop(b_parser *p) { - // find all OP_BREAK_PL placeholder and replace with the appropriate jump... + // find all OP_BREAK_PL placeholder and replace with the app + // ropriate jump... int i = p->innermost_loop_start; while (i < p->compiler->function->blob.count) { @@ -1037,14 +1036,13 @@ static int read_unicode_escape(b_parser *p, char *string, char *real_string, return count; } -static char *compile_string(b_parser *p) { - char *str = (char *)calloc((p->previous.length - (p->had_error ? 1 : 2)) + 1, sizeof(char)); - char *real = (char *)(p->previous.start + (p->had_error ? 0 : 1)); +static char *compile_string(b_parser *p, int *length) { + char *str = (char *)malloc(((p->previous.length - 2) + 1) * sizeof(char)); + char *real = (char *)p->previous.start + 1; - int real_length = p->previous.length - (p->had_error ? 1 : 2); - int i = 0, k = 0; + int real_length = p->previous.length - 2, k = 0; - for (; i < real_length; i++, k++) { + for (int i = 0; i < real_length; i++, k++) { char c = real[i]; if (c == '\\' && i < real_length - 1) { switch (real[i + 1]) { @@ -1109,13 +1107,15 @@ static char *compile_string(b_parser *p) { memcpy(str + k, &c, 1); } + *length = k; str[k] = '\0'; return str; } static void string(b_parser *p, bool can_assign) { - char *str = compile_string(p); - emit_constant(p, OBJ_VAL(copy_string(p->vm, str, (int)strlen(str)))); + int length; + char *str = compile_string(p, &length); + emit_constant(p, OBJ_VAL(copy_string(p->vm, str, length))); } static void string_interpolation(b_parser *p, bool can_assign) { @@ -1836,8 +1836,9 @@ static void using_statement(b_parser *p) { } else if (p->previous.type == FALSE_TOKEN) { table_set(p->vm, &sw->table, FALSE_VAL, jump); } else if (p->previous.type == LITERAL_TOKEN) { - char *str = compile_string(p); - b_obj_string *string = copy_string(p->vm, str, (int)strlen(str)); + int length; + char *str = compile_string(p, &length); + b_obj_string *string = copy_string(p->vm, str, length); table_set(p->vm, &sw->table, OBJ_VAL(string), jump); } else if (check_number(p)) { table_set(p->vm, &sw->table, compile_number(p), jump); @@ -1904,7 +1905,8 @@ static void die_statement(b_parser *p) { static void import_statement(b_parser *p) { consume(p, LITERAL_TOKEN, "expected module name"); - char *module_name = compile_string(p); + int module_name_length; + char *module_name = compile_string(p, &module_name_length); char *module_path = resolve_import_path(module_name, p->current_file); if (module_path == NULL) { @@ -1921,15 +1923,14 @@ static void import_statement(b_parser *p) { return; } - b_obj_func *function = - compile(p->vm, source, module_path, &p->compiler->function->blob); + b_obj_func *function = compile(p->vm, source, module_path, &p->compiler->function->blob); if (function == NULL) { error(p, "failed to import %s", module_name); return; } - function->name = copy_string(p->vm, module_name, (int)strlen(module_name)); + function->name = copy_string(p->vm, module_name, module_name_length); int import_constant = make_constant(p, OBJ_VAL(function)); emit_byte_and_short(p, OP_CALL_IMPORT, import_constant); @@ -2209,8 +2210,8 @@ b_obj_func *compile(b_vm *vm, const char *source, const char *file, parser.current_class = NULL; parser.current_file = file; - b_compiler compiler; - init_compiler(&parser, &compiler, TYPE_SCRIPT); + b_compiler *compiler = (b_compiler*) malloc(sizeof(b_compiler)); + init_compiler(&parser, compiler, TYPE_SCRIPT); advance(&parser); @@ -2219,7 +2220,7 @@ b_obj_func *compile(b_vm *vm, const char *source, const char *file, } b_obj_func *function = end_compiler(&parser); - vm->compiler = &compiler; + vm->compiler = compiler; return parser.had_error ? NULL : function; } diff --git a/src/memory.c b/src/memory.c index 7561d9da..127c196a 100644 --- a/src/memory.c +++ b/src/memory.c @@ -30,7 +30,7 @@ void *reallocate(b_vm *vm, void *pointer, size_t old_size, size_t new_size) { if (result == NULL) { fflush(stdout); // flush out anything on stdout first fprintf(stderr, "Exit: device out of memory\n"); - exit(1); + exit(EXIT_TERMINAL); } return result; } diff --git a/src/object.c b/src/object.c index 4f9faa25..de28630d 100644 --- a/src/object.c +++ b/src/object.c @@ -311,8 +311,7 @@ void print_object(b_value value, bool fix_string) { b_obj_bytes *copy_bytes(b_vm *vm, unsigned char *b, int length) { b_obj_bytes *bytes = new_bytes(vm, length); - - memcpy(bytes->bytes.bytes, b, length * sizeof(unsigned char *)); + memcpy(bytes->bytes.bytes, b, length); return bytes; } @@ -378,8 +377,7 @@ static char *dict_to_string(b_vm *vm, b_obj_dict *dict) { } char *object_to_string(b_vm *vm, b_value value) { - char *str = (char *)malloc(sizeof(char)); - memset(str, 0, sizeof(char)); + char *str = (char *)calloc(0, sizeof(char)); switch (OBJ_TYPE(value)) { case OBJ_SWITCH: { diff --git a/src/pathinfo.c b/src/pathinfo.c index 54d5fd93..4054a6d3 100644 --- a/src/pathinfo.c +++ b/src/pathinfo.c @@ -125,8 +125,7 @@ char *get_filename(char *filepath) { start = i; } length = length - start; - char *string = malloc(sizeof(char)); - memset(string, 0, sizeof(char)); + char *string = (char*)calloc(0, sizeof(char)); strncat(string, filepath + start, length); return string; @@ -198,7 +197,10 @@ bool is_core_library_file(char *filepath, char *file_name) { char *library_file = merge_paths(bird_directory, bird_file_name); if (file_exists(library_file)) { - return memcmp(library_file, filepath, (int) strlen(filepath)) == 0; + int filepath_length = (int) strlen(filepath); + int library_file_length = (int) strlen(library_file); + return library_file_length == filepath_length + && memcmp(library_file, filepath, filepath_length) == 0; } return false; } diff --git a/src/standard/http.c b/src/standard/http.c index 18c1dfb7..ce1623bf 100644 --- a/src/standard/http.c +++ b/src/standard/http.c @@ -113,11 +113,11 @@ DECLARE_MODULE_METHOD(http___client) { realpath(file->path->chars, NULL)); } - if (memcmp(request_type->chars, "GET", request_type->length) == 0) { + if (request_type->length == 3 && memcmp(request_type->chars, "GET", request_type->length) == 0) { curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L); - } else if (memcmp(request_type->chars, "POST", request_type->length) == 0) { + } else if (request_type->length == 4 && memcmp(request_type->chars, "POST", request_type->length) == 0) { curl_easy_setopt(curl, CURLOPT_POST, 1L); - } else if (memcmp(request_type->chars, "HEAD", request_type->length) == 0) { + } else if (request_type->length == 4 && memcmp(request_type->chars, "HEAD", request_type->length) == 0) { curl_easy_setopt(curl, CURLOPT_NOBODY, 1L); } else { curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, request_type->chars); diff --git a/src/util.c b/src/util.c index dd931ca5..f96d86bf 100644 --- a/src/util.c +++ b/src/util.c @@ -126,7 +126,7 @@ char *append_strings(const char *old, const char *new_str) { const size_t out_len = old_len + new_len; // allocate a pointer to the new string - char *out = calloc(out_len + 1, sizeof(char)); + char *out = calloc((int)out_len + 1, sizeof(char)); // concat both strings and return if (out != NULL) { @@ -138,6 +138,19 @@ char *append_strings(const char *old, const char *new_str) { return out; } +/*char *append_strings(char *old, char *new_str) { + // find the size of the string to allocate + const size_t out_len = strlen(old) + strlen(new_str); + char *result = realloc(old, out_len + 1); + + if (result != NULL) { + strcat(result, new_str); + result[out_len] = '\0'; // enforce string termination + } + + return result; +}*/ + int read_line(char line[], int max) { int nch = 0; int c; @@ -225,8 +238,9 @@ char *read_file(const char *path) { return buffer; } -void flush_output() { - if(fflush(stdout) != 0) { +inline void flush_output() { + fflush(stdout); + /*if(fflush(stdout) != 0) { fwrite(NULL, 0, 0, stdout); - } + }*/ } \ No newline at end of file diff --git a/src/value.c b/src/value.c index 1c3ea5d7..06b4c3a7 100644 --- a/src/value.c +++ b/src/value.c @@ -117,7 +117,7 @@ void echo_value(b_value value) { do_print_value(value, true); } static inline char *number_to_string(double number) { int length = snprintf(NULL, 0, NUMBER_FORMAT, number); - char *num_str = (char *) calloc(length, sizeof(char)); + char *num_str = (char *) calloc(length + 1, sizeof(char)); sprintf(num_str, NUMBER_FORMAT, number); return num_str; } diff --git a/src/vm.c b/src/vm.c index 97482523..f1c477ef 100644 --- a/src/vm.c +++ b/src/vm.c @@ -13,6 +13,7 @@ #include "b_file.h" #include "b_list.h" #include "b_string.h" +#include "util.h" #include #include @@ -39,8 +40,7 @@ static inline b_obj_func *get_frame_function(b_call_frame *frame) { } static b_value get_stack_trace(b_vm *vm){ - char *trace = (char *)malloc(sizeof(char)); - memset(trace, 0, sizeof(char)); + char *trace = (char *)calloc(0, sizeof(char)); for (int i = 0; i < vm->frame_count; i++) { b_call_frame *frame = &vm->frames[i]; @@ -62,8 +62,7 @@ static b_value get_stack_trace(b_vm *vm){ trace_part, i < vm->frame_count - 1 ? "