diff --git a/src/main.c b/src/main.c index f4811a0..1f83d95 100644 --- a/src/main.c +++ b/src/main.c @@ -481,7 +481,7 @@ int main(int argc, char *argv[]) { } clock_t start = clock(), end; RuntimeState state = init_runtime_state(translated, path); - Stack *main_scope = create_scope(Global_Scope); + Stack *main_scope = create_scope(Global_Scope, true); runtime(translated, state, main_scope, &err); end = clock(); diff --git a/src/runtime/call/call.c b/src/runtime/call/call.c index d368253..5a028ed 100644 --- a/src/runtime/call/call.c +++ b/src/runtime/call/call.c @@ -125,7 +125,7 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv, (int)object_name->value.as_str.length, object_name->value.as_str.data, object->value.argon_fn.number_of_parameters, argc); } - Stack *scope = create_scope(object->value.argon_fn.stack); + Stack *scope = create_scope(object->value.argon_fn.stack, true); for (size_t i = 0; i < argc; i++) { struct string_struct key = object->value.argon_fn.parameters[i]; ArgonObject *value = argv[i]; diff --git a/src/runtime/internals/hashmap/hashmap.c b/src/runtime/internals/hashmap/hashmap.c index 6eb0edd..8312bcb 100644 --- a/src/runtime/internals/hashmap/hashmap.c +++ b/src/runtime/internals/hashmap/hashmap.c @@ -9,33 +9,38 @@ #include "../../../memory.h" #include #include -#include #include +#include #include #include struct hashmap_GC *createHashmap_GC() { - size_t size = 8; - struct hashmap_GC *t = - (struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC) + sizeof(struct node_GC *) * size); - t->size = size; - t->order = 1; - t->list = (struct node_GC **)((char*)t + sizeof(struct hashmap_GC)); - memset(t->list, 0, sizeof(struct node_GC *) * size); - t->count = 0; - return t; + struct hashmap_GC *t = + (struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC)); + t->size = 0; + t->order = 1; + t->list = NULL; + t->hashmap_count = 0; + t->count = 0; + t->inline_count = 0; + return t; } void clear_hashmap_GC(struct hashmap_GC *t) { - if (!t->count) return; + if (!t->hashmap_count) + return; t->order = 1; t->count = 0; + t->inline_count = 0; + t->hashmap_count = 0; memset(t->list, 0, sizeof(struct node_GC *) * t->size); } void resize_hashmap_GC(struct hashmap_GC *t) { int old_size = t->size; int new_size = old_size * 2; + if (new_size == 0) + new_size = 8; struct node_GC **old_list = t->list; @@ -44,8 +49,9 @@ void resize_hashmap_GC(struct hashmap_GC *t) { memset(t->list, 0, sizeof(struct node_GC *) * new_size); t->size = new_size; - t->count = 0; - + if (!old_list) + return; + t->hashmap_count = 0; // Rehash old entries into new list for (int i = 0; i < old_size; i++) { struct node_GC *temp = old_list[i]; @@ -77,9 +83,6 @@ int hashmap_remove_GC(struct hashmap_GC *t, uint64_t hash) { prev = temp; temp = temp->next; } - list = NULL; - prev = NULL; - temp = NULL; return 0; } @@ -88,7 +91,23 @@ void hashmap_insert_GC(struct hashmap_GC *t, uint64_t hash, void *key, if (!order) { order = t->order++; } - if ((t->count + 1) > t->size * 0.75) { + size_t stop = t->inline_count; + for (size_t i = 0; i < stop; i++) { + if (t->inline_values[i].hash == hash) { + t->inline_values[i].val = val; + return; + } + } + if (!t->list && stop < INLINE_HASHMAP_ARRAY_SIZE) { + t->inline_values[stop].hash = hash; + t->inline_values[stop].key = key; + t->inline_values[stop].val = val; + t->inline_values[stop].order = order; + t->inline_count++; + t->count++; + return; + } + if ((t->hashmap_count + 1) > t->size * 0.75) { resize_hashmap_GC(t); } @@ -113,10 +132,18 @@ void hashmap_insert_GC(struct hashmap_GC *t, uint64_t hash, void *key, newNode->order = order; newNode->next = list; t->list[pos] = newNode; + t->hashmap_count++; t->count++; } void *hashmap_lookup_GC(struct hashmap_GC *t, uint64_t hash) { + size_t stop = t->inline_count; + for (size_t i = 0; i < stop; i++) { + if (t->inline_values[i].hash == hash) + return t->inline_values[i].val; + } + if (!t->list) + return NULL; int pos = hashCode_GC(t, hash); struct node_GC *list = t->list[pos]; struct node_GC *temp = list; diff --git a/src/runtime/internals/hashmap/hashmap.h b/src/runtime/internals/hashmap/hashmap.h index e2043de..10b0688 100644 --- a/src/runtime/internals/hashmap/hashmap.h +++ b/src/runtime/internals/hashmap/hashmap.h @@ -6,9 +6,12 @@ #ifndef HASHMAP_GC_H #define HASHMAP_GC_H +#include #include #include +#define INLINE_HASHMAP_ARRAY_SIZE 3 + struct node_GC { uint64_t hash; void *key; @@ -18,7 +21,10 @@ struct node_GC { }; struct hashmap_GC { size_t size; + struct node_GC inline_values[INLINE_HASHMAP_ARRAY_SIZE]; size_t count; + size_t inline_count; + size_t hashmap_count; size_t order; struct node_GC **list; }; diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index 70f4c61..b80bb87 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -601,7 +601,7 @@ void add_to_scope(Stack *stack, char *name, ArgonObject *value) { } void bootstrap_globals() { - Global_Scope = create_scope(NULL); + Global_Scope = create_scope(NULL, true); add_to_scope(Global_Scope, "string", ARGON_STRING_TYPE); add_to_scope(Global_Scope, "type", ARGON_TYPE_TYPE); add_to_scope(Global_Scope, "boolean", ARGON_BOOL_TYPE); @@ -687,8 +687,8 @@ RuntimeState init_runtime_state(Translated translated, char *path) { return runtime; } -Stack *create_scope(Stack *prev) { - if (!prev || prev->scope->count) { +Stack *create_scope(Stack *prev, bool force) { + if (force || !prev || prev->scope->count) { Stack *stack = ar_alloc(sizeof(Stack)); stack->fake_new_scopes = 0; stack->scope = createHashmap_GC(); @@ -790,7 +790,7 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack, state->head = pop_bytecode(translated, state); continue; DO_NEW_SCOPE: - currentStackFrame->stack = create_scope(currentStackFrame->stack); + currentStackFrame->stack = create_scope(currentStackFrame->stack, false); continue; DO_EMPTY_SCOPE: clear_hashmap_GC(currentStackFrame->stack->scope); diff --git a/src/runtime/runtime.h b/src/runtime/runtime.h index 9f339e8..54d6c63 100644 --- a/src/runtime/runtime.h +++ b/src/runtime/runtime.h @@ -87,7 +87,7 @@ static inline void run_instruction(Translated *translated, RuntimeState *state, RuntimeState init_runtime_state(Translated translated, char *path); -Stack *create_scope(Stack *prev); +Stack *create_scope(Stack *prev, bool force); void runtime(Translated translated, RuntimeState state, Stack *stack, ArErr *err); diff --git a/src/shell.c b/src/shell.c index 0a36a92..dbc10ec 100644 --- a/src/shell.c +++ b/src/shell.c @@ -168,7 +168,7 @@ char *read_all_stdin(size_t *out_len) { int shell() { - Stack *main_scope = create_scope(Global_Scope); + Stack *main_scope = create_scope(Global_Scope, true); if (!isatty(STDIN_FILENO)) { RuntimeState runtime_state; diff --git a/tests/iteration-test.ar b/tests/iteration-test.ar index f858c3e..2c929db 100644 --- a/tests/iteration-test.ar +++ b/tests/iteration-test.ar @@ -1,3 +1,3 @@ -let i = 1e6 +let i = 1e7 while (i) do - i = i-1 \ No newline at end of file + i=i-1 \ No newline at end of file