File 7972-erts-Don-t-allocate-a-new-heap-that-we-know-will-not.patch of Package erlang
From 48812d99f7c474a1edcd1c38b423897990dc9228 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Thu, 15 Dec 2022 22:23:35 +0100
Subject: [PATCH 2/4] erts: Don't allocate a new heap that we know will not
suffice
Base size of new new-heap of the 'need'
if it's larger than 'ygen_usage'.
---
erts/emulator/beam/erl_gc.c | 4 ++--
erts/emulator/test/gc_SUITE.erl | 19 +++++++++++++++++++
2 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c
index 14d16eb734..719720cdf1 100644
--- a/erts/emulator/beam/erl_gc.c
+++ b/erts/emulator/beam/erl_gc.c
@@ -1452,7 +1452,7 @@ minor_collection(Process* p, ErlHeapFragment *live_hf_end,
heap_size += OLD_HEND(p) - OLD_HEAP(p);
/* Add potential new young heap size */
- extra_heap_size = next_heap_size(p, stack_size + size_before, 0);
+ extra_heap_size = next_heap_size(p, stack_size + MAX(size_before,need), 0);
heap_size += extra_heap_size;
if (has_reached_max_heap_size(p, heap_size))
@@ -1494,7 +1494,7 @@ minor_collection(Process* p, ErlHeapFragment *live_hf_end,
Uint stack_size, size_after, adjust_size, need_after, new_sz, new_mature;
stack_size = STACK_START(p) - STACK_TOP(p);
- new_sz = stack_size + size_before;
+ new_sz = stack_size + MAX(size_before, need);
new_sz = next_heap_size(p, new_sz, 0);
prev_old_htop = p->old_htop;
diff --git a/erts/emulator/test/gc_SUITE.erl b/erts/emulator/test/gc_SUITE.erl
index 810409175e..ac519f30f8 100644
--- a/erts/emulator/test/gc_SUITE.erl
+++ b/erts/emulator/test/gc_SUITE.erl
@@ -32,6 +32,7 @@
grow_stack/1,
grow_stack_heap/1,
max_heap_size/1,
+ max_heap_size_large_hfrag/1,
minor_major_gc_option_async/1,
minor_major_gc_option_self/1,
gc_signal_order/1,
@@ -43,6 +44,7 @@ suite() ->
all() ->
[grow_heap, grow_stack, grow_stack_heap, max_heap_size,
+ max_heap_size_large_hfrag,
minor_major_gc_option_self,
minor_major_gc_option_async, gc_signal_order, gc_dirty_exec_proc,
alias_signals_in_gc].
@@ -204,6 +206,23 @@ long_receive() ->
ok
end.
+%% Trigger gc-after-bif with a large heap fragment, which provoked some bugs.
+max_heap_size_large_hfrag(Config) ->
+ {Pid, Ref} =
+ spawn_opt(
+ fun Fun() ->
+ erlang:make_tuple(2000, []),
+ Fun()
+ end,
+ [monitor, {max_heap_size, 1000}]),
+ %% Verify that max heap was triggered
+ {'DOWN', Ref, process, Pid, killed} =
+ receive M -> M
+ after 5000 ->
+ ct:fail({process_did_not_die, Pid, erlang:process_info(Pid)})
+ end,
+ ok.
+
minor_major_gc_option_self(_Config) ->
%% Try as major, the test process will self-trigger GC
check_gc_tracing_around(
--
2.35.3