diff options
-rw-r--r-- | erts/emulator/beam/beam_emu.c | 22 | ||||
-rw-r--r-- | erts/emulator/beam/erl_map.c | 6 |
2 files changed, 24 insertions, 4 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c index c753e57ddc..8288eb9798 100644 --- a/erts/emulator/beam/beam_emu.c +++ b/erts/emulator/beam/beam_emu.c @@ -6557,6 +6557,27 @@ new_map(Process* p, Eterm* reg, BeamInstr* I) BeamInstr *ptr; map_t *mp; + ptr = &Arg(4); + + if (n > MAP_SMALL_MAP_LIMIT) { + if (HeapWordsLeft(p) < n) { + erts_garbage_collect(p, n, reg, Arg(2)); + } + + mhp = p->htop; + thp = p->htop; + E = p->stop; + + for (i = 0; i < n/2; i++) { + GET_TERM(*ptr++, *mhp++); + GET_TERM(*ptr++, *mhp++); + } + + p->htop = mhp; + + return erts_hashmap_from_array(p, thp, n/2); + } + if (HeapWordsLeft(p) < need) { erts_garbage_collect(p, need, reg, Arg(2)); } @@ -6564,7 +6585,6 @@ new_map(Process* p, Eterm* reg, BeamInstr* I) thp = p->htop; mhp = thp + 1 + n/2; E = p->stop; - ptr = &Arg(4); keys = make_tuple(thp); *thp++ = make_arityval(n/2); diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c index 97f94d90ac..ea041e2303 100644 --- a/erts/emulator/beam/erl_map.c +++ b/erts/emulator/beam/erl_map.c @@ -426,7 +426,6 @@ static Eterm hashmap_from_validated_list(Process *p, Eterm list, Uint size) { } Eterm erts_hashmap_from_array(Process *p, Eterm *leafs, Uint n) { - Eterm tmp[2]; Uint32 sw, hx; Uint ix; hxnode_t *hxns; @@ -436,12 +435,13 @@ Eterm erts_hashmap_from_array(Process *p, Eterm *leafs, Uint n) { hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(hxnode_t)); for (ix = 0; ix < n; ix++) { - hx = hashmap_restore_hash(tmp,0,CAR(list_val(leafs[ix]))); + hx = hashmap_make_hash(*leafs); swizzle32(sw,hx); hxns[ix].hx = sw; - hxns[ix].val = leafs[ix]; + hxns[ix].val = make_list(leafs); hxns[ix].skip = 1; hxns[ix].i = ix; + leafs += 2; } res = hashmap_from_unsorted_array(p, hxns, n); |