[m-rev.] diff: Make a collection optional when reporting memory attribution

Paul Bone paul at bone.id.au
Mon Sep 26 22:11:40 AEST 2016


Make a collection optional when reporting memory attribution

As I upgraded the collector last week I noticed that we no-longer need to
run a garbage collection event in order to calculate memory attribution.
This patch makes running a collection optional.

library/benchmarking.m:
runtime/mercury_heap_profile.c:
runtime/mercury_heap_profile.h:
    Add an extra parameter to the Mercury predicates and C procedures to say
    whether a collection should occur.  The Mercury predicates were
    duplicated to preserve the old behaviour / compatibility.
---
 library/benchmarking.m         | 38 ++++++++++++++++++++++++++++----------
 runtime/mercury_heap_profile.c |  6 ++++--
 runtime/mercury_heap_profile.h |  3 ++-
 3 files changed, 34 insertions(+), 13 deletions(-)

diff --git a/library/benchmarking.m b/library/benchmarking.m
index 8b69bfe..6889967 100644
--- a/library/benchmarking.m
+++ b/library/benchmarking.m
@@ -19,6 +19,7 @@
 :- module benchmarking.
 :- interface.
 
+:- import_module bool.
 :- import_module io.
 :- import_module maybe.
 
@@ -42,14 +43,21 @@
     %
 :- impure pred report_full_memory_stats is det.
 
-    % report_memory_attribution(Label, !IO) is a procedure intended for use in
-    % profiling the memory usage by a program. In `memprof.gc' grades it has
-    % the side-effect of forcing a garbage collection and reporting a summary
-    % of the objects on the heap to a data file. See ``Using mprof -s for
-    % profiling memory retention'' in the Mercury User's Guide. The label is
-    % for your reference.
+    % report_memory_attribution(Label, Collect, !IO) is a procedure intended
+    % for use in profiling the memory usage by a program.  It is supported in
+    % `memprof.gc' grades only, in other grades it is a no-op.  It reports a
+    % summary of the objects on the heap to a data file. See ``Using mprof -s
+    % for profiling memory retention'' in the Mercury User's Guide. The label
+    % is for your reference.  If Collect is yes it has the effect of forcing a
+    % garbage collection before building the report.
     %
-    % On other grades this procedure does nothing.
+:- pred report_memory_attribution(string::in, bool::in, io::di, io::uo) is det.
+
+:- impure pred report_memory_attribution(string::in, bool::in) is det.
+
+    % report_memory_attribution(Label, !IO) is the same as
+    % report_memory_attribution/4 above, except that it always forces a
+    % collection (in 'memprof.gc' grades).
     %
 :- pred report_memory_attribution(string::in, io::di, io::uo) is det.
 
@@ -222,19 +230,29 @@ extern void ML_report_full_memory_stats(void);
 ").
 
 :- pragma foreign_proc("C",
-    report_memory_attribution(Label::in),
+    report_memory_attribution(Label::in, RunCollect::in),
     [will_not_call_mercury],
 "
+    MR_bool mr_run_collect = RunCollect == MR_YES ? MR_TRUE : MR_FALSE;
+
 #ifdef  MR_MPROF_PROFILE_MEMORY_ATTRIBUTION
-    MR_report_memory_attribution(Label);
+    MR_report_memory_attribution(Label, mr_run_collect);
 #else
     (void) Label;
 #endif
 ").
 
-report_memory_attribution(_) :-
+report_memory_attribution(_, _) :-
     impure impure_true.
 
+report_memory_attribution(Label) :-
+    impure report_memory_attribution(Label, yes).
+
+:- pragma promise_pure(report_memory_attribution/4).
+
+report_memory_attribution(Label, Collect, !IO) :-
+    impure report_memory_attribution(Label, Collect).
+
 :- pragma promise_pure(report_memory_attribution/3).
 
 report_memory_attribution(Label, !IO) :-
diff --git a/runtime/mercury_heap_profile.c b/runtime/mercury_heap_profile.c
index 8a9b90d..d4d068a 100644
--- a/runtime/mercury_heap_profile.c
+++ b/runtime/mercury_heap_profile.c
@@ -364,7 +364,7 @@ hash_addr(MR_Word key)
 }
 
 void
-MR_report_memory_attribution(const char *label)
+MR_report_memory_attribution(const char *label, MR_bool run_collect)
 {
 #ifdef MR_BOEHM_GC
   #ifndef MR_HIGHLEVEL_CODE
@@ -375,7 +375,9 @@ MR_report_memory_attribution(const char *label)
     MR_clear_regs_for_GC();
   #endif
 
-    GC_gcollect();
+    if (run_collect) {
+        GC_gcollect();
+    }
 
     GC_call_with_alloc_lock(enumerate_reachable_objects_locked, NULL);
     finish_reachable_report(label);
diff --git a/runtime/mercury_heap_profile.h b/runtime/mercury_heap_profile.h
index bab6794..5f2ffea 100644
--- a/runtime/mercury_heap_profile.h
+++ b/runtime/mercury_heap_profile.h
@@ -113,7 +113,8 @@ extern void     MR_prof_turn_off_heap_profiling(void);
 extern void     MR_register_alloc_sites(const MR_AllocSiteInfo *alloc_sites,
                     int size);
 
-extern void     MR_report_memory_attribution(MR_ConstString label);
+extern void     MR_report_memory_attribution(MR_ConstString label,
+                    MR_bool run_collect);
 
 extern void     MR_finish_prof_snapshots_file(void);
 
-- 
2.7.4



More information about the reviews mailing list