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 garbage collection, reduce stalls

+16 -25
-3
include/gc.h
··· 2 2 #define GC_H 3 3 4 4 #include <types.h> 5 - #include <stddef.h> 6 5 #include <stdbool.h> 7 6 8 7 #define ROPE_FLAG (1ULL << 63) ··· 21 20 #define GC_FWD_LOAD_FACTOR 70 22 21 #define GC_ROOTS_INITIAL_CAP 32 23 22 #define GC_CB(ret, name, arg) ret (*name)(void *ctx, arg old) 24 - 25 - size_t js_gc_compact(ant_t *js); 26 23 27 24 #define GC_CTX void *ctx 28 25 #define GC_FWD_OFF GC_CB(jsoff_t, fwd_off, jsoff_t)
+16 -22
src/gc.c
··· 675 675 } 676 676 } 677 677 678 - size_t js_gc_compact(ant_t *js) { 679 - if (!js || js->brk == 0) return 0; 680 - if (js->brk < 2 * 1024 * 1024) return 0; 678 + static void gc_compact(ant_t *js) { 679 + js->needs_gc = false; 680 + 681 + if (!js || js->brk == 0) return; 682 + if (js->brk < 2 * 1024 * 1024) return; 681 683 682 684 if (!js->gc_safe) { 683 - js->needs_gc = true; 684 - return 0; 685 + js->needs_gc = true; return; 685 686 } 686 687 687 688 mco_coro *running = mco_running(); 688 689 int in_coroutine = (running != NULL && running->stack_base != NULL); 689 690 690 691 if (in_coroutine) { 691 - js->needs_gc = true; 692 - return 0; 692 + js->needs_gc = true; return; 693 693 } 694 694 695 695 time_t now = time(NULL); ··· 705 705 if (elapsed >= 0.0 706 706 && elapsed < cooldown 707 707 && js->gc_alloc_since < js->brk / 4 708 - ) return 0; 708 + ) return; 709 709 } 710 + 710 711 if (now != (time_t)-1) gc_last_run_time = now; 711 - 712 - size_t old_brk = js->brk; 713 712 size_t new_size = js->size; 714 713 715 714 if (new_size > gc_scratch_size) { ··· 718 717 gc_scratch_size = gc_scratch_buf ? new_size : 0; 719 718 } 720 719 721 - if (!gc_scratch_buf) return 0; 720 + if (!gc_scratch_buf) return; 722 721 uint8_t *new_mem = gc_scratch_buf; 723 722 724 723 size_t bitmap_size = (js->brk / 8 + 7) / 8 + 1; 725 724 uint8_t *mark_bits = (uint8_t *)calloc(1, bitmap_size); 726 - if (!mark_bits) return 0; 725 + if (!mark_bits) return; 727 726 728 727 size_t estimated_objs = js->brk / 64; 729 728 if (estimated_objs < 256) estimated_objs = 256; ··· 736 735 ctx.mark_bits = mark_bits; 737 736 738 737 if (!fwd_init(&ctx.fwd, estimated_objs)) { 739 - free(mark_bits); 740 - return 0; 738 + free(mark_bits); return; 741 739 } 742 740 743 741 if (!work_init(&ctx.work, estimated_objs / 4 < 64 ? 64 : estimated_objs / 4)) { 744 742 fwd_free(&ctx.fwd); 745 - free(mark_bits); 746 - return 0; 743 + free(mark_bits); return; 747 744 } 748 745 749 746 ctx.failed = false; ··· 765 762 if (ctx.failed) { 766 763 free(mark_bits); 767 764 work_free(&ctx.work); 768 - fwd_free(&ctx.fwd); 769 - return 0; 765 + fwd_free(&ctx.fwd); return; 770 766 } 771 767 772 768 js_gc_update_roots(js, ··· 795 791 if (target < ARENA_GROW_INCREMENT) target = ARENA_GROW_INCREMENT; 796 792 if (target < old_size) { ant_arena_decommit(js->mem, old_size, target); js->size = (jsoff_t)target; } 797 793 } 798 - 799 - return (old_brk > new_brk ? old_brk - new_brk : 0); 800 794 } 801 795 802 796 void js_gc_maybe(ant_t *js) { ··· 814 808 if (thresh > max_thresh) thresh = max_thresh; 815 809 816 810 if (js->gc_alloc_since > thresh || js->needs_gc) { 817 - js->needs_gc = false; 818 - if (js_gc_compact(js) > 0) js->gc_alloc_since = 0; 811 + gc_compact(js); 812 + js->gc_alloc_since = 0; 819 813 } 820 814 }