123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196(**************************************************************************)(* *)(* OCaml *)(* *)(* Damien Doligez, projet Para, INRIA Rocquencourt *)(* Jacques-Henri Jourdan, projet Gallium, INRIA Paris *)(* *)(* Copyright 1996-2016 Institut National de Recherche en Informatique *)(* et en Automatique. *)(* *)(* All rights reserved. This file is distributed under the terms of *)(* the GNU Lesser General Public License version 2.1, with the *)(* special exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)typestat={minor_words:float;promoted_words:float;major_words:float;minor_collections:int;major_collections:int;heap_words:int;heap_chunks:int;live_words:int;live_blocks:int;free_words:int;free_blocks:int;largest_free:int;fragments:int;compactions:int;top_heap_words:int;stack_size:int;forced_major_collections:int;}typecontrol={minor_heap_size:int;major_heap_increment:int;space_overhead:int;verbose:int;max_overhead:int;stack_limit:int;allocation_policy:int;window_size:int;custom_major_ratio:int;custom_minor_ratio:int;custom_minor_max_size:int;}externalstat:unit->stat="caml_gc_stat"externalquick_stat:unit->stat="caml_gc_quick_stat"externalcounters:unit->(float*float*float)="caml_gc_counters"externalminor_words:unit->(float[@unboxed])="caml_gc_minor_words""caml_gc_minor_words_unboxed"externalget:unit->control="caml_gc_get"externalset:control->unit="caml_gc_set"externalminor:unit->unit="caml_gc_minor"externalmajor_slice:int->int="caml_gc_major_slice"externalmajor:unit->unit="caml_gc_major"externalfull_major:unit->unit="caml_gc_full_major"externalcompact:unit->unit="caml_gc_compaction"externalget_minor_free:unit->int="caml_get_minor_free"leteventlog_pause()=()leteventlog_resume()=()openPrintfletprint_statc=letst=stat()infprintfc"minor_collections: %d\n"st.minor_collections;fprintfc"major_collections: %d\n"st.major_collections;fprintfc"compactions: %d\n"st.compactions;fprintfc"forced_major_collections: %d\n"st.forced_major_collections;fprintfc"\n";letl1=String.length(sprintf"%.0f"st.minor_words)infprintfc"minor_words: %*.0f\n"l1st.minor_words;fprintfc"promoted_words: %*.0f\n"l1st.promoted_words;fprintfc"major_words: %*.0f\n"l1st.major_words;fprintfc"\n";letl2=String.length(sprintf"%d"st.top_heap_words)infprintfc"top_heap_words: %*d\n"l2st.top_heap_words;fprintfc"heap_words: %*d\n"l2st.heap_words;fprintfc"live_words: %*d\n"l2st.live_words;fprintfc"free_words: %*d\n"l2st.free_words;fprintfc"largest_free: %*d\n"l2st.largest_free;fprintfc"fragments: %*d\n"l2st.fragments;fprintfc"\n";fprintfc"live_blocks: %d\n"st.live_blocks;fprintfc"free_blocks: %d\n"st.free_blocks;fprintfc"heap_chunks: %d\n"st.heap_chunksletallocated_bytes()=let(mi,pro,ma)=counters()in(mi+.ma-.pro)*.float_of_int(Sys.word_size/8)externalfinalise:('a->unit)->'a->unit="caml_final_register"externalfinalise_last:(unit->unit)->'a->unit="caml_final_register_called_without_value"externalfinalise_release:unit->unit="caml_final_release"typealarm=boolAtomic.ttypealarm_rec={active:alarm;f:unit->unit}letreccall_alarmarec=ifAtomic.getarec.activethenbeginletfinally()=finalisecall_alarmarecinFun.protect~finallyarec.fendletdelete_alarma=Atomic.setafalse(* never inline, to prevent [arec] from being allocated statically *)let[@inlinenever]create_alarmf=letalarm=Atomic.maketrueinDomain.at_exit(fun()->delete_alarmalarm);letarec={active=alarm;f=f}infinalisecall_alarmarec;alarmmoduleMemprof=structtypettypeallocation_source=Normal|Marshal|Custom|Map_fileletstring_of_allocation_source=function|Normal->"Normal"|Marshal->"Marshal"|Custom->"Custom"|Map_file->"Map_file"typeallocation={n_samples:int;size:int;source:allocation_source;callstack:Printexc.raw_backtrace}type('minor,'major)tracker={alloc_minor:allocation->'minoroption;alloc_major:allocation->'majoroption;promote:'minor->'majoroption;dealloc_minor:'minor->unit;dealloc_major:'major->unit;}letnull_tracker={alloc_minor=(fun_->None);alloc_major=(fun_->None);promote=(fun_->None);dealloc_minor=(fun_->());dealloc_major=(fun_->());}externalc_start:float->int->('minor,'major)tracker->t="caml_memprof_start"letstart~sampling_rate?(callstack_size=max_int)tracker=c_startsampling_ratecallstack_sizetrackerexternalstop:unit->unit="caml_memprof_stop"externaldiscard:t->unit="caml_memprof_discard"endtypesuspended_collection_work=int(* Note: we do not currently expose this type outside the module,
because it could plausibly change in the future. In particular,
currently the runtime only track major allocations during ramp-up
work, but there are other sources of GC pressure, such as custom
block allocation, that could be tracked as well and should probably
be tracked separately. This suggests that the type of suspended work
could become a record of integers instead of one integer.
On the other hand, it would be nice to let users, say, smooth out
suspended work by splitting it in N smaller parts to be ramped down
separately. This would be possible by exposing the type as int, or
possibly by defining a division/splitting function for the abstract
type.
*)externalramp_up:(unit->'a)->'a*suspended_collection_work="caml_ml_gc_ramp_up"externalramp_down:suspended_collection_work->unit="caml_ml_gc_ramp_down"