MIRROR: javascript for ๐Ÿœ's, a tiny runtime with big ambitions
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

improve release in garbage collection

+56 -16
+16 -6
src/ant.c
··· 1070 1070 if (res != MCO_SUCCESS && mco_status(mco) != MCO_DEAD) { 1071 1071 remove_coroutine(coro); 1072 1072 free_coroutine(coro); 1073 - CORO_FREE(ctx); 1074 1073 return js_mkerr(js, "failed to start coroutine"); 1075 1074 } 1076 1075 ··· 1078 1077 if (mco_status(mco) == MCO_DEAD) { 1079 1078 remove_coroutine(coro); 1080 1079 free_coroutine(coro); 1081 - CORO_FREE(ctx); 1082 1080 } 1083 1081 1084 1082 return promise; ··· 1088 1086 if (coro) { 1089 1087 if (coro->mco) { 1090 1088 if (mco_running() == coro->mco) fprintf(stderr, "WARNING: Attempting to free a running coroutine\n"); 1089 + async_exec_context_t *ctx = (async_exec_context_t *)mco_get_user_data(coro->mco); 1090 + if (ctx) CORO_FREE(ctx); 1091 1091 mco_destroy(coro->mco); 1092 1092 coro->mco = NULL; 1093 1093 } ··· 2234 2234 } 2235 2235 2236 2236 if (remaining > 60 && js->filename && strcmp(js->filename, "[eval]") != 0) { 2237 - *n += (size_t) snprintf(js->errmsg + *n, remaining, "\n at Module.executeUserEntryPoint [as runMain] %s(ant:internal/modules/run_main:70:5)%s", dim, reset); 2237 + *n += (size_t) snprintf(js->errmsg + *n, remaining, "\n at Module.executeUserEntryPoint [as runMain] %s(ant:internal/modules/run_main:149:5)%s", dim, reset); 2238 2238 remaining = js->errmsg_size - *n; 2239 2239 } 2240 2240 2241 2241 if (remaining > 40 && js->filename && strcmp(js->filename, "[eval]") != 0) { 2242 - *n += (size_t) snprintf(js->errmsg + *n, remaining, "\n at %sant:internal/main:217:5%s", dim, reset); 2242 + *n += (size_t) snprintf(js->errmsg + *n, remaining, "\n at %sant:internal/call:21728:23%s", dim, reset); 2243 2243 } 2244 2244 } 2245 2245 ··· 18465 18465 } 18466 18466 18467 18467 utarray_clear(pd->handlers); 18468 + 18469 + if (pd->state != 0) { 18470 + utarray_free(pd->handlers); 18471 + HASH_DEL(promise_registry, pd); 18472 + free(pd); 18473 + } 18474 + 18468 18475 return js_mkundef(); 18469 18476 } 18470 18477 ··· 21317 21324 return js; 21318 21325 } 21319 21326 21327 + #define MIN_SIZE 16 * 1024 21328 + #define MAX_SIZE 1024 * 1024 * 1024 21329 + 21320 21330 struct js *js_create_dynamic(size_t initial_size, size_t max_size) { 21321 - if (initial_size < sizeof(struct js) + esize(T_OBJ)) initial_size = 16 * 1024; 21322 - if (max_size == 0 || max_size < initial_size) max_size = 512 * 1024 * 1024; 21331 + if (initial_size < sizeof(struct js) + esize(T_OBJ)) initial_size = MIN_SIZE; 21332 + if (max_size == 0 || max_size < initial_size) max_size = MAX_SIZE; 21323 21333 21324 21334 void *buf = ANT_GC_MALLOC(initial_size); 21325 21335 if (buf == NULL) return NULL;
+21 -1
src/gc.c
··· 9 9 #define MCO_API extern 10 10 #include "minicoro.h" 11 11 12 + #define GC_MIN_HEAP_SIZE (64 * 1024) 13 + #define GC_SHRINK_THRESHOLD 4 14 + 12 15 typedef struct gc_forward_node { 13 16 jsoff_t old_off; 14 17 jsoff_t new_off; ··· 331 334 } 332 335 333 336 size_t old_brk = js->brk; 334 - size_t new_size = js->size; 337 + size_t old_size = js->size; 338 + size_t new_size = old_size; 335 339 336 340 uint8_t *new_mem = (uint8_t *)ANT_GC_MALLOC(new_size); 337 341 if (!new_mem) return 0; ··· 372 376 js->brk = ctx.new_brk; 373 377 374 378 ANT_GC_FREE(old_mem); 379 + 380 + size_t used = ctx.new_brk; 381 + size_t shrunk_size = used * 2; 382 + if (shrunk_size < GC_MIN_HEAP_SIZE) shrunk_size = GC_MIN_HEAP_SIZE; 383 + shrunk_size = (shrunk_size + 7) & ~7; 384 + 385 + if (old_size >= GC_SHRINK_THRESHOLD * shrunk_size && shrunk_size < old_size) { 386 + uint8_t *shrunk_mem = (uint8_t *)ANT_GC_MALLOC(shrunk_size); 387 + if (shrunk_mem) { 388 + memcpy(shrunk_mem, js->mem, used); 389 + memset(shrunk_mem + used, 0, shrunk_size - used); 390 + ANT_GC_FREE(js->mem); 391 + js->mem = shrunk_mem; 392 + js->size = (jsoff_t)shrunk_size; 393 + } 394 + } 375 395 376 396 jsoff_t free_space = js->size - js->brk; 377 397 if (free_space < js->lwm || js->lwm == 0) {
+6 -8
src/main.c
··· 166 166 struct arg_lit *no_color = arg_lit0(NULL, "no-color", "disable colored output"); 167 167 struct arg_str *eval = arg_str0("e", "eval", "<script>", "evaluate script"); 168 168 struct arg_lit *print = arg_lit0("p", "print", "evaluate script and print result"); 169 - struct arg_int *initial_mem = arg_int0(NULL, "initial-mem", "<size>", "initial memory size in MB (default: 4)"); 170 - struct arg_int *max_mem = arg_int0(NULL, "max-mem", "<size>", "maximum memory size in MB (default: 512)"); 169 + struct arg_int *initial_mem = arg_int0(NULL, "initial-mem", "<size>", "initial memory size in KB (default: 16kb)"); 170 + struct arg_int *max_mem = arg_int0(NULL, "max-mem", "<size>", "maximum memory size in MB (default: 1024mb)"); 171 171 struct arg_file *localstorage_file = arg_file0(NULL, "localstorage-file", "<path>", "file path for localStorage persistence"); 172 172 struct arg_file *file = arg_file0(NULL, NULL, "<module.js>", "JavaScript module file to execute"); 173 173 struct arg_end *end = arg_end(20); ··· 203 203 const char *module_file = repl_mode ? NULL : (file->count > 0 ? file->filename[0] : NULL); 204 204 dump = debug->count; 205 205 206 - size_t initial_size = 16 * 1024; 207 - size_t max_size = 512 * 1024 * 1024; 208 - 209 - if (initial_mem->count > 0) initial_size = (size_t)initial_mem->ival[0] * 16 * 1024; 210 - if (max_mem->count > 0) max_size = (size_t)max_mem->ival[0] * 1024 * 1024; 211 206 if (no_color->count > 0) io_no_color = true; 212 207 213 - struct js *js = js_create_dynamic(initial_size, max_size); 208 + struct js *js = js_create_dynamic( 209 + initial_mem->count > 0 ? (size_t)initial_mem->ival[0] * 1024 : 0, 210 + max_mem->count > 0 ? (size_t)max_mem->ival[0] * 1024 * 1024 : 0 211 + ); 214 212 215 213 if (js == NULL) { 216 214 fprintf(stderr, "Error: Failed to allocate JavaScript runtime\n");
+13 -1
src/modules/server.c
··· 96 96 static uv_loop_t *g_loop = NULL; 97 97 static int g_loop_initialized = 0; 98 98 static uv_timer_t g_js_timer; 99 + static int g_request_count = 0; 99 100 100 101 static void server_signal_handler(int signum) { 101 102 (void)signum; ··· 686 687 http_server_t *server = client->server; 687 688 jsval_t result = js_mkundef(); 688 689 690 + if (++g_request_count >= 1000 * 10) { 691 + js_gc_compact(server->js); 692 + g_request_count = 0; 693 + 694 + server->store_obj = js_get_slot(server->js, rt->ant_obj, SLOT_DATA); 695 + server->handler = js_get_slot(server->js, server->store_obj, SLOT_DATA); 696 + } 697 + 689 698 response_ctx_t *res_ctx = malloc(sizeof(response_ctx_t)); 690 699 if (!res_ctx) { 691 700 fprintf(stderr, "Failed to allocate response context\n"); ··· 926 935 server->js = js; 927 936 server->port = port; 928 937 938 + server->store_obj = js_mkobj(js); 929 939 server->handler = (nargs >= 2) ? args[1] : js_mkundef(); 930 - server->store_obj = js_mkobj(js); 940 + 941 + js_set_slot(js, server->store_obj, SLOT_DATA, server->handler); 942 + js_set_slot(js, rt->ant_obj, SLOT_DATA, server->store_obj); 931 943 932 944 if (!g_loop_initialized) { 933 945 g_loop = uv_default_loop();