aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-07-07 11:41:29 +0200
committerGitHub <[email protected]>2017-07-07 11:41:29 +0200
commit31d6c0fb10d076f77de40f4845ba8e94a8ca6da9 (patch)
tree5250176487dc0eb1bd551ec78c93dc4dec8844c9 /erts/emulator/beam/beam_emu.c
parent74261aaef3a6d010685268ef81d50d06621b5077 (diff)
parent245aa4ed9b41aa601784598b0b3286d29b6d0085 (diff)
downloadotp-31d6c0fb10d076f77de40f4845ba8e94a8ca6da9.tar.gz
otp-31d6c0fb10d076f77de40f4845ba8e94a8ca6da9.tar.bz2
otp-31d6c0fb10d076f77de40f4845ba8e94a8ca6da9.zip
Merge pull request #1498 from michalmuskala/new_map_lit
Introduce new_map_lit operation in the loader OTP-14502
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index 872fba6899..507aa7636c 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -1080,6 +1080,7 @@ static BeamInstr* apply_fun(Process* p, Eterm fun,
static Eterm new_fun(Process* p, Eterm* reg,
ErlFunEntry* fe, int num_free) NOINLINE;
static Eterm new_map(Process* p, Eterm* reg, BeamInstr* I) NOINLINE;
+static Eterm new_small_map_lit(Process* p, Eterm* reg, Uint* n_exp, BeamInstr* I) NOINLINE;
static Eterm update_map_assoc(Process* p, Eterm* reg,
Eterm map, BeamInstr* I) NOINLINE;
static Eterm update_map_exact(Process* p, Eterm* reg,
@@ -2461,6 +2462,17 @@ void process_main(Eterm * x_reg_array, FloatDef* f_reg_array)
Next(3+Arg(2));
}
+ OpCase(i_new_small_map_lit_dIq): {
+ Eterm res;
+ Uint n;
+
+ HEAVY_SWAPOUT;
+ res = new_small_map_lit(c_p, reg, &n, I-1);
+ HEAVY_SWAPIN;
+ StoreResult(res, Arg(0));
+ Next(3+n);
+ }
+
#define PUT_TERM_REG(term, desc) \
do { \
switch (loader_tag(desc)) { \
@@ -7007,6 +7019,44 @@ new_map(Process* p, Eterm* reg, BeamInstr* I)
}
static Eterm
+new_small_map_lit(Process* p, Eterm* reg, Uint* n_exp, BeamInstr* I)
+{
+ Eterm* keys = tuple_val(Arg(3));
+ Uint n = arityval(*keys);
+ Uint need = n + 1 /* hdr */ + 1 /*size*/ + 1 /* ptr */ + 1 /* arity */;
+ Uint i;
+ BeamInstr *ptr;
+ flatmap_t *mp;
+ Eterm *mhp;
+ Eterm *E;
+
+ *n_exp = n;
+ ptr = &Arg(4);
+
+ ASSERT(n <= MAP_SMALL_MAP_LIMIT);
+
+ if (HeapWordsLeft(p) < need) {
+ erts_garbage_collect(p, need, reg, Arg(2));
+ }
+
+ mhp = p->htop;
+ E = p->stop;
+
+ mp = (flatmap_t *)mhp; mhp += MAP_HEADER_FLATMAP_SZ;
+ mp->thing_word = MAP_HEADER_FLATMAP;
+ mp->size = n;
+ mp->keys = Arg(3);
+
+ for (i = 0; i < n; i++) {
+ GET_TERM(*ptr++, *mhp++);
+ }
+
+ p->htop = mhp;
+
+ return make_flatmap(mp);
+}
+
+static Eterm
update_map_assoc(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
{
Uint n;