netscape-revival
sun-java/java/javai.c
/*
* @(#)javai.c 1.75 95/08/11
*
* Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL purposes and without
* fee is hereby granted provided that this copyright notice
* appears in all copies. Please refer to the file "copyright.html"
* for further important copyright and licensing information.
*
* SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
* THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*/
/*-
* interpret an java object file
*/
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <ctype.h>
#include "javaThreads.h"
#include "errno.h"
#include "tree.h"
#include "oobj.h"
#include "interpreter.h"
#include "exceptions.h"
#include "javaString.h"
#include "log.h"
#include "installpath.h"
#include "bool.h"
#include "jio.h"
#ifndef NATIVE
#include "iomgr.h"
#include <fcntl.h>
#ifndef XP_PC
#include <sys/wait.h>
#include <unistd.h>
#include <sys/signal.h>
#endif /* ! XP_PC */
#include <signal.h>
#else /* NATIVE */
#include "monitor.h"
#endif /* NATIVE */
#include "prglobal.h"
#include "prlink.h"
#if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) || defined(SCO) || defined(UNIXWARE) || (defined(XP_PC) && !defined(_WIN32))
extern PRStaticLinkTable rt_nodl_tab[];
#endif
#ifdef MONITOR
#include <mon.h>
#endif
#ifndef NATIVE
#include <java_lang_Thread.h>
#endif /* NATIVE */
int RELEASE =
#include "../../build/build_number"
;
extern int verbose_class_loading;
/* Force load in the language level natives */
extern void _java_lang_init(void);
extern Hjava_lang_Thread *InitializeClassThread(ExecEnv *ee, char **);
extern void InitializeAlloc(long max, long min);
#ifndef NATIVE
extern void InitializeSbrk(void);
#endif /* NATIVE */
extern void WaitToDie(void);
static void usage(void);
#ifdef MONITOR
static void MonitorTeardown(void) {
monitor( 0, 0, 0, 0, 0 );
}
static void MonitorSetup(void) {
extern int etext(void);
extern int _start(void);
int (* low)() = &_start;
int (* high)() = & etext;
WORD * stuff;
int textwords = ((int)high - (int)low) / 4;
int nbytes = sizeof(struct hdr) + 10*sizeof( struct cnt )
+ textwords*sizeof(WORD);
stuff = (WORD*)malloc( nbytes );
monitor( low, high, stuff, nbytes/sizeof(WORD), 10 );
sysAtexit( MonitorTeardown );
}
#endif
/* from properties_md.c */
extern char **user_props;
static int nprops = 0;
static int max_props = 0;
/* add a user property */
static void add_user_prop(char *def)
{
char *p, *str;
/* scan to the '=' */
for (p = def ; *p && *p != '=' ; p++);
/* grow the array (if needed) */
if (nprops + 2 > max_props) {
if (user_props == 0) {
user_props = (char **)malloc(16 * sizeof(char *));
max_props = 16;
} else {
char **new_props = (char **)malloc(2 * max_props * sizeof(char *));
memcpy(new_props, user_props, nprops * sizeof(char *));
free(user_props);
user_props = new_props;
max_props *= 2;
}
}
/* malloc the key */
str = (char *)malloc((p - def) + 1);
strncpy(str, def, p - def);
str[p - def] = '\0';
user_props[nprops++] = str;
/* malloc the value */
if (*p == '=') {
p++;
}
str = (char *)malloc(strlen(p) + 1);
strcpy(str, p);
user_props[nprops++] = str;
}
/*
* have to put the hidden copy of the command line argument list where GC
* will find it
*/
HArrayOfString *
commandLineArguments(int argc, char **argv, struct execenv *ee)
{
HArrayOfString *ret = (HArrayOfString *) ArrayAlloc(T_CLASS, argc);
if (ret == 0) {
OutOfMemory:
SignalError(ee, JAVAPKG "OutOfMemoryError", 0);
return 0;
}
/* Give the array a "type" */
unhand((HArrayOfObject *)ret)->body[argc] =
(JHandle *)FindClass(ee, JAVAPKG "String", TRUE);
while (--argc >= 0) {
char *s = argv[argc];
if ((unhand(ret)->body[argc] = makeJavaString(s, strlen(s))) == 0)
goto OutOfMemory;
}
return (HArrayOfString *) ret;
}
long
atomi(register char *p)
{
long v = 0;
long mult = 1;
long c;
while ((c = *p++))
switch (c) {
case 'M':
case 'm':
mult = 1024 * 1024;
break;
case 'K':
case 'k':
mult = 1024;
break;
default:
if (c < '0' || c > '9')
return -1;
v = v * 10 + c - '0';
break;
}
return v * mult;
}
/*
* The reason we do not use this routine anymore is that we explicitly
* leave stdin, stdout, and stderr, unblocked i.e we do not mark this
* file descriptors nonblocking and hence we do not have to undo i.e
* mark them blocking before we exit anymore. Look at iomgr.c for how
* these fds are left unmarked and more details
*/
#ifndef NATIVE
void
makeTTYsane()
{
nonblock_io(0, IO_BLOCK);
nonblock_io(1, IO_BLOCK);
nonblock_io(2, IO_BLOCK);
}
#endif /* NATIVE */
extern void InitializeAsyncMonitors(void);
#include <path_md.h>
/*
* Default values for minimum and maximum amounts of memory to devote
* to the Java heap. The current abstraction, which may not hold up
* forever, is that the initial size of the heap is the minimum heap.
*
* The maximum memory to map: As we're mmapping the memory, it looks
* like we should ask swapctl(2) how much swap we have, and thus what
* the maximum we've got is.
*
* These values can be overridden on the java command line.
*/
#ifdef USE_MALLOC
#define MINHEAPSIZE ((int) ( 3 * (1024*1024)))
#define MAXHEAPSIZE MINHEAPSIZE
#else
#define MINHEAPSIZE ((int) ( 1 * (1024*1024)))
#define MAXHEAPSIZE ((int) (16 * (1024*1024)))
#endif /* USE_MALLOC */
/*
* The default thread stack size. This is machine-dependent, because it
* is based on a platform's C stack usage.
*/
#define PROCSTACKSIZE (128 * 1024) /* Default size of a thread C stack */
int awt_init_xt = 1;
#if defined(STATIC_JAVA)
#include "prlink.h"
extern void _java_awt_init(void);
extern void _java_mmedia_init(void);
#if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) || defined(SCO) || defined(UNIXWARE)
extern PRStaticLinkTable au_nodl_tab[];
extern PRStaticLinkTable awt_nodl_tab[];
extern PRStaticLinkTable rt_nodl_tab[];
#endif
#endif /* STATIC_JAVA */
#if defined(XP_PC) && !defined(_WIN32)
#include "prlink.h"
extern PRStaticLinkTable rt_nodl_tab[];
#endif /* XP_PC && !_WIN32 */
#if defined(XP_UNIX) && defined(BREAKPTS)
extern void PR_InitInterrupts(void);
#endif
#if defined(XP_PC) && !defined(_WIN32)
/*
** On 16-bit windows, the Floating Point subsystem (WINEM87.DLL)
** must be explicitly initialized...
** Unfortunately, the necessary functions do not appear in any
** header files...
*/
void _acrtused2() {};
extern LPVOID pascal _FPInit();
extern void pascal _FPTerm(LPVOID);
#endif
#define INITBUFSIZE 1024
#define INITNARGS 32
/*
** Start an execution environment based on the arguments
** provided in argv
** ( called by start_java or set_argfile_opts, which is called by start_java )
*/
static int start_exec_env(int argc, char** argv)
{
int MinHeapSize = MINHEAPSIZE;
int MaxHeapSize = MAXHEAPSIZE;
long T;
Hjava_lang_Thread *self;
int on_exit(void (*)(), void *);
struct methodblock *mb = 0;
extern int noasyncgc;
extern int tracegc;
long debugport = 0L;
ExecEnv ee;
char * errmsg;
char *sourcefile = 0;
char **args = argv;
char **dargv = argv;
verifyclasses = VERIFY_REMOTE; /* we've decided this is the default */
while (--argc > 0)
if ((++argv)[0][0] == '-' && sourcefile == 0)
#ifdef TRACING
if (strcmp(*argv, "-t") == 0)
trace++;
else if (strcmp(*argv, "-tm") == 0)
tracem++;
else
#endif
#ifdef MONITOR
if (strcmp(*argv, "-m") == 0) {
MonitorSetup();
}
else
#endif
if (strcmp(*argv, "-v") == 0 || strcmp(*argv, "-verbose") == 0)
verbose++;
else if (strcmp(*argv, "-debug") == 0)
debugagent++;
else if (strncmp(*argv, "-debugport", 10) == 0 &&
(T = atomi(&argv[0][10])) >= 0)
debugport = T;
else if (strcmp(*argv, "-noasyncgc") == 0)
noasyncgc++;
else if (strcmp(*argv, "-verbosegc") == 0)
verbosegc++;
else if (strcmp(*argv, "-verbosecl") == 0)
verbose_class_loading++;
else if (strcmp(*argv, "-verify") == 0)
verifyclasses = VERIFY_ALL;
else if (strcmp(*argv, "-verifyremote") == 0)
verifyclasses = VERIFY_REMOTE;
else if (strcmp(*argv, "-noverify") == 0)
verifyclasses = VERIFY_NONE;
else if (strcmp(*argv, "-tracegc") == 0)
tracegc++;
else if (strcmp(*argv, "-prof") == 0) {
extern void javamon(int i);
sysAtexit(java_mon_dump);
javamon(1);
} else if (strcmp(*argv, "-cs") == 0 ||
strcmp(*argv, "-checksource") == 0)
SkipSourceChecks = 0;
else if (strncmp(*argv, "-ss", 3) == 0 &&
(T = atomi(&argv[0][3])) > 1000)
ProcStackSize = T;
else if (strncmp(*argv, "-oss", 3) == 0 &&
(T = atomi(&argv[0][3])) > 1000)
JavaStackSize = T;
else if (strncmp(*argv, "-ms", 3) == 0 &&
(T = atomi(&argv[0][3])) > 1000)
MinHeapSize = T;
else if (strncmp(*argv, "-mx", 3) == 0 &&
(T = atomi(&argv[0][3])) > 1000)
MaxHeapSize = T;
else if (strncmp(*argv, "-D", 2) == 0)
add_user_prop(*argv + 2);
#ifdef LOGGING
else if (strncmp(*argv, "-l", 2) == 0 &&
(T = atomi(&argv[0][2])) >= 0)
logging_level = T;
#endif
else if (strncmp(*argv, "-classpath", 10) == 0) {
if (argc > 1) {
char *buf = (char *)malloc(strlen(argv[1]) + 32);
sprintf(buf, "CLASSPATH=%s", argv[1]);
putenv(buf);
argc--; argv++;
} else {
fprintf(stderr,
"-classpath requires class path specification\n");
usage();
return 1;
}
} else if (strncmp(*argv, "-addpath", 10) == 0) {
char *cpcurrent = getenv("CLASSPATH");
if (cpcurrent == NULL)
cpcurrent = "";
if (argc > 1) {
char *buf = (char *)malloc(strlen(cpcurrent)+strlen(argv[1])+32);
sprintf(buf, "CLASSPATH=%s;%s", getenv("CLASSPATH"), argv[1]);
putenv(buf);
argc--; argv++;
} else {
fprintf(stderr,
"+classpath requires class path specification\n");
usage();
return 1;
}
} else if (strcmp(*argv, "-h") == 0 ||
strcmp(*argv, "-help") == 0 ||
strncmp(*argv, "?", 1) == 0 ||
strncmp(*argv, "-?", 2) == 0) {
usage();
return 0;
} else if (strcmp(*argv, "-version") == 0) {
fprintf(stderr, "%s version %d\n", progname, RELEASE);
return 0;
} else {
fprintf(stderr, "%s: illegal argument\n", *argv);
usage();
return 1;
}
else if (sourcefile)
*dargv++ = *argv;
else {
sourcefile = *argv;
}
*dargv = 0;
/* the rest of the args belong to the java program */
InitializeExecEnv(&ee, 0); /* Call before InitializeMem() */
InitializeMem(); /* Could throw exception on open() */
#ifdef USE_MALLOC
MinHeapSize = MaxHeapSize;
#endif /* USE_MALLOC */
InitializeAlloc(MaxHeapSize, MinHeapSize);
InitializeInterpreter(); /* Call before InitializeClassThread() */
self = InitializeClassThread(&ee, &errmsg);
if (self == 0) {
fprintf(stderr, "Unable to initialize threads: %s\n", errmsg);
sysExit(1);
}
setThreadName(self,MakeString("main",4));
if (sourcefile == 0) {
usage();
return 1;
} if (strchr(sourcefile, '/')) {
fprintf(stderr, "Invalid class name: %s\n", sourcefile);
usage();
return 1;
} else {
ClassClass *cb;
int i, c;
char classname[200];
/* Allow the use of '.' in class names (convert to /) */
for (i = 0; i < sizeof classname - 1 && (c = sourcefile[i]) != 0; i++) {
classname[i] = c;
if (c == '.') sourcefile[i] = '/';
if (c == '/') classname[i] = '.';
}
classname[i] = 0;
cb = FindClass(&ee, sourcefile, TRUE);
if (cb == 0) {
fprintf(stderr, "Can't find class %s\n", classname);
return 1;
}
cb->flags |= CCF_Sticky;
if (debugagent) {
ClassClass *agentcb = FindClass(&ee, "sun/tools/debug/Agent",
TRUE);
if (agentcb == 0) {
fprintf(stderr, "Can't find class sun.tools.debug.Agent\n");
return 1;
}
execute_java_static_method(0, agentcb, "boot", "(I)V", debugport);
}
/* Finish initialization of the main thread */
InitializeMainThread();
mb = cbMethods(cb);
for (i = cb->methods_count; --i >= 0; mb++) {
if ((strcmp(fieldname(&mb->fb), "main") == 0) &&
(strncmp(fieldsig(&mb->fb), "([Ljava/lang/String;)", 20) == 0)){
if (fieldsig(&mb->fb)[21] == SIGNATURE_VOID)
break;
/* If we matched all the way to the return type, and its
* return type is not SIGNATURE_VOID, then we know there is
* no method match because the compiler would complain about
* duplicate method declaration. */
fprintf(stderr, "In class %s: main must return void\n",
classname);
return 1;
}
}
if (i < 0) {
fprintf(stderr, "In class %s: void main(String argv[]) is not defined\n",
classname);
return 1;
}
if ((mb->fb.access & (ACC_STATIC|ACC_PUBLIC))
!= (ACC_STATIC|ACC_PUBLIC)) {
fprintf(stderr, "In class %s: main must be public and static\n", classname);
return 1;
}
#if !defined(XP_PC) || defined(_WIN32)
do_execute_java_method(&ee, cb, 0, 0, mb, TRUE,
(JHandle *)commandLineArguments(dargv - args, args, &ee));
#else
/*
** For 16-bit windows initialize the floating-point system before executing
** the java method. Restore the previous FP settings after the call...
*/
{
LPVOID oldHandler;
oldHandler = _FPInit();
do_execute_java_method(&ee, cb, 0, 0, mb, TRUE,
(JHandle *)commandLineArguments(dargv - args, args, &ee));
_FPTerm(oldHandler);
}
#endif
if (exceptionOccurred(&ee)) {
if (ee.thread && THREAD(ee.thread)->group) {
void *t = (void *)ee.exception.exc;
exceptionClear(&ee);
execute_java_dynamic_method(&ee, (void *)THREAD(ee.thread)->group,
"uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V", ee.thread, t);
}
}
}
/*
* The primordial thread is not allowed to exit until all user
* threads have exited. Note that the primordial thread's
* resources (e.g. its Java stack) have not been reclaimed at this
* point, even though it's got no chance of running again. The
* thread is still on the active thread queue and will be scanned
* on GC, so has to be left intact. This should be revisited.
*/
WaitToDie();
#if defined(XP_PC) /* jag, hack hack :) */
if( WSACleanup() ) {
fprintf(stderr, "error shutting down winsock\n");
return 1;
}
#endif
return 0;
}
/*
** Reads command line arguments from one or more files.
** This is a std workaround for the limited command line
** length on windows
*/
static int
set_argfile_opts(int nfiles, char** files) {
char* buf;
int bufsize = INITBUFSIZE;
int numchars = 0;
int begin = 0;
char** argv;
int argvsize = INITNARGS;
int argc = 0;
int c;
FILE *responseFile;
int i, j = 0;
int errcode;
void * reallocd; /* tmp ptr to memory that has been realloc'd */
if( !(buf = (char*) malloc( sizeof(char) * bufsize)) ){
fprintf(stderr,"Out of memory.\n");
return 1;
}
if( !(argv = (char**) malloc( sizeof(char*) * argvsize)) ){
free( buf );
fprintf(stderr, "Out of memory.\n");
return 1;
}
*argv = progname; /* crude but quick: keep argv[0] the same for parsing */
argc++;
while( nfiles-- ) {
if( (responseFile = fopen( files[j++],"r")) == NULL ) {
fprintf(stderr, "unable to open argument file %s", argv[1] );
errcode = 1;
goto Fail_Cleanup;
return 1;
}
/* read the entire file into memory */
numchars = 0;
while( (c = getc(responseFile) ) != EOF ) {
buf[numchars++] = (char) c;
if( numchars >= bufsize ) {
bufsize *= 2;
if( !(reallocd = realloc( buf, sizeof(char) * bufsize)) ) {
fprintf(stderr,"Out of memory.\n");
errcode = 1;
goto Fail_Cleanup;
} else {
buf = (char*) reallocd;
}
}
}
/* break into tokens */
begin = 0;
for( i = 0; i < bufsize; i++) {
if( isspace(buf[i]) ) {
buf[i] = (char) NULL;
argv[argc++] = strdup(buf + begin);
while( i < (bufsize-1) && isspace(buf[i+1]))
buf[++i] = (char) NULL;
begin = i + 1;
if( argc >= argvsize ) {
argvsize *= 2;
if( !(reallocd = realloc( argv, sizeof(char*) * argvsize)) ) {
fprintf(stderr,"Out of memory.\n");
errcode = 1;
goto Fail_Cleanup;
} else {
argv = (char**) reallocd;
}
}
}
}
if( fclose( responseFile ) ) {
fprintf(stderr,"error closing response file %s\n", files[j-1]);
errcode = 1;
goto Fail_Cleanup;
}
}
if( !(reallocd = realloc( argv, sizeof(char*) * argc)) ) {
/* this should never happen, really */
fprintf(stderr,"Out of memory.\n");
errcode = 1;
goto Fail_Cleanup;
} else {
argv = (char**) reallocd;
}
free(buf); buf = NULL;
errcode = start_exec_env( argc, argv );
Fail_Cleanup:
if ( buf ) { /* we got here due to error in this proc, before start_exec_env */
free( buf );
}
if( errcode ) { /* free stuff that the GC would have gotten */
for( i = 1; i < argc; i++ ) { /* argv[0] points to the real argv! */
free( argv[i] );
}
}
free( argv ); /* this isn't really argv -- see above */
return errcode;
}
JAVA_PUBLIC_API(int)
start_java(int argc, char **argv)
{
int ret = 0;
#if defined(XP_PC) /* jag, hack hack :) */
WSADATA wsaData;
WORD wVersionRequested = MAKEWORD(1,1);
if( WSAStartup( wVersionRequested, &wsaData ) ) {
fprintf(stderr, "winsock failed to initialize\n");
return 1;
}
#endif
PR_Init("javai", 5, 0, 0);
#ifdef XP_UNIX
PR_StartEvents(0);
#ifdef BREAKPTS
PR_InitInterrupts();
#endif
#endif /* XP_UNIX */
set_java_io_mode(JIO_UNRESTRICTED);
set_java_fs_mode(JFS_UNRESTRICTED);
set_java_rt_mode(JRT_UNRESTRICTED);
intrInit();
/* Initialize the monitor registry */
monitorRegistryInit();
/* Create the monitor cache */
monitorCacheInit();
#ifndef NATIVE
/* Initialize the special case for sbrk on Solaris (see synch.c) */
InitializeSbrk();
/* Initialize the async io */
InitializeAsyncIO();
#endif
#ifdef XP_PC
#if defined(_WIN32)
PR_LoadLibrary("jrt3230.dll");
PR_LoadStaticLibrary("jpeg.dll", NULL);
PR_LoadStaticLibrary("net.dll", NULL);
#else
PR_LoadLibrary("jrt1630.dll");
PR_LoadStaticLibrary("jpeg.dll", NULL);
PR_LoadStaticLibrary("net.dll", nn_nodl_tab);
PR_LoadStaticLibrary("app.dll", na_nodl_tab);
PR_LoadStaticLibrary("jso.dll", njs_nodl_tab);
#endif
#endif /* XP_PC */
#if defined(STATIC_JAVA)
#if defined(AIX) || defined(BSDI) || defined(HPUX) || defined(LINUX) || defined(SCO) || defined(UNIXWARE)
PR_LoadStaticLibrary("javart.so", rt_nodl_tab);
PR_LoadStaticLibrary("libawt.so", awt_nodl_tab);
#else
PR_LoadStaticLibrary("javart.so", NULL);
PR_LoadStaticLibrary("libawt.so", NULL);
#endif
PR_LoadStaticLibrary("libmm3230.so",au_nodl_tab);/* XXX for sun/audio */
PR_LoadStaticLibrary("libjpeg.so", NULL);
PR_LoadStaticLibrary("libnet.so", NULL);
#else /* STATIC_JAVA */
PR_LoadStaticLibrary("libjpeg.so", NULL);
PR_LoadStaticLibrary("libnet.so", NULL);
#endif
#ifdef DEBUG
/* on_exit(PrintStats, 0); */
#endif
{ /* assume -cs if executed as "java"
rather than "java" [DOES THIS MAKE SENSE ANY MORE??? */
char *p = &argv[0][strlen(argv[0]) - 1];
if (p[0] == 'g' && p[-1] == '_')
p -= 2;
if (p[0] != 'k')
SkipSourceChecks = 1;
}
/* Store the base of the primordial thread's stack */
mainstktop = (stackp_t) &argc;
if ((progname = strrchr(argv[0], LOCAL_DIR_SEPARATOR)) != 0) {
progname++;
} else {
progname = argv[0];
}
if( argc >= 2 && strcmp(argv[1],"-argfile") == 0 ) {
if( argc < 3 ) {
fprintf(stderr,
"-argfile requires argfile specification\n");
usage();
return 1;
}
ret = set_argfile_opts( argc - 2, argv + 2 );
} else {
ret = start_exec_env( argc, argv );
}
return ret;
}
void
Execute(char **command, char *alternate)
{
long pid, wpid;
long lapcnt;
int status = -1;
if (verbose) {
printf("[Executing");
for (lapcnt = 0; command[lapcnt]; lapcnt++)
printf(" %s", command[lapcnt]);
printf("]\n");
}
lapcnt = 0;
#ifdef XP_PC /* rjp */
sysAssert(0);
#else
while ((pid = fork()) < 0) {
if (lapcnt == 0)
write(2, "[ Running out of system memory, waiting...", 42);
lapcnt++;
sleep(5);
}
if (pid) {
if (lapcnt)
write(2, " got it ]\n", 10);
while ((wpid = wait(&status)) == -1 || wpid != pid);
if (status != 0) {
fprintf(stderr, "%s: failed (%X)\n", command[0], status);
sysExit(1);
}
} else {
lapcnt = 0;
while (1) {
execvp(command[0], command);
if (alternate)
execvp(alternate, command);
if (errno != ENOMEM) {
perror(command[0]);
sysExit(1);
}
if (lapcnt == 0)
write(2, "Waiting for system memory...\n", 29);
sleep(20);
}
}
#endif
if (verbose)
printf("[Finished %s]\n", command[0]);
}
static void usage()
{
fprintf(stderr, "Usage: %s [-options] class\n", progname);
fprintf(stderr, "\n");
fprintf(stderr, "where options include:\n");
fprintf(stderr, " -help print out this message\n");
fprintf(stderr, " -version print out the build version\n");
#ifndef trace
fprintf(stderr, " -t turn on instruction tracing\n");
fprintf(stderr, " -tm turn on method tracing\n");
#endif
#ifdef MONITOR
fprintf(stderr, " -m turn on monitoring\n");
#endif
fprintf(stderr, " -v -verbose turn on verbose mode\n");
fprintf(stderr, " -debug enable JAVA debugging\n");
fprintf(stderr, " -noasyncgc don't allow asynchronous gc's\n");
fprintf(stderr, " -verbosegc print a message when GCs occur\n");
fprintf(stderr, " -cs -checksource check if source is newer when loading classes\n");
fprintf(stderr, " -ss<number> set the C stack size of a process\n");
fprintf(stderr, " -oss<number> set the JAVA stack size of a process\n");
fprintf(stderr, " -ms<number> set the initial Java heap size\n");
fprintf(stderr, " -mx<number> set the maximum Java heap size\n");
fprintf(stderr, " -D<name>=<value> set a system property\n");
#ifdef LOGGING
fprintf(stderr, " -l<number> set the logging level\n");
#endif
fprintf(stderr, " -classpath <directories separated by colons>\n");
fprintf(stderr, " list directories in which to look for classes\n");
fprintf(stderr, " -prof output profiling data to ./java.prof\n");
fprintf(stderr, " -verify verify all classes when read in\n");
fprintf(stderr, " -verifyremote verify classes read in over "
"the network [default]\n");
fprintf(stderr, " -noverify do not verify any class\n");
}
void fakeref(void)
{
_java_lang_init();
#if defined(STATIC_JAVA)
_java_awt_init();
_java_mmedia_init();
#endif
}