aboutsummaryrefslogtreecommitdiffstats
path: root/erts
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-03-20 14:45:31 +0100
committerBjörn Gustavsson <[email protected]>2015-04-13 12:37:54 +0200
commit8c5a577ed55a607841989763d78b3950eebd5b5f (patch)
tree4be8ac0cee97359f1f0a8573e4d07aae7b27fd3f /erts
parent82b0a889fd2534af81e21c277657adf58699d73c (diff)
downloadotp-8c5a577ed55a607841989763d78b3950eebd5b5f.tar.gz
otp-8c5a577ed55a607841989763d78b3950eebd5b5f.tar.bz2
otp-8c5a577ed55a607841989763d78b3950eebd5b5f.zip
Correct transformation of put_map_assoc to new_map
A put_map_assoc instruction with an empty source map should be converted to a simpler new_map instruction. The transformation didn't happen because an empty source map is no longer represented as a NIL term (as it was in the beginning before map literals were implemented).
Diffstat (limited to 'erts')
-rw-r--r--erts/emulator/beam/beam_load.c17
-rw-r--r--erts/emulator/beam/ops.tab3
2 files changed, 19 insertions, 1 deletions
diff --git a/erts/emulator/beam/beam_load.c b/erts/emulator/beam/beam_load.c
index 02689e5b19..f140bb54cc 100644
--- a/erts/emulator/beam/beam_load.c
+++ b/erts/emulator/beam/beam_load.c
@@ -36,6 +36,7 @@
#include "beam_catches.h"
#include "erl_binary.h"
#include "erl_zlib.h"
+#include "erl_map.h"
#ifdef HIPE
#include "hipe_bif0.h"
@@ -4051,6 +4052,22 @@ tuple_append_put(LoaderState* stp, GenOpArg Arity, GenOpArg Dst,
}
/*
+ * Predicate to test whether the given literal is an empty map.
+ */
+
+static int
+is_empty_map(LoaderState* stp, GenOpArg Lit)
+{
+ Eterm term;
+
+ if (Lit.type != TAG_q) {
+ return 0;
+ }
+ term = stp->literals[Lit.val].term;
+ return is_flatmap(term) && flatmap_get_size(flatmap_val(term)) == 0;
+}
+
+/*
* Replace a get_map_elements with one key to an instruction with one
* element
*/
diff --git a/erts/emulator/beam/ops.tab b/erts/emulator/beam/ops.tab
index ae3b7d08b8..2c4458ae74 100644
--- a/erts/emulator/beam/ops.tab
+++ b/erts/emulator/beam/ops.tab
@@ -1473,7 +1473,8 @@ apply_last I P
# Map instructions in R17.
#
-put_map_assoc F n Dst Live Size Rest=* => new_map F Dst Live Size Rest
+put_map_assoc F Map Dst Live Size Rest=* | is_empty_map(Map) => \
+ new_map F Dst Live Size Rest
put_map_assoc F Src=s Dst Live Size Rest=* => \
update_map_assoc F Src Dst Live Size Rest
put_map_assoc F Src Dst Live Size Rest=* => \