don't make -ddump-if-trace imply -no-recomp
[ghc-hetmet.git] / rts / RtsFlags.c
index 43d527b..f8c8403 100644 (file)
@@ -28,6 +28,8 @@ RTS_FLAGS RtsFlags;
  */
 int     prog_argc = 0;    /* an "int" so as to match normal "argc" */
 char  **prog_argv = NULL;
+int     full_prog_argc = 0;    /* an "int" so as to match normal "argc" */
+char  **full_prog_argv = NULL;
 char   *prog_name = NULL; /* 'basename' of prog_argv[0] */
 int     rts_argc = 0;  /* ditto */
 char   *rts_argv[MAX_RTS_ARGS];
@@ -150,6 +152,18 @@ void initRtsFlagsDefaults(void)
 #endif
     RtsFlags.GcFlags.idleGCDelayTime    = 300; /* millisecs */
 
+#if osf3_HOST_OS
+/* ToDo: Perhaps by adjusting this value we can make linking without
+ * -static work (i.e., not generate a core-dumping executable)? */
+# if SIZEOF_VOID_P == 8
+    RtsFlags.GcFlags.heapBase           = 0x180000000L;
+# else
+#  error I have no idea where to begin the heap on a non-64-bit osf3 machine.
+# endif
+#else
+    RtsFlags.GcFlags.heapBase           = 0;   /* means don't care */
+#endif
+
 #ifdef DEBUG
     RtsFlags.DebugFlags.scheduler      = rtsFalse;
     RtsFlags.DebugFlags.interpreter    = rtsFalse;
@@ -165,15 +179,17 @@ void initRtsFlagsDefaults(void)
     RtsFlags.DebugFlags.par            = rtsFalse;
     RtsFlags.DebugFlags.linker         = rtsFalse;
     RtsFlags.DebugFlags.squeeze                = rtsFalse;
+    RtsFlags.DebugFlags.hpc            = rtsFalse;
 #endif
 
 #if defined(PROFILING) || defined(PAR)
     RtsFlags.CcFlags.doCostCentres     = 0;
 #endif /* PROFILING or PAR */
 
-#ifdef PROFILING
     RtsFlags.ProfFlags.doHeapProfile      = rtsFalse;
     RtsFlags.ProfFlags.profileInterval    = 100;
+
+#ifdef PROFILING
     RtsFlags.ProfFlags.includeTSOs        = rtsFalse;
     RtsFlags.ProfFlags.showCCSOnException = rtsFalse;
     RtsFlags.ProfFlags.maxRetainerSetSize = 8;
@@ -185,13 +201,12 @@ void initRtsFlagsDefaults(void)
     RtsFlags.ProfFlags.ccsSelector        = NULL;
     RtsFlags.ProfFlags.retainerSelector   = NULL;
     RtsFlags.ProfFlags.bioSelector        = NULL;
-
-#elif defined(DEBUG)
-    RtsFlags.ProfFlags.doHeapProfile      = rtsFalse;
 #endif
 
-    RtsFlags.MiscFlags.tickInterval    = 50;  /* In milliseconds */
-    RtsFlags.ConcFlags.ctxtSwitchTime  = 50;  /* In milliseconds */
+    RtsFlags.MiscFlags.tickInterval    = 20;  /* In milliseconds */
+    RtsFlags.ConcFlags.ctxtSwitchTime  = 20;  /* In milliseconds */
+
+    RtsFlags.MiscFlags.install_signal_handlers = rtsTrue;
 
 #ifdef THREADED_RTS
     RtsFlags.ParFlags.nNodes           = 1;
@@ -303,7 +318,8 @@ void initRtsFlagsDefaults(void)
     RtsFlags.TraceFlags.sched          = rtsFalse;
 
 #ifdef USE_PAPI
-    RtsFlags.PapiFlags.eventType        = PAPI_FLAG_BRANCH;
+    /* By default no special measurements taken */
+    RtsFlags.PapiFlags.eventType        = 0;
 #endif
 }
 
@@ -320,6 +336,7 @@ usage_text[] = {
 "The following run time system options are available:",
 "",
 "  -?       Prints this message and exits; the program is not executed",
+"  --info   Print information about the RTS used by this program",
 "",
 "  -K<size> Sets the maximum stack size (default 8M)  Egs: -K32k   -K512k",
 "  -k<size> Sets the initial thread stack size (default 1k)  Egs: -k4k   -k2m",
@@ -378,23 +395,20 @@ usage_text[] = {
 "  -L<chars>      Maximum length of a cost-centre stack in a heap profile",
 "                 (default: 25)",
 "",
-"  -i<sec>        Time between heap samples (seconds, default: 0.1)",
-"",
 "  -xt            Include threads (TSOs) in a heap profile",
 "",
 "  -xc      Show current cost centre stack on raising an exception",
+"",
 # endif
 #endif /* PROFILING or PAR */
-#if !defined(PROFILING) && defined(DEBUG)
+#if !defined(PROFILING)
 "",
-"  -h<break-down> Debugging Heap residency profile",
-"                 (output file <program>.hp)",
-"     break-down: L = closure label (default)",
-"                 T = closure type (constructor, thunk etc.)",
+"  -hT      Heap residency profile (output file <program>.hp)",
 #endif
+"  -i<sec>  Time between heap samples (seconds, default: 0.1)",
 "",
 #if defined(TICKY_TICKY)
-"  -r<file>  Produce reduction profiling statistics (with -rstderr for stderr)",
+"  -r<file>  Produce ticky-ticky statistics (with -rstderr for stderr)",
 "",
 #endif
 #if defined(PAR)
@@ -404,7 +418,7 @@ usage_text[] = {
 "  -C<secs>  Context-switch interval in seconds.",
 "            0 or no argument means switch as often as possible.",
 "            Default: 0.02 sec; resolution is set by -V below.",
-"  -V<secs>  Master tick interval in seconds.",
+"  -V<secs>  Master tick interval in seconds (0 == disable timer).",
 "            This sets the resolution for -C and the profile timer -i.",
 "            Default: 0.02 sec.",
 "",
@@ -426,6 +440,7 @@ usage_text[] = {
 "  -Dl  DEBUG: linker",
 "  -Dm  DEBUG: stm",
 "  -Dz  DEBUG: stack squezing",
+"  -Dc  DEBUG: program coverage",
 "",
 #endif /* DEBUG */
 #if defined(THREADED_RTS) && !defined(NOSMP)
@@ -433,6 +448,8 @@ usage_text[] = {
 "  -qm       Don't automatically migrate threads between CPUs",
 "  -qw       Migrate a thread to the current CPU when it is woken up",
 #endif
+"  --install-signal-handlers=<yes|no>",
+"            Install signal handlers (default: yes)",
 #if defined(THREADED_RTS) || defined(PAR)
 "  -e<size>  Size of spark pools (default 100)",
 #endif
@@ -462,6 +479,7 @@ usage_text[] = {
 "            2 - level 2 cache misses",
 "            b - branch mispredictions",
 "            s - stalled cycles",
+"            e - cache miss and branch misprediction events",
 #endif
 "",
 "RTS options may also be specified using the GHCRTS environment variable.",
@@ -653,6 +671,28 @@ error = rtsTrue;
                error = rtsTrue;
                break;
 
+              /* This isn't going to allow us to keep related options
+                 together as we add more --* flags. We really need a
+                 proper options parser. */
+             case '-':
+                  if (strequal("install-signal-handlers=yes",
+                               &rts_argv[arg][2])) {
+                      RtsFlags.MiscFlags.install_signal_handlers = rtsTrue;
+                  }
+                  else if (strequal("install-signal-handlers=no",
+                               &rts_argv[arg][2])) {
+                      RtsFlags.MiscFlags.install_signal_handlers = rtsFalse;
+                  }
+                  else if (strequal("info",
+                               &rts_argv[arg][2])) {
+                      printRtsInfo();
+                      exit(0);
+                  }
+                  else {
+                     errorBelch("unknown RTS option: %s",rts_argv[arg]);
+                     error = rtsTrue;
+                  }
+                 break;
              case 'A':
                RtsFlags.GcFlags.minAllocAreaSize
                  = decode(rts_argv[arg]+2) / BLOCK_SIZE;
@@ -676,6 +716,9 @@ error = rtsTrue;
                case 's':
                  RtsFlags.PapiFlags.eventType = PAPI_FLAG_STALLS;
                  break;
+               case 'e':
+                 RtsFlags.PapiFlags.eventType = PAPI_FLAG_CB_EVENTS;
+                 break;
                default:
                  bad_option( rts_argv[arg] );
                }
@@ -754,6 +797,9 @@ error = rtsTrue;
                      case 'z':
                          RtsFlags.DebugFlags.squeeze = rtsTrue;
                          break;
+                     case 'c':
+                         RtsFlags.DebugFlags.hpc = rtsTrue;
+                         break;
                      default:
                          bad_option( rts_argv[arg] );
                      }
@@ -905,12 +951,9 @@ error = rtsTrue;
                       }
                  ) break;
              case 'h': /* serial heap profile */
-#if !defined(PROFILING) && defined(DEBUG)
+#if !defined(PROFILING)
                switch (rts_argv[arg][2]) {
                  case '\0':
-                 case 'L':
-                   RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_INFOPTR;
-                   break;
                  case 'T':
                    RtsFlags.ProfFlags.doHeapProfile = HEAP_BY_CLOSURE_TYPE;
                    break;
@@ -1026,7 +1069,6 @@ error = rtsTrue;
 #endif /* PROFILING */
                break;
 
-#if defined(PROFILING) 
              case 'i': /* heap sample interval */
                if (rts_argv[arg][2] == '\0') {
                  /* use default */
@@ -1038,7 +1080,6 @@ error = rtsTrue;
                    RtsFlags.ProfFlags.profileInterval = cst;
                }
                break;
-#endif
 
              /* =========== CONCURRENT ========================= */
              case 'C': /* context switch interval */
@@ -1076,6 +1117,12 @@ error = rtsTrue;
                      errorBelch("bad value for -N");
                      error = rtsTrue;
                    }
+#if defined(PROFILING)
+                    if (RtsFlags.ParFlags.nNodes > 1) {
+                        errorBelch("bad option %s: only -N1 is supported with profiling", rts_argv[arg]);
+                     error = rtsTrue;
+                    }
+#endif
                }
                ) break;
 
@@ -1171,6 +1218,16 @@ error = rtsTrue;
                    error = rtsTrue;
                    break;
 
+                case 'b': /* heapBase in hex; undocumented */
+                    if (rts_argv[arg][3] != '\0') {
+                        RtsFlags.GcFlags.heapBase
+                            = strtol(rts_argv[arg]+3, (char **) NULL, 16);
+                    } else {
+                        errorBelch("-xb: requires argument");
+                        error = rtsTrue;
+                    }
+                    break;
+
                   case 'c': /* Debugging tool: show current cost centre on an exception */
                     PROFILING_BUILD_ONLY(
                        RtsFlags.ProfFlags.showCCSOnException = rtsTrue;
@@ -1201,13 +1258,20 @@ error = rtsTrue;
        }
     }
 
-    // Determine what tick interval we should use for the RTS timer
-    // by taking the shortest of the various intervals that we need to
-    // monitor.
-    if (RtsFlags.MiscFlags.tickInterval <= 0) {
+    if (RtsFlags.MiscFlags.tickInterval < 0) {
         RtsFlags.MiscFlags.tickInterval = 50;
     }
 
+    // If the master timer is disabled, turn off the other timers.
+    if (RtsFlags.MiscFlags.tickInterval == 0) {
+        RtsFlags.ConcFlags.ctxtSwitchTime  = 0;
+        RtsFlags.GcFlags.idleGCDelayTime   = 0;
+        RtsFlags.ProfFlags.profileInterval = 0;
+    }
+
+    // Determine what tick interval we should use for the RTS timer
+    // by taking the shortest of the various intervals that we need to
+    // monitor.
     if (RtsFlags.ConcFlags.ctxtSwitchTime > 0) {
         RtsFlags.MiscFlags.tickInterval =
             stg_min(RtsFlags.ConcFlags.ctxtSwitchTime,
@@ -1220,13 +1284,11 @@ error = rtsTrue;
                     RtsFlags.MiscFlags.tickInterval);
     }
 
-#ifdef PROFILING
     if (RtsFlags.ProfFlags.profileInterval > 0) {
         RtsFlags.MiscFlags.tickInterval =
             stg_min(RtsFlags.ProfFlags.profileInterval,
                     RtsFlags.MiscFlags.tickInterval);
     }
-#endif
 
     if (RtsFlags.ConcFlags.ctxtSwitchTime > 0) {
         RtsFlags.ConcFlags.ctxtSwitchTicks =
@@ -1236,10 +1298,13 @@ error = rtsTrue;
         RtsFlags.ConcFlags.ctxtSwitchTicks = 0;
     }
 
-#ifdef PROFILING
-    RtsFlags.ProfFlags.profileIntervalTicks =
-        RtsFlags.ProfFlags.profileInterval / RtsFlags.MiscFlags.tickInterval;
-#endif
+    if (RtsFlags.ProfFlags.profileInterval > 0) {
+        RtsFlags.ProfFlags.profileIntervalTicks =
+            RtsFlags.ProfFlags.profileInterval / 
+            RtsFlags.MiscFlags.tickInterval;
+    } else {
+        RtsFlags.ProfFlags.profileIntervalTicks = 0;
+    }
 
     if (error) {
        const char **p;
@@ -2360,3 +2425,29 @@ setProgArgv(int argc, char *argv[])
    prog_argv = argv;
    setProgName(prog_argv);
 }
+
+/* These functions record and recall the full arguments, including the
+   +RTS ... -RTS options. The reason for adding them was so that the
+   ghc-inplace program can pass /all/ the arguments on to the real ghc. */
+void
+getFullProgArgv(int *argc, char **argv[])
+{
+    if (argc) { *argc = full_prog_argc; }
+    if (argv) { *argv = full_prog_argv; }
+}
+
+void
+setFullProgArgv(int argc, char *argv[])
+{
+    int i;
+    full_prog_argc = argc;
+    full_prog_argv = stgCallocBytes(argc + 1, sizeof (char *),
+                                    "setFullProgArgv 1");
+    for (i = 0; i < argc; i++) {
+        full_prog_argv[i] = stgMallocBytes(strlen(argv[i]) + 1,
+                                           "setFullProgArgv 2");
+        strcpy(full_prog_argv[i], argv[i]);
+    }
+    full_prog_argv[argc] = NULL;
+}
+