diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index c821ff9f3a42..a5213f3bba36 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -562,7 +562,10 @@ delay_garbage_collection(Process *p, int need, int fcalls) /* Point at the end of the address range to ensure that * test for the safe range in the new heap in the - * update_record_in_place instruction fails. */ + * update_record_in_place instruction fails. Save the previous + * value of the high water mark to make it possible to make the + * next GC a minor one. */ + p->abandoned_high_water = p->high_water; p->high_water = (Eterm *) (Uint) -1; } @@ -1382,8 +1385,8 @@ minor_collection(Process* p, ErlHeapFragment *live_hf_end, Uint need, Eterm* objv, int nobj, Uint ygen_usage, Uint *recl) { - Eterm *mature = p->abandoned_heap ? p->abandoned_heap : p->heap; - Uint mature_size = p->high_water - mature; + Eterm *mature; + Uint mature_size; Uint size_before = ygen_usage; #ifdef DEBUG Uint debug_tmp = 0; @@ -1391,6 +1394,22 @@ minor_collection(Process* p, ErlHeapFragment *live_hf_end, need += S_RESERVED; + +#ifdef DEBUG + if (p->abandoned_heap) { + ASSERT(p->abandoned_heap <= p->abandoned_high_water); + ASSERT(p->abandoned_high_water != (Uint) -1); + } +#endif + + if (p->abandoned_heap) { + mature = p->abandoned_heap; + mature_size = p->abandoned_high_water - mature; + } else { + mature = p->heap; + mature_size = p->high_water - mature; + } + /* * Check if we have gone past the max heap size limit */ diff --git a/erts/emulator/beam/erl_process.h b/erts/emulator/beam/erl_process.h index b3eae36e7089..acf8e41a5210 100644 --- a/erts/emulator/beam/erl_process.h +++ b/erts/emulator/beam/erl_process.h @@ -1113,6 +1113,7 @@ struct process { Uint16 gen_gcs; /* Number of (minor) generational GCs. */ Uint16 max_gen_gcs; /* Max minor gen GCs before fullsweep. */ Eterm *high_water; + Eterm *abandoned_high_water; Eterm *old_hend; /* Heap pointers for generational GC. */ Eterm *old_htop; Eterm *old_heap;