aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator
diff options
context:
space:
mode:
authorSverker Eriksson <[email protected]>2019-01-09 21:51:58 +0100
committerSverker Eriksson <[email protected]>2019-01-09 21:51:58 +0100
commit5b93b30de9a7aa356f2a394bc3592a43b02adec5 (patch)
tree024fb6320ec1ca1f4a2a2346318de2d20c01cb2d /erts/emulator
parentfaf6b3809544f40043b82552742572b6fa9bb339 (diff)
downloadotp-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.c37
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