001: /*
002: * @(#)CVM.java 1.116 06/11/07
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.misc;
029:
030: import java.lang.reflect.Method;
031: import java.lang.reflect.InvocationTargetException;
032: import sun.misc.Version;
033: import java.io.FileInputStream;
034: import java.util.jar.JarFile;
035: import java.util.jar.Manifest;
036: import java.util.jar.Attributes;
037: import java.io.IOException;
038: import java.util.ArrayList;
039: import java.io.File;
040: import java.util.StringTokenizer;
041:
042: public final class CVM {
043: /** WARNING! NO STATIC INITIALIZER IS ALLOWED IN THIS CLASS!
044:
045: More precisely, no initial assignment is allowed to either of
046: these two variables. */
047: private static String mainClassName;
048: private static String[] mainArgs;
049:
050: private static String savedNativeOptions;
051:
052: // The status of command-line argument parsing
053: public static final int ARG_PARSE_UNINIT = 0;
054: public static final int ARG_PARSE_OK = 1;
055: public static final int ARG_PARSE_ERR = 2;
056: public static final int ARG_PARSE_EXITVM = 3;
057: public static final int ARG_PARSE_USAGE = 4;
058:
059: private static int parseStatus;
060:
061: private static void usage(String nativeOptions) {
062: // Print usage statement
063: System.err
064: .println("usage: cvm [-fullversion] [-showversion] [-version] [-help] "
065: + "[-D<property>=<value>] [-XbuildOptions] [-XshowBuildOptions] "
066: + "[-XappName=<value>] "
067: + "[-cp <classpath> | -classpath <classpath>] "
068: + nativeOptions
069: + "{<main class name> | -jar <jarfile> | -appletviewer <URL>} "
070: + "[<arguments>...]");
071: }
072:
073: /** Parse command line options handed up from ansiJavaMain through
074: JNI_CreateJavaVM. This parses command line options like -D to
075: define user-specified properties; it must be called after
076: System.initializeSystemClass(). In its current usage it
077: receives argv[1..(argc - 1)] in String form from the C
078: initialization code, with "-Xcvm" prepended onto the main
079: class and its arguments. This allows the building of the
080: String array which will later be passed to main() to be done
081: in Java. Note that it is not necessary to use this
082: functionality. */
083: public static int parseCommandLineOptions(String[] args,
084: String nativeOptions, boolean ignoreUnrecognized) {
085: parseStatus = ARG_PARSE_UNINIT;
086:
087: String pathSeparator = System
088: .getProperty("path.separator", ":");
089: ArrayList xrunArgs = new ArrayList();
090: ArrayList agentlibArgs = new ArrayList();
091:
092: for (int i = 0; i < args.length; i++) {
093:
094: /* %comment: rt039 */
095:
096: /* NOTE: It would be best to move the support for
097: -XappName into the PP layer */
098: if (args[i].startsWith("-D")
099: || args[i].startsWith("-XappName")) {
100: if (!addUserProperty(args[i].substring(2))) {
101: System.err.println("Error parsing property "
102: + args[i]);
103: usage(nativeOptions);
104: parseStatus = ARG_PARSE_ERR;
105: return parseStatus;
106: }
107: } else if (args[i].startsWith("-version")) {
108: Version.print(true); // Long version
109: parseStatus = ARG_PARSE_EXITVM; // Don't parse any more
110: return parseStatus;
111: } else if (args[i].startsWith("-showversion")) {
112: Version.print(true); // Long version
113: // continue with VM execution
114: } else if (args[i].startsWith("-Xnoagent")) {
115: // eat this old jdb launching option
116: // continue with VM execution
117: } else if (args[i].startsWith("-Xtrace:")) {
118: String traceArg = args[i].substring(8);
119: int debugFlags = Integer.decode(traceArg).intValue();
120: CVM.setDebugFlags(debugFlags);
121: // continue with VM execution
122: } else if (args[i].startsWith("-agentlib")
123: || args[i].startsWith("-agentpath")) {
124: if (!agentlibSupported()) {
125: System.err
126: .println("-agentlib, -agentpath not supported");
127: usage(nativeOptions);
128: parseStatus = ARG_PARSE_ERR;
129: return parseStatus;
130: }
131: agentlibArgs.add(args[i]);
132: // continue with VM execution
133: } else if (args[i].startsWith("-Xrun")) {
134: if (!xrunSupported()) {
135: System.err.println("-Xrun not supported");
136: usage(nativeOptions);
137: parseStatus = ARG_PARSE_ERR;
138: return parseStatus;
139: }
140: xrunArgs.add(args[i]);
141: // continue with VM execution
142: } else if (args[i].startsWith("-Xdebug")) {
143: if (!xdebugSet()) {
144: System.err
145: .println("-Xdebug not supported, debugging not enabled");
146: usage(nativeOptions);
147: parseStatus = ARG_PARSE_ERR;
148: return parseStatus;
149: }
150: // continue with VM execution
151: } else if (args[i].startsWith("-XtimeStamping")) {
152: TimeStamps.enable();
153: } else if (args[i].startsWith("-Xjit:")) {
154: String jitArg = args[i].substring(6);
155: if (!JIT.reparseJitOptions(jitArg)) {
156: System.err.println("Error parsing JIT args "
157: + args[i]);
158: usage(nativeOptions);
159: parseStatus = ARG_PARSE_ERR;
160: return parseStatus;
161: }
162: // continue with VM execution
163: } else if (args[i].startsWith("-Xverify:")) {
164: String verifyArg = args[i].substring(9);
165: if (!CVM.parseVerifyOptions(verifyArg)) {
166: System.err.println("Error parsing verify args "
167: + args[i]);
168: usage(nativeOptions);
169: parseStatus = ARG_PARSE_ERR;
170: return parseStatus;
171: }
172: // continue with VM execution
173: } else if (args[i].startsWith("-Xopt:")) {
174: String xoptArg = args[i].substring(6);
175: if (!CVM.parseXoptOptions(xoptArg)) {
176: System.err.println("Error parsing -Xopt args "
177: + args[i]);
178: usage(nativeOptions);
179: parseStatus = ARG_PARSE_ERR;
180: return parseStatus;
181: }
182: // continue with VM execution
183: } else if (args[i].startsWith("-Xss")) {
184: String xssArg = args[i].substring(4);
185: if (!CVM.parseXssOption(xssArg)) {
186: System.err.println("Error parsing -Xss args "
187: + args[i]);
188: usage(nativeOptions);
189: parseStatus = ARG_PARSE_ERR;
190: return parseStatus;
191: }
192: // continue with VM execution
193: } else if (args[i].startsWith("-Xgc:")) {
194: String xgcArg = args[i].substring(5);
195: if (!CVM.parseXgcOptions(xgcArg)) {
196: System.err.println("Error parsing -Xgc args "
197: + args[i]);
198: usage(nativeOptions);
199: parseStatus = ARG_PARSE_ERR;
200: return parseStatus;
201: }
202: // continue with VM execution
203: } else if (args[i].startsWith("-fullversion")) {
204: Version.print(false); // Short version
205: parseStatus = ARG_PARSE_EXITVM; // Don't parse any more
206: return parseStatus;
207: } else if (args[i].startsWith("-ea")
208: || args[i].startsWith("-enableassertions")
209: || args[i].startsWith("-da")
210: || args[i].startsWith("-disableassertions")
211: || args[i].startsWith("-esa")
212: || args[i].startsWith("-enablesystemassertions")
213: || args[i].startsWith("-dsa")
214: || args[i].startsWith("-disablesystemassertions")) {
215: if (!CVM.parseAssertionOptions(args[i])) {
216: System.err.println("Error parsing assertion args "
217: + args[i]);
218: usage(nativeOptions);
219: parseStatus = ARG_PARSE_ERR;
220: return parseStatus;
221: }
222: // continue with VM execution
223: } else if (args[i].startsWith("-XbuildOptions")) {
224: printBuildOptions();
225: parseStatus = ARG_PARSE_EXITVM; // Don't parse any more
226: return parseStatus;
227: } else if (args[i].startsWith("-XshowBuildOptions")) {
228: printBuildOptions();
229: // continue with VM execution
230: } else if (args[i].startsWith("-Xcvm")
231: || args[i].startsWith("-Xjar")
232: || args[i].startsWith("-appletviewer")) {
233:
234: /* TODO: It would be best to move "-appletviewer" to
235: the PP layer */
236:
237: if (args[i].startsWith("-Xjar")) {
238: try {
239: // get main class name from manifest
240: JarFile jarFile = new JarFile(args[i]
241: .substring(6));
242: Manifest man = jarFile.getManifest();
243: Attributes attr;
244: mainClassName = null;
245: if (man != null) {
246: attr = man.getMainAttributes();
247: mainClassName = attr.getValue("Main-Class");
248: }
249: if (mainClassName == null) {
250: System.err
251: .println("-jar: Could not find Main-Class manifest attribute");
252: usage(nativeOptions);
253: parseStatus = ARG_PARSE_ERR;
254: return parseStatus;
255: }
256: } catch (IOException e) {
257: e.printStackTrace();
258: parseStatus = ARG_PARSE_ERR;
259: return parseStatus;
260: }
261:
262: } else if (args[i].startsWith("-appletviewer")) {
263: mainClassName = ("sun.applet.AppletViewer");
264: } else {
265: // We have to assume that everything else in the
266: // command line options is the main class plus its
267: // arguments.
268: mainClassName = args[i].substring(5);
269: }
270:
271: if (mainClassName.startsWith("-")
272: || mainClassName.length() == 0) {
273: System.err.println("Main class name \""
274: + mainClassName + "\" is not valid");
275: usage(nativeOptions);
276: parseStatus = ARG_PARSE_ERR;
277: return parseStatus;
278: }
279: mainClassName = mainClassName.replace('/', '.');
280:
281: int numMainArgs = args.length - i - 1;
282: mainArgs = new String[numMainArgs];
283: for (int j = 0; j < numMainArgs; j++) {
284: String arg = args[i + j + 1];
285: if (!arg.startsWith("-Xcvm")) {
286: throw new InternalError(
287: "Illegal use of -Xcvm internal "
288: + "command line options");
289: }
290: mainArgs[j] = arg.substring(5);
291: }
292: break;
293: // NOTE: do we really want to check all possible options here, or
294: // should the caller have filtered out the options that it understood?
295: } else {
296: if (args[i].startsWith("-")) {
297: if (args[i].equals("-help")) {
298: usage(nativeOptions);
299: parseStatus = ARG_PARSE_USAGE;
300: return parseStatus;
301: }
302: if (!ignoreUnrecognized
303: && !args[i].equals("-jar")
304: && !args[i].equals("-cp")
305: && !args[i].equals("-classpath")
306: && !args[i].startsWith("-Xcp")
307: && !args[i].startsWith("-Xms")
308: && !args[i].startsWith("-Xmx")
309: && !args[i].startsWith("-Xserver")
310: && !args[i].startsWith("-Xbootclasspath=")
311: && !args[i].startsWith("-Xbootclasspath:")
312: && !args[i]
313: .startsWith("-Xbootclasspath/a=")
314: && !args[i]
315: .startsWith("-Xbootclasspath/a:")) {
316: System.err.println("Unrecognized option "
317: + args[i]);
318: usage(nativeOptions);
319: parseStatus = ARG_PARSE_ERR;
320: return parseStatus;
321: }
322: } else if (!args[i].startsWith("_timeStamp")) {
323: // NOTE: I don't think this code path should be
324: // encountered anymore since we have -Xcvm
325: System.err
326: .println("Unrecognized option " + args[i]);
327: usage(nativeOptions);
328: parseStatus = ARG_PARSE_ERR;
329: return parseStatus;
330: }
331: }
332: }
333:
334: savedNativeOptions = nativeOptions;
335:
336: //
337: // Handle agentlib options
338: //
339: if (agentlibArgs.size() > 0) {
340: if (!agentlibInitialize(agentlibArgs.size())) {
341: return ARG_PARSE_ERR;
342: }
343:
344: Object[] agentOpts = agentlibArgs.toArray();
345: for (int j = 0; j < agentOpts.length; j++) {
346: if (!agentlibProcess((String) agentOpts[j])) {
347: return ARG_PARSE_ERR;
348: }
349: }
350: }
351:
352: //
353: // Handle Xrun options
354: //
355: if (xrunArgs.size() > 0) {
356: if (!xrunInitialize(xrunArgs.size())) {
357: return ARG_PARSE_ERR;
358: }
359:
360: Object[] xrunOpts = xrunArgs.toArray();
361: for (int j = 0; j < xrunOpts.length; j++) {
362: if (!xrunProcess((String) xrunOpts[j])) {
363: return ARG_PARSE_ERR;
364: }
365: }
366: }
367:
368: parseStatus = ARG_PARSE_OK;
369: return parseStatus;
370: }
371:
372: private static String[] initializePath(String propName) {
373: String ldpath = System.getProperty(propName, "");
374: String ps = File.pathSeparator;
375: int ldlen = ldpath.length();
376: int i, j, n;
377: // Count the separators in the path
378: i = ldpath.indexOf(ps);
379: n = 0;
380: while (i >= 0) {
381: n++;
382: i = ldpath.indexOf(ps, i + 1);
383: }
384:
385: // allocate the array of paths - n :'s = n + 1 path elements
386: String[] paths = new String[n + 1];
387:
388: // Fill the array with paths from the ldpath
389: n = i = 0;
390: j = ldpath.indexOf(ps);
391: while (j >= 0) {
392: if (j - i > 0) {
393: paths[n++] = ldpath.substring(i, j);
394: } else if (j - i == 0) {
395: paths[n++] = ".";
396: }
397: i = j + 1;
398: j = ldpath.indexOf(ps, i);
399: }
400: paths[n] = ldpath.substring(i, ldlen);
401: return paths;
402: }
403:
404: private static String[] usrPaths;
405: private static String[] sysPaths;
406: private static String[] builtinPaths;
407:
408: /** Helper function for parseCommandLineOptions(), above */
409: private static boolean addUserProperty(String property) {
410: // Cut it at the '=' into key, value
411: int equalsIdx = property.indexOf('=');
412: String key;
413: String value;
414: if (equalsIdx == -1) {
415: key = property;
416: value = "";
417: } else {
418: key = property.substring(0, equalsIdx);
419: value = property
420: .substring(equalsIdx + 1, property.length());
421: }
422:
423: //
424: // In case appending to old value is necessary
425: //
426: // String pathSeparator = System.getProperty("path.separator", ":");
427: // String oldval = System.getProperty(key);
428: // if ((oldval != null) && !oldval.equals("")) {
429: // String newval = oldval + pathSeparator + value;
430: // value = newval;
431: // }
432: //
433:
434: System.setProperty(key, value);
435: if (key.equals("java.library.path")) {
436: //System.err.println("INVALIDATING java.library.path setting");
437: usrPaths = null;
438: } else if (key.equals("sun.boot.library.path")) {
439: //System.err.println("INVALIDATING sun.boot.library.path setting");
440: sysPaths = null;
441: }
442:
443: return true;
444: }
445:
446: private static void printPath(String name, String[] path) {
447: System.err.print(name + " search path: ");
448: for (int k = 0; k < path.length; k++) {
449: System.err.print("[" + path[k] + "] ");
450: }
451: System.err.println();
452: }
453:
454: public static String[] getUserLibrarySearchPaths() {
455: if (usrPaths == null) {
456: usrPaths = initializePath("java.library.path");
457: // printPath("java.library.path", usrPaths);
458: }
459: return usrPaths;
460: }
461:
462: public static String[] getSystemLibrarySearchPaths() {
463: if (sysPaths == null) {
464: sysPaths = initializePath("sun.boot.library.path");
465: // printPath("sun.boot.library.path", sysPaths);
466: }
467: return sysPaths;
468: }
469:
470: public static String[] getBuiltinLibrarySearchPaths() {
471: if (builtinPaths == null) {
472: builtinPaths = initializePath("java.library.builtins");
473: // printPath("java.library.builtins", builtinPaths);
474: }
475: return builtinPaths;
476: }
477:
478: /* This is called by ansi_java_md.c using the JNI after
479: parseCommandLineOptions is called. Note that calling this is
480: optional -- the user's code may instead parse argv to find the
481: main class and its arguments. This returns the VM-internal,
482: "slashified" class name, because this is a VM-internal
483: method. */
484: public static int getParseStatus() {
485: return parseStatus;
486: }
487:
488: public static String getMainClassName() {
489: return mainClassName.replace('.', '/');
490: }
491:
492: /* This is called by ansi_java_md.c using the JNI after
493: parseCommandLineOptions is called. Note that calling this is
494: optional -- the user's code may instead parse argv to find the
495: main class and its arguments. */
496: public static String[] getMainArguments() {
497: return mainArgs;
498: }
499:
500: /* Forget what we parsed */
501: static void resetMain() {
502: mainClassName = null;
503: mainArgs = null;
504: }
505:
506: static void runMain() throws Throwable {
507: if (parseStatus != ARG_PARSE_OK) {
508: return;
509: }
510:
511: if (mainClassName == null) {
512: System.err.println("Main class name missing.");
513: usage(savedNativeOptions);
514: return;
515: }
516:
517: {
518: ClassLoader sys = ClassLoader.getSystemClassLoader();
519: Class mainClass = sys.loadClass(mainClassName);
520: Class[] args = { mainArgs.getClass() };
521: Method mainMethod = mainClass.getMethod("main", args);
522: mainMethod.setAccessible(true);
523: Object[] args2 = { mainArgs };
524: try {
525: mainMethod.invoke(null, args2);
526: } catch (InvocationTargetException i) {
527: throw i.getTargetException();
528: }
529: }
530: }
531:
532: /* Set the systemClassLoader */
533: public native static void setSystemClassLoader(ClassLoader loader);
534:
535: /*
536: * Debug flags: The debug build of CVM has many debugging features that
537: * can be enabled or disabled at runtime. There is a separate
538: * flag for each feature. Most of them are for enabling or disabling
539: * debugging trace statements.
540: */
541:
542: public static final int DEBUGFLAG_TRACE_OPCODE = 0x00000001;
543: public static final int DEBUGFLAG_TRACE_METHOD = 0x00000002;
544: public static final int DEBUGFLAG_TRACE_STATUS = 0x00000004;
545: public static final int DEBUGFLAG_TRACE_FASTLOCK = 0x00000008;
546: public static final int DEBUGFLAG_TRACE_DETLOCK = 0x00000010;
547: public static final int DEBUGFLAG_TRACE_MUTEX = 0x00000020;
548: public static final int DEBUGFLAG_TRACE_CS = 0x00000040;
549: public static final int DEBUGFLAG_TRACE_GCSTARTSTOP = 0x00000080;
550: public static final int DEBUGFLAG_TRACE_GCSCAN = 0x00000100;
551: public static final int DEBUGFLAG_TRACE_GCSCANOBJ = 0x00000200;
552: public static final int DEBUGFLAG_TRACE_GCALLOC = 0x00000400;
553: public static final int DEBUGFLAG_TRACE_GCCOLLECT = 0x00000800;
554: public static final int DEBUGFLAG_TRACE_GCSAFETY = 0x00001000;
555: public static final int DEBUGFLAG_TRACE_CLINIT = 0x00002000;
556: public static final int DEBUGFLAG_TRACE_EXCEPTIONS = 0x00004000;
557: public static final int DEBUGFLAG_TRACE_MISC = 0x00008000;
558: public static final int DEBUGFLAG_TRACE_BARRIERS = 0x00010000;
559: public static final int DEBUGFLAG_TRACE_STACKMAPS = 0x00020000;
560: public static final int DEBUGFLAG_TRACE_CLASSLOADING = 0x00040000;
561: public static final int DEBUGFLAG_TRACE_CLASSLOOKUP = 0x00080000;
562: public static final int DEBUGFLAG_TRACE_TYPEID = 0x00100000;
563: public static final int DEBUGFLAG_TRACE_VERIFIER = 0x00200000;
564: public static final int DEBUGFLAG_TRACE_WEAKREFS = 0x00400000;
565: public static final int DEBUGFLAG_TRACE_CLASSUNLOAD = 0x00800000;
566: public static final int DEBUGFLAG_TRACE_CLASSLINK = 0x01000000;
567: public static final int DEBUGFLAG_TRACE_LVM = 0x02000000;
568:
569: /*
570: * Methods for checking, setting, and clearing the state of debug
571: * flags. All of the following methods return the previous state of
572: * the flags.
573: *
574: * You can pass in more than one flag at a time to any of the methods.
575: */
576: public native static int checkDebugFlags(int flags);
577:
578: public native static int setDebugFlags(int flags);
579:
580: public native static int clearDebugFlags(int flags);
581:
582: public native static int restoreDebugFlags(int flags, int oldvalue);
583:
584: /*
585: * Debug JIT flags: If built with JIT tracing enabled, CVM has
586: * JIT debugging trace features that can be enabled or disabled at
587: * runtime. There is a separate flag for each feature.
588: */
589: public static final int DEBUGFLAG_TRACE_JITSTATUS = 0x00000001;
590: public static final int DEBUGFLAG_TRACE_JITBCTOIR = 0x00000002;
591: public static final int DEBUGFLAG_TRACE_JITCODEGEN = 0x00000004;
592: public static final int DEBUGFLAG_TRACE_JITSTATS = 0x00000008;
593: public static final int DEBUGFLAG_TRACE_JITIROPT = 0x00000010;
594: public static final int DEBUGFLAG_TRACE_JITINLINING = 0x00000020;
595: public static final int DEBUGFLAG_TRACE_JITOSR = 0x00000040;
596: public static final int DEBUGFLAG_TRACE_JITREGLOCALS = 0x00000080;
597: public static final int DEBUGFLAG_TRACE_JITERROR = 0x00000100;
598: public static final int DEBUGFLAG_TRACE_JITPATCHEDINVOKES = 0x00000100;
599:
600: /*
601: * Methods for checking, setting, and clearing the state of debug
602: * JIT flags. All of the following methods return the previous state of
603: * the flags.
604: *
605: * You can pass in more than one flag at a time to any of the methods.
606: */
607: public native static int checkDebugJITFlags(int flags);
608:
609: public native static int setDebugJITFlags(int flags);
610:
611: public native static int clearDebugJITFlags(int flags);
612:
613: public native static int restoreDebugJITFlags(int flags,
614: int oldvalue);
615:
616: // NOTE
617: // Some of these public native methods are quite dangerous.
618: // We need to make sure that applets cannot call them.
619:
620: /* Type specific array copiers: */
621: public native static void copyBooleanArray(boolean[] src,
622: int src_position, boolean[] dst, int dst_position,
623: int length);
624:
625: public native static void copyByteArray(byte[] src,
626: int src_position, byte[] dst, int dst_position, int length);
627:
628: public native static void copyCharArray(char[] src,
629: int src_position, char[] dst, int dst_position, int length);
630:
631: public native static void copyShortArray(short[] src,
632: int src_position, short[] dst, int dst_position, int length);
633:
634: public native static void copyIntArray(int[] src, int src_position,
635: int[] dst, int dst_position, int length);
636:
637: public native static void copyFloatArray(float[] src,
638: int src_position, float[] dst, int dst_position, int length);
639:
640: public native static void copyLongArray(long[] src,
641: int src_position, long[] dst, int dst_position, int length);
642:
643: public native static void copyDoubleArray(double[] src,
644: int src_position, double[] dst, int dst_position, int length);
645:
646: /* copyObjectArray() copies array elements from one array to another.
647: Unlike System.arraycopy(), this method can only copy elements for
648: non-primitive arrays with some restrictions. The restrictions are that
649: the src and dst array must be of the same type, or the dst array must
650: be of type java.lang.Object[] (not just a compatible sub-type). The
651: caller is responsible for doing the appropriate null checks, bounds
652: checks, array element type assignment checks if necessary, and ensure
653: that the passed in arguments do violate any of these checks and
654: restrictions. If the condition of these checks and restrictions are
655: not taken cared of by the caller, copyObjectArray() can fail in
656: unpredictable ways.
657: */
658: public native static void copyObjectArray(Object[] src,
659: int src_position, Object[] dst, int dst_position, int length);
660:
661: public static void copyArray(Object[] src, int src_position,
662: Object[] dst, int dst_position, int length) {
663: System.arraycopy(src, src_position, dst, dst_position, length);
664: }
665:
666: /*
667: * Used by Class.runStaticInitializers() to execute the <linit> method
668: * of the specified class.
669: */
670: public native static void executeClinit(Class c);
671:
672: /*
673: * Use by Class.runStaticInitializers() to free up the code for the
674: * specified class' <clinit> method.
675: */
676: public native static void freeClinit(Class c);
677:
678: /*
679: * Used by Launcher.defineClassPrivate() to execute the
680: * Class.loadSuperClasses method in a way that avoids C recursion.
681: */
682: native static void executeLoadSuperClasses(Class c);
683:
684: /*
685: * Manage remote exceptions
686: */
687: public native static void disableRemoteExceptions();
688:
689: public native static void enableRemoteExceptions();
690:
691: // Should be invoked through Thread.stop() that ensures target's ee is alive
692: public native static void throwRemoteException(Thread target,
693: Throwable t);
694:
695: /*
696: * Manage interrupts
697: */
698: // Returns true if interrupts were already masked. No
699: // internal nesting count is maintained.
700: public native static boolean maskInterrupts();
701:
702: // Should only be called if maskInterrupts() returned false
703: public native static void unmaskInterrupts();
704:
705: /*
706: * Allows system methods to bypass compiler checks and throw
707: * exceptions. Useful for rewriting native methods in Java.
708: */
709: public native static Error throwLocalException(Throwable t);
710:
711: /*
712: * Mark current context as artificial
713: */
714: public native static void setContextArtificial();
715:
716: /* CLDC/MIDP support */
717: /*
718: * Used to find out if the classloader of the caller's caller
719: * is sun.misc.MIDletClassLoader or
720: * sun.misc.MIDPImplementationClassLoader.
721: */
722: public static native boolean callerCLIsMIDCLs();
723:
724: // %begin lvm
725: /*
726: * Used to suppress initialization of Reference handler
727: * (java.lang.ref.Reference) in a child Logical VM.
728: */
729: public native static boolean inMainLVM();
730:
731: // %end lvm
732:
733: /*
734: * Some heap dumping utilties.
735: */
736: public native static void gcDumpHeapSimple();
737:
738: public native static void gcDumpHeapVerbose();
739:
740: public native static void gcDumpHeapStats();
741:
742: public native static void trace(int i);
743:
744: public native static void setDebugEvents(boolean on);
745:
746: public native static void postThreadExit();
747:
748: /* Inflates an object's monitor and mark it sticky so it's never freed. */
749: public native static boolean objectInflatePermanently(Object obj);
750:
751: /* enable/disable compilations by current thread */
752: public static native void setThreadNoCompilationsFlag(boolean enable);
753:
754: /** Returns the class of the method <code>realFramesToSkip</code>
755: frames up the stack (zero-based), ignoring frames associated
756: with java.lang.reflect.Method.invoke() and its implementation.
757: The first frame is that associated with this method, so
758: <code>getCallerClass(0)</code> returns the Class object for
759: sun.reflect.Reflection. Frames associated with
760: java.lang.reflect.Method.invoke() and its implementation are
761: completely ignored and do not count toward the number of "real"
762: frames skipped. */
763: public native static Class getCallerClass(int realFramesToSkip);
764:
765: //
766: // True if JIT supported, false otherwise
767: //
768: public native static boolean isCompilerSupported();
769:
770: // Request a dump of the profiling data collected by the compiler if
771: // available:
772: public native static void dumpCompilerProfileData();
773:
774: //
775: // Dump various stats
776: //
777: public native static void dumpStats();
778:
779: //
780: // Mark the current location of the code buffer. Below this mark,
781: // methods are supposed to be persistent.
782: //
783: public native static void markCodeBuffer();
784:
785: //
786: // Enable compilation.
787: //
788: public native static void initializeJITPolicy();
789:
790: //
791: // Initialize pre-compiled code.
792: //
793: public native static boolean initializeAOTCode();
794:
795: //
796: // Re-parse the -Xverify option from the Java side
797: //
798: public native static boolean parseVerifyOptions(String verifyArg);
799:
800: //
801: // Re-parse the -Xopt options from the Java side
802: //
803: public native static boolean parseXoptOptions(String xoptArg);
804:
805: //
806: // Re-parse the -Xgc options from the Java side
807: //
808: public native static boolean parseXgcOptions(String xgcArg);
809:
810: //
811: // Re-parse the -Xss options from the Java side
812: //
813: public native static boolean parseXssOption(String xssArg);
814:
815: //
816: // Parse assertion options
817: //
818: public native static boolean parseAssertionOptions(String xgcArg);
819:
820: //
821: // Is -agentlib, -agentpath supported?
822: //
823: public native static boolean agentlibSupported();
824:
825: //
826: // Initialize agentlib processing
827: //
828: public native static boolean agentlibInitialize(int numOptions);
829:
830: //
831: // Process agentlib option
832: //
833: public native static boolean agentlibProcess(String agentArg);
834:
835: //
836: // Is -Xrun supported?
837: //
838: public native static boolean xrunSupported();
839:
840: //
841: // Initialize Xrun processing
842: //
843: public native static boolean xrunInitialize(int numOptions);
844:
845: //
846: // Process Xrun option
847: //
848: public native static boolean xrunProcess(String xrunArg);
849:
850: //
851: // Enable debugging
852: //
853: public native static boolean xdebugSet();
854:
855: static class Preloader {
856: //
857: // Register ClassLoader for ROMized classes
858: //
859: public static boolean registerClassLoader(String name,
860: ClassLoader cl) {
861: String preloadedClassLoaders = getClassLoaderNames();
862: if (preloadedClassLoaders == null) {
863: return false;
864: }
865: int classLoaderIndex = 0;
866: StringTokenizer st = new StringTokenizer(
867: preloadedClassLoaders, ",");
868: while (st.hasMoreTokens()) {
869: if (name.equals(st.nextToken())) {
870: registerClassLoader0(classLoaderIndex, cl);
871: return true;
872: }
873: ++classLoaderIndex;
874: }
875: return false;
876: }
877:
878: private native static String getClassLoaderNames();
879:
880: private native static void registerClassLoader0(int clIndex,
881: ClassLoader cl);
882: };
883:
884: //
885: // Intrinsics for faster synchronization of simple methods. There
886: // are strict limitations on how and when they used.
887: //
888: public native static boolean simpleLockGrab(Object lockObj);
889:
890: public native static void simpleLockRelease(Object lockObj);
891:
892: /**
893: * Prints build options used for this build.
894: * Called by "-XbuildOptions and -XshowBuildOptions command line options.
895: */
896: public static void printBuildOptions() {
897: System.err.print(getBuildOptionString(null));
898: }
899:
900: // NOTE: The dummy argument is just a convenient way to reserve space on
901: // stack for the return value of this CNI method.
902: private static native String getBuildOptionString(Object dummy);
903: }
|