PageRenderTime 59ms CodeModel.GetById 31ms RepoModel.GetById 0ms app.codeStats 0ms

/asmrun/startup.c

https://bitbucket.org/HongboZhang/ocaml
C | 196 lines | 146 code | 23 blank | 27 comment | 27 complexity | c7ad2b23c5ed6a4f379b47992a4a7f08 MD5 | raw file
Possible License(s): LGPL-2.0, GPL-2.0
  1. /***********************************************************************/
  2. /* */
  3. /* OCaml */
  4. /* */
  5. /* Xavier Leroy and Damien Doligez, INRIA Rocquencourt */
  6. /* */
  7. /* Copyright 1996 Institut National de Recherche en Informatique et */
  8. /* en Automatique. All rights reserved. This file is distributed */
  9. /* under the terms of the GNU Library General Public License, with */
  10. /* the special exception on linking described in file ../LICENSE. */
  11. /* */
  12. /***********************************************************************/
  13. /* $Id$ */
  14. /* Start-up code */
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include "callback.h"
  18. #include "backtrace.h"
  19. #include "custom.h"
  20. #include "debugger.h"
  21. #include "fail.h"
  22. #include "freelist.h"
  23. #include "gc.h"
  24. #include "gc_ctrl.h"
  25. #include "intext.h"
  26. #include "memory.h"
  27. #include "misc.h"
  28. #include "mlvalues.h"
  29. #include "osdeps.h"
  30. #include "printexc.h"
  31. #include "stack.h"
  32. #include "sys.h"
  33. #ifdef HAS_UI
  34. #include "ui.h"
  35. #endif
  36. extern int caml_parser_trace;
  37. CAMLexport header_t caml_atom_table[256];
  38. char * caml_code_area_start, * caml_code_area_end;
  39. /* Initialize the atom table and the static data and code area limits. */
  40. struct segment { char * begin; char * end; };
  41. static void init_atoms(void)
  42. {
  43. extern struct segment caml_data_segments[], caml_code_segments[];
  44. int i;
  45. struct code_fragment * cf;
  46. for (i = 0; i < 256; i++) {
  47. caml_atom_table[i] = Make_header(0, i, Caml_white);
  48. }
  49. if (caml_page_table_add(In_static_data,
  50. caml_atom_table, caml_atom_table + 256) != 0)
  51. caml_fatal_error("Fatal error: not enough memory for the initial page table");
  52. for (i = 0; caml_data_segments[i].begin != 0; i++) {
  53. /* PR#5509: we must include the zero word at end of data segment,
  54. because pointers equal to caml_data_segments[i].end are static data. */
  55. if (caml_page_table_add(In_static_data,
  56. caml_data_segments[i].begin,
  57. caml_data_segments[i].end + sizeof(value)) != 0)
  58. caml_fatal_error("Fatal error: not enough memory for the initial page table");
  59. }
  60. caml_code_area_start = caml_code_segments[0].begin;
  61. caml_code_area_end = caml_code_segments[0].end;
  62. for (i = 1; caml_code_segments[i].begin != 0; i++) {
  63. if (caml_code_segments[i].begin < caml_code_area_start)
  64. caml_code_area_start = caml_code_segments[i].begin;
  65. if (caml_code_segments[i].end > caml_code_area_end)
  66. caml_code_area_end = caml_code_segments[i].end;
  67. }
  68. /* Register the code in the table of code fragments */
  69. cf = caml_stat_alloc(sizeof(struct code_fragment));
  70. cf->code_start = caml_code_area_start;
  71. cf->code_end = caml_code_area_end;
  72. cf->digest_computed = 0;
  73. caml_ext_table_init(&caml_code_fragments_table, 8);
  74. caml_ext_table_add(&caml_code_fragments_table, cf);
  75. }
  76. /* Configuration parameters and flags */
  77. static uintnat percent_free_init = Percent_free_def;
  78. static uintnat max_percent_free_init = Max_percent_free_def;
  79. static uintnat minor_heap_init = Minor_heap_def;
  80. static uintnat heap_chunk_init = Heap_chunk_def;
  81. static uintnat heap_size_init = Init_heap_def;
  82. static uintnat max_stack_init = Max_stack_def;
  83. /* Parse the CAMLRUNPARAM variable */
  84. /* The option letter for each runtime option is the first letter of the
  85. last word of the ML name of the option (see [stdlib/gc.mli]).
  86. Except for l (maximum stack size) and h (initial heap size).
  87. */
  88. /* Note: option l is irrelevant to the native-code runtime. */
  89. /* If you change these functions, see also their copy in byterun/startup.c */
  90. static void scanmult (char *opt, uintnat *var)
  91. {
  92. char mult = ' ';
  93. int val;
  94. sscanf (opt, "=%u%c", &val, &mult);
  95. sscanf (opt, "=0x%x%c", &val, &mult);
  96. switch (mult) {
  97. case 'k': *var = (uintnat) val * 1024; break;
  98. case 'M': *var = (uintnat) val * 1024 * 1024; break;
  99. case 'G': *var = (uintnat) val * 1024 * 1024 * 1024; break;
  100. default: *var = (uintnat) val; break;
  101. }
  102. }
  103. static void parse_camlrunparam(void)
  104. {
  105. char *opt = getenv ("OCAMLRUNPARAM");
  106. uintnat p;
  107. if (opt == NULL) opt = getenv ("CAMLRUNPARAM");
  108. if (opt != NULL){
  109. while (*opt != '\0'){
  110. switch (*opt++){
  111. case 's': scanmult (opt, &minor_heap_init); break;
  112. case 'i': scanmult (opt, &heap_chunk_init); break;
  113. case 'h': scanmult (opt, &heap_size_init); break;
  114. case 'l': scanmult (opt, &max_stack_init); break;
  115. case 'o': scanmult (opt, &percent_free_init); break;
  116. case 'O': scanmult (opt, &max_percent_free_init); break;
  117. case 'v': scanmult (opt, &caml_verb_gc); break;
  118. case 'b': caml_record_backtrace(Val_true); break;
  119. case 'p': caml_parser_trace = 1; break;
  120. case 'a': scanmult (opt, &p); caml_set_allocation_policy (p); break;
  121. }
  122. }
  123. }
  124. }
  125. /* These are termination hooks used by the systhreads library */
  126. struct longjmp_buffer caml_termination_jmpbuf;
  127. void (*caml_termination_hook)(void *) = NULL;
  128. extern value caml_start_program (void);
  129. extern void caml_init_ieee_floats (void);
  130. extern void caml_init_signals (void);
  131. void caml_main(char **argv)
  132. {
  133. char * exe_name;
  134. #ifdef __linux__
  135. static char proc_self_exe[256];
  136. #endif
  137. value res;
  138. char tos;
  139. caml_init_ieee_floats();
  140. caml_init_custom_operations();
  141. #ifdef DEBUG
  142. caml_verb_gc = 63;
  143. #endif
  144. caml_top_of_stack = &tos;
  145. parse_camlrunparam();
  146. caml_init_gc (minor_heap_init, heap_size_init, heap_chunk_init,
  147. percent_free_init, max_percent_free_init);
  148. init_atoms();
  149. caml_init_signals();
  150. caml_debugger_init (); /* force debugger.o stub to be linked */
  151. exe_name = argv[0];
  152. if (exe_name == NULL) exe_name = "";
  153. #ifdef __linux__
  154. if (caml_executable_name(proc_self_exe, sizeof(proc_self_exe)) == 0)
  155. exe_name = proc_self_exe;
  156. else
  157. exe_name = caml_search_exe_in_path(exe_name);
  158. #else
  159. exe_name = caml_search_exe_in_path(exe_name);
  160. #endif
  161. caml_sys_init(exe_name, argv);
  162. if (sigsetjmp(caml_termination_jmpbuf.buf, 0)) {
  163. if (caml_termination_hook != NULL) caml_termination_hook(NULL);
  164. return;
  165. }
  166. res = caml_start_program();
  167. if (Is_exception_result(res))
  168. caml_fatal_uncaught_exception(Extract_exception(res));
  169. }
  170. void caml_startup(char **argv)
  171. {
  172. caml_main(argv);
  173. }