diff options
author | Björn-Egil Dahlberg <[email protected]> | 2017-02-27 15:27:05 +0100 |
---|---|---|
committer | Björn-Egil Dahlberg <[email protected]> | 2017-02-28 15:55:25 +0100 |
commit | 4bbbf4ff9b3fe4be24bf8d57780c84d5b3ca0f77 (patch) | |
tree | 2c2ceb87baf72f5fcdf0bb5e9b267aabaabf0aed /erts/emulator/beam/erl_gc.c | |
parent | 3202e753383d495bce8008721e94428788d4f400 (diff) | |
download | otp-4bbbf4ff9b3fe4be24bf8d57780c84d5b3ca0f77.tar.gz otp-4bbbf4ff9b3fe4be24bf8d57780c84d5b3ca0f77.tar.bz2 otp-4bbbf4ff9b3fe4be24bf8d57780c84d5b3ca0f77.zip |
erts: Convert small sub-binaries to heap-binaries
In many cases sub-binaries costs more memory than converting them to heap-binaries.
Sub-binaries also has a hidden cost of pinning larger binaries in memory.
By converting binaries this cost is reduced.
Byte aligned sub-binaries upto 24 bytes (64-bit) or 12 bytes (32-bit) are converted.
Diffstat (limited to 'erts/emulator/beam/erl_gc.c')
-rw-r--r-- | erts/emulator/beam/erl_gc.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/erts/emulator/beam/erl_gc.c b/erts/emulator/beam/erl_gc.c index 8cc7fc0142..26f6b6339d 100644 --- a/erts/emulator/beam/erl_gc.c +++ b/erts/emulator/beam/erl_gc.c @@ -3256,6 +3256,39 @@ reply_gc_info(void *vgcirp) gcireq_free(vgcirp); } +void erts_sub_binary_to_heap_binary(Eterm **pp, Eterm **hpp, Eterm *orig) { + Eterm *ptr = *pp; + Eterm *htop = *hpp; + Eterm gval; + ErlSubBin *sb = (ErlSubBin *)ptr; + ErlHeapBin *hb = (ErlHeapBin *)htop; + Eterm *real_bin; + byte *bs; + + real_bin = binary_val(follow_moved(sb->orig, (Eterm)0)); + + if (*real_bin == HEADER_PROC_BIN) { + bs = ((ProcBin *) real_bin)->bytes + sb->offs; + } else { + bs = (byte *)(&(((ErlHeapBin *) real_bin)->data)) + sb->offs; + } + + hb->thing_word = header_heap_bin(sb->size); + hb->size = sb->size; + sys_memcpy((byte *)hb->data, bs, sb->size); + + gval = make_boxed(htop); + *orig = gval; + *ptr = gval; + + ptr += ERL_SUB_BIN_SIZE; + htop += heap_bin_size(sb->size); + + *hpp = htop; + *pp = ptr; +} + + Eterm erts_gc_info_request(Process *c_p) { |