diff options
author | Björn Gustavsson <[email protected]> | 2017-07-07 11:41:29 +0200 |
---|---|---|
committer | GitHub <[email protected]> | 2017-07-07 11:41:29 +0200 |
commit | 31d6c0fb10d076f77de40f4845ba8e94a8ca6da9 (patch) | |
tree | 5250176487dc0eb1bd551ec78c93dc4dec8844c9 /erts/emulator/beam/beam_emu.c | |
parent | 74261aaef3a6d010685268ef81d50d06621b5077 (diff) | |
parent | 245aa4ed9b41aa601784598b0b3286d29b6d0085 (diff) | |
download | otp-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.c | 50 |
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; |