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.

optimize GC during coroutine execution by deferring compaction

+20 -15
+3 -3
src/ant.c
··· 22519 22519 22520 22520 promise_data_entry_t *pd, *pd_tmp; 22521 22521 promise_data_entry_t *new_unhandled = NULL; 22522 + 22522 22523 for ( 22523 22524 promise_data_entry_t *new_promise_registry = NULL, *_once = NULL; !_once; _once = (void*)1, 22524 22525 promise_registry = new_promise_registry, unhandled_rejections = new_unhandled ··· 22534 22535 22535 22536 bool can_collect = (pd->state != 0) && (utarray_len(pd->handlers) == 0); 22536 22537 if (can_collect) { utarray_free(pd->handlers); free(pd); continue; } 22537 - 22538 22538 pd->obj_offset = new_off; 22539 22539 FWD_VAL(pd->value); 22540 22540 UTARRAY_EACH(pd->handlers, promise_handler_t, h) { ··· 22546 22546 HASH_ADD(hh, new_promise_registry, promise_id, sizeof(uint32_t), pd); 22547 22547 if (in_unhandled) HASH_ADD(hh_unhandled, new_unhandled, promise_id, sizeof(uint32_t), pd); 22548 22548 } 22549 + 22549 22550 22550 22551 proxy_data_t *proxy, *proxy_tmp; 22551 22552 for (proxy_data_t *new_proxy_registry = NULL, *_once = NULL; !_once; _once = (void*)1, proxy_registry = new_proxy_registry) ··· 22651 22652 res = js_stmt(js); 22652 22653 if (js->needs_gc && js->eval_depth == 1) { 22653 22654 js->needs_gc = false; 22654 - js_gc_compact(js); 22655 - js->gc_alloc_since = 0; 22655 + if (js_gc_compact(js) > 0) js->gc_alloc_since = 0; 22656 22656 } 22657 22657 if (js->flags & F_RETURN) break; 22658 22658 }
+10 -8
src/gc.c
··· 573 573 if (!js || js->brk == 0) return 0; 574 574 if (js->brk < 2 * 1024 * 1024) return 0; 575 575 576 + mco_coro *running = mco_running(); 577 + int in_coroutine = (running != NULL && running->stack_base != NULL); 578 + 579 + if (in_coroutine) { 580 + js->needs_gc = true; 581 + return 0; 582 + } 583 + 576 584 time_t now = time(NULL); 577 585 if (now != (time_t)-1 && gc_last_run_time != 0) { 578 586 double elapsed = difftime(now, gc_last_run_time); ··· 588 596 && js->gc_alloc_since < js->brk / 4 589 597 ) return 0; 590 598 } 591 - 592 - mco_coro *running = mco_running(); 593 - int in_coroutine = (running != NULL && running->stack_base != NULL); 594 - 595 - if (in_coroutine) return 0; 596 599 if (now != (time_t)-1) gc_last_run_time = now; 597 600 598 601 size_t old_brk = js->brk; ··· 681 684 return (old_brk > new_brk ? old_brk - new_brk : 0); 682 685 } 683 686 684 - void js_maybe_gc(ant_t *js) { 687 + void js_gc_maybe(ant_t *js) { 685 688 jsoff_t thresh = js->brk / 4; 686 689 687 690 jsoff_t min_thresh = gc_throttled ··· 697 700 698 701 if (js->gc_alloc_since > thresh || js->needs_gc) { 699 702 js->needs_gc = false; 700 - js_gc_compact(js); 701 - js->gc_alloc_since = 0; 703 + if (js_gc_compact(js) > 0) js->gc_alloc_since = 0; 702 704 } 703 705 }
+1 -2
src/reactor.c
··· 47 47 48 48 if (js->needs_gc) { 49 49 js->needs_gc = false; 50 - js_gc_compact(js); 51 - js->gc_alloc_since = 0; 50 + if (js_gc_compact(js) > 0) js->gc_alloc_since = 0; 52 51 } 53 52 54 53 if (g_poll_hook) g_poll_hook(g_poll_hook_data);
+2
src/sugar.c
··· 1 1 #include "internal.h" 2 + #include "gc.h" 2 3 #include "errors.h" 3 4 #include "sugar.h" 4 5 ··· 250 251 if (mco_status(mco) == MCO_DEAD) { 251 252 remove_coroutine(coro); 252 253 free_coroutine(coro); 254 + js_gc_maybe(js); 253 255 } 254 256 255 257 return promise;
+4 -2
tests/test_gc_coro.js
··· 53 53 clearInterval(interval); 54 54 console.log('Done - forcing GC...'); 55 55 Ant.gc(); 56 - const after = Ant.stats(); 57 - console.log(`after GC: arena ${(after.arenaUsed / 1024 / 1024).toFixed(1)}MB`); 56 + setTimeout(() => { 57 + const after = Ant.stats(); 58 + console.log(`after GC: arena ${(after.arenaUsed / 1024 / 1024).toFixed(1)}MB`); 59 + }, 10); 58 60 } 59 61 }, 10); // 500 * 10ms = 5 seconds