aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam/erl_process_dump.c
diff options
context:
space:
mode:
authorBjörn Gustavsson <[email protected]>2017-10-12 12:45:18 +0200
committerBjörn Gustavsson <[email protected]>2017-10-18 14:05:01 +0200
commit31ad587b6d75e8697964e2b80709fb3b3d2901d5 (patch)
treeee2be766357d2687251d357bf1da491c1056a5eb /erts/emulator/beam/erl_process_dump.c
parentea1ddd8800c82fb8ae7ac2f54f4217a35d6f463d (diff)
downloadotp-31ad587b6d75e8697964e2b80709fb3b3d2901d5.tar.gz
otp-31ad587b6d75e8697964e2b80709fb3b3d2901d5.tar.bz2
otp-31ad587b6d75e8697964e2b80709fb3b3d2901d5.zip
Don't dump literal areas that are not referenced at all
Diffstat (limited to 'erts/emulator/beam/erl_process_dump.c')
-rw-r--r--erts/emulator/beam/erl_process_dump.c114
1 files changed, 97 insertions, 17 deletions
diff --git a/erts/emulator/beam/erl_process_dump.c b/erts/emulator/beam/erl_process_dump.c
index d893853063..9fd024cae8 100644
--- a/erts/emulator/beam/erl_process_dump.c
+++ b/erts/emulator/beam/erl_process_dump.c
@@ -52,9 +52,11 @@ static void print_function_from_pc(fmtfn_t to, void *to_arg, BeamInstr* x);
static void heap_dump(fmtfn_t to, void *to_arg, Eterm x);
static void dump_binaries(fmtfn_t to, void *to_arg, Binary* root);
static void dump_externally(fmtfn_t to, void *to_arg, Eterm term);
+static void mark_literal(Eterm* ptr);
+static void init_literal_areas(void);
static void dump_literals(fmtfn_t to, void *to_arg);
static void dump_module_literals(fmtfn_t to, void *to_arg,
- struct erl_module_instance* mp);
+ ErtsLiteralArea* lit_area);
static Binary* all_binaries;
@@ -68,7 +70,8 @@ erts_deep_process_dump(fmtfn_t to, void *to_arg)
int i, max = erts_ptab_max(&erts_proc);
all_binaries = NULL;
-
+ init_literal_areas();
+
for (i = 0; i < max; i++) {
Process *p = erts_pix2proc(i);
if (p && p->i != ENULL) {
@@ -377,7 +380,9 @@ heap_dump(fmtfn_t to, void *to_arg, Eterm x)
next = (Eterm *) x;
} else if (is_list(x)) {
ptr = list_val(x);
- if (ptr[0] != OUR_NIL && !erts_is_literal(x, ptr)) {
+ if (erts_is_literal(x, ptr)) {
+ mark_literal(ptr);
+ } else if (ptr[0] != OUR_NIL) {
erts_print(to, to_arg, PTR_FMT ":l", ptr);
dump_element(to, to_arg, ptr[0]);
erts_putc(to, to_arg, '|');
@@ -396,7 +401,9 @@ heap_dump(fmtfn_t to, void *to_arg, Eterm x)
ptr = boxed_val(x);
hdr = *ptr;
- if (hdr != OUR_NIL && !erts_is_literal(x, ptr)) {
+ if (erts_is_literal(x, ptr)) {
+ mark_literal(ptr);
+ } else if (hdr != OUR_NIL) {
erts_print(to, to_arg, PTR_FMT ":", ptr);
if (is_arity_value(hdr)) {
Uint i;
@@ -642,42 +649,115 @@ dump_externally(fmtfn_t to, void *to_arg, Eterm term)
}
}
+/*
+ * Handle dumping of literal areas.
+ */
+
+static ErtsLiteralArea** lit_areas;
+static Uint num_lit_areas;
+
+static int compare_areas(const void * a, const void * b)
+{
+ ErtsLiteralArea** a_p = (ErtsLiteralArea **) a;
+ ErtsLiteralArea** b_p = (ErtsLiteralArea **) b;
+
+ if (*a_p < *b_p) {
+ return -1;
+ } else if (*b_p < *a_p) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+
static void
-dump_literals(fmtfn_t to, void *to_arg)
+init_literal_areas(void)
{
int i;
Module* modp;
ErtsCodeIndex code_ix;
+ ErtsLiteralArea** area_p;
code_ix = erts_active_code_ix();
erts_rlock_old_code(code_ix);
- erts_print(to, to_arg, "=literals\n");
-
+ lit_areas = area_p = erts_dump_lit_areas;
+ num_lit_areas = 0;
for (i = 0; i < module_code_size(code_ix); i++) {
modp = module_code(i, code_ix);
if (modp == NULL) {
continue;
}
- dump_module_literals(to, to_arg, &modp->curr);
- dump_module_literals(to, to_arg, &modp->old);
+ if (modp->curr.code_length > 0 &&
+ modp->curr.code_hdr->literal_area) {
+ *area_p++ = modp->curr.code_hdr->literal_area;
+ }
+ if (modp->old.code_length > 0 && modp->old.code_hdr->literal_area) {
+ *area_p++ = modp->old.code_hdr->literal_area;
+ }
+ }
+
+ num_lit_areas = area_p - lit_areas;
+ ASSERT(num_lit_areas <= erts_dump_num_lit_areas);
+ for (i = 0; i < num_lit_areas; i++) {
+ lit_areas[i]->off_heap = 0;
+ }
+
+ qsort(lit_areas, num_lit_areas, sizeof(ErtsLiteralArea *),
+ compare_areas);
+
+ erts_runlock_old_code(code_ix);
+}
+
+static int search_areas(const void * a, const void * b) {
+ Eterm* key = (Eterm *) a;
+ ErtsLiteralArea** b_p = (ErtsLiteralArea **) b;
+ if (key < b_p[0]->start) {
+ return -1;
+ } else if (b_p[0]->end <= key) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+static void mark_literal(Eterm* ptr)
+{
+ ErtsLiteralArea** ap;
+
+ ap = bsearch(ptr, lit_areas, num_lit_areas, sizeof(ErtsLiteralArea*),
+ search_areas);
+ ASSERT(ap);
+ ap[0]->off_heap = (struct erl_off_heap_header *) 1;
+}
+
+
+static void
+dump_literals(fmtfn_t to, void *to_arg)
+{
+ ErtsCodeIndex code_ix;
+ int i;
+
+ code_ix = erts_active_code_ix();
+ erts_rlock_old_code(code_ix);
+
+ erts_print(to, to_arg, "=literals\n");
+ for (i = 0; i < num_lit_areas; i++) {
+ if (lit_areas[i]->off_heap) {
+ dump_module_literals(to, to_arg, lit_areas[i]);
+ }
}
+
erts_runlock_old_code(code_ix);
}
static void
-dump_module_literals(fmtfn_t to, void *to_arg, struct erl_module_instance* mp)
+dump_module_literals(fmtfn_t to, void *to_arg, ErtsLiteralArea* lit_area)
{
- BeamCodeHeader* code;
- ErtsLiteralArea* lit_area;
Eterm* htop;
Eterm* hend;
- if (mp->code_length == 0) {
- return;
- }
- code = mp->code_hdr;
- lit_area = code->literal_area;
htop = lit_area->start;
hend = lit_area->end;
while (htop < hend) {