001 /* 002 * This file is part of the Jikes RVM project (http://jikesrvm.org). 003 * 004 * This file is licensed to You under the Eclipse Public License (EPL); 005 * You may not use this file except in compliance with the License. You 006 * may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/eclipse-1.0.php 009 * 010 * See the COPYRIGHT.txt file distributed with this work for information 011 * regarding copyright ownership. 012 */ 013 package org.jikesrvm; 014 015 import org.jikesrvm.ArchitectureSpecific.ThreadLocalState; 016 import org.jikesrvm.adaptive.controller.Controller; 017 import org.jikesrvm.adaptive.util.CompilerAdvice; 018 import org.jikesrvm.classloader.Atom; 019 import org.jikesrvm.classloader.BootstrapClassLoader; 020 import org.jikesrvm.classloader.RVMClass; 021 import org.jikesrvm.classloader.RVMClassLoader; 022 import org.jikesrvm.classloader.RVMMember; 023 import org.jikesrvm.classloader.MemberReference; 024 import org.jikesrvm.classloader.RVMMethod; 025 import org.jikesrvm.classloader.TypeDescriptorParsing; 026 import org.jikesrvm.classloader.TypeReference; 027 import org.jikesrvm.compilers.baseline.BaselineCompiler; 028 import org.jikesrvm.compilers.common.BootImageCompiler; 029 import org.jikesrvm.compilers.common.RuntimeCompiler; 030 import org.jikesrvm.mm.mminterface.MemoryManager; 031 import org.jikesrvm.runtime.BootRecord; 032 import org.jikesrvm.runtime.DynamicLibrary; 033 import org.jikesrvm.runtime.Entrypoints; 034 import org.jikesrvm.runtime.ExitStatus; 035 import org.jikesrvm.runtime.Magic; 036 import org.jikesrvm.runtime.RuntimeEntrypoints; 037 import org.jikesrvm.runtime.SysCall; 038 039 import static org.jikesrvm.runtime.SysCall.sysCall; 040 import org.jikesrvm.scheduler.Lock; 041 import org.jikesrvm.scheduler.MainThread; 042 import org.jikesrvm.scheduler.Synchronization; 043 import org.jikesrvm.scheduler.RVMThread; 044 import org.jikesrvm.runtime.FileSystem; 045 import org.jikesrvm.tuningfork.TraceEngine; 046 import org.vmmagic.pragma.Entrypoint; 047 import org.vmmagic.pragma.Inline; 048 import org.vmmagic.pragma.Interruptible; 049 import org.vmmagic.pragma.NoInline; 050 import org.vmmagic.pragma.Uninterruptible; 051 import org.vmmagic.pragma.UninterruptibleNoWarn; 052 import org.vmmagic.pragma.Unpreemptible; 053 import org.vmmagic.pragma.UnpreemptibleNoWarn; 054 import org.vmmagic.unboxed.Address; 055 import org.vmmagic.unboxed.Extent; 056 import org.vmmagic.unboxed.ObjectReference; 057 import org.vmmagic.unboxed.Offset; 058 import org.vmmagic.unboxed.Word; 059 060 /** 061 * A virtual machine. 062 */ 063 @Uninterruptible 064 public class VM extends Properties implements Constants, ExitStatus { 065 066 /** 067 * Reference to the main thread that is the first none VM thread run 068 */ 069 public static MainThread mainThread; 070 071 //----------------------------------------------------------------------// 072 // Initialization. // 073 //----------------------------------------------------------------------// 074 075 /** 076 * Prepare VM classes for use by boot image writer. 077 * @param classPath class path to be used by RVMClassLoader 078 * @param bootCompilerArgs command line arguments for the bootimage compiler 079 */ 080 @Interruptible 081 public static void initForBootImageWriter(String classPath, String[] bootCompilerArgs) { 082 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 083 if (VM.VerifyAssertions) VM._assert(!VM.runningTool); 084 writingBootImage = true; 085 init(classPath, bootCompilerArgs); 086 } 087 088 /** 089 * Prepare VM classes for use by tools. 090 */ 091 @Interruptible 092 public static void initForTool() { 093 initForTool(System.getProperty("java.class.path")); 094 } 095 096 /** 097 * Prepare VM classes for use by tools. 098 * @param classpath class path to be used by RVMClassLoader 099 */ 100 @Interruptible 101 public static void initForTool(String classpath) { 102 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 103 if (VM.VerifyAssertions) VM._assert(!VM.writingBootImage); 104 runningTool = true; 105 init(classpath, null); 106 } 107 108 /** 109 * Begin VM execution.<p> 110 * 111 * Uninterruptible because we are not setup to execute a yieldpoint 112 * or stackoverflow check in the prologue this early in booting.<p> 113 * 114 * The following machine registers are set by "C" bootstrap program 115 * before calling this method: 116 * <ol> 117 * <li>JTOC_POINTER - required for accessing globals 118 * <li>FRAME_POINTER - required for accessing locals 119 * <li>THREAD_ID_REGISTER - required for method prolog (stack overflow check) 120 * </ol> 121 */ 122 @UnpreemptibleNoWarn("No point threading until threading is booted") 123 @Entrypoint 124 public static void boot() { 125 writingBootImage = false; 126 runningVM = true; 127 verboseBoot = BootRecord.the_boot_record.verboseBoot; 128 129 sysWriteLockOffset = Entrypoints.sysWriteLockField.getOffset(); 130 if (verboseBoot >= 1) VM.sysWriteln("Booting"); 131 132 // Set up the current RVMThread object. The bootstrap program 133 // has placed a pointer to the current RVMThread in a special 134 // register. 135 if (verboseBoot >= 1) VM.sysWriteln("Setting up current RVMThread"); 136 ThreadLocalState.boot(); 137 138 // Finish thread initialization that couldn't be done in boot image. 139 // The "stackLimit" must be set before any interruptible methods are called 140 // because it's accessed by compiler-generated stack overflow checks. 141 // 142 if (verboseBoot >= 1) VM.sysWriteln("Doing thread initialization"); 143 RVMThread currentThread = RVMThread.getCurrentThread(); 144 currentThread.stackLimit = Magic.objectAsAddress( 145 currentThread.getStack()).plus(ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_GUARD); 146 147 finishBooting(); 148 } 149 150 /** 151 * Complete the task of booting Jikes RVM. 152 * Done in a secondary method mainly because this code 153 * doesn't have to be uninterruptible and this is the cleanest 154 * way to make that distinction. 155 */ 156 @Interruptible 157 private static void finishBooting() { 158 159 // get pthread_id from OS and store into vm_processor field 160 // 161 sysCall.sysSetupHardwareTrapHandler(); 162 RVMThread.getCurrentThread().pthread_id = sysCall.sysGetThreadId(); 163 RVMThread.availableProcessors = SysCall.sysCall.sysNumProcessors(); 164 165 // Set up buffer locks used by Thread for logging and status dumping. 166 // This can happen at any point before we start running 167 // multi-threaded. 168 Services.boot(); 169 170 // Initialize memory manager. 171 // This must happen before any uses of "new". 172 // 173 if (verboseBoot >= 1) { 174 VM.sysWriteln("Setting up memory manager: bootrecord = ", 175 Magic.objectAsAddress(BootRecord.the_boot_record)); 176 } 177 MemoryManager.boot(BootRecord.the_boot_record); 178 179 // Reset the options for the baseline compiler to avoid carrying 180 // them over from bootimage writing time. 181 // 182 if (verboseBoot >= 1) VM.sysWriteln("Initializing baseline compiler options to defaults"); 183 BaselineCompiler.initOptions(); 184 185 // Fetch arguments from program command line. 186 // 187 if (verboseBoot >= 1) VM.sysWriteln("Fetching command-line arguments"); 188 CommandLineArgs.fetchCommandLineArguments(); 189 190 // Process most virtual machine command line arguments. 191 // 192 if (verboseBoot >= 1) VM.sysWriteln("Early stage processing of command line"); 193 CommandLineArgs.earlyProcessCommandLineArguments(); 194 195 // Early initialization of TuningFork tracing engine. 196 TraceEngine.engine.earlyStageBooting(); 197 198 // Allow Memory Manager to respond to its command line arguments 199 // 200 if (verboseBoot >= 1) VM.sysWriteln("Collector processing rest of boot options"); 201 MemoryManager.postBoot(); 202 203 // Initialize class loader. 204 // 205 String bootstrapClasses = CommandLineArgs.getBootstrapClasses(); 206 if (verboseBoot >= 1) VM.sysWriteln("Initializing bootstrap class loader: ", bootstrapClasses); 207 RVMClassLoader.boot(); // Wipe out cached application class loader 208 BootstrapClassLoader.boot(bootstrapClasses); 209 210 // Initialize statics that couldn't be placed in bootimage, either 211 // because they refer to external state (open files), or because they 212 // appear in fields that are unique to Jikes RVM implementation of 213 // standard class library (not part of standard JDK). 214 // We discover the latter by observing "host has no field" and 215 // "object not part of bootimage" messages printed out by bootimage 216 // writer. 217 // 218 if (verboseBoot >= 1) VM.sysWriteln("Running various class initializers"); 219 220 if (VM.BuildForGnuClasspath) { 221 runClassInitializer("java.util.WeakHashMap"); // Need for ThreadLocal 222 } 223 runClassInitializer("org.jikesrvm.classloader.Atom$InternedStrings"); 224 225 if (VM.BuildForGnuClasspath) { 226 runClassInitializer("gnu.classpath.SystemProperties"); 227 runClassInitializer("java.lang.Throwable$StaticData"); 228 } 229 230 runClassInitializer("java.lang.Runtime"); 231 runClassInitializer("java.lang.System"); 232 runClassInitializer("sun.misc.Unsafe"); 233 234 runClassInitializer("java.lang.Character"); 235 runClassInitializer("org.jikesrvm.classloader.TypeReferenceVector"); 236 runClassInitializer("org.jikesrvm.classloader.MethodVector"); 237 runClassInitializer("org.jikesrvm.classloader.FieldVector"); 238 // Turn off security checks; about to hit EncodingManager. 239 // Commented out because we haven't incorporated this into the CVS head 240 // yet. 241 // java.security.JikesRVMSupport.turnOffChecks(); 242 if (VM.BuildForGnuClasspath) { 243 runClassInitializer("java.lang.ThreadGroup"); 244 } 245 /* We can safely allocate a java.lang.Thread now. The boot 246 thread (running right now, as a Thread) has to become a full-fledged 247 Thread, since we're about to encounter a security check: 248 249 EncodingManager checks a system property, 250 which means that the permissions checks have to be working, 251 which means that VMAccessController will be invoked, 252 which means that ThreadLocal.get() will be called, 253 which calls Thread.getCurrentThread(). 254 255 So the boot Thread needs to be associated with a real Thread for 256 Thread.getCurrentThread() to return. */ 257 VM.safeToAllocateJavaThread = true; 258 259 if (VM.BuildForGnuClasspath) { 260 runClassInitializer("java.lang.ThreadLocal"); 261 runClassInitializer("java.lang.ThreadLocalMap"); 262 } 263 // Possibly fix VMAccessController's contexts and inGetContext fields 264 if (VM.BuildForGnuClasspath) { 265 runClassInitializer("java.security.VMAccessController"); 266 } 267 if (VM.BuildForHarmony) { 268 runClassInitializer("java.security.AccessController"); 269 } 270 if (verboseBoot >= 1) VM.sysWriteln("Booting Lock"); 271 Lock.boot(); 272 273 // Enable multiprocessing. 274 // Among other things, after this returns, GC and dynamic class loading are enabled. 275 // 276 if (verboseBoot >= 1) VM.sysWriteln("Booting scheduler"); 277 RVMThread.boot(); 278 DynamicLibrary.boot(); 279 280 if (verboseBoot >= 1) VM.sysWriteln("Enabling GC"); 281 MemoryManager.enableCollection(); 282 283 if (verboseBoot >= 1) VM.sysWriteln("Setting up boot thread"); 284 RVMThread.getCurrentThread().setupBootJavaThread(); 285 286 // Create JNI Environment for boot thread. 287 // After this point the boot thread can invoke native methods. 288 org.jikesrvm.jni.JNIEnvironment.boot(); 289 if (verboseBoot >= 1) VM.sysWriteln("Initializing JNI for boot thread"); 290 RVMThread.getCurrentThread().initializeJNIEnv(); 291 if (verboseBoot >= 1) VM.sysWriteln("JNI initialized for boot thread"); 292 293 if (VM.BuildForHarmony) { 294 System.loadLibrary("hyluni"); 295 System.loadLibrary("hythr"); 296 System.loadLibrary("hyniochar"); 297 } 298 runClassInitializer("java.io.File"); // needed for when we initialize the 299 // system/application class loader. 300 runClassInitializer("java.lang.String"); 301 if (VM.BuildForGnuClasspath) { 302 runClassInitializer("gnu.java.security.provider.DefaultPolicy"); 303 } 304 runClassInitializer("java.net.URL"); // needed for URLClassLoader 305 /* Needed for ApplicationClassLoader, which in turn is needed by 306 VMClassLoader.getSystemClassLoader() */ 307 if (VM.BuildForGnuClasspath) { 308 runClassInitializer("java.net.URLClassLoader"); 309 } 310 /* Used if we start up Jikes RVM with the -jar argument; that argument 311 * means that we need a working -jar before we can return an 312 * Application Class Loader. */ 313 runClassInitializer("java.net.URLConnection"); 314 if (VM.BuildForGnuClasspath) { 315 runClassInitializer("gnu.java.net.protocol.jar.Connection$JarFileCache"); 316 runClassInitializer("java.lang.ClassLoader$StaticData"); 317 } 318 runClassInitializer("java.lang.Class$StaticData"); 319 320 runClassInitializer("java.nio.charset.Charset"); 321 if (VM.BuildForGnuClasspath) { 322 runClassInitializer("java.nio.charset.CharsetEncoder"); 323 } 324 runClassInitializer("java.nio.charset.CoderResult"); 325 if (VM.BuildForHarmony) { 326 runClassInitializer("org.apache.harmony.niochar.CharsetProviderImpl"); 327 } 328 329 runClassInitializer("java.io.PrintWriter"); // Uses System.getProperty 330 System.setProperty("line.separator", "\n"); 331 runClassInitializer("java.io.PrintStream"); // Uses System.getProperty 332 runClassInitializer("java.util.Locale"); 333 runClassInitializer("java.util.ResourceBundle"); 334 runClassInitializer("java.util.zip.CRC32"); 335 if (VM.BuildForHarmony) { 336 System.loadLibrary("hyarchive"); 337 } 338 runClassInitializer("java.util.zip.Inflater"); 339 if (VM.BuildForGnuClasspath) { 340 runClassInitializer("java.util.zip.DeflaterHuffman"); 341 runClassInitializer("java.util.zip.InflaterDynHeader"); 342 runClassInitializer("java.util.zip.InflaterHuffmanTree"); 343 } 344 // Run class initializers that require JNI 345 if (verboseBoot >= 1) VM.sysWriteln("Running late class initializers"); 346 if (VM.BuildForGnuClasspath) { 347 System.loadLibrary("javaio"); 348 } 349 runClassInitializer("java.lang.Math"); 350 runClassInitializer("java.util.TreeMap"); 351 if (VM.BuildForGnuClasspath) { 352 runClassInitializer("gnu.java.nio.VMChannel"); 353 runClassInitializer("gnu.java.nio.FileChannelImpl"); 354 } 355 runClassInitializer("java.io.FileDescriptor"); 356 runClassInitializer("java.io.FilePermission"); 357 runClassInitializer("java.util.jar.JarFile"); 358 if (VM.BuildForGnuClasspath) { 359 runClassInitializer("java.util.zip.ZipFile$PartialInputStream"); 360 } 361 runClassInitializer("java.util.zip.ZipFile"); 362 if (VM.BuildForHarmony) { 363 runClassInitializer("java.util.Hashtable"); 364 runClassInitializer("java.util.jar.Manifest"); 365 runClassInitializer("java.util.jar.Attributes$Name"); 366 runClassInitializer("java.util.BitSet"); 367 runClassInitializer("java.util.regex.Matcher"); 368 runClassInitializer("java.util.regex.Pattern"); 369 runClassInitializer("org.apache.harmony.luni.internal.net.www.protocol.jar.JarURLConnection"); 370 runClassInitializer("org.apache.harmony.luni.platform.OSMemory"); 371 runClassInitializer("org.apache.harmony.luni.platform.Platform"); 372 runClassInitializer("org.apache.harmony.luni.platform.AbstractMemorySpy"); 373 runClassInitializer("org.apache.harmony.luni.platform.PlatformAddress"); 374 runClassInitializer("org.apache.harmony.nio.internal.FileChannelImpl"); 375 runClassInitializer("com.ibm.icu.util.ULocale"); 376 runClassInitializer("java.io.ObjectStreamClass"); 377 runClassInitializer("java.io.ObjectStreamClass$OSCThreadLocalCache"); 378 runClassInitializer("java.io.ObjectInputStream"); 379 runClassInitializer("java.security.MessageDigest"); 380 } 381 if (VM.BuildForGnuClasspath) { 382 runClassInitializer("java.lang.VMDouble"); 383 } 384 runClassInitializer("java.util.PropertyPermission"); 385 runClassInitializer("org.jikesrvm.classloader.RVMAnnotation"); 386 runClassInitializer("java.lang.annotation.RetentionPolicy"); 387 runClassInitializer("java.lang.annotation.ElementType"); 388 runClassInitializer("java.lang.Thread$State"); 389 if (VM.BuildForGnuClasspath) { 390 runClassInitializer("java.lang.VMClassLoader"); 391 } 392 393 if (verboseBoot >= 1) VM.sysWriteln("initializing standard streams"); 394 // Initialize java.lang.System.out, java.lang.System.err, java.lang.System.in 395 FileSystem.initializeStandardStreams(); 396 397 /////////////////////////////////////////////////////////////// 398 // The VM is now fully booted. // 399 // By this we mean that we can execute arbitrary Java code. // 400 /////////////////////////////////////////////////////////////// 401 if (verboseBoot >= 1) VM.sysWriteln("VM is now fully booted"); 402 403 // Inform interested subsystems that VM is fully booted. 404 VM.fullyBooted = true; 405 MemoryManager.fullyBootedVM(); 406 BaselineCompiler.fullyBootedVM(); 407 TraceEngine.engine.fullyBootedVM(); 408 409 runClassInitializer("java.util.logging.Level"); 410 if (VM.BuildForGnuClasspath) { 411 runClassInitializer("gnu.java.nio.charset.EncodingHelper"); 412 runClassInitializer("java.lang.reflect.Proxy"); 413 runClassInitializer("java.lang.reflect.Proxy$ProxySignature"); 414 } 415 runClassInitializer("java.util.logging.Logger"); 416 if (VM.BuildForHarmony) { 417 Entrypoints.luni1.setObjectValueUnchecked(null, null); 418 Entrypoints.luni2.setObjectValueUnchecked(null, null); 419 Entrypoints.luni3.setObjectValueUnchecked(null, null); 420 Entrypoints.luni4.setObjectValueUnchecked(null, null); 421 Entrypoints.luni5.setObjectValueUnchecked(null, null); 422 Entrypoints.luni6.setObjectValueUnchecked(null, null); 423 //runClassInitializer("java.lang.String$ConsolePrintStream"); 424 runClassInitializer("org.apache.harmony.luni.util.Msg"); 425 runClassInitializer("org.apache.harmony.archive.internal.nls.Messages"); 426 runClassInitializer("org.apache.harmony.luni.internal.nls.Messages"); 427 runClassInitializer("org.apache.harmony.nio.internal.nls.Messages"); 428 runClassInitializer("org.apache.harmony.niochar.internal.nls.Messages"); 429 runClassInitializer("java.util.logging.LogManager"); 430 } 431 432 // Initialize compiler that compiles dynamically loaded classes. 433 // 434 if (verboseBoot >= 1) VM.sysWriteln("Initializing runtime compiler"); 435 RuntimeCompiler.boot(); 436 437 // Process remainder of the VM's command line arguments. 438 if (verboseBoot >= 1) VM.sysWriteln("Late stage processing of command line"); 439 String[] applicationArguments = CommandLineArgs.lateProcessCommandLineArguments(); 440 441 if (VM.verboseClassLoading || verboseBoot >= 1) VM.sysWrite("[VM booted]\n"); 442 443 if (VM.BuildForAdaptiveSystem) { 444 if (verboseBoot >= 1) VM.sysWriteln("Initializing adaptive system"); 445 Controller.boot(); 446 } 447 448 // The first argument must be a class name. 449 if (verboseBoot >= 1) VM.sysWriteln("Extracting name of class to execute"); 450 if (applicationArguments.length == 0) { 451 pleaseSpecifyAClass(); 452 } 453 if (applicationArguments.length > 0 && !TypeDescriptorParsing.isJavaClassName(applicationArguments[0])) { 454 VM.sysWrite("vm: \""); 455 VM.sysWrite(applicationArguments[0]); 456 VM.sysWrite("\" is not a legal Java class name.\n"); 457 pleaseSpecifyAClass(); 458 } 459 460 if (applicationArguments.length > 0 && applicationArguments[0].startsWith("-X")) { 461 VM.sysWrite("vm: \""); 462 VM.sysWrite(applicationArguments[0]); 463 VM.sysWrite("\" is not a recognized Jikes RVM command line argument.\n"); 464 VM.sysExit(VM.EXIT_STATUS_BOGUS_COMMAND_LINE_ARG); 465 } 466 467 if (verboseBoot >= 1) VM.sysWriteln("Initializing Application Class Loader"); 468 RVMClassLoader.getApplicationClassLoader(); 469 RVMClassLoader.declareApplicationClassLoaderIsReady(); 470 471 if (verboseBoot >= 1) { 472 VM.sysWriteln("Turning back on security checks. Letting people see the ApplicationClassLoader."); 473 } 474 // Turn on security checks again. 475 // Commented out because we haven't incorporated this into the main CVS 476 // tree yet. 477 // java.security.JikesRVMSupport.fullyBootedVM(); 478 479 if (VM.BuildForGnuClasspath) { 480 runClassInitializer("java.lang.ClassLoader$StaticData"); 481 } 482 483 if (VM.BuildForAdaptiveSystem) { 484 CompilerAdvice.postBoot(); 485 } 486 487 // enable alignment checking 488 if (VM.AlignmentChecking) { 489 SysCall.sysCall.sysEnableAlignmentChecking(); 490 } 491 492 // Schedule "main" thread for execution. 493 if (verboseBoot >= 2) VM.sysWriteln("Creating main thread"); 494 // Create main thread. 495 if (verboseBoot >= 1) VM.sysWriteln("Constructing mainThread"); 496 mainThread = new MainThread(applicationArguments); 497 498 // Schedule "main" thread for execution. 499 if (verboseBoot >= 1) VM.sysWriteln("Starting main thread"); 500 mainThread.start(); 501 502 // End of boot thread. 503 // 504 if (VM.TraceThreads) RVMThread.trace("VM.boot", "completed - terminating"); 505 if (verboseBoot >= 2) { 506 VM.sysWriteln("Boot sequence completed; finishing boot thread"); 507 } 508 509 RVMThread.getCurrentThread().terminate(); 510 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 511 } 512 513 @Interruptible 514 private static void pleaseSpecifyAClass() { 515 VM.sysWrite("vm: Please specify a class to execute.\n"); 516 VM.sysWrite("vm: You can invoke the VM with the \"-help\" flag for usage information.\n"); 517 VM.sysExit(VM.EXIT_STATUS_BOGUS_COMMAND_LINE_ARG); 518 } 519 520 /** 521 * Run {@code <clinit>} method of specified class, if that class appears 522 * in bootimage and actually has a clinit method (we are flexible to 523 * allow one list of classes to work with different bootimages and 524 * different version of classpath (eg 0.05 vs. cvs head). 525 * <p> 526 * This method is called only while the VM boots. 527 * 528 * @param className 529 */ 530 @Interruptible 531 static void runClassInitializer(String className) { 532 if (verboseBoot >= 2) { 533 sysWrite("running class intializer for "); 534 sysWriteln(className); 535 } 536 Atom classDescriptor = Atom.findOrCreateAsciiAtom(className.replace('.', '/')).descriptorFromClassName(); 537 TypeReference tRef = 538 TypeReference.findOrCreate(BootstrapClassLoader.getBootstrapClassLoader(), classDescriptor); 539 RVMClass cls = (RVMClass) tRef.peekType(); 540 if (null == cls) { 541 sysWrite("Failed to run class intializer for "); 542 sysWrite(className); 543 sysWriteln(" as the class does not exist."); 544 } else if (!cls.isInBootImage()) { 545 sysWrite("Failed to run class intializer for "); 546 sysWrite(className); 547 sysWriteln(" as the class is not in the boot image."); 548 } else { 549 RVMMethod clinit = cls.getClassInitializerMethod(); 550 if (clinit != null) { 551 clinit.compile(); 552 if (verboseBoot >= 10) VM.sysWriteln("invoking method " + clinit); 553 try { 554 Magic.invokeClassInitializer(clinit.getCurrentEntryCodeArray()); 555 } catch (Error e) { 556 throw e; 557 } catch (Throwable t) { 558 ExceptionInInitializerError eieio = 559 new ExceptionInInitializerError(t); 560 throw eieio; 561 } 562 // <clinit> is no longer needed: reclaim space by removing references to it 563 clinit.invalidateCompiledMethod(clinit.getCurrentCompiledMethod()); 564 } else { 565 if (verboseBoot >= 10) VM.sysWriteln("has no clinit method "); 566 } 567 cls.setAllFinalStaticJTOCEntries(); 568 } 569 } 570 571 //----------------------------------------------------------------------// 572 // Execution environment. // 573 //----------------------------------------------------------------------// 574 575 /** 576 * Verify a runtime assertion (die w/traceback if assertion fails).<p> 577 * 578 * Note: code your assertion checks as 579 * {@code if (VM.VerifyAssertions) VM._assert(xxx);} 580 * @param b the assertion to verify 581 */ 582 @Inline(value=Inline.When.AllArgumentsAreConstant) 583 public static void _assert(boolean b) { 584 _assert(b, null, null); 585 } 586 587 /** 588 * Verify a runtime assertion (die w/message and traceback if 589 * assertion fails).<p> 590 * 591 * Note: code your assertion checks as 592 * {@code if (VM.VerifyAssertions) VM._assert(xxx);} 593 * 594 * @param b the assertion to verify 595 * @param message the message to print if the assertion is false 596 */ 597 @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0}) 598 public static void _assert(boolean b, String message) { 599 _assert(b, message, null); 600 } 601 602 @Inline(value=Inline.When.ArgumentsAreConstant, arguments={0}) 603 public static void _assert(boolean b, String msg1, String msg2) { 604 if (!VM.VerifyAssertions) { 605 sysWriteln("vm: somebody forgot to conditionalize their call to assert with"); 606 sysWriteln("vm: if (VM.VerifyAssertions)"); 607 _assertionFailure("vm internal error: assert called when !VM.VerifyAssertions", null); 608 } 609 if (!b) _assertionFailure(msg1, msg2); 610 } 611 612 @NoInline 613 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 614 private static void _assertionFailure(String msg1, String msg2) { 615 if (msg1 == null && msg2 == null) { 616 msg1 = "vm internal error at:"; 617 } 618 if (msg2 == null) { 619 msg2 = msg1; 620 msg1 = null; 621 } 622 if (VM.runningVM) { 623 if (msg1 != null) { 624 sysWrite(msg1); 625 } 626 sysFail(msg2); 627 } 628 throw new RuntimeException((msg1 != null ? msg1 : "") + msg2); 629 } 630 631 /** 632 * Format a 32 bit number as "0x" followed by 8 hex digits. 633 * Do this without referencing Integer or Character classes, 634 * in order to avoid dynamic linking. 635 * TODO: move this method to Services. 636 * @param number 637 * @return a String with the hex representation of the integer 638 */ 639 @Interruptible 640 public static String intAsHexString(int number) { 641 char[] buf = new char[10]; 642 int index = 10; 643 while (--index > 1) { 644 int digit = number & 0x0000000f; 645 buf[index] = digit <= 9 ? (char) ('0' + digit) : (char) ('a' + digit - 10); 646 number >>= 4; 647 } 648 buf[index--] = 'x'; 649 buf[index] = '0'; 650 return new String(buf); 651 } 652 653 /** 654 * Format a 64 bit number as "0x" followed by 16 hex digits. 655 * Do this without referencing Long or Character classes, 656 * in order to avoid dynamic linking. 657 * TODO: move this method to Services. 658 * @param number 659 * @return a String with the hex representation of the long 660 */ 661 @Interruptible 662 public static String longAsHexString(long number) { 663 char[] buf = new char[18]; 664 int index = 18; 665 while (--index > 1) { 666 int digit = (int) (number & 0x000000000000000fL); 667 buf[index] = digit <= 9 ? (char) ('0' + digit) : (char) ('a' + digit - 10); 668 number >>= 4; 669 } 670 buf[index--] = 'x'; 671 buf[index] = '0'; 672 return new String(buf); 673 } 674 675 /** 676 * Format a 32/64 bit number as "0x" followed by 8/16 hex digits. 677 * Do this without referencing Integer or Character classes, 678 * in order to avoid dynamic linking. 679 * TODO: move this method to Services. 680 * @param addr The 32/64 bit number to format. 681 * @return a String with the hex representation of an Address 682 */ 683 @Interruptible 684 public static String addressAsHexString(Address addr) { 685 int len = 2 + (BITS_IN_ADDRESS >> 2); 686 char[] buf = new char[len]; 687 while (--len > 1) { 688 int digit = addr.toInt() & 0x0F; 689 buf[len] = digit <= 9 ? (char) ('0' + digit) : (char) ('a' + digit - 10); 690 addr = addr.toWord().rshl(4).toAddress(); 691 } 692 buf[len--] = 'x'; 693 buf[len] = '0'; 694 return new String(buf); 695 } 696 697 @SuppressWarnings({"unused", "CanBeFinal", "UnusedDeclaration"}) 698 // accessed via EntryPoints 699 @Entrypoint 700 private static int sysWriteLock = 0; 701 private static Offset sysWriteLockOffset = Offset.max(); 702 703 private static void swLock() { 704 if (sysWriteLockOffset.isMax()) return; 705 while (!Synchronization.testAndSet(Magic.getJTOC(), sysWriteLockOffset, 1)) { 706 ; 707 } 708 } 709 710 private static void swUnlock() { 711 if (sysWriteLockOffset.isMax()) return; 712 Synchronization.fetchAndStore(Magic.getJTOC(), sysWriteLockOffset, 0); 713 } 714 715 /** 716 * Low level print to console. 717 * @param value what is printed 718 */ 719 @NoInline 720 /* don't waste code space inlining these --dave */ 721 private static void write(Atom value) { 722 value.sysWrite(); 723 } 724 725 /** 726 * Low level print to console. 727 * @param value what is printed 728 */ 729 @NoInline 730 /* don't waste code space inlining these --dave */ 731 public static void write(RVMMember value) { 732 write(value.getMemberRef()); 733 } 734 735 /** 736 * Low level print to console. 737 * @param value what is printed 738 */ 739 @NoInline 740 /* don't waste code space inlining these --dave */ 741 public static void write(MemberReference value) { 742 write(value.getType().getName()); 743 write("."); 744 write(value.getName()); 745 write(" "); 746 write(value.getDescriptor()); 747 } 748 749 /** 750 * Low level print to console. 751 * @param value what is printed 752 */ 753 @NoInline 754 /* don't waste code space inlining these --dave */ 755 public static void write(String value) { 756 if (value == null) { 757 write("null"); 758 } else { 759 if (runningVM) { 760 char[] chars = java.lang.JikesRVMSupport.getBackingCharArray(value); 761 int numChars = java.lang.JikesRVMSupport.getStringLength(value); 762 int offset = java.lang.JikesRVMSupport.getStringOffset(value); 763 for (int i = 0; i < numChars; i++) { 764 write(chars[offset + i]); 765 } 766 } else { 767 writeNotRunningVM(value); 768 } 769 } 770 } 771 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 772 private static void writeNotRunningVM(String value) { 773 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 774 System.err.print(value); 775 } 776 777 /** 778 * Low level print to console. 779 * @param value character array that is printed 780 * @param len number of characters printed 781 */ 782 @NoInline 783 /* don't waste code space inlining these --dave */ 784 public static void write(char[] value, int len) { 785 for (int i = 0, n = len; i < n; ++i) { 786 if (runningVM) 787 /* Avoid triggering a potential read barrier 788 * 789 * TODO: Convert this to use org.mmtk.vm.Barriers.getArrayNoBarrier 790 */ { 791 write(Magic.getCharAtOffset(value, Offset.fromIntZeroExtend(i << LOG_BYTES_IN_CHAR))); 792 } else { 793 write(value[i]); 794 } 795 } 796 } 797 798 /** 799 * Low level print of a <code>char</code>to console. 800 * @param value The character to print 801 */ 802 @NoInline 803 /* don't waste code space inlining these --dave */ 804 public static void write(char value) { 805 if (runningVM) { 806 sysCall.sysConsoleWriteChar(value); 807 } else { 808 writeNotRunningVM(value); 809 } 810 } 811 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 812 private static void writeNotRunningVM(char value) { 813 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 814 System.err.print(value); 815 } 816 817 /** 818 * Low level print of <code>double</code> to console. 819 * 820 * @param value <code>double</code> to be printed 821 * @param postDecimalDigits Number of decimal places 822 */ 823 @NoInline 824 /* don't waste code space inlining these --dave */ 825 public static void write(double value, int postDecimalDigits) { 826 if (runningVM) { 827 sysCall.sysConsoleWriteDouble(value, postDecimalDigits); 828 } else { 829 writeNotRunningVM(value); 830 } 831 } 832 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 833 private static void writeNotRunningVM(double value) { 834 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 835 System.err.print(value); 836 } 837 838 /** 839 * Low level print of an <code>int</code> to console. 840 * @param value what is printed 841 */ 842 @NoInline 843 /* don't waste code space inlining these --dave */ 844 public static void write(int value) { 845 if (runningVM) { 846 int mode = (value < -(1 << 20) || value > (1 << 20)) ? 2 : 0; // hex only or decimal only 847 sysCall.sysConsoleWriteInteger(value, mode); 848 } else { 849 writeNotRunningVM(value); 850 } 851 } 852 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 853 private static void writeNotRunningVM(int value) { 854 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 855 System.err.print(value); 856 } 857 858 /** 859 * Low level print to console. 860 * @param value What is printed, as hex only 861 */ 862 @NoInline 863 /* don't waste code space inlining these --dave */ 864 public static void writeHex(int value) { 865 if (runningVM) { 866 sysCall.sysConsoleWriteInteger(value, 2 /*just hex*/); 867 } else { 868 writeHexNotRunningVM(value); 869 } 870 } 871 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 872 private static void writeHexNotRunningVM(int value) { 873 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 874 System.err.print(Integer.toHexString(value)); 875 } 876 877 /** 878 * Low level print to console. 879 * @param value what is printed, as hex only 880 */ 881 @NoInline 882 /* don't waste code space inlining these --dave */ 883 public static void writeHex(long value) { 884 if (runningVM) { 885 sysCall.sysConsoleWriteLong(value, 2); 886 } else { 887 writeHexNotRunningVM(value); 888 } 889 } 890 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 891 private static void writeHexNotRunningVM(long value) { 892 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 893 System.err.print(Long.toHexString(value)); 894 } 895 896 @NoInline 897 /* don't waste code space inlining these --dave */ 898 public static void writeDec(Word value) { 899 if (VM.BuildFor32Addr) { 900 write(value.toInt()); 901 } else { 902 write(value.toLong()); 903 } 904 } 905 906 @NoInline 907 /* don't waste code space inlining these --dave */ 908 public static void writeHex(Word value) { 909 if (VM.BuildFor32Addr) { 910 writeHex(value.toInt()); 911 } else { 912 writeHex(value.toLong()); 913 } 914 } 915 916 @NoInline 917 /* don't waste code space inlining these --dave */ 918 public static void writeHex(Address value) { 919 writeHex(value.toWord()); 920 } 921 922 @NoInline 923 /* don't waste code space inlining these --dave */ 924 public static void writeHex(ObjectReference value) { 925 writeHex(value.toAddress().toWord()); 926 } 927 928 @NoInline 929 /* don't waste code space inlining these --dave */ 930 public static void writeHex(Extent value) { 931 writeHex(value.toWord()); 932 } 933 934 @NoInline 935 /* don't waste code space inlining these --dave */ 936 public static void writeHex(Offset value) { 937 writeHex(value.toWord()); 938 } 939 940 /** 941 * Low level print to console. 942 * @param value what is printed, as int only 943 */ 944 @NoInline 945 /* don't waste code space inlining these --dave */ 946 public static void writeInt(int value) { 947 if (runningVM) { 948 sysCall.sysConsoleWriteInteger(value, 0 /*just decimal*/); 949 } else { 950 writeNotRunningVM(value); 951 } 952 } 953 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 954 private static void writeNotRunningVM(long value) { 955 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 956 System.err.print(value); 957 } 958 959 /** 960 * Low level print to console. 961 * @param value what is printed 962 */ 963 @NoInline 964 /* don't waste code space inlining these --dave */ 965 public static void write(long value) { 966 write(value, true); 967 } 968 969 /** 970 * Low level print to console. 971 * @param value what is printed 972 * @param hexToo how to print: true - print as decimal followed by hex 973 * false - print as decimal only 974 */ 975 @NoInline 976 /* don't waste code space inlining these --dave */ 977 public static void write(long value, boolean hexToo) { 978 if (runningVM) { 979 sysCall.sysConsoleWriteLong(value, hexToo ? 1 : 0); 980 } else { 981 writeNotRunningVM(value); 982 } 983 } 984 985 @NoInline 986 /* don't waste code space inlining these --dave */ 987 public static void writeField(int fieldWidth, String s) { 988 write(s); 989 int len = getStringLength(s); 990 while (fieldWidth > len++) write(" "); 991 } 992 993 @UninterruptibleNoWarn("Interruptible code not reachable at runtime") 994 private static int getStringLength(String s) { 995 if (VM.runningVM) { 996 return java.lang.JikesRVMSupport.getStringLength(s); 997 } else { 998 return s.length(); 999 } 1000 } 1001 /** 1002 * Low level print to console. 1003 * @param value print value and left-fill with enough spaces to print at least fieldWidth characters 1004 */ 1005 @NoInline 1006 /* don't waste code space inlining these --dave */ 1007 public static void writeField(int fieldWidth, int value) { 1008 int len = 1, temp = value; 1009 if (temp < 0) { 1010 len++; 1011 temp = -temp; 1012 } 1013 while (temp >= 10) { 1014 len++; 1015 temp /= 10; 1016 } 1017 while (fieldWidth > len++) write(" "); 1018 if (runningVM) { 1019 sysCall.sysConsoleWriteInteger(value, 0); 1020 } else { 1021 writeNotRunningVM(value); 1022 } 1023 } 1024 1025 /** 1026 * Low level print of the {@link Atom} <code>s</code> to the console. 1027 * Left-fill with enough spaces to print at least <code>fieldWidth</code> 1028 * characters 1029 * @param fieldWidth Minimum width to print. 1030 * @param s The {@link Atom} to print. 1031 */ 1032 @NoInline 1033 /* don't waste code space inlining these --dave */ 1034 public static void writeField(int fieldWidth, Atom s) { 1035 int len = s.length(); 1036 while (fieldWidth > len++) write(" "); 1037 write(s); 1038 } 1039 1040 public static void writeln() { 1041 write('\n'); 1042 } 1043 1044 public static void write(double d) { 1045 write(d, 2); 1046 } 1047 1048 public static void write(Word addr) { 1049 writeHex(addr); 1050 } 1051 1052 public static void write(Address addr) { 1053 writeHex(addr); 1054 } 1055 1056 public static void write(ObjectReference object) { 1057 writeHex(object); 1058 } 1059 1060 public static void write(Offset addr) { 1061 writeHex(addr); 1062 } 1063 1064 public static void write(Extent addr) { 1065 writeHex(addr); 1066 } 1067 1068 public static void write(boolean b) { 1069 write(b ? "true" : "false"); 1070 } 1071 1072 /** 1073 * A group of multi-argument sysWrites with optional newline. Externally visible methods. 1074 */ 1075 @NoInline 1076 public static void sysWrite(Atom a) { 1077 swLock(); 1078 write(a); 1079 swUnlock(); 1080 } 1081 1082 @NoInline 1083 public static void sysWriteln(Atom a) { 1084 swLock(); 1085 write(a); 1086 write("\n"); 1087 swUnlock(); 1088 } 1089 1090 @NoInline 1091 public static void sysWrite(RVMMember m) { 1092 swLock(); 1093 write(m); 1094 swUnlock(); 1095 } 1096 1097 @NoInline 1098 public static void sysWrite(MemberReference mr) { 1099 swLock(); 1100 write(mr); 1101 swUnlock(); 1102 } 1103 1104 @NoInline 1105 public static void sysWriteln() { 1106 swLock(); 1107 write("\n"); 1108 swUnlock(); 1109 } 1110 1111 @NoInline 1112 public static void sysWrite(char c) { write(c); } 1113 1114 @NoInline 1115 public static void sysWriteField(int w, int v) { 1116 swLock(); 1117 writeField(w, v); 1118 swUnlock(); 1119 } 1120 1121 @NoInline 1122 public static void sysWriteField(int w, String s) { 1123 swLock(); 1124 writeField(w, s); 1125 swUnlock(); 1126 } 1127 1128 @NoInline 1129 public static void sysWriteHex(int v) { 1130 swLock(); 1131 writeHex(v); 1132 swUnlock(); 1133 } 1134 1135 @NoInline 1136 public static void sysWriteHex(long v) { 1137 swLock(); 1138 writeHex(v); 1139 swUnlock(); 1140 } 1141 1142 @NoInline 1143 public static void sysWriteHex(Address v) { 1144 swLock(); 1145 writeHex(v); 1146 swUnlock(); 1147 } 1148 1149 @NoInline 1150 public static void sysWriteInt(int v) { 1151 swLock(); 1152 writeInt(v); 1153 swUnlock(); 1154 } 1155 1156 @NoInline 1157 public static void sysWriteLong(long v) { 1158 swLock(); 1159 write(v, false); 1160 swUnlock(); 1161 } 1162 1163 @NoInline 1164 public static void sysWrite(double d, int p) { 1165 swLock(); 1166 write(d, p); 1167 swUnlock(); 1168 } 1169 1170 @NoInline 1171 public static void sysWrite(double d) { 1172 swLock(); 1173 write(d); 1174 swUnlock(); 1175 } 1176 1177 @NoInline 1178 public static void sysWrite(String s) { 1179 swLock(); 1180 write(s); 1181 swUnlock(); 1182 } 1183 1184 @NoInline 1185 public static void sysWrite(char[] c, int l) { 1186 swLock(); 1187 write(c, l); 1188 swUnlock(); 1189 } 1190 1191 @NoInline 1192 public static void sysWrite(Address a) { 1193 swLock(); 1194 write(a); 1195 swUnlock(); 1196 } 1197 1198 @NoInline 1199 public static void sysWriteln(Address a) { 1200 swLock(); 1201 write(a); 1202 writeln(); 1203 swUnlock(); 1204 } 1205 1206 @NoInline 1207 public static void sysWrite(ObjectReference o) { 1208 swLock(); 1209 write(o); 1210 swUnlock(); 1211 } 1212 1213 @NoInline 1214 public static void sysWriteln(ObjectReference o) { 1215 swLock(); 1216 write(o); 1217 writeln(); 1218 swUnlock(); 1219 } 1220 1221 @NoInline 1222 public static void sysWrite(Offset o) { 1223 swLock(); 1224 write(o); 1225 swUnlock(); 1226 } 1227 1228 @NoInline 1229 public static void sysWriteln(Offset o) { 1230 swLock(); 1231 write(o); 1232 writeln(); 1233 swUnlock(); 1234 } 1235 1236 @NoInline 1237 public static void sysWrite(Word w) { 1238 swLock(); 1239 write(w); 1240 swUnlock(); 1241 } 1242 1243 @NoInline 1244 public static void sysWriteln(Word w) { 1245 swLock(); 1246 write(w); 1247 writeln(); 1248 swUnlock(); 1249 } 1250 1251 @NoInline 1252 public static void sysWrite(Extent e) { 1253 swLock(); 1254 write(e); 1255 swUnlock(); 1256 } 1257 1258 @NoInline 1259 public static void sysWriteln(Extent e) { 1260 swLock(); 1261 write(e); 1262 writeln(); 1263 swUnlock(); 1264 } 1265 1266 @NoInline 1267 public static void sysWrite(boolean b) { 1268 swLock(); 1269 write(b); 1270 swUnlock(); 1271 } 1272 1273 @NoInline 1274 public static void sysWrite(int i) { 1275 swLock(); 1276 write(i); 1277 swUnlock(); 1278 } 1279 1280 @NoInline 1281 public static void sysWriteln(int i) { 1282 swLock(); 1283 write(i); 1284 writeln(); 1285 swUnlock(); 1286 } 1287 1288 @NoInline 1289 public static void sysWriteln(double d) { 1290 swLock(); 1291 write(d); 1292 writeln(); 1293 swUnlock(); 1294 } 1295 1296 @NoInline 1297 public static void sysWriteln(long l) { 1298 swLock(); 1299 write(l); 1300 writeln(); 1301 swUnlock(); 1302 } 1303 1304 @NoInline 1305 public static void sysWriteln(boolean b) { 1306 swLock(); 1307 write(b); 1308 writeln(); 1309 swUnlock(); 1310 } 1311 1312 @NoInline 1313 public static void sysWriteln(String s) { 1314 swLock(); 1315 write(s); 1316 writeln(); 1317 swUnlock(); 1318 } 1319 1320 @NoInline 1321 public static void sysWriteln(String s, Atom a) { 1322 swLock(); 1323 write(s); 1324 write(a); 1325 writeln(); 1326 swUnlock(); 1327 } 1328 1329 @NoInline 1330 public static void sysWrite(String s, int i) { 1331 swLock(); 1332 write(s); 1333 write(i); 1334 swUnlock(); 1335 } 1336 1337 @NoInline 1338 public static void sysWriteln(String s, int i) { 1339 swLock(); 1340 write(s); 1341 write(i); 1342 writeln(); 1343 swUnlock(); 1344 } 1345 1346 @NoInline 1347 public static void sysWrite(String s, boolean b) { 1348 swLock(); 1349 write(s); 1350 write(b); 1351 swUnlock(); 1352 } 1353 1354 @NoInline 1355 public static void sysWriteln(String s, boolean b) { 1356 swLock(); 1357 write(s); 1358 write(b); 1359 writeln(); 1360 swUnlock(); 1361 } 1362 1363 @NoInline 1364 public static void sysWrite(String s, double d) { 1365 swLock(); 1366 write(s); 1367 write(d); 1368 swUnlock(); 1369 } 1370 1371 @NoInline 1372 public static void sysWriteln(String s, double d) { 1373 swLock(); 1374 write(s); 1375 write(d); 1376 writeln(); 1377 swUnlock(); 1378 } 1379 1380 @NoInline 1381 public static void sysWrite(double d, String s) { 1382 swLock(); 1383 write(d); 1384 write(s); 1385 swUnlock(); 1386 } 1387 1388 @NoInline 1389 public static void sysWriteln(double d, String s) { 1390 swLock(); 1391 write(d); 1392 write(s); 1393 writeln(); 1394 swUnlock(); 1395 } 1396 1397 @NoInline 1398 public static void sysWrite(String s, long i) { 1399 swLock(); 1400 write(s); 1401 write(i); 1402 swUnlock(); 1403 } 1404 1405 @NoInline 1406 public static void sysWriteln(String s, long i) { 1407 swLock(); 1408 write(s); 1409 write(i); 1410 writeln(); 1411 swUnlock(); 1412 } 1413 1414 @NoInline 1415 public static void sysWriteln(String s1, long i1,String s2, long i2) { 1416 swLock(); 1417 write(s1); 1418 write(i1); 1419 write(s2); 1420 write(i2); 1421 writeln(); 1422 swUnlock(); 1423 } 1424 1425 @NoInline 1426 public static void sysWrite(int i, String s) { 1427 swLock(); 1428 write(i); 1429 write(s); 1430 swUnlock(); 1431 } 1432 1433 @NoInline 1434 public static void sysWriteln(int i, String s) { 1435 swLock(); 1436 write(i); 1437 write(s); 1438 writeln(); 1439 swUnlock(); 1440 } 1441 1442 @NoInline 1443 public static void sysWrite(String s1, String s2) { 1444 swLock(); 1445 write(s1); 1446 write(s2); 1447 swUnlock(); 1448 } 1449 1450 @NoInline 1451 public static void sysWriteln(String s1, String s2) { 1452 swLock(); 1453 write(s1); 1454 write(s2); 1455 writeln(); 1456 swUnlock(); 1457 } 1458 1459 @NoInline 1460 public static void sysWrite(String s, Address a) { 1461 swLock(); 1462 write(s); 1463 write(a); 1464 swUnlock(); 1465 } 1466 1467 @NoInline 1468 public static void sysWriteln(String s, Address a) { 1469 swLock(); 1470 write(s); 1471 write(a); 1472 writeln(); 1473 swUnlock(); 1474 } 1475 1476 @NoInline 1477 public static void sysWrite(String s, ObjectReference r) { 1478 swLock(); 1479 write(s); 1480 write(r); 1481 swUnlock(); 1482 } 1483 1484 @NoInline 1485 public static void sysWriteln(String s, ObjectReference r) { 1486 swLock(); 1487 write(s); 1488 write(r); 1489 writeln(); 1490 swUnlock(); 1491 } 1492 1493 @NoInline 1494 public static void sysWrite(String s, Offset o) { 1495 swLock(); 1496 write(s); 1497 write(o); 1498 swUnlock(); 1499 } 1500 1501 @NoInline 1502 public static void sysWriteln(String s, Offset o) { 1503 swLock(); 1504 write(s); 1505 write(o); 1506 writeln(); 1507 swUnlock(); 1508 } 1509 1510 @NoInline 1511 public static void sysWrite(String s, Word w) { 1512 swLock(); 1513 write(s); 1514 write(w); 1515 swUnlock(); 1516 } 1517 1518 @NoInline 1519 public static void sysWriteln(String s, Word w) { 1520 swLock(); 1521 write(s); 1522 write(w); 1523 writeln(); 1524 swUnlock(); 1525 } 1526 1527 @NoInline 1528 public static void sysWrite(String s1, String s2, Address a) { 1529 swLock(); 1530 write(s1); 1531 write(s2); 1532 write(a); 1533 swUnlock(); 1534 } 1535 1536 @NoInline 1537 public static void sysWrite(String s1, Address a, String s2) { 1538 swLock(); 1539 write(s1); 1540 write(a); 1541 write(s2); 1542 swUnlock(); 1543 } 1544 1545 @NoInline 1546 public static void sysWriteln(String s1, String s2, Address a) { 1547 swLock(); 1548 write(s1); 1549 write(s2); 1550 write(a); 1551 writeln(); 1552 swUnlock(); 1553 } 1554 1555 @NoInline 1556 public static void sysWriteln(String s1, Address a,String s2) { 1557 swLock(); 1558 write(s1); 1559 write(a); 1560 write(s2); 1561 writeln(); 1562 swUnlock(); 1563 } 1564 @NoInline 1565 public static void sysWriteln(String s1, Address a1,Address a2) { 1566 swLock(); 1567 write(s1); 1568 write(a1); 1569 write(" "); 1570 write(a2); 1571 writeln(); 1572 swUnlock(); 1573 } 1574 @NoInline 1575 public static void sysWrite(String s1, String s2, int i) { 1576 swLock(); 1577 write(s1); 1578 write(s2); 1579 write(i); 1580 swUnlock(); 1581 } 1582 1583 @NoInline 1584 public static void sysWriteln(int i, Address a, RVMMethod m) { 1585 swLock(); 1586 write(i); 1587 write(" "); 1588 write(a); 1589 write(" "); 1590 write(m.getDeclaringClass().getDescriptor()); 1591 write("."); 1592 write(m.getName()); 1593 write(m.getDescriptor()); 1594 write("\n"); 1595 swUnlock(); 1596 } 1597 1598 @NoInline 1599 public static void sysWriteln(int i, Address a, Address b) { 1600 swLock(); 1601 write(i); 1602 write(" "); 1603 write(a); 1604 write(" "); 1605 write(b); 1606 write("\n"); 1607 swUnlock(); 1608 } 1609 1610 @NoInline 1611 public static void sysWriteln(String s1, String s2, int i) { 1612 swLock(); 1613 write(s1); 1614 write(s2); 1615 write(i); 1616 writeln(); 1617 swUnlock(); 1618 } 1619 1620 @NoInline 1621 public static void sysWrite(String s1, int i, String s2) { 1622 swLock(); 1623 write(s1); 1624 write(i); 1625 write(s2); 1626 swUnlock(); 1627 } 1628 1629 @NoInline 1630 public static void sysWriteln(String s1, int i, String s2) { 1631 swLock(); 1632 write(s1); 1633 write(i); 1634 write(s2); 1635 writeln(); 1636 swUnlock(); 1637 } 1638 1639 @NoInline 1640 public static void sysWrite(String s1, Offset o, String s2) { 1641 swLock(); 1642 write(s1); 1643 write(o); 1644 write(s2); 1645 swUnlock(); 1646 } 1647 1648 @NoInline 1649 public static void sysWriteln(String s1, Offset o, String s2) { 1650 swLock(); 1651 write(s1); 1652 write(o); 1653 write(s2); 1654 writeln(); 1655 swUnlock(); 1656 } 1657 1658 @NoInline 1659 public static void sysWrite(String s1, String s2, String s3) { 1660 swLock(); 1661 write(s1); 1662 write(s2); 1663 write(s3); 1664 swUnlock(); 1665 } 1666 1667 @NoInline 1668 public static void sysWriteln(String s1, String s2, String s3) { 1669 swLock(); 1670 write(s1); 1671 write(s2); 1672 write(s3); 1673 writeln(); 1674 swUnlock(); 1675 } 1676 1677 @NoInline 1678 public static void sysWriteln(String s1, String s2, String s3, Address a) { 1679 swLock(); 1680 write(s1); 1681 write(s2); 1682 write(s3); 1683 write(a); 1684 writeln(); 1685 swUnlock(); 1686 } 1687 1688 @NoInline 1689 public static void sysWrite(int i1, String s, int i2) { 1690 swLock(); 1691 write(i1); 1692 write(s); 1693 write(i2); 1694 swUnlock(); 1695 } 1696 1697 @NoInline 1698 public static void sysWriteln(int i1, String s, int i2) { 1699 swLock(); 1700 write(i1); 1701 write(s); 1702 write(i2); 1703 writeln(); 1704 swUnlock(); 1705 } 1706 1707 @NoInline 1708 public static void sysWrite(int i1, String s1, String s2) { 1709 swLock(); 1710 write(i1); 1711 write(s1); 1712 write(s2); 1713 swUnlock(); 1714 } 1715 1716 @NoInline 1717 public static void sysWriteln(int i1, String s1, String s2) { 1718 swLock(); 1719 write(i1); 1720 write(s1); 1721 write(s2); 1722 writeln(); 1723 swUnlock(); 1724 } 1725 1726 @NoInline 1727 public static void sysWrite(String s1, String s2, String s3, String s4) { 1728 swLock(); 1729 write(s1); 1730 write(s2); 1731 write(s3); 1732 write(s4); 1733 swUnlock(); 1734 } 1735 1736 @NoInline 1737 public static void sysWriteln(String s1, String s2, String s3, String s4) { 1738 swLock(); 1739 write(s1); 1740 write(s2); 1741 write(s3); 1742 write(s4); 1743 writeln(); 1744 swUnlock(); 1745 } 1746 1747 @NoInline 1748 public static void sysWrite(String s1, String s2, String s3, String s4, String s5) { 1749 swLock(); 1750 write(s1); 1751 write(s2); 1752 write(s3); 1753 write(s4); 1754 write(s5); 1755 swUnlock(); 1756 } 1757 1758 @NoInline 1759 public static void sysWriteln(String s1, String s2, String s3, String s4, String s5) { 1760 swLock(); 1761 write(s1); 1762 write(s2); 1763 write(s3); 1764 write(s4); 1765 write(s5); 1766 writeln(); 1767 swUnlock(); 1768 } 1769 1770 @NoInline 1771 public static void sysWriteln(String s1, int i, String s3, Address a, String s5) { 1772 swLock(); 1773 write(s1); 1774 write(i); 1775 write(s3); 1776 write(a); 1777 write(s5); 1778 writeln(); 1779 swUnlock(); 1780 } 1781 1782 @NoInline 1783 public static void sysWriteln(int i, String s, Address a) { 1784 swLock(); 1785 write(i); 1786 write(s); 1787 write(a); 1788 writeln(); 1789 swUnlock(); 1790 } 1791 1792 @NoInline 1793 public static void sysWrite(String s1, int i1, String s2, int i2) { 1794 swLock(); 1795 write(s1); 1796 write(i1); 1797 write(s2); 1798 write(i2); 1799 swUnlock(); 1800 } 1801 1802 @NoInline 1803 public static void sysWriteln(String s1, int i1, String s2, int i2) { 1804 swLock(); 1805 write(s1); 1806 write(i1); 1807 write(s2); 1808 write(i2); 1809 writeln(); 1810 swUnlock(); 1811 } 1812 1813 @NoInline 1814 public static void sysWriteln(String s1, int i, String s2, Address a) { 1815 swLock(); 1816 write(s1); 1817 write(i); 1818 write(s2); 1819 write(a); 1820 writeln(); 1821 swUnlock(); 1822 } 1823 1824 @NoInline 1825 public static void sysWriteln(String s1, int i, String s2, Word w) { 1826 swLock(); 1827 write(s1); 1828 write(i); 1829 write(s2); 1830 write(w); 1831 writeln(); 1832 swUnlock(); 1833 } 1834 1835 @NoInline 1836 public static void sysWriteln(String s1, int i, String s2, double d) { 1837 swLock(); 1838 write(s1); 1839 write(i); 1840 write(s2); 1841 write(d); 1842 writeln(); 1843 swUnlock(); 1844 } 1845 1846 @NoInline 1847 public static void sysWriteln(String s1, int i, String s2, Word w, String s3) { 1848 swLock(); 1849 write(s1); 1850 write(i); 1851 write(s2); 1852 write(w); 1853 write(s3); 1854 writeln(); 1855 swUnlock(); 1856 } 1857 1858 @NoInline 1859 public static void sysWriteln(String s1, int i1, String s2, int i2, String s3) { 1860 swLock(); 1861 write(s1); 1862 write(i1); 1863 write(s2); 1864 write(i2); 1865 write(s3); 1866 writeln(); 1867 swUnlock(); 1868 } 1869 1870 @NoInline 1871 public static void sysWriteln(String s1, int i1, String s2, int i2, String s3, int i3) { 1872 swLock(); 1873 write(s1); 1874 write(i1); 1875 write(s2); 1876 write(i2); 1877 write(s3); 1878 write(i3); 1879 writeln(); 1880 swUnlock(); 1881 } 1882 1883 @NoInline 1884 public static void sysWrite(String s1, int i1, String s2, long l1) { 1885 swLock(); 1886 write(s1); 1887 write(i1); 1888 write(s2); 1889 write(l1); 1890 swUnlock(); 1891 } 1892 1893 @NoInline 1894 public static void sysWriteln(String s1, int i1, String s2, long l1) { 1895 swLock(); 1896 write(s1); 1897 write(i1); 1898 write(s2); 1899 write(l1); 1900 writeln(); 1901 swUnlock(); 1902 } 1903 1904 @NoInline 1905 public static void sysWrite(String s1, Offset o, String s2, int i) { 1906 swLock(); 1907 write(s1); 1908 write(o); 1909 write(s2); 1910 write(i); 1911 swUnlock(); 1912 } 1913 1914 @NoInline 1915 public static void sysWriteln(String s1, Offset o, String s2, int i) { 1916 swLock(); 1917 write(s1); 1918 write(o); 1919 write(s2); 1920 write(i); 1921 writeln(); 1922 swUnlock(); 1923 } 1924 1925 @NoInline 1926 public static void sysWrite(String s1, double d, String s2) { 1927 swLock(); 1928 write(s1); 1929 write(d); 1930 write(s2); 1931 swUnlock(); 1932 } 1933 1934 @NoInline 1935 public static void sysWriteln(String s1, double d, String s2) { 1936 swLock(); 1937 write(s1); 1938 write(d); 1939 write(s2); 1940 writeln(); 1941 swUnlock(); 1942 } 1943 1944 @NoInline 1945 public static void sysWriteln(String s1, long l1, String s2, long l2, String s3) { 1946 swLock(); 1947 write(s1); 1948 write(l1); 1949 write(s2); 1950 write(l2); 1951 write(s3); 1952 writeln(); 1953 swUnlock(); 1954 } 1955 1956 @NoInline 1957 public static void sysWrite(String s1, String s2, int i1, String s3) { 1958 swLock(); 1959 write(s1); 1960 write(s2); 1961 write(i1); 1962 write(s3); 1963 swUnlock(); 1964 } 1965 1966 @NoInline 1967 public static void sysWriteln(String s1, String s2, int i1, String s3) { 1968 swLock(); 1969 write(s1); 1970 write(s2); 1971 write(i1); 1972 write(s3); 1973 writeln(); 1974 swUnlock(); 1975 } 1976 1977 @NoInline 1978 public static void sysWrite(String s1, String s2, String s3, int i1) { 1979 swLock(); 1980 write(s1); 1981 write(s2); 1982 write(s3); 1983 write(i1); 1984 swUnlock(); 1985 } 1986 1987 @NoInline 1988 public static void sysWriteln(String s1, String s2, String s3, int i1) { 1989 swLock(); 1990 write(s1); 1991 write(s2); 1992 write(s3); 1993 write(i1); 1994 writeln(); 1995 swUnlock(); 1996 } 1997 1998 @NoInline 1999 public static void sysWrite(String s1, String s2, String s3, String s4, int i5, String s6) { 2000 swLock(); 2001 write(s1); 2002 write(s2); 2003 write(s3); 2004 write(s4); 2005 write(i5); 2006 write(s6); 2007 swUnlock(); 2008 } 2009 2010 @NoInline 2011 public static void sysWriteln(String s1, String s2, String s3, String s4, int i5, String s6) { 2012 swLock(); 2013 write(s1); 2014 write(s2); 2015 write(s3); 2016 write(s4); 2017 write(i5); 2018 write(s6); 2019 writeln(); 2020 swUnlock(); 2021 } 2022 2023 @NoInline 2024 public static void sysWrite(int i, String s1, double d, String s2) { 2025 swLock(); 2026 write(i); 2027 write(s1); 2028 write(d); 2029 write(s2); 2030 swUnlock(); 2031 } 2032 2033 @NoInline 2034 public static void sysWriteln(int i, String s1, double d, String s2) { 2035 swLock(); 2036 write(i); 2037 write(s1); 2038 write(d); 2039 write(s2); 2040 writeln(); 2041 swUnlock(); 2042 } 2043 2044 @NoInline 2045 public static void sysWrite(String s1, String s2, String s3, int i1, String s4) { 2046 swLock(); 2047 write(s1); 2048 write(s2); 2049 write(s3); 2050 write(i1); 2051 write(s4); 2052 swUnlock(); 2053 } 2054 2055 @NoInline 2056 public static void sysWriteln(String s1, String s2, String s3, int i1, String s4) { 2057 swLock(); 2058 write(s1); 2059 write(s2); 2060 write(s3); 2061 write(i1); 2062 write(s4); 2063 writeln(); 2064 swUnlock(); 2065 } 2066 2067 @NoInline 2068 public static void sysWrite(String s1, Address a1, String s2, Address a2) { 2069 swLock(); 2070 write(s1); 2071 write(a1); 2072 write(s2); 2073 write(a2); 2074 swUnlock(); 2075 } 2076 2077 @NoInline 2078 public static void sysWriteln(String s1, Address a1, String s2, Address a2) { 2079 swLock(); 2080 write(s1); 2081 write(a1); 2082 write(s2); 2083 write(a2); 2084 writeln(); 2085 swUnlock(); 2086 } 2087 2088 @NoInline 2089 public static void sysWrite(String s1, Address a, String s2, int i) { 2090 swLock(); 2091 write(s1); 2092 write(a); 2093 write(s2); 2094 write(i); 2095 swUnlock(); 2096 } 2097 2098 @NoInline 2099 public static void sysWriteln(String s1, Address a, String s2, int i) { 2100 swLock(); 2101 write(s1); 2102 write(a); 2103 write(s2); 2104 write(i); 2105 writeln(); 2106 swUnlock(); 2107 } 2108 2109 @NoInline 2110 public static void sysWriteln(String s0, Address a1, String s1, Word w1, String s2, int i1, String s3, int i2, String s4, Word w2, String s5, int i3) { 2111 swLock(); 2112 write(s0); 2113 write(a1); 2114 write(s1); 2115 write(w1); 2116 write(s2); 2117 write(i1); 2118 write(s3); 2119 write(i2); 2120 write(s4); 2121 write(w2); 2122 write(s5); 2123 write(i3); 2124 writeln(); 2125 swUnlock(); 2126 } 2127 2128 private static void showThread() { 2129 write("Thread "); 2130 write(RVMThread.getCurrentThread().getThreadSlot()); 2131 write(": "); 2132 } 2133 2134 @NoInline 2135 public static void tsysWriteln(String s) { 2136 swLock(); 2137 showThread(); 2138 write(s); 2139 writeln(); 2140 swUnlock(); 2141 } 2142 2143 @NoInline 2144 public static void tsysWriteln(String s1, String s2, String s3, int i4, String s5, String s6) { 2145 swLock(); 2146 showThread(); 2147 write(s1); 2148 write(s2); 2149 write(s3); 2150 write(i4); 2151 write(s5); 2152 write(s6); 2153 writeln(); 2154 swUnlock(); 2155 } 2156 2157 @NoInline 2158 public static void tsysWriteln(String s1, String s2, String s3, String s4, String s5, String s6, String s7, int i8, 2159 String s9, String s10, String s11, String s12, String s13) { 2160 swLock(); 2161 showThread(); 2162 write(s1); 2163 write(s2); 2164 write(s3); 2165 write(s4); 2166 write(s5); 2167 write(s6); 2168 write(s7); 2169 write(i8); 2170 write(s9); 2171 write(s10); 2172 write(s11); 2173 write(s12); 2174 write(s13); 2175 writeln(); 2176 swUnlock(); 2177 } 2178 2179 @NoInline 2180 public static void tsysWriteln(String s1, String s2, String s3, String s4, String s5, String s6, String s7, int i8, 2181 String s9, String s10, String s11, String s12, String s13, int i14) { 2182 swLock(); 2183 showThread(); 2184 write(s1); 2185 write(s2); 2186 write(s3); 2187 write(s4); 2188 write(s5); 2189 write(s6); 2190 write(s7); 2191 write(i8); 2192 write(s9); 2193 write(s10); 2194 write(s11); 2195 write(s12); 2196 write(s13); 2197 write(i14); 2198 writeln(); 2199 swUnlock(); 2200 } 2201 @NoInline 2202 public static void tsysWrite(char[] c, int l) { 2203 swLock(); 2204 showThread(); 2205 write(c, l); 2206 swUnlock(); 2207 } 2208 2209 @NoInline 2210 public static void tsysWriteln(Address a) { 2211 swLock(); 2212 showThread(); 2213 write(a); 2214 writeln(); 2215 swUnlock(); 2216 } 2217 2218 @NoInline 2219 public static void tsysWriteln(String s, int i) { 2220 swLock(); 2221 showThread(); 2222 write(s); 2223 write(i); 2224 writeln(); 2225 swUnlock(); 2226 } 2227 2228 @NoInline 2229 public static void tsysWriteln(String s, Address a) { 2230 swLock(); 2231 showThread(); 2232 write(s); 2233 write(a); 2234 writeln(); 2235 swUnlock(); 2236 } 2237 2238 @NoInline 2239 public static void tsysWriteln(String s1, Address a1, String s2, Address a2) { 2240 swLock(); 2241 showThread(); 2242 write(s1); 2243 write(a1); 2244 write(s2); 2245 write(a2); 2246 writeln(); 2247 swUnlock(); 2248 } 2249 2250 @NoInline 2251 public static void tsysWriteln(String s1, Address a1, String s2, Address a2, String s3, Address a3) { 2252 swLock(); 2253 showThread(); 2254 write(s1); 2255 write(a1); 2256 write(s2); 2257 write(a2); 2258 write(s3); 2259 write(a3); 2260 writeln(); 2261 swUnlock(); 2262 } 2263 2264 @NoInline 2265 public static void tsysWriteln(String s1, Address a1, String s2, Address a2, String s3, Address a3, String s4, 2266 Address a4) { 2267 swLock(); 2268 showThread(); 2269 write(s1); 2270 write(a1); 2271 write(s2); 2272 write(a2); 2273 write(s3); 2274 write(a3); 2275 write(s4); 2276 write(a4); 2277 writeln(); 2278 swUnlock(); 2279 } 2280 2281 @NoInline 2282 public static void tsysWriteln(String s1, Address a1, String s2, Address a2, String s3, Address a3, String s4, 2283 Address a4, String s5, Address a5) { 2284 swLock(); 2285 showThread(); 2286 write(s1); 2287 write(a1); 2288 write(s2); 2289 write(a2); 2290 write(s3); 2291 write(a3); 2292 write(s4); 2293 write(a4); 2294 write(s5); 2295 write(a5); 2296 writeln(); 2297 swUnlock(); 2298 } 2299 2300 /** 2301 * Produce a message requesting a bug report be submitted 2302 */ 2303 @NoInline 2304 public static void bugReportMessage() { 2305 VM.sysWriteln("********************************************************************************"); 2306 VM.sysWriteln("* Abnormal termination of Jikes RVM *\n"+ 2307 "* Jikes RVM terminated abnormally indicating a problem in the virtual machine. *\n"+ 2308 "* Jikes RVM relies on community support to get debug information. Help improve *\n"+ 2309 "* Jikes RVM for everybody by reporting this error. Please see: *\n"+ 2310 "* http://jikesrvm.org/Reporting+Bugs *"); 2311 VM.sysWriteln("********************************************************************************"); 2312 } 2313 2314 /** 2315 * Exit virtual machine due to internal failure of some sort. 2316 * @param message error message describing the problem 2317 */ 2318 @NoInline 2319 public static void sysFail(String message) { 2320 handlePossibleRecursiveCallToSysFail(message); 2321 2322 // print a traceback and die 2323 if(!RVMThread.getCurrentThread().isCollectorThread()) { 2324 RVMThread.traceback(message); 2325 } else { 2326 VM.sysWriteln("Died in GC:"); 2327 RVMThread.traceback(message); 2328 VM.sysWriteln("Virtual machine state:"); 2329 RVMThread.dumpVirtualMachine(); 2330 } 2331 bugReportMessage(); 2332 if (VM.runningVM) { 2333 VM.shutdown(EXIT_STATUS_SYSFAIL); 2334 } else { 2335 VM.sysExit(EXIT_STATUS_SYSFAIL); 2336 } 2337 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 2338 } 2339 2340 /** 2341 * Exit virtual machine due to internal failure of some sort. This 2342 * two-argument form is needed for us to call before the VM's Integer class 2343 * is initialized. 2344 * 2345 * @param message error message describing the problem 2346 * @param number an integer to append to <code>message</code>. 2347 */ 2348 @NoInline 2349 public static void sysFail(String message, int number) { 2350 handlePossibleRecursiveCallToSysFail(message, number); 2351 2352 // print a traceback and die 2353 RVMThread.traceback(message, number); 2354 bugReportMessage(); 2355 if (VM.runningVM) { 2356 VM.shutdown(EXIT_STATUS_SYSFAIL); 2357 } else { 2358 VM.sysExit(EXIT_STATUS_SYSFAIL); 2359 } 2360 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 2361 } 2362 2363 /** 2364 * Exit virtual machine. 2365 * @param value value to pass to host o/s 2366 */ 2367 @NoInline 2368 @UninterruptibleNoWarn("We're never returning to the caller, so even though this code is preemptible it is safe to call from any context") 2369 public static void sysExit(int value) { 2370 handlePossibleRecursiveCallToSysExit(); 2371 2372 if (VM.countThreadTransitions) { 2373 RVMThread.reportThreadTransitionCounts(); 2374 } 2375 2376 if (Options.stackTraceAtExit) { 2377 VM.sysWriteln("[Here is the context of the call to VM.sysExit(", value, ")...:"); 2378 VM.disableGC(); 2379 RVMThread.dumpStack(); 2380 VM.enableGC(); 2381 VM.sysWriteln("... END context of the call to VM.sysExit]"); 2382 } 2383 if (runningVM) { 2384 Callbacks.notifyExit(value); 2385 VM.shutdown(value); 2386 } else { 2387 System.exit(value); 2388 } 2389 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 2390 } 2391 2392 /** 2393 * Shut down the virtual machine. 2394 * Should only be called if the VM is running. 2395 * @param value exit value 2396 */ 2397 @Uninterruptible 2398 public static void shutdown(int value) { 2399 handlePossibleRecursiveShutdown(); 2400 2401 if (VM.VerifyAssertions) VM._assert(VM.runningVM); 2402 sysCall.sysExit(value); 2403 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 2404 } 2405 2406 private static int inSysFail = 0; 2407 2408 public static boolean sysFailInProgress() { 2409 return inSysFail > 0; 2410 } 2411 2412 private static void handlePossibleRecursiveCallToSysFail(String message) { 2413 handlePossibleRecursiveExit("sysFail", ++inSysFail, message); 2414 } 2415 2416 private static void handlePossibleRecursiveCallToSysFail(String message, int number) { 2417 handlePossibleRecursiveExit("sysFail", ++inSysFail, message, number); 2418 } 2419 2420 private static int inSysExit = 0; 2421 2422 private static void handlePossibleRecursiveCallToSysExit() { 2423 handlePossibleRecursiveExit("sysExit", ++inSysExit); 2424 } 2425 2426 private static int inShutdown = 0; 2427 2428 /** Used only by VM.shutdown() */ 2429 private static void handlePossibleRecursiveShutdown() { 2430 handlePossibleRecursiveExit("shutdown", ++inShutdown); 2431 } 2432 2433 private static void handlePossibleRecursiveExit(String called, int depth) { 2434 handlePossibleRecursiveExit(called, depth, null); 2435 } 2436 2437 private static void handlePossibleRecursiveExit(String called, int depth, String message) { 2438 handlePossibleRecursiveExit(called, depth, message, false, -9999999); 2439 } 2440 2441 private static void handlePossibleRecursiveExit(String called, int depth, String message, int number) { 2442 handlePossibleRecursiveExit(called, depth, message, true, number); 2443 } 2444 2445 /** @param called Name of the function called: "sysExit", "sysFail", or 2446 * "shutdown". 2447 * @param depth How deep are we in that function? 2448 * @param message What message did it have? null means this particular 2449 * shutdown function does not come with a message. 2450 * @param showNumber Print <code>number</code> following 2451 * <code>message</code>? 2452 * @param number Print this number, if <code>showNumber</code> is {@code true}. */ 2453 private static void handlePossibleRecursiveExit(String called, int depth, String message, boolean showNumber, 2454 int number) { 2455 if (depth > 1 && 2456 (depth <= 2457 maxSystemTroubleRecursionDepth + VM.maxSystemTroubleRecursionDepthBeforeWeStopVMSysWrite)) { 2458 if (showNumber) { 2459 tsysWriteln("VM.", 2460 called, 2461 "(): We're in a", 2462 " (likely)", 2463 " recursive call to VM.", 2464 called, 2465 "(), ", 2466 depth, 2467 " deep\n", 2468 message == null ? "" : " ", 2469 message == null ? "" : called, 2470 message == null ? "" : " was called with the message: ", 2471 message == null ? "" : message, 2472 number); 2473 } else { 2474 tsysWriteln("VM.", 2475 called, 2476 "(): We're in a", 2477 " (likely)", 2478 " recursive call to VM.", 2479 called, 2480 "(), ", 2481 depth, 2482 " deep\n", 2483 message == null ? "" : " ", 2484 message == null ? "" : called, 2485 message == null ? "" : " was called with the message: ", 2486 message == null ? "" : message); 2487 } 2488 } 2489 if (depth > maxSystemTroubleRecursionDepth) { 2490 dieAbruptlyRecursiveSystemTrouble(); 2491 if (VM.VerifyAssertions) VM._assert(VM.NOT_REACHED); 2492 } 2493 } 2494 2495 /** Have we already called dieAbruptlyRecursiveSystemTrouble()? 2496 Only for use if we're recursively shutting down! Used by 2497 dieAbruptlyRecursiveSystemTrouble() only. */ 2498 2499 private static boolean inDieAbruptlyRecursiveSystemTrouble = false; 2500 2501 public static void dieAbruptlyRecursiveSystemTrouble() { 2502 if (!inDieAbruptlyRecursiveSystemTrouble) { 2503 inDieAbruptlyRecursiveSystemTrouble = true; 2504 sysWriteln("VM.dieAbruptlyRecursiveSystemTrouble(): Dying abruptly", 2505 "; we're stuck in a recursive shutdown/exit."); 2506 } 2507 /* Emergency death. */ 2508 sysCall.sysExit(EXIT_STATUS_RECURSIVELY_SHUTTING_DOWN); 2509 /* And if THAT fails, go into an infinite loop. Ugly, but it's better than 2510 returning from this function and leading to yet more cascading errors. 2511 and misleading error messages. (To the best of my knowledge, we have 2512 never yet reached this point.) */ 2513 while (true) { 2514 ; 2515 } 2516 } 2517 2518 //----------------// 2519 // implementation // 2520 //----------------// 2521 2522 /** 2523 * Create class instances needed for boot image or initialize classes 2524 * needed by tools. 2525 * @param bootstrapClasspath places where VM implementation class reside 2526 * @param bootCompilerArgs command line arguments to pass along to the 2527 * boot compiler's init routine. 2528 */ 2529 @Interruptible 2530 private static void init(String bootstrapClasspath, String[] bootCompilerArgs) { 2531 if (VM.VerifyAssertions) VM._assert(!VM.runningVM); 2532 2533 // create dummy boot record 2534 // 2535 BootRecord.the_boot_record = new BootRecord(); 2536 2537 // initialize type subsystem and classloader 2538 RVMClassLoader.init(bootstrapClasspath); 2539 2540 // initialize remaining subsystems needed for compilation 2541 // 2542 if (writingBootImage) { 2543 // initialize compiler that builds boot image 2544 BootImageCompiler.init(bootCompilerArgs); 2545 } 2546 RuntimeEntrypoints.init(); 2547 RVMThread.init(); 2548 } 2549 2550 public static void disableYieldpoints() { RVMThread.getCurrentThread().disableYieldpoints(); } 2551 public static void enableYieldpoints() { RVMThread.getCurrentThread().enableYieldpoints(); } 2552 2553 /** 2554 * The disableGC() and enableGC() methods are for use as guards to protect 2555 * code that must deal with raw object addresses in a collection-safe manner 2556 * (i.e. code that holds raw pointers across "gc-sites").<p> 2557 * 2558 * Authors of code running while GC is disabled must be certain not to 2559 * allocate objects explicitly via "new", or implicitly via methods that, 2560 * in turn, call "new" (such as string concatenation expressions that are 2561 * translated by the java compiler into String() and StringBuffer() 2562 * operations). Furthermore, to prevent deadlocks, code running with GC 2563 * disabled must not lock any objects. This means the code must not execute 2564 * any bytecodes that require runtime support (e.g. via RuntimeEntrypoints) 2565 * such as: 2566 * <ul> 2567 * <li>calling methods or accessing fields of classes that haven't yet 2568 * been loaded/resolved/instantiated 2569 * <li>calling synchronized methods 2570 * <li>entering synchronized blocks 2571 * <li>allocating objects with "new" 2572 * <li>throwing exceptions 2573 * <li>executing trap instructions (including stack-growing traps) 2574 * <li>storing into object arrays, except when runtime types of lhs & rhs 2575 * match exactly 2576 * <li>typecasting objects, except when runtime types of lhs & rhs 2577 * match exactly 2578 * </ul> 2579 * 2580 * <p> 2581 * Recommendation: as a debugging aid, Allocator implementations 2582 * should test "Thread.disallowAllocationsByThisThread" to verify that 2583 * they are never called while GC is disabled. 2584 */ 2585 @Inline 2586 @Unpreemptible("We may boost the size of the stack with GC disabled and may get preempted doing this") 2587 public static void disableGC() { 2588 disableGC(false); // Recursion is not allowed in this context. 2589 } 2590 2591 /** 2592 * disableGC: Disable GC if it hasn't already been disabled. This 2593 * enforces a stack discipline; we need it for the JNI Get*Critical and 2594 * Release*Critical functions. Should be matched with a subsequent call to 2595 * enableGC(). 2596 */ 2597 @Inline 2598 @Unpreemptible("We may boost the size of the stack with GC disabled and may get preempted doing this") 2599 public static void disableGC(boolean recursiveOK) { 2600 // current (non-GC) thread is going to be holding raw addresses, therefore we must: 2601 // 2602 // 1. make sure we have enough stack space to run until GC is re-enabled 2603 // (otherwise we might trigger a stack reallocation) 2604 // (We can't resize the stack if there's a native frame, so don't 2605 // do it and hope for the best) 2606 // 2607 // 2. force all other threads that need GC to wait until this thread 2608 // is done with the raw addresses 2609 // 2610 // 3. ensure that this thread doesn't try to allocate any objects 2611 // (because an allocation attempt might trigger a collection that 2612 // would invalidate the addresses we're holding) 2613 // 2614 2615 RVMThread myThread = RVMThread.getCurrentThread(); 2616 2617 // 0. Sanity Check; recursion 2618 int gcDepth = myThread.getDisableGCDepth(); 2619 if (VM.VerifyAssertions) VM._assert(gcDepth >= 0); 2620 gcDepth++; 2621 myThread.setDisableGCDepth(gcDepth); 2622 if (gcDepth > 1) { 2623 return; // We've already disabled it. 2624 } 2625 2626 // 1. 2627 // 2628 if (Magic.getFramePointer().minus(ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_GCDISABLED) 2629 .LT(myThread.stackLimit) && !myThread.hasNativeStackFrame()) { 2630 RVMThread.resizeCurrentStack(myThread.getStackLength()+ 2631 ArchitectureSpecific.StackframeLayoutConstants.STACK_SIZE_GCDISABLED, null); 2632 } 2633 2634 // 2. 2635 // 2636 myThread.disableYieldpoints(); 2637 2638 // 3. 2639 // 2640 if (VM.VerifyAssertions) { 2641 if (!recursiveOK) { 2642 VM._assert(!myThread.getDisallowAllocationsByThisThread()); // recursion not allowed 2643 } 2644 myThread.setDisallowAllocationsByThisThread(); 2645 } 2646 } 2647 2648 /** 2649 * enable GC; entry point when recursion is not OK. 2650 */ 2651 @Inline 2652 public static void enableGC() { 2653 enableGC(false); // recursion not OK. 2654 } 2655 2656 /** 2657 * enableGC(): Re-Enable GC if we're popping off the last 2658 * possibly-recursive {@link #disableGC} request. This enforces a stack discipline; 2659 * we need it for the JNI Get*Critical and Release*Critical functions. 2660 * Should be matched with a preceding call to {@link #disableGC}. 2661 */ 2662 @Inline 2663 public static void enableGC(boolean recursiveOK) { 2664 RVMThread myThread = RVMThread.getCurrentThread(); 2665 int gcDepth = myThread.getDisableGCDepth(); 2666 if (VM.VerifyAssertions) { 2667 VM._assert(gcDepth >= 1); 2668 VM._assert(myThread.getDisallowAllocationsByThisThread()); 2669 } 2670 gcDepth--; 2671 myThread.setDisableGCDepth(gcDepth); 2672 if (gcDepth > 0) { 2673 return; 2674 } 2675 2676 // Now the actual work of re-enabling GC. 2677 myThread.clearDisallowAllocationsByThisThread(); 2678 myThread.enableYieldpoints(); 2679 } 2680 2681 /** 2682 * Is this a build for 32bit addressing? NB. this method is provided 2683 * to give a hook to the IA32 assembler that won't be compiled away 2684 * by javac 2685 */ 2686 public static boolean buildFor32Addr() { 2687 return BuildFor32Addr; 2688 } 2689 2690 /** 2691 * Is this a build for SSE2? NB. this method is provided to give a 2692 * hook to the IA32 assembler that won't be compiled away by javac 2693 */ 2694 public static boolean buildForSSE2() { 2695 return BuildForSSE2; 2696 } 2697 } 2698