aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--erts/emulator/beam/beam_emu.c22
-rw-r--r--erts/emulator/beam/erl_map.c6
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);