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

openSUSE Build Service is sponsored by