diff options
author | Lukas Larsson <[email protected]> | 2019-01-18 09:17:57 +0100 |
---|---|---|
committer | GitHub <[email protected]> | 2019-01-18 09:17:57 +0100 |
commit | 2a95d46dd626b0acc57e79b596d00dea01f8270a (patch) | |
tree | 489ecb6cfe69394e521aab9732cadcc6a0f7db67 /erts | |
parent | 0e11bf631d5705f6d9f2889959e8ef4a17b79e97 (diff) | |
parent | 5b93b30de9a7aa356f2a394bc3592a43b02adec5 (diff) | |
download | otp-2a95d46dd626b0acc57e79b596d00dea01f8270a.tar.gz otp-2a95d46dd626b0acc57e79b596d00dea01f8270a.tar.bz2 otp-2a95d46dd626b0acc57e79b596d00dea01f8270a.zip |
Merge pull request #2055 from josevalim/jv-no-bin-alloc-on-empty-append/OTP-15535
Do not allocate new bitstring/binary on empty append
Diffstat (limited to 'erts')
-rw-r--r-- | erts/emulator/beam/erl_bits.c | 16 | ||||
-rw-r--r-- | erts/emulator/test/bs_construct_SUITE.erl | 14 |
2 files changed, 26 insertions, 4 deletions
diff --git a/erts/emulator/beam/erl_bits.c b/erts/emulator/beam/erl_bits.c index e82c776e70..f5807d25d7 100644 --- a/erts/emulator/beam/erl_bits.c +++ b/erts/emulator/beam/erl_bits.c @@ -1331,6 +1331,14 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term, } } + if (build_size_in_bits == 0) { + 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) { c_p->freason = SYSTEM_LIMIT; return THE_NON_VALUE; @@ -1388,13 +1396,13 @@ 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]; + bin = reg[live]; } hp = c_p->htop; @@ -1412,6 +1420,10 @@ erts_bs_append(Process* c_p, Eterm* reg, Uint live, Eterm build_size_term, } } + if (build_size_in_bits == 0) { + return bin; + } + if((ERTS_UINT_MAX - build_size_in_bits) < erts_bin_offset) { c_p->freason = SYSTEM_LIMIT; return THE_NON_VALUE; diff --git a/erts/emulator/test/bs_construct_SUITE.erl b/erts/emulator/test/bs_construct_SUITE.erl index ce50bcdd86..ad05cb3689 100644 --- a/erts/emulator/test/bs_construct_SUITE.erl +++ b/erts/emulator/test/bs_construct_SUITE.erl @@ -26,7 +26,7 @@ init_per_suite/1, end_per_suite/1, test1/1, test2/1, test3/1, test4/1, test5/1, testf/1, not_used/1, in_guard/1, - mem_leak/1, coerce_to_float/1, bjorn/1, + mem_leak/1, coerce_to_float/1, bjorn/1, append_empty_is_same/1, huge_float_field/1, huge_binary/1, system_limit/1, badarg/1, copy_writable_binary/1, kostis/1, dynamic/1, bs_add/1, otp_7422/1, zero_width/1, bad_append/1, bs_add_overflow/1]). @@ -39,7 +39,7 @@ suite() -> all() -> [test1, test2, test3, test4, test5, testf, not_used, - in_guard, mem_leak, coerce_to_float, bjorn, + in_guard, mem_leak, coerce_to_float, bjorn, append_empty_is_same, huge_float_field, huge_binary, system_limit, badarg, copy_writable_binary, kostis, dynamic, bs_add, otp_7422, zero_width, bad_append, bs_add_overflow]. @@ -520,6 +520,16 @@ do_more(Bin, Sz) -> do_something() -> throw(blurf). +append_empty_is_same(Config) when is_list(Config) -> + NonWritableBin = <<"123">>, + true = erts_debug:same(NonWritableBin, append(NonWritableBin, <<>>)), + WritableBin = <<(id(<<>>))/binary,0,1,2,3,4,5,6,7>>, + true = erts_debug:same(WritableBin, append(WritableBin, <<>>)), + ok. + +append(A, B) -> + <<A/binary, B/binary>>. + huge_float_field(Config) when is_list(Config) -> {'EXIT',{badarg,_}} = (catch <<0.0:9/float-unit:8>>), huge_float_check(catch <<0.0:67108865/float-unit:64>>), |