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 dynamic memory management

+50 -6
+21 -4
src/ant.c
··· 1059 1059 } 1060 1060 1061 1061 if (!(work & WORK_BLOCKING) && (work & WORK_TIMERS)) { 1062 - if (js->gc_alloc_since > 256 * 1024 * 1024 || js->needs_gc) { 1062 + jsoff_t gc_thresh = js->brk / 2; 1063 + if (gc_thresh < 4 * 1024 * 1024) gc_thresh = 4 * 1024 * 1024; 1064 + if (js->gc_alloc_since > gc_thresh || js->needs_gc) { 1063 1065 js->needs_gc = false; 1064 1066 js_gc_compact(js); 1065 1067 js->gc_alloc_since = 0; ··· 2473 2475 js->brk += (jsoff_t) size; 2474 2476 js->gc_alloc_since += (jsoff_t) size; 2475 2477 2476 - if (js->gc_alloc_since > 256 * 1024 * 1024) js->needs_gc = true; 2478 + jsoff_t threshold = js->brk / 2; 2479 + if (threshold < 4 * 1024 * 1024) threshold = 4 * 1024 * 1024; 2480 + if (js->gc_alloc_since > threshold) js->needs_gc = true; 2477 2481 } 2478 2482 2479 2483 static inline jsoff_t js_alloc(struct js *js, size_t size) { ··· 22485 22489 22486 22490 js->owns_mem = true; 22487 22491 js->max_size = (jsoff_t) max_size; 22492 + 22493 + struct js *new_js = (struct js *)malloc(sizeof(struct js)); 22494 + if (new_js == NULL) { 22495 + ant_arena_free(arena, max_size); 22496 + free(init_buf); 22497 + return NULL; 22498 + } 22499 + 22500 + memcpy(new_js, js, sizeof(struct js)); 22501 + free(init_buf); 22488 22502 22489 - return js; 22503 + return new_js; 22490 22504 } 22491 22505 22492 22506 void js_destroy(struct js *js) { ··· 22505 22519 js->for_let_stack = NULL; 22506 22520 } 22507 22521 22508 - if (js->owns_mem) ant_arena_free(js->mem, js->max_size); 22522 + if (js->owns_mem) { 22523 + ant_arena_free(js->mem, js->max_size); 22524 + free(js); 22525 + } 22509 22526 } 22510 22527 22511 22528 inline double js_getnum(jsval_t value) { return tod(value); }
+29 -2
src/gc.c
··· 513 513 time_t now = time(NULL); 514 514 if (now != (time_t)-1 && gc_last_run_time != 0) { 515 515 double elapsed = difftime(now, gc_last_run_time); 516 - if (elapsed >= 0.0 && elapsed < 5.0) return 0; 516 + double cooldown; 517 + if (js->brk > 128 * 1024 * 1024) cooldown = 5.0; 518 + else if (js->brk > 64 * 1024 * 1024) cooldown = 10.0; 519 + else if (js->brk > 16 * 1024 * 1024) cooldown = 15.0; 520 + else cooldown = 30.0; 521 + if (elapsed >= 0.0 && elapsed < cooldown) return 0; 517 522 } 518 523 519 524 mco_coro *running = mco_running(); 520 525 int in_coroutine = (running != NULL && running->stack_base != NULL); 521 526 522 - if (in_coroutine || js_has_pending_coroutines()) return 0; 527 + if (in_coroutine) return 0; 523 528 if (now != (time_t)-1) gc_last_run_time = now; 524 529 525 530 size_t old_brk = js->brk; ··· 607 612 free(mark_bits); 608 613 work_free(&ctx.work); 609 614 fwd_free(&ctx.fwd); 615 + 616 + if (gc_scratch_buf) { 617 + gc_munmap(gc_scratch_buf, gc_scratch_size); 618 + gc_scratch_buf = NULL; 619 + gc_scratch_size = 0; 620 + } 621 + 622 + size_t page_size = 4096; 623 + size_t used_pages = (ctx.new_brk + page_size - 1) & ~(page_size - 1); 624 + 625 + if (js->size > used_pages) { 626 + size_t release_size = js->size - used_pages; 627 + void *release_start = js->mem + used_pages; 628 + 629 + #ifdef _WIN32 630 + VirtualFree(release_start, release_size, MEM_DECOMMIT); 631 + VirtualAlloc(release_start, release_size, MEM_COMMIT, PAGE_READWRITE); 632 + #else 633 + void *p = mmap(release_start, release_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0); 634 + if (p == MAP_FAILED) madvise(release_start, release_size, MADV_DONTNEED); 635 + #endif 636 + } 610 637 611 638 return (old_brk > ctx.new_brk ? old_brk - ctx.new_brk : 0); 612 639 }