123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293(************************************************************************)(* * The Rocq Prover / The Rocq Development Team *)(* v * Copyright INRIA, CNRS and contributors *)(* <O___,, * (see version control and CREDITS file for authors & dates) *)(* \VV/ **************************************************************)(* // * This file is distributed under the terms of the *)(* * GNU Lesser General Public License Version 2.1 *)(* * (see LICENSE file for the text of the license) *)(************************************************************************)(** GC tweaking *)(** Work around a broken Gc.set function in released OCaml versions between
4.08.0 and 4.11.1 inclusive. *)letgc_set:Gc.control->unit=letopenGcinletfixed_setcontrol=let{custom_major_ratio;custom_minor_ratio;custom_minor_max_size;_}=controlinletcontrol={controlwithcustom_major_ratio=custom_major_ratiolsr1;custom_minor_ratio=custom_minor_ratiolsr1;custom_minor_max_size=custom_minor_max_sizelsr1;}inGc.setcontrolin(* the fix has been backported to all of these branches, so any
version after these will be fixed. *)matchCoq_config.caml_version_numswith|[4;11;1]|[4;11;0]|[4;10;2]|[4;10;1]|[4;10;0]|[4;09;1]|[4;09;0]|[4;08;1]|[4;08;0]->fixed_set|_->Gc.set(** Rocq is a heavy user of persistent data structures and symbolic ASTs, so the
minor heap is heavily solicited. Unfortunately, the default size is far too
small, so we enlarge it a lot (128 times larger).
To better handle huge memory consumers, we also augment the default major
heap increment and the GC pressure coefficient.
*)letset_gc_policy()=gc_set{(Gc.get())withGc.minor_heap_size=32*1024*1024(* 32Mwords x 8 bytes/word = 256Mb *);Gc.space_overhead=120}letset_gc_best_fit()=gc_set{(Gc.get())withGc.allocation_policy=2(* best-fit *);Gc.space_overhead=200}letinit_gc()=try(* OCAMLRUNPARAM environment variable is set.
* In that case, we let ocamlrun to use the values provided by the user.
*)ignore(Sys.getenv"OCAMLRUNPARAM")withNot_found->(* OCAMLRUNPARAM environment variable is not set.
* In this case, we put in place our preferred configuration.
*)set_gc_policy();ifCoq_config.caml_version_nums>=[4;10;0]thenset_gc_best_fit()else()letinit_ocaml()=init_gc();(* Get error message (and backtrace if enabled) on Ctrl-C instead of just exiting the process *)Sys.catch_breaktrueletinit_coqlibopts=matchopts.Coqargs.config.Coqargs.coqlibwith|None->()|Somes->Boot.Env.set_coqlibsletprint_query~usage=letopenCoqargsinfunction|PrintVersion->Boot.Usage.version()|PrintMachineReadableVersion->Boot.Usage.machine_readable_version()|PrintWhere->letenv=Boot.Env.init()inletcoqlib=Boot.Env.coqlibenv|>Boot.Path.to_stringinprint_endlinecoqlib|PrintHelp->Boot.Usage.print_usagestderrusage|PrintConfig->Envars.print_configstdoutletdirpath_of_filef=letldir0=tryletlp=Loadpath.find_load_path(Filename.dirnamef)inLoadpath.logicallpwithNot_found->Libnames.default_root_prefixinletf=tryFilename.chop_extension(Filename.basenamef)withInvalid_argument_->finletid=Names.Id.of_stringfinletldir=Libnames.add_dirpath_suffixldir0idinldirletdirpath_of_top=function|Coqargs.TopPhysicalf->dirpath_of_filef|TopLogicaldp->Libnames.dirpath_of_stringdpletparse_arguments~parse_extra?(initial_args=Coqargs.default)args=letopts,extras=Coqargs.parse_args~init:initial_argsargsinletcustomopts,extras=parse_extraoptsextrasinifnot(CList.is_emptyextras)thenbeginprerr_endline("Don't know what to do with "^String.concat" "extras);prerr_endline"See -help for the list of supported options";exit1end;opts,customoptsletprint_memory_stat()=letopenPpin(* -m|--memory from the command-line *)Feedback.msg_notice(str"total heap size = "++int(CObj.heap_size_kb())++str" kbytes"++fnl());(* operf-macro interface:
https://github.com/OCamlPro/operf-macro *)tryletfn=Sys.getenv"OCAML_GC_STATS"inletoc=open_outfninGc.print_statoc;close_outocwithexnwhenCErrors.noncriticalexn->()letto_vo_path(x:Coqargs.vo_path):Loadpath.vo_path={implicit=x.implicit;unix_path=x.unix_path;coq_path=Libnames.dirpath_of_stringx.rocq_path;recursive=true;}letinit_load_pathsopts=letopenCoqargsinletboot_ml_path,boot_vo_path=ifopts.pre.bootthen[],[]elseletcoqenv=Boot.Env.init()inCoqloadpath.init_load_path~coqenvinletml_path=opts.pre.ml_includes@boot_ml_pathinList.iterMltop.add_ml_dir(List.revml_path);List.iterLoadpath.add_vo_pathboot_vo_path;letenv_ocamlpath=try[Sys.getenv"OCAMLPATH"]withNot_found->[]inletenv_ocamlpath=ml_path@env_ocamlpathinletocamlpathsep=ifSys.unixthen":"else";"inletenv_ocamlpath=String.concatocamlpathsepenv_ocamlpathinFindlib.init~env_ocamlpath()letinit_profile~file=letch=open_outfileinletfname=Filename.basenamefileinNewProfile.init{output=Format.formatter_of_out_channelch;fname;};at_exit(fun()->NewProfile.finish();close_outch)letinit_runtime~usageopts=letopenCoqargsinVernacextend.static_linking_done();Option.iter(funfile->init_profile~file)opts.config.profile;Lib.init();init_coqlibopts;ifopts.post.memory_statthenat_exitprint_memory_stat;(* excluded directories *)List.iterSystem.exclude_directoryopts.config.exclude_dirs;(* Paths for loading stuff *)init_load_pathsopts;matchopts.Coqargs.mainwith|Coqargs.Queriesq->List.iter(print_query~usage)q;exit0|Coqargs.Run->()letinit_documentopts=letopenCoqargsin(* this isn't in init_load_paths because processes (typically
vscoqtop) are allowed to have states with differing vo paths (but
not with differing -boot or ml paths) *)List.iter(funx->Loadpath.add_vo_path@@to_vo_pathx)opts.pre.vo_includes;(* Kernel configuration *)Global.set_impredicative_setopts.config.logic.impredicative_set;Global.set_indices_matteropts.config.logic.indices_matter;Global.set_check_universes(notopts.config.logic.type_in_type);Global.set_VMopts.config.enable_VM;Global.set_native_compiler(matchopts.config.native_compilerwithNativeOff->false|NativeOn_->true);Global.set_rewrite_rules_allowedopts.config.logic.rewrite_rules;(* XXX these flags should probably be in the summary *)(* Native output dir *)Nativelib.output_dir:=opts.config.native_output_dir;Nativelib.include_dirs:=opts.config.native_include_dirs;(* Default output dir *)Flags.output_directory:=opts.config.output_directory;(* Test mode *)Flags.test_mode:=opts.config.test_mode;(* beautify *)ifopts.config.beautifythenbeginFlags.beautify:=true;Flags.record_comments:=true;end;ifopts.config.quietthenbeginFlags.quiet:=true;Flags.make_warnfalse;end;()letwarn_require_not_found=CWarnings.create~name:"compatibility-module-not-found"~category:CWarnings.CoreCategories.filesystemPp.(fun(prefix,lib)->strbrk"Did not find compatibility module "++Libnames.pr_qualidlib++pr_opt(funprefix->str"with prefix "++Libnames.pr_qualidprefix)prefix++str".")letrequire_file~intern~prefix~lib~export~allow_failure=letmp=Libnames.qualid_of_stringlibinletmfrom=Option.mapLibnames.qualid_of_stringprefixinletexp=Option.map(function|Coqargs.Import->Vernacexpr.Import,None|Coqargs.Export->Vernacexpr.Export,None)exportintryFlags.silently(Vernacentries.vernac_require~internmfromexp)[mp,Vernacexpr.ImportAll]with(Synterp.UnmappedLibrary_|Synterp.NotFoundLibrary_)whenallow_failure->warn_require_not_found(mfrom,mp)letwarn_no_native_compiler=CWarnings.create_inNativeconv.w_native_disabledPp.(funs->strbrk"Native compiler is disabled,"++strbrk" -native-compiler "++strbrks++strbrk" option ignored.")letwarn_deprecated_native_compiler=CWarnings.create~name:"deprecated-native-compiler-option"~category:Deprecation.Version.v8_14(fun()->Pp.strbrk"The native-compiler option is deprecated. To compile native \
files ahead of time, use the coqnative binary instead.")letinterp_set_optionoptvold=letopenGoptionsinletopt=String.concat" "optinmatcholdwith|BoolValue_->BoolValue(Coqargs.get_bool~optv)|IntValue_->IntValue(Coqargs.get_int_opt~optv)|StringValue_->StringValuev|StringOptValue_->StringOptValue(Somev)letset_option(opt,v)=letopenGoptionsinmatch(v:Coqargs.option_command)with|OptionUnset->unset_option_value_gen~locality:OptLocalopt|OptionSetNone->set_bool_option_value_gen~locality:OptLocalopttrue|OptionSet(Somev)->set_option_value~locality:OptLocal(interp_set_optionopt)optv|OptionAppendv->set_string_option_append_value_gen~locality:OptLocaloptvlethandle_injection~intern=letopenCoqargsinfunction|RequireInjection{lib;prefix;export;allow_failure}->require_file~intern~lib~prefix~export~allow_failure|OptionInjectiono->set_optiono|WarnNoNatives->warn_no_native_compilers|WarnNativeDeprecated->warn_deprecated_native_compiler()letstart_library~intern~topinjections=Flags.verboselyDeclaremods.start_librarytop;CWarnings.override_unknown_warning[@ocaml.warning"-3"]:=true;List.iter(handle_injection~intern)injections;CWarnings.override_unknown_warning[@ocaml.warning"-3"]:=false