diff options
author | Björn Gustavsson <bjorn@erlang.org> | 2015-03-24 15:06:25 +0100 |
---|---|---|
committer | Björn Gustavsson <bjorn@erlang.org> | 2015-04-13 12:37:55 +0200 |
commit | 47e1ed4c0681a73c9d6bc8d24ece85dd77957034 (patch) | |
tree | 03223cf0215a2012bf803ef8b28264fd394016f9 /erts/emulator/beam/beam_emu.c | |
parent | c8893f9aaf6ff585c44259aad21914ccbe904783 (diff) | |
download | otp-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.c | 9 |
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) { |