diff options
author | Sverker Eriksson <[email protected]> | 2019-01-09 21:51:58 +0100 |
---|---|---|
committer | Sverker Eriksson <[email protected]> | 2019-01-09 21:51:58 +0100 |
commit | 5b93b30de9a7aa356f2a394bc3592a43b02adec5 (patch) | |
tree | 024fb6320ec1ca1f4a2a2346318de2d20c01cb2d /erts/emulator | |
parent | faf6b3809544f40043b82552742572b6fa9bb339 (diff) | |
download | otp-5b93b30de9a7aa356f2a394bc3592a43b02adec5.tar.gz otp-5b93b30de9a7aa356f2a394bc3592a43b02adec5.tar.bz2 otp-5b93b30de9a7aa356f2a394bc3592a43b02adec5.zip |
Move back gc before 'src_bytes' is read
otherwise gc may move the binary data and make 'src_bytes' invalid.
Diffstat (limited to 'erts/emulator')
-rw-r--r-- | erts/emulator/beam/erl_bits.c | 37 |
1 files changed, 16 insertions, 21 deletions
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c index 051feb5977..f5807d25d7 100644 --- a/erts/emulator/beam/erl_bits.c +++ b/erts/emulator/beam/erl_bits.c @@ -1332,7 +1332,11 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term, } if (build_size_in_bits == 0) { - goto return_bin; + if (c_p->stop - c_p->htop < extra_words) { + (void) erts_garbage_collect(c_p, extra_words, reg, live+1); + bin = reg[live]; + } + return bin; } if((ERTS_UINT_MAX - build_size_in_bits) < erts_bin_offset) { @@ -1392,6 +1396,16 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term, Uint bitsize; Eterm* hp; + /* + * Allocate heap space. + */ + heap_need = PROC_BIN_SIZE + ERL_SUB_BIN_SIZE + extra_words; + if (c_p->stop - c_p->htop < heap_need) { + (void) erts_garbage_collect(c_p, heap_need, reg, live+1); + bin = reg[live]; + } + hp = c_p->htop; + /* * Calculate sizes. The size of the new binary, is the sum of the * build size and the size of the old binary. Allow some room @@ -1407,17 +1421,8 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term, } if (build_size_in_bits == 0) { - goto return_bin; - } - - /* - * Allocate heap space. - */ - heap_need = PROC_BIN_SIZE + ERL_SUB_BIN_SIZE + extra_words; - if (c_p->stop - c_p->htop < heap_need) { - (void) erts_garbage_collect(c_p, heap_need, reg, live+1); + return bin; } - hp = c_p->htop; if((ERTS_UINT_MAX - build_size_in_bits) < erts_bin_offset) { c_p->freason = SYSTEM_LIMIT; @@ -1478,16 +1483,6 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term, return make_binary(sb); } - - return_bin: - { - if (c_p->stop - c_p->htop < extra_words) { - reg[live] = bin; - (void) erts_garbage_collect(c_p, extra_words, reg, live+1); - bin = reg[live]; - } - return bin; - } } Eterm |