summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Dolan <sdolan@janestreet.com>2019-05-27 13:22:39 +0100
committerGitHub <noreply@github.com>2019-05-27 13:22:39 +0100
commit455bd0ffae85a9b63cb331ac532ea2ab52fe418c (patch)
tree9d54f0a42416a5f7d5646eb710cc090de17a6040
parent393dc1d3ce500174ba8d94db0dd34bd48ea549fe (diff)
parent16611aacc150adec0b801cf1a5b1e5989261c8d3 (diff)
downloadocaml-455bd0ffae85a9b63cb331ac532ea2ab52fe418c.tar.gz
Merge pull request #8684 from jhjourdan/memprof_binomial
Use binomial distribution instead of Poisson distribution in Memprof
-rw-r--r--runtime/.depend64
-rw-r--r--runtime/caml/memory.h2
-rw-r--r--runtime/caml/misc.h3
-rw-r--r--runtime/intern.c2
-rw-r--r--runtime/memory.c4
-rw-r--r--runtime/memprof.c209
-rw-r--r--runtime/signals_nat.c8
-rw-r--r--stdlib/gc.mli32
-rw-r--r--testsuite/tests/statmemprof/arrays_in_major.byte.reference8
-rw-r--r--testsuite/tests/statmemprof/arrays_in_major.ml31
-rw-r--r--testsuite/tests/statmemprof/arrays_in_major.opt.reference8
-rw-r--r--testsuite/tests/statmemprof/arrays_in_minor.byte.reference6
-rw-r--r--testsuite/tests/statmemprof/arrays_in_minor.ml29
-rw-r--r--testsuite/tests/statmemprof/arrays_in_minor.opt.reference6
-rw-r--r--testsuite/tests/statmemprof/exception_callback.ml6
-rw-r--r--testsuite/tests/statmemprof/exception_callback.reference2
-rw-r--r--testsuite/tests/statmemprof/lists_in_minor.byte.reference6
-rw-r--r--testsuite/tests/statmemprof/lists_in_minor.ml17
18 files changed, 211 insertions, 232 deletions
diff --git a/runtime/.depend b/runtime/.depend
index df5b6c69bc..b110cd17ed 100644
--- a/runtime/.depend
+++ b/runtime/.depend
@@ -177,7 +177,7 @@ memprof_b.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_b.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -210,7 +210,7 @@ printexc_b.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_b.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -225,13 +225,13 @@ signals_byt_b.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_b.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_b.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -490,7 +490,7 @@ memprof_bd.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_bd.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -523,7 +523,7 @@ printexc_bd.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_bd.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -538,13 +538,13 @@ signals_byt_bd.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_bd.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_bd.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -799,7 +799,7 @@ memprof_bi.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_bi.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -832,7 +832,7 @@ printexc_bi.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_bi.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -847,13 +847,13 @@ signals_byt_bi.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_bi.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_bi.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -1108,7 +1108,7 @@ memprof_bpic.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_bpic.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -1141,7 +1141,7 @@ printexc_bpic.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_bpic.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -1156,13 +1156,13 @@ signals_byt_bpic.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_bpic.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_bpic.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -1414,7 +1414,7 @@ memprof_n.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_n.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -1447,7 +1447,7 @@ printexc_n.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_n.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -1462,13 +1462,13 @@ signals_byt_n.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_n.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_n.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -1724,7 +1724,7 @@ memprof_nd.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_nd.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -1757,7 +1757,7 @@ printexc_nd.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_nd.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -1772,13 +1772,13 @@ signals_byt_nd.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_nd.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_nd.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -2030,7 +2030,7 @@ memprof_ni.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_ni.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -2063,7 +2063,7 @@ printexc_ni.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_ni.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -2078,13 +2078,13 @@ signals_byt_ni.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_ni.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_ni.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -2336,7 +2336,7 @@ memprof_npic.$(O): memprof.c caml/memprof.h caml/config.h caml/m.h caml/s.h \
caml/signals.h caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h \
caml/minor_gc.h caml/address_class.h caml/memprof.h caml/minor_gc.h \
caml/backtrace_prim.h caml/backtrace.h caml/exec.h caml/weak.h \
- caml/stack.h
+ caml/stack.h caml/misc.h
meta_npic.$(O): meta.c caml/alloc.h caml/misc.h caml/config.h caml/m.h caml/s.h \
caml/mlvalues.h caml/config.h caml/fail.h caml/fix_code.h caml/interp.h \
caml/intext.h caml/io.h caml/major_gc.h caml/freelist.h caml/memory.h \
@@ -2369,7 +2369,7 @@ printexc_npic.$(O): printexc.c caml/backtrace.h caml/mlvalues.h caml/config.h \
caml/m.h caml/s.h caml/misc.h caml/exec.h caml/callback.h \
caml/debugger.h caml/fail.h caml/misc.h caml/mlvalues.h caml/printexc.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
- caml/address_class.h caml/memprof.h
+ caml/address_class.h caml/memprof.h caml/memprof.h
roots_byt_npic.$(O): roots_byt.c caml/finalise.h caml/roots.h caml/misc.h \
caml/config.h caml/m.h caml/s.h caml/memory.h caml/gc.h caml/mlvalues.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
@@ -2384,13 +2384,13 @@ signals_byt_npic.$(O): signals_byt.c caml/config.h caml/m.h caml/s.h \
caml/memory.h caml/config.h caml/gc.h caml/mlvalues.h caml/misc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
caml/memprof.h caml/osdeps.h caml/memory.h caml/signals.h \
- caml/signals_machdep.h caml/memprof.h
+ caml/signals_machdep.h
signals_npic.$(O): signals.c caml/alloc.h caml/misc.h caml/config.h caml/m.h \
caml/s.h caml/mlvalues.h caml/callback.h caml/config.h caml/fail.h \
caml/memory.h caml/gc.h caml/major_gc.h caml/freelist.h caml/minor_gc.h \
caml/address_class.h caml/memprof.h caml/misc.h caml/mlvalues.h \
caml/roots.h caml/memory.h caml/signals.h caml/signals_machdep.h \
- caml/sys.h
+ caml/sys.h caml/memprof.h
signals_nat_npic.$(O): signals_nat.c caml/fail.h caml/misc.h caml/config.h \
caml/m.h caml/s.h caml/mlvalues.h caml/memory.h caml/gc.h \
caml/major_gc.h caml/freelist.h caml/minor_gc.h caml/address_class.h \
diff --git a/runtime/caml/memory.h b/runtime/caml/memory.h
index 2ff2d194c0..038419abbc 100644
--- a/runtime/caml/memory.h
+++ b/runtime/caml/memory.h
@@ -45,7 +45,7 @@ CAMLextern value caml_alloc_shr_with_profinfo (mlsize_t, tag_t, intnat);
#endif /* WITH_PROFINFO */
/* Variant of [caml_alloc_shr] where no memprof sampling is performed. */
-CAMLextern value caml_alloc_shr_no_track (mlsize_t, tag_t);
+CAMLextern value caml_alloc_shr_no_track_noexc (mlsize_t, tag_t);
/* Variant of [caml_alloc_shr] where no memprof sampling is performed,
and re-using the profinfo associated with the header given in
diff --git a/runtime/caml/misc.h b/runtime/caml/misc.h
index 4466d292e7..1076a7a18d 100644
--- a/runtime/caml/misc.h
+++ b/runtime/caml/misc.h
@@ -179,6 +179,9 @@ static inline int caml_umul_overflow(uintnat a, uintnat b, uintnat * res)
extern int caml_umul_overflow(uintnat a, uintnat b, uintnat * res);
#endif
+/* From floats.c */
+extern double caml_log1p(double);
+
/* Windows Unicode support */
#ifdef _WIN32
diff --git a/runtime/intern.c b/runtime/intern.c
index 96cb74f8bf..f43999057e 100644
--- a/runtime/intern.c
+++ b/runtime/intern.c
@@ -633,7 +633,7 @@ static void intern_alloc(mlsize_t whsize, mlsize_t num_objects,
#undef Restore_after_gc
}
}else{
- intern_block = caml_alloc_shr_no_track (wosize, String_tag);
+ intern_block = caml_alloc_shr_no_track_noexc (wosize, String_tag);
/* do not do the urgent_gc check here because it might darken
intern_block into gray and break the intern_color assertion below */
if (intern_block == 0) {
diff --git a/runtime/memory.c b/runtime/memory.c
index 4aee2dac3c..a4b76783e4 100644
--- a/runtime/memory.c
+++ b/runtime/memory.c
@@ -574,7 +574,7 @@ CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag)
caml_spacetime_my_profinfo (NULL, wosize));
}
-CAMLexport value caml_alloc_shr_no_track (mlsize_t wosize, tag_t tag)
+CAMLexport value caml_alloc_shr_no_track_noexc (mlsize_t wosize, tag_t tag)
{
return caml_alloc_shr_aux (wosize, tag, 0, 0,
caml_spacetime_my_profinfo (NULL, wosize));
@@ -585,7 +585,7 @@ CAMLexport value caml_alloc_shr (mlsize_t wosize, tag_t tag)
return caml_alloc_shr_aux (wosize, tag, 1, 1, NO_PROFINFO);
}
-CAMLexport value caml_alloc_shr_no_track (mlsize_t wosize, tag_t tag)
+CAMLexport value caml_alloc_shr_no_track_noexc (mlsize_t wosize, tag_t tag)
{
return caml_alloc_shr_aux (wosize, tag, 0, 0, NO_PROFINFO);
}
diff --git a/runtime/memprof.c b/runtime/memprof.c
index c42663ed16..0f74b38241 100644
--- a/runtime/memprof.c
+++ b/runtime/memprof.c
@@ -27,6 +27,7 @@
#include "caml/backtrace_prim.h"
#include "caml/weak.h"
#include "caml/stack.h"
+#include "caml/misc.h"
static uint32_t mt_state[624];
static uint32_t mt_index;
@@ -34,22 +35,21 @@ static uint32_t mt_index;
/* [lambda] is the mean number of samples for each allocated word (including
block headers). */
static double lambda = 0;
- /* Inverse of [lamdba]. Meaningless if lamdba = 0 */
-static double lambda_inverse = 0;
+ /* Precomputed value of [1/log(1-lambda)], for fast sampling of
+ geometric distribution.
+ Dummy if [lambda = 0]. */
+static double one_log1m_lambda;
int caml_memprof_suspended = 0;
static intnat callstack_size = 0;
static value memprof_callback = Val_unit;
-/* Position of the next sample in the minor heap. Equals
- [caml_young_alloc_start] if no sampling is planned in the current
- minor heap.
+/* Pointer to the word following the next sample in the minor
+ heap. Equals [caml_young_alloc_start] if no sampling is planned in
+ the current minor heap.
Invariant: [caml_memprof_young_trigger <= caml_young_ptr].
*/
value* caml_memprof_young_trigger;
-/* The continuous position of the next minor sample within the next
- sampled word. Always in [0, 1[. */
-static double next_sample_frac_part;
/* Whether memprof has been initialized. */
static int init = 0;
@@ -87,95 +87,42 @@ static double mt_generate_uniform(void)
1.16415321826934814453125e-10; /* 2^-33 */
}
-/* C99's [lgammaf] function is not available in some compilers
- (including MSVC). Here is our own approximate implementation of the
- log-factorial function.
-
- Requirement: [n] is a non-negative integer.
-
- We use Ramanujan's formula. For n < 10^8, the absolute error is
- less than 10^-6, which is way better than what we need.
- */
-static double lfact(double n)
+/* Simulate a geometric variable of parameter [lambda].
+ The result is clipped in [1..Max_long]
+ Requires [lambda > 0]. */
+static uintnat mt_generate_geom()
{
- static double tab[10] = {
- 0.0000000000, 0.0000000000, 0.6931471806, 1.7917594692, 3.1780538303,
- 4.7874917428, 6.5792512120, 8.5251613611, 10.6046029027, 12.8018274801 };
- if(n < 10)
- return tab[(int)n];
- return n*(log(n) - 1) + (1./6)*log(((8*n + 4)*n + 1)*n + 1./34)
- + 0.5723649429; /* log(pi)/2 */
+ /* We use the float versions of exp/log, since these functions are
+ significantly faster, and we really don't need much precision
+ here. The entropy contained in [next_mt_generate_geom] is anyway
+ bounded by the entropy provided by [mt_generate_uniform], which
+ is 32bits. */
+ double res = 1 + logf(mt_generate_uniform()) * one_log1m_lambda;
+ if(res > Max_long) return Max_long;
+ return (uintnat)res;
}
-#define MAX_MT_GENERATE_POISSON (1<<29)
-static double next_mt_generate_poisson;
-/* Simulate a Poisson distribution of parameter [lambda*len]. The
- result is clipped to the interval [0..MAX_MT_GENERATE_POISSON] */
-static int32_t mt_generate_poisson(double len)
-{
- double cur_lambda = lambda * len;
- CAMLassert(cur_lambda >= 0 && cur_lambda < 1e20);
-
- if(cur_lambda < 20) {
- /* First algorithm when [cur_lambda] is small: we proceed by
- repeated simulations of exponential distributions. */
-
- next_mt_generate_poisson -= cur_lambda;
- if(next_mt_generate_poisson > 0) {
- /* Fast path if [cur_lambda] is small: we reuse the same
- exponential sample across several calls to
- [mt_generate_poisson]. */
- return 0;
- } else {
- /* We use the float versions of exp/log, since these functions
- are significantly faster, and we really don't need much
- precision here. The entropy contained in
- [next_mt_generate_poisson] is anyway bounded by the entropy
- provided by [mt_generate_uniform], which is 32bits. */
- double p = expf(-next_mt_generate_poisson);
- int32_t k = 0;
- do {
- k++;
- p *= mt_generate_uniform();
- } while(p > 1);
-
- /* [p] is now uniformly distributed in [0, 1] and independent
- from other variables (including [k]). We can therefore reuse
- [p] for reinitializing [next_mt_generate_poisson]. */
- next_mt_generate_poisson = -logf(p);
-
- return k;
- }
+static uintnat next_mt_generate_binom;
+/* Simulate a binomial variable of parameters [len] and [lambda].
+ This sampling algorithm has running time linear with [len *
+ lambda]. We could use more a involved algorithm, but this should
+ be good enough since, in the average use case, [lambda] <= 0.01 and
+ therefore the generation of the binomial variable is amortized by
+ the initialialization of the corresponding block.
- } else {
- /* Second algorithm when [cur_lambda] is large. Taken from: */
- /* The Computer Generation of Poisson Random Variables
- A. C. Atkinson Journal of the Royal Statistical Society.
- Series C (Applied Statistics) Vol. 28, No. 1 (1979), pp. 29-35
- "Method PA" */
-
- double c, beta_inverse, k, log_cur_lambda;
- log_cur_lambda = log(cur_lambda);
- c = 0.767 - 3.36/cur_lambda;
- beta_inverse = sqrt(0.30396355092701332623 * cur_lambda);
- /* ^ = 3./(PI*PI) */
- k = log(c*beta_inverse) - cur_lambda;
- while(1) {
- double u, n, v, y;
- u = mt_generate_uniform();
- y = log(1./u-1);
- n = floor(cur_lambda - y*beta_inverse + 0.5);
- if(n < 0.)
- continue;
- v = mt_generate_uniform();
- /* When [cur_lambda] is large, we expect [n*log_cur_lambda] and
- [lfact(n)] to be close, while both being relatively
- large. Hence, here, we may actually need the double precision
- in the computation of log and lfact. */
- if(y + log(v*u*u) < k + n*log_cur_lambda - lfact(n))
- return n > MAX_MT_GENERATE_POISSON ? MAX_MT_GENERATE_POISSON : n;
- }
- }
+ If needed, we could use algorithm BTRS from the paper:
+ Hormann, Wolfgang. "The generation of binomial random variates."
+ Journal of statistical computation and simulation 46.1-2 (1993), pp101-110.
+
+ Requires [lambda > 0] and [len < Max_long].
+ */
+static uintnat mt_generate_binom(uintnat len)
+{
+ uintnat res;
+ for(res = 0; next_mt_generate_binom < len; res++)
+ next_mt_generate_binom += mt_generate_geom();
+ next_mt_generate_binom -= len;
+ return res;
}
/**** Interface with the OCaml code. ****/
@@ -186,7 +133,7 @@ CAMLprim value caml_memprof_set(value v)
double l = Double_val(Field(v, 0));
intnat sz = Long_val(Field(v, 1));
- if(sz < 0 || !(l >= 0.) || l > 1.)
+ if(sz < 0 || !(l >= 0.) || l > 1.) /* Checks that [l] is not NAN. */
caml_invalid_argument("caml_memprof_set");
if(!init) {
@@ -199,14 +146,18 @@ CAMLprim value caml_memprof_set(value v)
mt_state[i] = 0x6c078965 * (mt_state[i-1] ^ (mt_state[i-1] >> 30)) + i;
caml_register_generational_global_root(&memprof_callback);
-
- next_mt_generate_poisson = -logf(mt_generate_uniform());
}
lambda = l;
- lambda_inverse = 1/l;
+ if(l > 0) {
+ one_log1m_lambda = l == 1 ? 0 : 1/caml_log1p(-l);
+ next_mt_generate_binom = mt_generate_geom();
+ }
+
caml_memprof_renew_minor_sample();
+
callstack_size = sz;
+
caml_modify_generational_global_root(&memprof_callback, Field(v, 2));
CAMLreturn(Val_unit);
@@ -219,7 +170,7 @@ enum ml_alloc_kind {
Serialized = Val_long(2)
};
-static value do_callback(tag_t tag, intnat wosize, int32_t occurrences,
+static value do_callback(tag_t tag, uintnat wosize, uintnat occurrences,
value callstack, enum ml_alloc_kind cb_kind) {
CAMLparam1(callstack);
CAMLlocal1(sample_info);
@@ -240,18 +191,18 @@ static value do_callback(tag_t tag, intnat wosize, int32_t occurrences,
static value capture_callstack_major()
{
value res;
- intnat wosize = caml_current_callstack_size(callstack_size);
+ uintnat wosize = caml_current_callstack_size(callstack_size);
/* We do not use [caml_alloc] to make sure the GC will not get called. */
if(wosize == 0) return Atom (0);
- res = caml_alloc_shr_no_track(wosize, 0);
- caml_current_callstack_write(res);
+ res = caml_alloc_shr_no_track_noexc(wosize, 0);
+ if(res != 0) caml_current_callstack_write(res);
return res;
}
static value capture_callstack_minor()
{
value res;
- intnat wosize = caml_current_callstack_size(callstack_size);
+ uintnat wosize = caml_current_callstack_size(callstack_size);
CAMLassert(caml_memprof_suspended); /* => no samples in the call stack. */
res = caml_alloc(wosize, 0);
caml_current_callstack_write(res);
@@ -261,7 +212,7 @@ static value capture_callstack_minor()
struct caml_memprof_postponed_block {
value block;
value callstack;
- int32_t occurrences;
+ uintnat occurrences;
struct caml_memprof_postponed_block* next;
} *caml_memprof_postponed_head = NULL;
@@ -272,17 +223,22 @@ struct caml_memprof_postponed_block {
call is performed when possible. */
void caml_memprof_track_alloc_shr(value block)
{
- int32_t occurrences;
+ uintnat occurrences;
CAMLassert(Is_in_heap(block));
/* This test also makes sure memprof is initialized. */
if(lambda == 0 || caml_memprof_suspended)
return;
- occurrences = mt_generate_poisson(Whsize_val(block));
+ occurrences = mt_generate_binom(Whsize_val(block));
if(occurrences > 0) {
+ value callstack;
struct caml_memprof_postponed_block* pb =
caml_stat_alloc_noexc(sizeof(struct caml_memprof_postponed_block));
- value callstack = capture_callstack_major();
if(pb == NULL) return;
+ callstack = capture_callstack_major();
+ if(callstack == 0) {
+ caml_stat_free(pb);
+ return;
+ }
pb->block = block;
caml_register_generational_global_root(&pb->block);
pb->callstack = callstack;
@@ -358,34 +314,21 @@ static void shift_sample(uintnat n)
/* Renew the next sample in the minor heap. This needs to be called
after each minor sampling and after each minor collection. In
- practice, because we disable sampling during callbacks, this is
- called at each sampling (including major ones). These extra calls
- do not change the statistical properties of the sampling because of
- the memorylessness of the exponential distribution. */
+ practice, this is called at each sampling in the minor heap and at
+ each minor collection. Extra calls do not change the statistical
+ properties of the sampling because of the memorylessness of the
+ geometric distribution. */
void caml_memprof_renew_minor_sample(void)
{
- double exp;
- uintnat max, exp_int;
if(lambda == 0) /* No trigger in the current minor heap. */
caml_memprof_young_trigger = caml_young_alloc_start;
else {
- exp = - lambda_inverse * logf(mt_generate_uniform());
- max = caml_young_ptr - caml_young_alloc_start;
- if(exp >= (double)max) /* No trigger in the current minor heap. */
+ uintnat geom = mt_generate_geom();
+ if(caml_young_ptr - caml_young_alloc_start < geom)
+ /* No trigger in the current minor heap. */
caml_memprof_young_trigger = caml_young_alloc_start;
- else {
- exp_int = (uintnat)exp;
- /* This assertion can be false only if [max] is not exactly
- representable as a double, which cannot happen if the size of the
- minor heap does not reach 2^52. */
- CAMLassert(exp_int < max);
-
- caml_memprof_young_trigger = caml_young_ptr - exp_int;
-
- next_sample_frac_part = exp - exp_int;
- CAMLassert(0 <= next_sample_frac_part && next_sample_frac_part < 1);
- }
+ caml_memprof_young_trigger = caml_young_ptr - (geom - 1);
}
caml_update_young_limit();
@@ -399,8 +342,7 @@ void caml_memprof_track_young(tag_t tag, uintnat wosize)
CAMLparam0();
CAMLlocal2(ephe, callstack);
uintnat whsize = Whsize_wosize(wosize);
- double rest;
- int32_t occurrences;
+ uintnat occurrences;
if(caml_memprof_suspended) {
caml_memprof_renew_minor_sample();
@@ -408,7 +350,7 @@ void caml_memprof_track_young(tag_t tag, uintnat wosize)
}
/* If [lambda == 0], then [caml_memprof_young_trigger] should be
- equal to [caml_young_alloc_start]. But this function is only
+ equal to [caml_young_alloc_start]. But this function is only
called with [caml_young_alloc_start <= caml_young_ptr <
caml_memprof_young_trigger], which is contradictory. */
CAMLassert(lambda > 0);
@@ -420,11 +362,8 @@ void caml_memprof_track_young(tag_t tag, uintnat wosize)
call the callback and use as a sample the block which will be
allocated right after the callback. */
- /* [rest] is the size of the part of the allocated block which is
- after the sampling point. */
- rest = (caml_memprof_young_trigger - caml_young_ptr) - next_sample_frac_part;
- CAMLassert(rest >= 0);
- occurrences = mt_generate_poisson(rest) + 1;
+ occurrences =
+ mt_generate_binom(caml_memprof_young_trigger - 1 - caml_young_ptr) + 1;
/* Restore the minor heap in a valid state and suspend sampling for
calling the callback.
diff --git a/runtime/signals_nat.c b/runtime/signals_nat.c
index 42224b6854..ce05dff35c 100644
--- a/runtime/signals_nat.c
+++ b/runtime/signals_nat.c
@@ -77,7 +77,13 @@ void caml_garbage_collection(void)
/* TEMPORARY: if we have just sampled an allocation in native mode,
we simply renew the sample to ignore it. Otherwise, renewing now
will not have any effect on the sampling distribution, because of
- the memorylessness of the Poisson process. */
+ the memorylessness of the Bernoulli process.
+
+ FIXME: if the sampling rate is 1, this leads to infinite loop,
+ because we are using a binomial distribution in [memprof.c]. This
+ will go away when the sampling of natively allocated blocks will
+ be correctly implemented.
+ */
caml_memprof_renew_minor_sample();
if (caml_requested_major_slice || caml_requested_minor_gc ||
caml_young_ptr - caml_young_trigger < Max_young_whsize){
diff --git a/stdlib/gc.mli b/stdlib/gc.mli
index 9242033a0f..2de9a5d8ee 100644
--- a/stdlib/gc.mli
+++ b/stdlib/gc.mli
@@ -387,14 +387,15 @@ val delete_alarm : alarm -> unit
(** [delete_alarm a] will stop the calls to the function associated
to [a]. Calling [delete_alarm a] again has no effect. *)
-(** [Memprof] is a sampling engine for allocated words. The blocks
- are sampled according to a Poisson process. That is, every block
- has a probability of being sampled which is proportional to its
- size, and large blocks can be sampled several times. The samples
- appear using a configurable sampling rate.
-
- This engine is typically used by a statistical memory profiler.
- *)
+(** [Memprof] is a sampling engine for allocated memory words. Every
+ allocated word has a probability of being sampled equal to a
+ configurable sampling rate. Since blocks are composed of several
+ words, a block can potentially be sampled several times. When a
+ block is sampled (i.e., it contains at least one sample word), a
+ user-defined callback is called.
+
+ This engine makes it possible to implement a low-overhead memory
+ profiler as an OCaml library. *)
module Memprof :
sig
type alloc_kind =
@@ -409,10 +410,11 @@ module Memprof :
type sample_info = {
n_samples: int;
- (** The number of samples in this block. Always >= 1, it is sampled
- according to a Poisson process, and in average equal to the
- size of the block (including the header) multiplied by lambda
- (the sampling rate). *)
+ (** The number of samples in this block. Always >= 1, it is
+ sampled according to a binomial distribution whose
+ parameters are the size of the block (including the header)
+ and the sampling rate. Hence, it is in average equal to the
+ size of the block multiplied by the sampling rate. *)
kind: alloc_kind;
(** The kind of the allocation. *)
tag: int;
@@ -446,9 +448,9 @@ module Memprof :
type 'a ctrl = {
sampling_rate : float;
(** The sampling rate in samples per word (including headers).
- Usually, with cheap callbacks, a rate of 0.001 has no
- visible effect on performance, and 0.01 causes the program
- to run a few percent slower. *)
+ Usually, with cheap callbacks, a rate of 0.001 has no
+ visible effect on performance, and 0.01 causes the program
+ to run a few percent slower. *)
callstack_size : int;
(** The length of the callstack recorded at every sample. *)
callback : 'a callback
diff --git a/testsuite/tests/statmemprof/arrays_in_major.byte.reference b/testsuite/tests/statmemprof/arrays_in_major.byte.reference
index 26f7865568..4f74573d0d 100644
--- a/testsuite/tests/statmemprof/arrays_in_major.byte.reference
+++ b/testsuite/tests/statmemprof/arrays_in_major.byte.reference
@@ -1,13 +1,13 @@
check_nosample
check_ephe_full_major
check_no_nested
-check_distrib 300 3000 1 0.000010
+check_distrib 300 3000 3 0.000010
check_distrib 300 3000 1 0.000100
check_distrib 300 3000 1 0.010000
-check_distrib 300 3000 1 1.000000
+check_distrib 300 3000 1 0.900000
check_distrib 300 300 100000 0.100000
check_distrib 300000 300000 30 0.100000
check_callstack
-Raised by primitive operation at file "arrays_in_major.ml", line 136, characters 2-35
-Called from file "arrays_in_major.ml", line 142, characters 9-27
+Raised by primitive operation at file "arrays_in_major.ml", line 147, characters 2-35
+Called from file "arrays_in_major.ml", line 153, characters 9-27
OK !
diff --git a/testsuite/tests/statmemprof/arrays_in_major.ml b/testsuite/tests/statmemprof/arrays_in_major.ml
index c757d503dd..adb20bae2e 100644
--- a/testsuite/tests/statmemprof/arrays_in_major.ml
+++ b/testsuite/tests/statmemprof/arrays_in_major.ml
@@ -58,7 +58,11 @@ let check_no_nested () =
Printf.printf "check_no_nested\n%!";
let in_callback = ref false in
start {
- sampling_rate = 1.;
+ (* FIXME: we should use 1. to make sure the block is sampled,
+ but the runtime does an infinite loop in native mode in this
+ case. This bug will go away when the sampling of natively
+ allocated will be correctly implemented. *)
+ sampling_rate = 0.5;
callstack_size = 10;
callback = fun _ ->
assert (not !in_callback);
@@ -92,22 +96,25 @@ let check_distrib lo hi cnt rate =
stop ();
(* The probability distribution of the number of samples follows a
- poisson distribution with mean tot_alloc*rate. Given that we
- expect this quantity to be large (i.e., > 100), this distribution
- is approximately equal to a normal distribution. We compute a
- 1e-8 confidence interval for !smp using quantiles of the normal
- distribution, and check that we are in this confidence interval. *)
+ binomial distribution of parameters tot_alloc and rate. Given
+ that tot_alloc*rate and tot_alloc*(1-rate) are large (i.e., >
+ 100), this distribution is approximately equal to a normal
+ distribution. We compute a 1e-8 confidence interval for !smp
+ using quantiles of the normal distribution, and check that we are
+ in this confidence interval. *)
let tot_alloc = cnt*(lo+hi+2)*(hi-lo+1)/2 in
+ assert (float tot_alloc *. rate > 100. &&
+ float tot_alloc *. (1. -. rate) > 100.);
let mean = float tot_alloc *. rate in
- let stddev = sqrt mean in
+ let stddev = sqrt (float tot_alloc *. rate *. (1. -. rate)) in
(* This assertion has probability to fail close to 1e-8. *)
assert (abs_float (mean -. float !smp) <= stddev *. 5.7)
let () =
- check_distrib 300 3000 1 0.00001;
+ check_distrib 300 3000 3 0.00001;
check_distrib 300 3000 1 0.0001;
check_distrib 300 3000 1 0.01;
- check_distrib 300 3000 1 1.;
+ check_distrib 300 3000 1 0.9;
check_distrib 300 300 100000 0.1;
check_distrib 300000 300000 30 0.1
@@ -127,7 +134,11 @@ let[@inline never] check_callstack () =
Printf.printf "check_callstack\n%!";
let callstack = ref None in
start {
- sampling_rate = 1.;
+ (* FIXME: we should use 1. to make sure the block is sampled,
+ but the runtime does an infinite loop in native mode in this
+ case. This bug will go away when the sampling of natively
+ allocated will be correctly implemented. *)
+ sampling_rate = 0.5;
callstack_size = 10;
callback = fun info ->
if info.kind = Major then callstack := Some info.callstack;
diff --git a/testsuite/tests/statmemprof/arrays_in_major.opt.reference b/testsuite/tests/statmemprof/arrays_in_major.opt.reference
index 464f0d5b52..36d45330b2 100644
--- a/testsuite/tests/statmemprof/arrays_in_major.opt.reference
+++ b/testsuite/tests/statmemprof/arrays_in_major.opt.reference
@@ -1,14 +1,14 @@
check_nosample
check_ephe_full_major
check_no_nested
-check_distrib 300 3000 1 0.000010
+check_distrib 300 3000 3 0.000010
check_distrib 300 3000 1 0.000100
check_distrib 300 3000 1 0.010000
-check_distrib 300 3000 1 1.000000
+check_distrib 300 3000 1 0.900000
check_distrib 300 300 100000 0.100000
check_distrib 300000 300000 30 0.100000
check_callstack
Raised by primitive operation at file "arrays_in_major.ml", line 17, characters 14-28
-Called from file "arrays_in_major.ml", line 136, characters 2-35
-Called from file "arrays_in_major.ml", line 142, characters 9-27
+Called from file "arrays_in_major.ml", line 147, characters 2-35
+Called from file "arrays_in_major.ml", line 153, characters 9-27
OK !
diff --git a/testsuite/tests/statmemprof/arrays_in_minor.byte.reference b/testsuite/tests/statmemprof/arrays_in_minor.byte.reference
index 64149f8b0e..183af7bbf9 100644
--- a/testsuite/tests/statmemprof/arrays_in_minor.byte.reference
+++ b/testsuite/tests/statmemprof/arrays_in_minor.byte.reference
@@ -4,10 +4,10 @@ check_no_nested
check_distrib 1 250 1000 0.000010
check_distrib 1 250 1000 0.000100
check_distrib 1 250 1000 0.010000
-check_distrib 1 250 1000 1.000000
+check_distrib 1 250 1000 0.900000
check_distrib 1 1 10000000 0.010000
check_distrib 250 250 100000 0.100000
check_callstack
-Raised by primitive operation at file "arrays_in_minor.ml", line 142, characters 2-35
-Called from file "arrays_in_minor.ml", line 148, characters 9-27
+Raised by primitive operation at file "arrays_in_minor.ml", line 153, characters 2-35
+Called from file "arrays_in_minor.ml", line 159, characters 9-27
OK !
diff --git a/testsuite/tests/statmemprof/arrays_in_minor.ml b/testsuite/tests/statmemprof/arrays_in_minor.ml
index aa275e103d..fa8b26ecfa 100644
--- a/testsuite/tests/statmemprof/arrays_in_minor.ml
+++ b/testsuite/tests/statmemprof/arrays_in_minor.ml
@@ -63,7 +63,11 @@ let check_no_nested () =
Printf.printf "check_no_nested\n%!";
let in_callback = ref false in
start {
- sampling_rate = 1.;
+ (* FIXME: we should use 1. to make sure the block is sampled,
+ but the runtime does an infinite loop in native mode in this
+ case. This bug will go away when the sampling of natively
+ allocated will be correctly implemented. *)
+ sampling_rate = 0.5;
callstack_size = 10;
callback = fun _ ->
assert (not !in_callback);
@@ -98,14 +102,17 @@ let check_distrib lo hi cnt rate =
stop ();
(* The probability distribution of the number of samples follows a
- poisson distribution with mean tot_alloc*rate. Given that we
- expect this quantity to be large (i.e., > 100), this distribution
- is approximately equal to a normal distribution. We compute a
- 1e-8 confidence interval for !smp using quantiles of the normal
- distribution, and check that we are in this confidence interval. *)
+ binomial distribution of parameters tot_alloc and rate. Given
+ that tot_alloc*rate and tot_alloc*(1-rate) are large (i.e., >
+ 100), this distribution is approximately equal to a normal
+ distribution. We compute a 1e-8 confidence interval for !smp
+ using quantiles of the normal distribution, and check that we are
+ in this confidence interval. *)
let tot_alloc = cnt*(lo+hi+2)*(hi-lo+1)/2 in
+ assert (float tot_alloc *. rate > 100. &&
+ float tot_alloc *. (1. -. rate) > 100.);
let mean = float tot_alloc *. rate in
- let stddev = sqrt mean in
+ let stddev = sqrt (float tot_alloc *. rate *. (1. -. rate)) in
(* This assertion has probability to fail close to 1e-8. *)
assert (abs_float (mean -. float !smp) <= stddev *. 5.7)
@@ -113,7 +120,7 @@ let () =
check_distrib 1 250 1000 0.00001;
check_distrib 1 250 1000 0.0001;
check_distrib 1 250 1000 0.01;
- check_distrib 1 250 1000 1.;
+ check_distrib 1 250 1000 0.9;
check_distrib 1 1 10000000 0.01;
check_distrib 250 250 100000 0.1
@@ -133,7 +140,11 @@ let[@inline never] check_callstack () =
Printf.printf "check_callstack\n%!";
let callstack = ref None in
start {
- sampling_rate = 1.;
+ (* FIXME: we should use 1. to make sure the block is sampled,
+ but the runtime does an infinite loop in native mode in this
+ case. This bug will go away when the sampling of natively
+ allocated will be correctly implemented. *)
+ sampling_rate = 0.5;
callstack_size = 10;
callback = fun info ->
if info.tag = 0 then callstack := Some info.callstack;
diff --git a/testsuite/tests/statmemprof/arrays_in_minor.opt.reference b/testsuite/tests/statmemprof/arrays_in_minor.opt.reference
index d2d95bf2ef..e62709ca30 100644
--- a/testsuite/tests/statmemprof/arrays_in_minor.opt.reference
+++ b/testsuite/tests/statmemprof/arrays_in_minor.opt.reference
@@ -4,11 +4,11 @@ check_no_nested
check_distrib 1 250 1000 0.000010
check_distrib 1 250 1000 0.000100
check_distrib 1 250 1000 0.010000
-check_distrib 1 250 1000 1.000000
+check_distrib 1 250 1000 0.900000
check_distrib 1 1 10000000 0.010000
check_distrib 250 250 100000 0.100000
check_callstack
Raised by primitive operation at file "arrays_in_minor.ml", line 22, characters 20-34
-Called from file "arrays_in_minor.ml", line 142, characters 2-35
-Called from file "arrays_in_minor.ml", line 148, characters 9-27
+Called from file "arrays_in_minor.ml", line 153, characters 2-35
+Called from file "arrays_in_minor.ml", line 159, characters 9-27
OK !
diff --git a/testsuite/tests/statmemprof/exception_callback.ml b/testsuite/tests/statmemprof/exception_callback.ml
index 750a8e9c4d..a490c0f2aa 100644
--- a/testsuite/tests/statmemprof/exception_callback.ml
+++ b/testsuite/tests/statmemprof/exception_callback.ml
@@ -12,7 +12,11 @@ let _ = Printexc.record_backtrace false
let _ =
start {
- sampling_rate = 1.;
+ (* FIXME: we should use 1. to make sure the block is sampled,
+ but the runtime does an infinite loop in native mode in this
+ case. This bug will go away when the sampling of natively
+ allocated will be correctly implemented. *)
+ sampling_rate = 0.5;
callstack_size = 10;
callback = fun _ -> assert false
};
diff --git a/testsuite/tests/statmemprof/exception_callback.reference b/testsuite/tests/statmemprof/exception_callback.reference
index 361b2d71e6..3c141ac1e9 100644
--- a/testsuite/tests/statmemprof/exception_callback.reference
+++ b/testsuite/tests/statmemprof/exception_callback.reference
@@ -1 +1 @@
-Fatal error: exception File "exception_callback.ml", line 17, characters 24-30: Assertion failed
+Fatal error: exception File "exception_callback.ml", line 21, characters 24-30: Assertion failed
diff --git a/testsuite/tests/statmemprof/lists_in_minor.byte.reference b/testsuite/tests/statmemprof/lists_in_minor.byte.reference
index e769d0b888..68bfe388e0 100644
--- a/testsuite/tests/statmemprof/lists_in_minor.byte.reference
+++ b/testsuite/tests/statmemprof/lists_in_minor.byte.reference
@@ -4,9 +4,9 @@ check_distrib 1000000 10 0.000100
check_distrib 1000000 10 0.001000
check_distrib 1000000 10 0.010000
check_distrib 100000 10 0.100000
-check_distrib 100000 10 1.000000
+check_distrib 100000 10 0.900000
check_callstack
Raised by primitive operation at file "lists_in_minor.ml", line 15, characters 11-33
-Called from file "lists_in_minor.ml", line 67, characters 2-26
-Called from file "lists_in_minor.ml", line 74, characters 2-20
+Called from file "lists_in_minor.ml", line 70, characters 2-26
+Called from file "lists_in_minor.ml", line 77, characters 2-20
OK !
diff --git a/testsuite/tests/statmemprof/lists_in_minor.ml b/testsuite/tests/statmemprof/lists_in_minor.ml
index 416b520aac..d28ecbe117 100644
--- a/testsuite/tests/statmemprof/lists_in_minor.ml
+++ b/testsuite/tests/statmemprof/lists_in_minor.ml
@@ -34,14 +34,17 @@ let check_distrib len cnt rate =
stop ();
(* The probability distribution of the number of samples follows a
- poisson distribution with mean tot_alloc*rate. Given that we
- expect this quantity to be large (i.e., > 100), this distribution
- is approximately equal to a normal distribution. We compute a
- 1e-8 confidence interval for !smp using quantiles of the normal
- distribution, and check that we are in this confidence interval. *)
+ binomial distribution of parameters tot_alloc and rate. Given
+ that tot_alloc*rate and tot_alloc*(1-rate) are large (i.e., >
+ 100), this distribution is approximately equal to a normal
+ distribution. We compute a 1e-8 confidence interval for !smp
+ using quantiles of the normal distribution, and check that we are
+ in this confidence interval. *)
let tot_alloc = cnt*len*3 in
+ assert (float tot_alloc *. rate > 100. &&
+ float tot_alloc *. (1. -. rate) > 100.);
let mean = float tot_alloc *. rate in
- let stddev = sqrt mean in
+ let stddev = sqrt (float tot_alloc *. rate *. (1. -. rate)) in
(* This assertion has probability to fail close to 1e-8. *)
assert (abs_float (mean -. float !smp) <= stddev *. 5.7)
@@ -52,7 +55,7 @@ let () =
check_distrib 1000000 10 0.001;
check_distrib 1000000 10 0.01;
check_distrib 100000 10 0.1;
- check_distrib 100000 10 1.
+ check_distrib 100000 10 0.9
let[@inline never] check_callstack () =
Printf.printf "check_callstack\n%!";