aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_map.c
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <egil@erlang.org>2015-03-03 12:46:05 +0100
committerBjörn-Egil Dahlberg <egil@erlang.org>2015-03-12 19:15:31 +0100
commit9794b73998690178538a1dfc193565dcd477b4fe (patch)
tree64a98ff673023c77410fd671639d2bbed7d9176c /erts/emulator/beam/erl_map.c
parentba117527441b58886a06c0feff40677b9fa48983 (diff)
downloadotp-9794b73998690178538a1dfc193565dcd477b4fe.tar.gz
otp-9794b73998690178538a1dfc193565dcd477b4fe.tar.bz2
otp-9794b73998690178538a1dfc193565dcd477b4fe.zip
erts: Fix update_map_assoc instruction
Did not build a hashmap once the small limit was exceeded.
Diffstat (limited to 'erts/emulator/beam/erl_map.c')
-rw-r--r--erts/emulator/beam/erl_map.c31
1 files changed, 31 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_map.c b/erts/emulator/beam/erl_map.c
index 1703f86b0e..e26b97d75c 100644
--- a/erts/emulator/beam/erl_map.c
+++ b/erts/emulator/beam/erl_map.c
@@ -452,6 +452,37 @@ Eterm erts_hashmap_from_array(Process *p, Eterm *leafs, Uint n) {
return res;
}
+
+Eterm erts_hashmap_from_ks_and_vs(Process *p, Eterm *ks, Eterm *vs, Uint n) {
+ Uint32 sw, hx;
+ Uint i;
+ hxnode_t *hxns;
+ Eterm *hp, res;
+
+ ASSERT(n > 0);
+
+ hp = HAlloc(p, (2 * n));
+
+ /* create tmp hx values and leaf ptrs */
+ hxns = (hxnode_t *)erts_alloc(ERTS_ALC_T_TMP, n * sizeof(hxnode_t));
+
+ for(i = 0; i < n; i++) {
+ hx = hashmap_make_hash(ks[i]);
+ swizzle32(sw,hx);
+ hxns[i].hx = sw;
+ hxns[i].val = CONS(hp, ks[i], vs[i]); hp += 2;
+ hxns[i].skip = 1; /* will be reassigned in from_array */
+ hxns[i].i = i;
+ }
+
+ res = hashmap_from_unsorted_array(p, hxns, n);
+
+ erts_free(ERTS_ALC_T_TMP, (void *) hxns);
+ ERTS_VERIFY_UNUSED_TEMP_ALLOC(p);
+
+ return res;
+}
+
static Eterm hashmap_from_unsorted_array(Process *p, hxnode_t *hxns, Uint n) {
Uint jx = 0, ix = 0, lx, cx;
Eterm res;