File 5811-erts-Optimize-maps-merge-2-further-with-heap-mutatio.patch of Package erlang

From 93d1dd208da2e974715ad55df0ba939c36e02ed0 Mon Sep 17 00:00:00 2001
From: Sverker Eriksson <sverker@erlang.org>
Date: Fri, 17 Mar 2023 13:36:54 +0100
Subject: [PATCH] erts: Optimize maps:merge/2 further with heap mutation

If both maps have all the keys and 1st map have a literal key tuple
but 2nd map does not, then we mutate 2nd map with literal key tuple
before returning it.
---
 erts/emulator/beam/erl_map.c     | 10 ++++++++++
 erts/emulator/test/map_SUITE.erl |  2 ++
 2 files changed, 12 insertions(+)

diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c
index 47109ccc84..e7452f4e8c 100644
--- a/erts/emulator/beam/erl_map.c
+++ b/erts/emulator/beam/erl_map.c
@@ -1407,6 +1407,16 @@ static Eterm flatmap_merge(Process *p, Eterm map1, Eterm map2) {
 
         if (n == n2) {
             /* Reuse entire map2 */
+            if (n == n1
+                &&  erts_is_literal(mp1->keys, boxed_val(mp1->keys))
+                && !erts_is_literal(mp2->keys, boxed_val(mp2->keys))) {
+                /*
+                 * We want map2, but map1 has a nice literal key tuple.
+                 * Solution: MUTATE HEAP to get both.
+                 */
+                ASSERT(eq(mp1->keys, mp2->keys));
+                mp2->keys = mp1->keys;
+            }
             HRelease(p, hp, (Eterm *)mp_new);
             return map2;
         }
diff --git a/erts/emulator/test/map_SUITE.erl b/erts/emulator/test/map_SUITE.erl
index 99e5e1af7d..030ad5ee13 100644
--- a/erts/emulator/test/map_SUITE.erl
+++ b/erts/emulator/test/map_SUITE.erl
@@ -2207,6 +2207,8 @@ t_bif_map_merge(Config) when is_list(Config) ->
     false = erts_debug:same(erts_internal:map_to_tuple_keys(MS_c), MS_keys),
     MS_cc = maps:merge(MS, MS_c),
     true = erts_debug:same(MS_cc, MS_c),
+    %% not only do we reuse MS_c, it has mutated to use the literal keys of MS
+    true = erts_debug:same(erts_internal:map_to_tuple_keys(MS_c), MS_keys),
 
     MS_d = maps:merge(MS_c, MS),
     true = erts_debug:same(MS_d, MS),
-- 
2.35.3

openSUSE Build Service is sponsored by