+ // Thread stack size specified by the -Xss runtime argument.
+ size_t stack_size = 0;
+
+ // Start time of the VM
+ jlong startTime = 0;
+
+ // Arguments passed to the VM
+ JArray<jstring>* vmArgs;
+
+ // Currently loaded classes
+ jint loadedClasses = 0;
+
+ // Unloaded classes
+ jlong unloadedClasses = 0;
+}
+
+// We accept all non-standard options accepted by Sun's java command,
+// for compatibility with existing application launch scripts.
+static jint
+parse_x_arg (char* option_string)
+{
+ if (strlen (option_string) <= 0)
+ return -1;
+
+ if (! strcmp (option_string, "int"))
+ {
+ // FIXME: this should cause the vm to never load shared objects
+ }
+ else if (! strcmp (option_string, "mixed"))
+ {
+ // FIXME: allow interpreted and native code
+ }
+ else if (! strcmp (option_string, "batch"))
+ {
+ // FIXME: disable background JIT'ing
+ }
+ else if (! strcmp (option_string, "debug"))
+ {
+ remoteDebug = true;
+ }
+#ifdef INTERPRETER
+ else if (! strncmp (option_string, "runjdwp:", 8))
+ {
+ if (strlen (option_string) > 8)
+ jdwpOptions = &option_string[8];
+ else
+ {
+ fprintf (stderr,
+ "libgcj: argument required for JDWP options");
+ return -1;
+ }
+ }
+#endif // INTERPRETER
+ else if (! strncmp (option_string, "bootclasspath:", 14))
+ {
+ // FIXME: add a parse_bootclasspath_arg function
+ }
+ else if (! strncmp (option_string, "bootclasspath/a:", 16))
+ {
+ }
+ else if (! strncmp (option_string, "bootclasspath/p:", 16))
+ {
+ }
+ else if (! strcmp (option_string, "check:jni"))
+ {
+ // FIXME: enable strict JNI checking
+ }
+ else if (! strcmp (option_string, "future"))
+ {
+ // FIXME: enable strict class file format checks
+ }
+ else if (! strcmp (option_string, "noclassgc"))
+ {
+ // FIXME: disable garbage collection for classes
+ }
+ else if (! strcmp (option_string, "incgc"))
+ {
+ // FIXME: incremental garbage collection
+ }
+ else if (! strncmp (option_string, "loggc:", 6))
+ {
+ if (option_string[6] == '\0')
+ {
+ fprintf (stderr,
+ "libgcj: filename argument expected for loggc option\n");
+ return -1;
+ }
+ // FIXME: set gc logging filename
+ }
+ else if (! strncmp (option_string, "ms", 2))
+ {
+ // FIXME: ignore this option until PR 20699 is fixed.
+ // _Jv_SetInitialHeapSize (option_string + 2);
+ }
+ else if (! strncmp (option_string, "mx", 2))
+ _Jv_SetMaximumHeapSize (option_string + 2);
+ else if (! strcmp (option_string, "prof"))
+ {
+ // FIXME: enable profiling of program running in vm
+ }
+ else if (! strncmp (option_string, "runhprof:", 9))
+ {
+ // FIXME: enable specific type of vm profiling. add a
+ // parse_runhprof_arg function
+ }
+ else if (! strcmp (option_string, "rs"))
+ {
+ // FIXME: reduced system signal usage. disable thread dumps,
+ // only terminate in response to user-initiated calls,
+ // e.g. System.exit()
+ }
+ else if (! strncmp (option_string, "ss", 2))
+ {
+ _Jv_SetStackSize (option_string + 2);
+ }
+ else if (! strcmp (option_string, "X:+UseAltSigs"))
+ {
+ // FIXME: use signals other than SIGUSR1 and SIGUSR2
+ }
+ else if (! strcmp (option_string, "share:off"))
+ {
+ // FIXME: don't share class data
+ }
+ else if (! strcmp (option_string, "share:auto"))
+ {
+ // FIXME: share class data where possible
+ }
+ else if (! strcmp (option_string, "share:on"))
+ {
+ // FIXME: fail if impossible to share class data
+ }
+ else
+ {
+ // Unrecognized.
+ return -1;
+ }
+ return 0;
+}
+
+static jint
+parse_verbose_args (char* option_string,
+ bool ignore_unrecognized)
+{
+ size_t len = sizeof ("-verbose") - 1;
+
+ if (strlen (option_string) < len)
+ return -1;
+
+ if (option_string[len] == ':'
+ && option_string[len + 1] != '\0')
+ {
+ char* verbose_args = option_string + len + 1;
+
+ do
+ {
+ if (! strncmp (verbose_args,
+ "gc", sizeof ("gc") - 1))
+ {
+ if (verbose_args[sizeof ("gc") - 1] == '\0'
+ || verbose_args[sizeof ("gc") - 1] == ',')
+ {
+ // FIXME: we should add functions to boehm-gc that
+ // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and
+ // GC_print_back_height.
+ verbose_args += sizeof ("gc") - 1;
+ }
+ else
+ {
+ verbose_arg_err:
+ fprintf (stderr, "libgcj: unknown verbose option: %s\n",
+ option_string);
+ return -1;
+ }
+ }
+ else if (! strncmp (verbose_args,
+ "class",
+ sizeof ("class") - 1))
+ {
+ if (verbose_args[sizeof ("class") - 1] == '\0'
+ || verbose_args[sizeof ("class") - 1] == ',')
+ {
+ gcj::verbose_class_flag = true;
+ verbose_args += sizeof ("class") - 1;
+ }
+ else
+ goto verbose_arg_err;
+ }
+ else if (! strncmp (verbose_args, "jni",
+ sizeof ("jni") - 1))
+ {
+ if (verbose_args[sizeof ("jni") - 1] == '\0'
+ || verbose_args[sizeof ("jni") - 1] == ',')
+ {
+ // FIXME: enable JNI messages.
+ verbose_args += sizeof ("jni") - 1;
+ }
+ else
+ goto verbose_arg_err;
+ }
+ else if (ignore_unrecognized
+ && verbose_args[0] == 'X')
+ {
+ // ignore unrecognized non-standard verbose option
+ while (verbose_args[0] != '\0'
+ && verbose_args[0] != ',')
+ verbose_args++;
+ }
+ else if (verbose_args[0] == ',')
+ {
+ verbose_args++;
+ }
+ else
+ goto verbose_arg_err;
+
+ if (verbose_args[0] == ',')
+ verbose_args++;
+ }
+ while (verbose_args[0] != '\0');
+ }
+ else if (option_string[len] == 'g'
+ && option_string[len + 1] == 'c'
+ && option_string[len + 2] == '\0')
+ {
+ // FIXME: we should add functions to boehm-gc that
+ // toggle GC_print_stats, GC_PRINT_ADDRESS_MAP and
+ // GC_print_back_height.
+ return 0;
+ }
+ else if (option_string[len] == '\0')
+ {
+ gcj::verbose_class_flag = true;
+ return 0;
+ }
+ else
+ {
+ // unrecognized option beginning with -verbose
+ return -1;
+ }
+ return 0;
+}
+
+#ifdef INTERPRETER
+// This function loads the agent functions for JVMTI from the library indicated
+// by name. It returns a negative value on failure, the value of which
+// indicates where ltdl failed, it also prints an error message.
+static jint
+load_jvmti_agent (const char *name)
+{
+#ifdef USE_LTDL
+ if (lt_dlinit ())
+ {
+ fprintf (stderr,
+ "libgcj: Error in ltdl init while loading agent library.\n");
+ return -1;
+ }
+
+ lt_dlhandle lib = lt_dlopenext (name);
+ if (!lib)
+ {
+ fprintf (stderr,
+ "libgcj: Error opening agent library.\n");
+ return -2;
+ }