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