aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/beam_emu.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2015-03-24 15:06:25 +0100
committerBjörn Gustavsson <[email protected]>2015-04-13 12:37:55 +0200
commit47e1ed4c0681a73c9d6bc8d24ece85dd77957034 (patch)
tree03223cf0215a2012bf803ef8b28264fd394016f9 /erts/emulator/beam/beam_emu.c
parentc8893f9aaf6ff585c44259aad21914ccbe904783 (diff)
downloadotp-47e1ed4c0681a73c9d6bc8d24ece85dd77957034.tar.gz
otp-47e1ed4c0681a73c9d6bc8d24ece85dd77957034.tar.bz2
otp-47e1ed4c0681a73c9d6bc8d24ece85dd77957034.zip
beam_emu: Slightly optimize update_map_{assoc,exact}
In the update loop for big maps, the E variable is restored for each turn of the loop. It only needs to be restored if a garbage collection has been performed. Also add a new test case that attempts to force several garbage collections while updating a map, to help us find bugs with incorrect restoration of the E variable after a garbage collection.
Diffstat (limited to 'erts/emulator/beam/beam_emu.c')
-rw-r--r--erts/emulator/beam/beam_emu.c9
1 files changed, 3 insertions, 6 deletions
diff --git a/erts/emulator/beam/beam_emu.c b/erts/emulator/beam/beam_emu.c
index f25b9f594d..4e64dce95c 100644
--- a/erts/emulator/beam/beam_emu.c
+++ b/erts/emulator/beam/beam_emu.c
@@ -6572,10 +6572,9 @@ update_map_assoc(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
reg[live] = res;
erts_garbage_collect(p, 0, reg, live+1);
res = reg[live];
+ E = p->stop;
}
- E = p->stop;
-
new_p += 2;
}
return res;
@@ -6781,7 +6780,6 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
res = map;
E = p->stop;
while(n--) {
- /* assoc can't fail */
GET_TERM(new_p[0], new_key);
GET_TERM(new_p[1], val);
hx = hashmap_make_hash(new_key);
@@ -6795,10 +6793,9 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
reg[live] = res;
erts_garbage_collect(p, 0, reg, live+1);
res = reg[live];
+ E = p->stop;
}
- E = p->stop;
-
new_p += 2;
}
return res;
@@ -6808,7 +6805,7 @@ update_map_exact(Process* p, Eterm* reg, Eterm map, BeamInstr* I)
num_old = flatmap_get_size(old_mp);
/*
- * If the old map is empty, create a new map.
+ * If the old map is empty, fail.
*/
if (num_old == 0) {