From 8c5a577ed55a607841989763d78b3950eebd5b5f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B6rn=20Gustavsson?= Date: Fri, 20 Mar 2015 14:45:31 +0100 Subject: 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). --- erts/emulator/beam/beam_load.c | 17 +++++++++++++++++ erts/emulator/beam/ops.tab | 3 ++- 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'erts') 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" @@ -4050,6 +4051,22 @@ tuple_append_put(LoaderState* stp, GenOpArg Arity, GenOpArg Dst, return op; } +/* + * 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=* => \ -- cgit v1.2.3