aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_gc.h
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.h
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.h')
-rw-r--r--erts/emulator/beam/erl_gc.h70
1 files changed, 49 insertions, 21 deletions
diff --git a/erts/emulator/beam/erl_gc.h b/erts/emulator/beam/erl_gc.h
index 1cce426d21..2e2be2ee47 100644
--- a/erts/emulator/beam/erl_gc.h
+++ b/erts/emulator/beam/erl_gc.h
@@ -28,6 +28,8 @@
#define ERTS_POTENTIALLY_LONG_GC_HSIZE (128*1024) /* Words */
#include "erl_map.h"
+#include "erl_fun.h"
+#include "erl_bits.h"
#define IS_MOVED_BOXED(x) (!is_header((x)))
#define IS_MOVED_CONS(x) (is_non_value((x)))
@@ -45,27 +47,53 @@ do { \
HTOP += 2; /* update tospace htop */ \
} while(0)
-#define MOVE_BOXED(PTR,HDR,HTOP,ORIG) \
-do { \
- Eterm gval; \
- Sint nelts; \
- \
- ASSERT(is_header(HDR)); \
- nelts = header_arity(HDR); \
- switch ((HDR) & _HEADER_SUBTAG_MASK) { \
- case SUB_BINARY_SUBTAG: nelts++; break; \
- case MAP_SUBTAG: \
- if (is_flatmap_header(HDR)) nelts+=flatmap_get_size(PTR) + 1; \
- else nelts += hashmap_bitcount(MAP_HEADER_VAL(HDR)); \
- break; \
- case FUN_SUBTAG: nelts+=((ErlFunThing*)(PTR))->num_free+1; break; \
- } \
- gval = make_boxed(HTOP); \
- *ORIG = gval; \
- *HTOP++ = HDR; \
- *PTR++ = gval; \
- while (nelts--) *HTOP++ = *PTR++; \
-} while(0)
+#define MOVE_BOXED(PTR,HDR,HTOP,ORIG) \
+ do { \
+ move_boxed(&(PTR), HDR, &(HTOP), ORIG); \
+ } while(0)
+
+void erts_sub_binary_to_heap_binary(Eterm **pp, Eterm **hpp, Eterm *orig);
+ERTS_GLB_INLINE void move_boxed(Eterm **pp, Eterm hdr, Eterm **hpp, Eterm *orig);
+
+#if ERTS_GLB_INLINE_INCL_FUNC_DEF
+ERTS_GLB_INLINE void move_boxed(Eterm **pp, Eterm hdr, Eterm **hpp, Eterm *orig)
+{
+ Eterm gval;
+ Sint nelts;
+ Eterm *ptr = *pp;
+ Eterm *htop = *hpp;
+
+ ASSERT(is_header(hdr));
+ nelts = header_arity(hdr);
+ switch ((hdr) & _HEADER_SUBTAG_MASK) {
+ case SUB_BINARY_SUBTAG:
+ {
+ ErlSubBin *sb = (ErlSubBin *)ptr;
+ /* convert sub-binary to heap-binary if applicable */
+ if (sb->bitsize == 0 && sb->bitoffs == 0 &&
+ sb->is_writable == 0 && sb->size <= sizeof(Eterm) * 3) {
+ erts_sub_binary_to_heap_binary(pp, hpp, orig);
+ return;
+ }
+ }
+ nelts++;
+ break;
+ case MAP_SUBTAG:
+ if (is_flatmap_header(hdr)) nelts+=flatmap_get_size(ptr) + 1;
+ else nelts += hashmap_bitcount(MAP_HEADER_VAL(hdr));
+ break;
+ case FUN_SUBTAG: nelts+=((ErlFunThing*)(ptr))->num_free+1; break;
+ }
+ gval = make_boxed(htop);
+ *orig = gval;
+ *htop++ = hdr;
+ *ptr++ = gval;
+ while (nelts--) *htop++ = *ptr++;
+
+ *hpp = htop;
+ *pp = ptr;
+}
+#endif
#define ErtsInYoungGen(TPtr, Ptr, OldHeap, OldHeapSz) \
(!erts_is_literal((TPtr), (Ptr)) \