aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_gc.c
diff options
context:
space:
mode:
authorBjörn-Egil Dahlberg <[email protected]>2017-02-27 15:27:05 +0100
committerBjörn-Egil Dahlberg <[email protected]>2017-02-28 15:55:25 +0100
commit4bbbf4ff9b3fe4be24bf8d57780c84d5b3ca0f77 (patch)
tree2c2ceb87baf72f5fcdf0bb5e9b267aabaabf0aed /erts/emulator/beam/erl_gc.c
parent3202e753383d495bce8008721e94428788d4f400 (diff)
downloadotp-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.c33
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)
{