From a5dd6499d53ed596e2f8aa17ee35ff87cd32fe60 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Thu, 19 Nov 2015 17:07:06 +0100 Subject: Distinguish between GC disabled by BIFs and other disabled GC Processes remember heap fragments that are known to be fully live due to creation in a just called BIF that yields in the live_hf_end field. This field must not be used if we have not disabled GC in a BIF. F_DELAY_GC has been introduced in order to distinguish between to two different scenarios. - F_DISABLE_GC should *only* be used by BIFs. This when the BIF needs to yield while preventig a GC. - F_DELAY_GC should only be used when GC is temporarily disabled while the process is scheduled. A process must not be scheduled out while F_DELAY_GC is set. --- erts/emulator/beam/erl_gc.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'erts/emulator/beam/erl_gc.c') diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index 3bb1f601aa..3784367195 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -440,8 +440,15 @@ delay_garbage_collection(Process *p, ErlHeapFragment *live_hf_end, int need) ERTS_HOLE_CHECK(p); - if (p->live_hf_end == ERTS_INVALID_HFRAG_PTR) + if ((p->flags & F_DISABLE_GC) + && p->live_hf_end == ERTS_INVALID_HFRAG_PTR) { + /* + * A BIF yielded with disabled GC. Remember + * heap fragments created by the BIF until we + * do next GC. + */ p->live_hf_end = live_hf_end; + } if (need == 0) return 1; @@ -564,10 +571,12 @@ garbage_collect(Process* p, ErlHeapFragment *live_hf_end, DTRACE_CHARBUF(pidbuf, DTRACE_TERM_BUF_SIZE); #endif - if (p->flags & F_DISABLE_GC) + if (p->flags & (F_DISABLE_GC|F_DELAY_GC)) return delay_garbage_collection(p, live_hf_end, need); - if (p->live_hf_end != ERTS_INVALID_HFRAG_PTR) + if (p->abandoned_heap) + live_hf_end = ERTS_INVALID_HFRAG_PTR; + else if (p->live_hf_end != ERTS_INVALID_HFRAG_PTR) live_hf_end = p->live_hf_end; esdp = erts_get_scheduler_data(); -- cgit v1.2.3