|
View:
New views
1 Messages
—
Rating Filter:
Alert me
|
|
|
SF.net SVN: jikesrvm:[14791] rvmroot/trunkRevision: 14791
http://jikesrvm.svn.sourceforge.net/jikesrvm/?rev=14791&view=rev Author: captain5050 Date: 2008-07-24 20:24:53 +0000 (Thu, 24 Jul 2008) Log Message: ----------- RVM-598: increase use of unpreemptible, in particular thread yield and locking code should be unpreemptible as it can cause a context switch. Modified Paths: -------------- rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Collection.java rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Strings.java rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/gcspy/Util.java rvmroot/trunk/rvm/src/org/jikesrvm/Services.java rvmroot/trunk/rvm/src/org/jikesrvm/VM.java rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/Organizer.java rvmroot/trunk/rvm/src/org/jikesrvm/classloader/RVMType.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineExceptionDeliverer.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/CompiledMethod.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/ExceptionTable.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/HardwareTrapCompiledMethod.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptCompiledMethod.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptSaveVolatile.java rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/ia32/OptExceptionDeliverer.java rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNICompiledMethod.java rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIEnvironment.java rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/CollectorThread.java rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/Handshake.java rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/ObjectModel.java rvmroot/trunk/rvm/src/org/jikesrvm/runtime/ExceptionDeliverer.java rvmroot/trunk/rvm/src/org/jikesrvm/runtime/RuntimeEntrypoints.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Processor.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/RVMThread.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Scheduler.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/ThinLock.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenLock.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenProcessor.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenScheduler.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenThread.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadEventWaitQueue.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadIOQueue.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadProcessWaitQueue.java rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/Wait.java Modified: rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Collection.java =================================================================== --- rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Collection.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Collection.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -12,28 +12,29 @@ */ package org.jikesrvm.mm.mmtk; -import org.mmtk.plan.Plan; -import org.mmtk.plan.CollectorContext; -import org.mmtk.plan.MutatorContext; -import org.mmtk.utility.Finalizer; -import org.mmtk.utility.options.Options; - +import org.jikesrvm.ArchitectureSpecific; import org.jikesrvm.VM; +import org.jikesrvm.classloader.Atom; +import org.jikesrvm.classloader.RVMMethod; import org.jikesrvm.compilers.common.CompiledMethod; import org.jikesrvm.compilers.common.CompiledMethods; +import org.jikesrvm.mm.mminterface.Selected; +import org.jikesrvm.mm.mminterface.CollectorThread; import org.jikesrvm.runtime.Magic; import org.jikesrvm.scheduler.Processor; +import org.jikesrvm.scheduler.RVMThread; import org.jikesrvm.scheduler.Scheduler; -import org.jikesrvm.scheduler.RVMThread; -import org.jikesrvm.ArchitectureSpecific; -import org.jikesrvm.classloader.Atom; -import org.jikesrvm.classloader.RVMMethod; -import org.jikesrvm.mm.mminterface.Selected; -import org.jikesrvm.mm.mminterface.CollectorThread; +import org.mmtk.plan.CollectorContext; +import org.mmtk.plan.MutatorContext; +import org.mmtk.plan.Plan; +import org.mmtk.utility.Finalizer; +import org.mmtk.utility.options.Options; +import org.vmmagic.pragma.Inline; +import org.vmmagic.pragma.Interruptible; +import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; +import org.vmmagic.unboxed.Address; -import org.vmmagic.unboxed.*; -import org.vmmagic.pragma.*; - @Uninterruptible public class Collection extends org.mmtk.vm.Collection implements org.mmtk.utility.Constants, org.jikesrvm.Constants { @@ -73,7 +74,7 @@ * @param why the reason why a collection was triggered. 0 to * <code>TRIGGER_REASONS - 1</code>. */ - @LogicallyUninterruptible + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public final void triggerCollection(int why) { triggerCollectionStatic(why); } @@ -81,7 +82,7 @@ /** * Joins a collection. */ - @LogicallyUninterruptible + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public final void joinCollection() { if (Options.verbose.getValue() >= 4) { VM.sysWriteln("Entered Collection.joinCollection(). Stack:"); @@ -101,7 +102,7 @@ * @param why the reason why a collection was triggered. 0 to * <code>TRIGGER_REASONS - 1</code>. */ - @LogicallyUninterruptible + @Unpreemptible("Change state of thread possibly context switching if generating exception") public static void triggerCollectionStatic(int why) { if (VM.VerifyAssertions) VM._assert((why >= 0) && (why < TRIGGER_REASONS)); @@ -135,7 +136,7 @@ * Check if there is an out of memory error waiting. */ @Inline - @LogicallyUninterruptible + @Unpreemptible("Exceptions may possibly cause yields") private static void checkForOutOfMemoryError(boolean afterCollection) { RVMThread myThread = Scheduler.getCurrentThread(); OutOfMemoryError oome = myThread.getOutOfMemoryError(); @@ -193,6 +194,7 @@ * Trigger an asynchronous collection, checking for memory * exhaustion first. */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public final void triggerAsyncCollection(int why) { Plan.setCollectionTriggered(); if (Options.verbose.getValue() >= 1) { @@ -313,6 +315,7 @@ * true if yielded. */ @Inline + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public boolean yieldpoint() { if (Processor.getCurrentProcessor().takeYieldpoint != 0) { RVMThread.yieldpointFromBackedge(); Modified: rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java =================================================================== --- rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/ReferenceProcessor.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -53,7 +53,7 @@ * Class fields */ - private static Lock lock = new Lock("ReferenceProcessor"); + private static final Lock lock = new Lock("ReferenceProcessor"); private static final ReferenceProcessor softReferenceProcessor = new ReferenceProcessor(Semantics.SOFT); @@ -202,6 +202,7 @@ * @param ref The reference to add */ @NoInline + @Unpreemptible("Non-preemptible but yield when table needs to be grown") private void addCandidate(Reference<?> ref, ObjectReference referent) { if (TRACE) { ObjectReference referenceAsAddress = ObjectReference.fromObject(ref); Modified: rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Strings.java =================================================================== --- rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Strings.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/Strings.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -18,7 +18,8 @@ import org.vmmagic.pragma.*; -@Uninterruptible public final class Strings extends org.mmtk.vm.Strings { +@Uninterruptible +public final class Strings extends org.mmtk.vm.Strings { /** * Log a message. * @@ -46,24 +47,28 @@ * <b>TODO:</b> There are special memory management semantics here that * someone should document. * - * @param src the source string + * @param str the source string * @param dst the destination array * @param dstBegin the start offset in the desination array * @param dstEnd the index after the last character in the * destination to copy to * @return the number of characters copied. */ - @LogicallyUninterruptible - public int copyStringToChars(String src, char [] dst, + public int copyStringToChars(String str, char [] dst, int dstBegin, int dstEnd) { - if (VM.runningVM) + if (VM.runningVM) { Processor.getCurrentProcessor().disableThreadSwitching("Disabled for MMTk string copy"); - int len = src.length(); - int n = (dstBegin + len <= dstEnd) ? len : (dstEnd - dstBegin); - for (int i = 0; i < n; i++) - Services.setArrayNoBarrier(dst, dstBegin + i, src.charAt(i)); - if (VM.runningVM) + } + char[] str_backing = java.lang.JikesRVMSupport.getBackingCharArray(str); + int str_length = java.lang.JikesRVMSupport.getStringLength(str); + int str_offset = java.lang.JikesRVMSupport.getStringOffset(str); + int n = (dstBegin + str_length <= dstEnd) ? str_length : (dstEnd - dstBegin); + for (int i = 0; i < n; i++) { + Services.setArrayNoBarrier(dst, dstBegin + i, str_backing[str_offset+i]); + } + if (VM.runningVM) { Processor.getCurrentProcessor().enableThreadSwitching(); + } return n; } } Modified: rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/gcspy/Util.java =================================================================== --- rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/gcspy/Util.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/MMTk/ext/vm/jikesrvm/org/jikesrvm/mm/mmtk/gcspy/Util.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -19,7 +19,6 @@ import org.jikesrvm.runtime.Magic; import static org.jikesrvm.runtime.SysCall.sysCall; -import org.jikesrvm.scheduler.Synchronization; import org.jikesrvm.classloader.RVMArray; import org.jikesrvm.objectmodel.ObjectModel; import org.jikesrvm.runtime.RuntimeEntrypoints; @@ -32,8 +31,8 @@ */ @Uninterruptible public class Util extends org.mmtk.vm.gcspy.Util implements Constants { private static final boolean DEBUG_ = false; - private static final int LOG_BYTES_IN_WORD = LOG_BYTES_IN_INT; - private static final int BYTES_IN_WORD = 1 << LOG_BYTES_IN_WORD; + public static final int KILOBYTE = 1024; + public static final int MEGABYTE = 1024 * 1024; /** * Allocate an array of bytes with malloc @@ -63,27 +62,6 @@ sysCall.sysFree(addr); } - - // From VM.java - @SuppressWarnings({"unused", "CanBeFinal", "UnusedDeclaration"}) // Accessed by native code - private static int sysWriteLock = 0; - private static Offset sysWriteLockOffset = Offset.max(); - - private static void swLock() { - if (org.jikesrvm.VM.BuildWithGCSpy) { - if (sysWriteLockOffset.isMax()) return; - while (!Synchronization.testAndSet(Magic.getJTOC(), sysWriteLockOffset, 1)) - ; - } - } - - private static void swUnlock() { - if (org.jikesrvm.VM.BuildWithGCSpy) { - if (sysWriteLockOffset.isMax()) return; - Synchronization.fetchAndStore(Magic.getJTOC(), sysWriteLockOffset, 0); - } - } - /** * Convert a String to a 0-terminated array of bytes * @@ -94,7 +72,7 @@ * which are interruptible. We protect these calls with a * swLock/swUnlock mechanism, as per VM.sysWrite on String */ - @LogicallyUninterruptible + @Unpreemptible public final Address getBytes(String str) { if (org.jikesrvm.VM.BuildWithGCSpy) { if (str == null) @@ -106,36 +84,20 @@ // Grab some memory sufficient to hold the null terminated string, // rounded up to an integral number of ints. - int len; - swLock(); - len = str.length(); - swUnlock(); - int size = ((len >>> LOG_BYTES_IN_WORD) + 1) << LOG_BYTES_IN_WORD; + char[] str_backing = java.lang.JikesRVMSupport.getBackingCharArray(str); + int str_length = java.lang.JikesRVMSupport.getStringLength(str); + int str_offset = java.lang.JikesRVMSupport.getStringOffset(str); + int size = (str_length + 4) & -4; Address rtn = malloc(size); - // Write the string into it, one word at a time, being carefull about endianism - for (int w = 0; w <= (len >>> LOG_BYTES_IN_WORD); w++) { - int value = 0; - int offset = w << LOG_BYTES_IN_WORD; - int shift = 0; - for (int b = 0; b < BYTES_IN_WORD; b++) { - byte byteVal = 0; - if (offset + b < len) { - swLock(); - byteVal = (byte) str.charAt(offset + b); // dodgy conversion! - swUnlock(); - } - // Endianism matters - if (org.jikesrvm.VM.BuildForIA32) { - value = (byteVal << shift) | value; - } else { - org.jikesrvm.VM._assert(org.jikesrvm.VM.NOT_REACHED); - value = (value << shift) | byteVal; // not tested - } - shift += BITS_IN_BYTE; - } - rtn.store(value, Offset.fromIntSignExtend(offset)); + // Write the string into it, one byte at a time (dodgy conversion) + for (int i=0; i < str_length; i++) { + rtn.store((byte)str_backing[str_offset+i], Offset.fromIntSignExtend(i)); } + // Zero rest of byte[] + for (int i=str_length; i < size; i++) { + rtn.store((byte)0, Offset.fromIntSignExtend(i-str_offset)); + } if (DEBUG_) { sysCall.sysWriteBytes(2/*SysTraceFd*/, rtn, size); Log.write("\n"); } @@ -145,9 +107,6 @@ } } - public static final int KILOBYTE = 1024; - public static final int MEGABYTE = 1024 * 1024; - /** * Pretty print a size, converting from bytes to kilo- or mega-bytes as appropriate * @@ -223,4 +182,3 @@ return 0; } } - Modified: rvmroot/trunk/rvm/src/org/jikesrvm/Services.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/Services.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/Services.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -21,6 +21,8 @@ import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.pragma.UninterruptibleNoWarn; +import org.vmmagic.pragma.Unpreemptible; +import org.vmmagic.pragma.UnpreemptibleNoWarn; import org.vmmagic.unboxed.Offset; /** @@ -434,4 +436,18 @@ else return src[index]; } + + @Unpreemptible("Creates arrays possibly causes scheduling") + public static String stringConcatenator(String... args) { + String result=""; + for (String s:args) { + result = stringConcatenate(result, s); + } + return result; + } + + @UnpreemptibleNoWarn("Creates arrays possibly causes scheduling, no warning on call to string API") + public static String stringConcatenate(String a, String b) { + return a.concat(b); + } } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/VM.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/VM.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/VM.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -50,10 +50,11 @@ import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.Interruptible; -import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.pragma.UninterruptibleNoWarn; +import org.vmmagic.pragma.Unpreemptible; +import org.vmmagic.pragma.UnpreemptibleNoWarn; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Extent; import org.vmmagic.unboxed.ObjectReference; @@ -982,15 +983,22 @@ } } - @LogicallyUninterruptible @NoInline /* don't waste code space inlining these --dave */ public static void writeField(int fieldWidth, String s) { write(s); - int len = s.length(); + int len = getStringLength(s); while (fieldWidth > len++) write(" "); } + @UninterruptibleNoWarn("Interruptible code not reachable at runtime") + private static int getStringLength(String s) { + if (VM.runningVM) { + return java.lang.JikesRVMSupport.getStringLength(s); + } else { + return s.length(); + } + } /** * Low level print to console. * @param value print value and left-fill with enough spaces to print at least fieldWidth characters @@ -2158,8 +2166,8 @@ * Exit virtual machine. * @param value value to pass to host o/s */ - @LogicallyUninterruptible /* TODO: This is completely wrong. This method is very much Interruptible */ @NoInline + @UnpreemptibleNoWarn public static void sysExit(int value) { handlePossibleRecursiveCallToSysExit(); if (Options.stackTraceAtExit) { @@ -2185,6 +2193,7 @@ * Should only be called if the VM is running. * @param value exit value */ + @Uninterruptible public static void shutdown(int value) { handlePossibleRecursiveShutdown(); @@ -2381,7 +2390,7 @@ * they are never called while gc is disabled. */ @Inline - @Interruptible + @Unpreemptible("We may boost the size of the stack with GC disabled and may get preempted doing this") public static void disableGC() { disableGC(false); // Recursion is not allowed in this context. } @@ -2393,7 +2402,7 @@ * enableGC(). */ @Inline - @Interruptible + @Unpreemptible("We may boost the size of the stack with GC disabled and may get preempted doing this") public static void disableGC(boolean recursiveOK) { // current (non-gc) thread is going to be holding raw addresses, therefore we must: // Modified: rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/Organizer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/Organizer.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/adaptive/measurements/organizers/Organizer.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -18,6 +18,7 @@ import org.jikesrvm.scheduler.greenthreads.GreenThreadQueue; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; /** * An Organizer acts an an intermediary between the low level @@ -84,7 +85,7 @@ * listener uses its own protocol to ensure that exactly 1 * thread will attempt to activate the organizer. */ - @Uninterruptible + @Unpreemptible private void passivate() { if (listener != null) { if (VM.VerifyAssertions) VM._assert(!listener.isActive()); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/classloader/RVMType.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/classloader/RVMType.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/classloader/RVMType.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -296,6 +296,18 @@ } /** + * Instance of java.lang.Class corresponding to this type. + * This is commonly used for reflection. + */ + @Uninterruptible + public final Class<?> getResolvedClassForType() { + // Resolve the class so that we don't need to resolve it + // in reflection code + if (VM.VerifyAssertions) VM._assert(VM.runningVM && isResolved()); + return classForType; + } + + /** * Get offset of tib slot from start of jtoc, in bytes. */ @Uninterruptible Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/BaselineCompiledMethod.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -30,6 +30,7 @@ import org.jikesrvm.runtime.StackBrowser; import org.vmmagic.pragma.SynchronizedObject; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Offset; /** @@ -161,6 +162,7 @@ return exceptionDeliverer; } + @Unpreemptible public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) { if (eTable == null) { return -1; @@ -298,6 +300,7 @@ } /** Get the lock acquisition offset */ + @Uninterruptible public Offset getLockAcquisitionOffset() { return Offset.fromIntZeroExtend(lockOffset); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineCompilerImpl.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -119,6 +119,7 @@ /** * The last true local */ + @Uninterruptible public static int getEmptyStackOffset(NormalMethod m) { return getFirstLocalOffset(m) - (m.getLocalWords() << LG_WORDSIZE) + WORDSIZE; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineExceptionDeliverer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineExceptionDeliverer.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/baseline/ia32/BaselineExceptionDeliverer.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -24,6 +24,7 @@ import org.jikesrvm.scheduler.Processor; import org.jikesrvm.scheduler.Scheduler; import org.jikesrvm.scheduler.RVMThread; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -37,6 +38,7 @@ * Pass control to a catch block. */ @Override + @Unpreemptible("Deliver exception possibly from unpreemptible code") public void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, ArchitectureSpecific.Registers registers) { Address fp = registers.getInnermostFramePointer(); @@ -78,6 +80,7 @@ /** * Unwind a stackframe. */ + @Unpreemptible("Unwind stack possibly from unpreemptible code") public void unwindStackFrame(CompiledMethod compiledMethod, ArchitectureSpecific.Registers registers) { NormalMethod method = (NormalMethod) compiledMethod.getMethod(); Address fp = registers.getInnermostFramePointer(); @@ -88,7 +91,7 @@ if (instr.sGT(lockOffset)) { // we actually have the lock, so must unlock it. Object lock; if (method.isStatic()) { - lock = method.getDeclaringClass().getClassForType(); + lock = method.getDeclaringClass().getResolvedClassForType(); } else { lock = Magic.addressAsObject(fp.plus(BaselineCompilerImpl.locationToOffset(((BaselineCompiledMethod) compiledMethod).getGeneralLocalLocation( @@ -107,5 +110,3 @@ registers.unwindStackFrame(); } } - - Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/CompiledMethod.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/CompiledMethod.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/CompiledMethod.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -27,6 +27,7 @@ import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.SynchronizedObject; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; import org.vmmagic.unboxed.Word; @@ -426,6 +427,7 @@ * gc disabled when called by RuntimeEntrypoints.deliverException(). * </ul> */ + @Unpreemptible public abstract int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType); /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/ExceptionTable.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/ExceptionTable.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/ExceptionTable.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -17,6 +17,7 @@ import org.jikesrvm.classloader.DynamicTypeCheck; import org.jikesrvm.classloader.RVMType; import org.jikesrvm.objectmodel.TIB; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Offset; /** @@ -42,6 +43,7 @@ * @param exceptionType the type of exception that was raised * @return the machine code offset of the catch block. */ + @Unpreemptible public static int findCatchBlockForInstruction(int[] eTable, Offset instructionOffset, RVMType exceptionType) { for (int i = 0, n = eTable.length; i < n; i += 4) { // note that instructionOffset points to the instruction after the PEI Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/HardwareTrapCompiledMethod.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/HardwareTrapCompiledMethod.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/common/HardwareTrapCompiledMethod.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -20,6 +20,7 @@ import org.jikesrvm.runtime.StackBrowser; import org.vmmagic.pragma.SynchronizedObject; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Offset; /** @@ -52,6 +53,7 @@ return null; } + @Unpreemptible public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) { return -1; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptCompiledMethod.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptCompiledMethod.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptCompiledMethod.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -41,6 +41,7 @@ import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.SynchronizedObject; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Offset; /** @@ -84,7 +85,7 @@ /** * Find "catch" block for a machine instruction of this method. */ - @Interruptible + @Unpreemptible public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) { if (eTable == null) { return -1; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptSaveVolatile.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptSaveVolatile.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/OptSaveVolatile.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -21,7 +21,7 @@ import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.SaveVolatile; -import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -37,7 +37,7 @@ * @see org.jikesrvm.compilers.opt.driver.OptimizingCompiler (hooks to recognize & specially compile this class) */ @SaveVolatile -@Uninterruptible +@Unpreemptible("Yield methods shouldn't be preempted") public class OptSaveVolatile { /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/ia32/OptExceptionDeliverer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/ia32/OptExceptionDeliverer.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/compilers/opt/runtimesupport/ia32/OptExceptionDeliverer.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -23,6 +23,7 @@ import org.jikesrvm.scheduler.Processor; import org.jikesrvm.scheduler.Scheduler; import org.jikesrvm.scheduler.RVMThread; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -38,6 +39,7 @@ /** * Pass control to a catch block. */ + @Unpreemptible("Deliver exception possibly from unpreemptible code") public void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, Registers registers) { OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod; @@ -116,6 +118,7 @@ /** * Unwind a stackframe. */ + @Unpreemptible("Unwind stack possibly from unpreemptible code") public void unwindStackFrame(CompiledMethod compiledMethod, Registers registers) { Address fp = registers.getInnermostFramePointer(); OptCompiledMethod optMethod = (OptCompiledMethod) compiledMethod; @@ -154,4 +157,3 @@ } } } - Modified: rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNICompiledMethod.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNICompiledMethod.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNICompiledMethod.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -21,6 +21,7 @@ import org.jikesrvm.runtime.StackBrowser; import org.vmmagic.pragma.SynchronizedObject; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Offset; /** @@ -67,6 +68,7 @@ return false; } + @Unpreemptible public int findCatchBlockForInstruction(Offset instructionOffset, RVMType exceptionType) { return -1; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIEnvironment.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIEnvironment.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/jni/JNIEnvironment.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -19,6 +19,7 @@ import org.jikesrvm.scheduler.Processor; import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.pragma.Untraced; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.AddressArray; @@ -27,7 +28,7 @@ /** * A JNIEnvironment is created for each Java thread. */ -public class JNIEnvironment implements SizeConstants { +public final class JNIEnvironment implements SizeConstants { /** * initial size for JNI refs, later grow as needed @@ -179,6 +180,7 @@ * terminating a thread that has a JNI environment allocated to it. * @param env the JNIEnvironment to deallocate */ + @Unpreemptible("Deallocate environment but may contend with environment being allocated") public static synchronized void deallocateEnvironment(JNIEnvironment env) { env.next = pool; pool = env; @@ -188,27 +190,27 @@ * accessor methods */ @Uninterruptible - public final boolean hasNativeStackFrame() { + public boolean hasNativeStackFrame() { return alwaysHasNativeFrame || JNIRefsTop != 0; } @Uninterruptible - public final Address topJavaFP() { + public Address topJavaFP() { return JNITopJavaFP; } @Uninterruptible - public final AddressArray refsArray() { + public AddressArray refsArray() { return JNIRefs; } @Uninterruptible - public final int refsTop() { + public int refsTop() { return JNIRefsTop; } @Uninterruptible - public final int savedRefsFP() { + public int savedRefsFP() { return JNIRefsSavedFP; } @@ -219,7 +221,7 @@ * @param ref the object to put on stack * @return offset of entry in JNIRefs stack */ - public final int pushJNIRef(Object ref) { + public int pushJNIRef(Object ref) { if (ref == null) { return 0; } @@ -252,7 +254,7 @@ * @param offset in JNIRefs stack * @return reference at that offset */ - public final Object getJNIRef(int offset) { + public Object getJNIRef(int offset) { if (offset > JNIRefsTop) { VM.sysWrite("JNI ERROR: getJNIRef for illegal offset > TOP, "); VM.sysWrite(offset); @@ -272,7 +274,7 @@ * Remove a reference from the JNIRefs stack. * @param offset in JNIRefs stack */ - public final void deleteJNIRef(int offset) { + public void deleteJNIRef(int offset) { if (offset > JNIRefsTop) { VM.sysWrite("JNI ERROR: getJNIRef for illegal offset > TOP, "); VM.sysWrite(offset); @@ -290,7 +292,7 @@ * Dump the JNIRefs stack to the sysWrite stream */ @Uninterruptible - public final void dumpJniRefsStack() { + public void dumpJniRefsStack() { int jniRefOffset = JNIRefsTop; VM.sysWrite("\n* * dump of JNIEnvironment JniRefs Stack * *\n"); VM.sysWrite("* JNIRefs = "); @@ -316,7 +318,7 @@ * to the Java caller; clear the exception by recording null * @param e An exception or error */ - public final void recordException(Throwable e) { + public void recordException(Throwable e) { // don't overwrite the first exception except to clear it if (pendingException == null || e == null) { pendingException = e; @@ -326,7 +328,7 @@ /** * @return the pending exception */ - public final Throwable getException() { + public Throwable getException() { return pendingException; } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/CollectorThread.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/CollectorThread.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/CollectorThread.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -36,6 +36,7 @@ import org.vmmagic.pragma.NoOptCompile; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -280,7 +281,7 @@ * * @param handshake Handshake for the requested collection */ - @Uninterruptible + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void asyncCollect(Handshake handshake, int why) { handshake.requestAndContinue(why); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/Handshake.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/Handshake.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/Handshake.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -20,6 +20,7 @@ import org.jikesrvm.scheduler.greenthreads.GreenThread; import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; /** * Handshake handles mutator requests to initiate a collection, and @@ -82,7 +83,7 @@ * caller continues until it yields to the GC. It may thus make * this call at an otherwise unsafe point. */ - @Uninterruptible + @Unpreemptible("Change state of thread possibly context switching if generating exception") public void requestAndContinue(int why) { request(why); } @@ -119,7 +120,7 @@ * for the collection. They reside in the thread dispatch queues of their * processors, until the collector threads re-enable thread switching. */ - @Uninterruptible + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") private void initiateCollection() { /* check that scheduler initialization is complete */ @@ -174,7 +175,7 @@ * * @return The number of GC threads. */ - @Uninterruptible + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") private int waitForPrecedingGC() { /* * Get the number of GC threads. Include NativeDaemonProcessor @@ -228,7 +229,7 @@ * * @return true if the completion flag is not already set. */ - @Uninterruptible + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") private boolean request(int why) { lock.acquire(); if (completionFlag) { @@ -274,5 +275,3 @@ lock.release(); } } - - Modified: rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/mm/mminterface/MemoryManager.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -55,6 +55,8 @@ import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.Pure; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; +import org.vmmagic.pragma.UnpreemptibleNoWarn; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Extent; import org.vmmagic.unboxed.ObjectReference; @@ -669,7 +671,7 @@ * See also: bytecode 0xbc ("newarray") and 0xbd ("anewarray") */ @Inline - @Interruptible + @Unpreemptible public static Object allocateArray(int numElements, int logElementSize, int headerSize, TIB tib, int allocator, int align, int offset, int site) { int elemBytes = numElements << logElementSize; @@ -688,7 +690,7 @@ * so it can be forced out of line. */ @NoInline - @Interruptible + @UnpreemptibleNoWarn private static void throwLargeArrayOutOfMemoryError() { throw new OutOfMemoryError(); } @@ -819,7 +821,7 @@ * @return The stack */ @Inline - @Interruptible + @Unpreemptible public static byte[] newStack(int bytes, boolean immortal) { if (!VM.runningVM) { return new byte[bytes]; Modified: rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/JavaHeader.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -29,6 +29,7 @@ import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.ObjectReference; import org.vmmagic.unboxed.Offset; @@ -576,6 +577,7 @@ /** * Generic lock */ + @Unpreemptible("Become another thread when lock is contended, don't preempt in other cases") public static void genericLock(Object o) { ThinLock.lock(o, STATUS_OFFSET); } @@ -583,6 +585,7 @@ /** * Generic unlock */ + @Unpreemptible("No interruption unless of exceptions") public static void genericUnlock(Object o) { ThinLock.unlock(o, STATUS_OFFSET); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/ObjectModel.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/ObjectModel.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/objectmodel/ObjectModel.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -26,6 +26,7 @@ import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Extent; import org.vmmagic.unboxed.ObjectReference; @@ -462,6 +463,7 @@ * Generic lock */ @Entrypoint + @Unpreemptible("Become another thread when lock is contended, don't preempt in other cases") public static void genericLock(Object o) { JavaHeader.genericLock(o); } @@ -470,6 +472,7 @@ * Generic unlock */ @Entrypoint + @Unpreemptible("No preemption normally, but may raise exceptions") public static void genericUnlock(Object o) { JavaHeader.genericUnlock(o); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/runtime/ExceptionDeliverer.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/runtime/ExceptionDeliverer.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/runtime/ExceptionDeliverer.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -14,6 +14,7 @@ import org.jikesrvm.ArchitectureSpecific.Registers; import org.jikesrvm.compilers.common.CompiledMethod; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; /** @@ -59,6 +60,7 @@ * @param registers registers to be loaded before passing control to * catch block */ + @Unpreemptible("Deliver exception possibly from unpreemptible code") public abstract void deliverException(CompiledMethod compiledMethod, Address catchBlockInstructionAddress, Throwable exceptionObject, Registers registers); @@ -82,5 +84,6 @@ * @param registers thread state to be updated by restoring non-volatiles * and unwinding the stackframe */ + @Unpreemptible("Unwind stack possibly from unpreemptible code") public abstract void unwindStackFrame(CompiledMethod compiledMethod, Registers registers); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/runtime/RuntimeEntrypoints.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/runtime/RuntimeEntrypoints.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/runtime/RuntimeEntrypoints.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -36,6 +36,8 @@ import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.Pure; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; +import org.vmmagic.pragma.UnpreemptibleNoWarn; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -583,6 +585,7 @@ */ @NoInline @Entrypoint + @Unpreemptible("Deliver exception possibly from unpreemptible code") public static void athrow(Throwable exceptionObject) { RVMThread myThread = Scheduler.getCurrentThread(); Registers exceptionRegisters = myThread.getExceptionRegisters(); @@ -923,6 +926,7 @@ * <li> <em> or </em> current thread is terminated if no catch block is found * </ul> */ + @Unpreemptible("Deliver exception trying to avoid preemption") private static void deliverException(Throwable exceptionObject, Registers exceptionRegisters) { if (VM.TraceExceptionDelivery) { VM.sysWriteln("RuntimeEntrypoints.deliverException() entered; just got an exception object."); @@ -966,11 +970,14 @@ VM.sysWriteln("RuntimeEntrypoints.deliverException() found no catch block."); } /* No appropriate catch block found. */ + handleUncaughtException(exceptionObject); + } + @UnpreemptibleNoWarn("Uncaught exception handling that may cause preemption") + private static void handleUncaughtException(Throwable exceptionObject) { Scheduler.getCurrentThread().handleUncaughtException(exceptionObject); } - /** * Skip over all frames below currfp with saved code pointers outside of heap * (C frames), stopping at the native frame immediately preceding the glue @@ -1030,6 +1037,7 @@ * invokers save/restore any nonvolatiles, so we're probably ok. * --dave 6/29/01 */ + @Uninterruptible private static void unwindInvisibleStackFrame(Registers registers) { registers.unwindStackFrame(); } Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Processor.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Processor.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Processor.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -22,6 +22,7 @@ import org.vmmagic.pragma.Inline; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.pragma.Untraced; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -358,6 +359,7 @@ * Note: This method is ONLY intended for use by Thread. * @param timerTick timer interrupted if true */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public abstract void dispatch(boolean timerTick); /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/RVMThread.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/RVMThread.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -38,11 +38,12 @@ import org.vmmagic.pragma.BaselineSaveLSRegisters; import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Interruptible; -import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.NoOptCompile; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; +import org.vmmagic.pragma.UnpreemptibleNoWarn; import org.vmmagic.pragma.Untraced; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -556,8 +557,8 @@ * @param oldState the previous thread state * @param newState the new thread state */ - @LogicallyUninterruptible @Entrypoint + @UnpreemptibleNoWarn("Change state of thread possibly context switching if generating exception") protected final void changeThreadState(State oldState, State newState) { if (trace) { VM.sysWrite("Thread.changeThreadState: thread=", threadSlot, name); @@ -568,8 +569,15 @@ if (state == oldState) { state = newState; } else { - throw new IllegalThreadStateException("Illegal thread state change from " + - oldState + " to " + newState + " when in state " + state + " in thread " + name); + throw new IllegalThreadStateException( + Services.stringConcatenator("Illegal thread state change from ", + java.lang.JikesRVMSupport.getEnumName(oldState), + " to ", + java.lang.JikesRVMSupport.getEnumName(newState), + " when in state ", + java.lang.JikesRVMSupport.getEnumName(state), + " in thread ", + name)); } } @@ -644,6 +652,7 @@ * Update internal state of Thread and Scheduler to indicate that * a thread is about to start */ + @Unpreemptible("Exceptions may possibly cause yields") public final void registerThread() { changeThreadState(State.NEW, State.RUNNABLE); registerThreadInternal(); @@ -801,6 +810,7 @@ // OSR_BaselineExecStateExtractor.java, should then restore all non-volatiles before stack replacement //todo fix this -- related to SaveVolatile @Entrypoint + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void yieldpointFromPrologue() { Address fp = Magic.getFramePointer(); org.jikesrvm.scheduler.greenthreads.GreenThread.yieldpoint(PROLOGUE, fp); @@ -816,6 +826,7 @@ // OSR_BaselineExecStateExtractor.java, should then restore all non-volatiles before stack replacement // TODO fix this -- related to SaveVolatile @Entrypoint + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void yieldpointFromBackedge() { Address fp = Magic.getFramePointer(); org.jikesrvm.scheduler.greenthreads.GreenThread.yieldpoint(BACKEDGE, fp); @@ -831,6 +842,7 @@ // OSR_BaselineExecStateExtractor.java, should then restore all non-volatiles before stack replacement // TODO fix this -- related to SaveVolatile @Entrypoint + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void yieldpointFromEpilogue() { Address fp = Magic.getFramePointer(); org.jikesrvm.scheduler.greenthreads.GreenThread.yieldpoint(EPILOGUE, fp); @@ -849,7 +861,7 @@ * Suspend execution of current thread until it is resumed. * Call only if caller has appropriate security clearance. */ - @LogicallyUninterruptible + @Unpreemptible("Exceptions may possibly cause yields") public final void suspend() { Throwable rethrow = null; changeThreadState(State.RUNNABLE, State.SUSPENDED); @@ -967,8 +979,7 @@ * @param o the object synchronized on * @param millis the number of milliseconds to wait for notification */ - @LogicallyUninterruptible - /* only loses control at expected points -- I think -dave */ + @Interruptible public static void wait(Object o, long millis) { if (STATS) timedWaitOperations++; RVMThread t = Scheduler.getCurrentThread(); @@ -992,15 +1003,16 @@ */ protected abstract void notifyAllInternal(Object o, Lock l); - @LogicallyUninterruptible - private static void raiseIllegalMonitorStateException(String msg, Object o) { - throw new IllegalMonitorStateException(msg + o); + @UnpreemptibleNoWarn("Possible context when generating exception") + public static void raiseIllegalMonitorStateException(String msg, Object o) { + throw new IllegalMonitorStateException(Services.stringConcatenate(msg, o.toString())); } /** * Support for Java {@link java.lang.Object#notify()} synchronization primitive. * * @param o the object synchronized on */ + @Interruptible public static void notify(Object o) { if (STATS) notifyOperations++; Lock l = ObjectModel.getHeavyLock(o, false); @@ -1018,6 +1030,7 @@ * @param o the object synchronized on * @see java.lang.Object#notifyAll */ + @Interruptible public static void notifyAll(Object o) { if (STATS) notifyAllOperations++; Scheduler.LockModel l = (Scheduler.LockModel)ObjectModel.getHeavyLock(o, false); @@ -1041,7 +1054,6 @@ /** * Deliver the throwable stopping/interrupting this thread */ - @LogicallyUninterruptible public void kill(Throwable cause, boolean throwImmediately) { // yield() will notice the following and take appropriate action this.causeOfThreadDeath = cause; @@ -1141,7 +1153,6 @@ /** * Get this thread's index in {@link Scheduler#threads}[]. */ - @LogicallyUninterruptible public final int getIndex() { if (VM.VerifyAssertions) VM._assert((state == State.TERMINATED) || Scheduler.threads[threadSlot] == this); return threadSlot; @@ -1163,7 +1174,7 @@ * @param exceptionRegisters register state at which stack overflow trap * was encountered (null --> normal method call, not a trap) */ - @Interruptible + @Unpreemptible public static void resizeCurrentStack(int newSize, Registers exceptionRegisters) { if (traceAdjustments) VM.sysWrite("Thread: resizeCurrentStack\n"); if (MemoryManager.gcInProgress()) { @@ -1560,18 +1571,22 @@ /** * Throw the external interrupt associated with the thread now it is running */ - @LogicallyUninterruptible + @Unpreemptible("Exceptions may possibly cause yields") protected final void postExternalInterrupt() { throwInterruptWhenScheduled = false; Throwable t = causeOfThreadDeath; causeOfThreadDeath = null; if (t instanceof InterruptedException && t != proxyInterruptException) { - t.fillInStackTrace(); + fillInStackTrace(t); } state = State.RUNNABLE; RuntimeEntrypoints.athrow(t); } + @UnpreemptibleNoWarn("Call out to API possibly losing control") + private static void fillInStackTrace(Throwable t) { + t.fillInStackTrace(); + } /** * Was this thread interrupted? * @return whether the thread has been interrupted Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Scheduler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Scheduler.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/Scheduler.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -32,9 +32,10 @@ import org.jikesrvm.scheduler.greenthreads.GreenScheduler; import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Interruptible; -import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.UninterruptibleNoWarn; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; @@ -151,16 +152,9 @@ * <b>Assumption:</b> call is guarded by threadCreationMutex. * @return the thread slot assigned this thread */ - @LogicallyUninterruptible static int assignThreadSlot(RVMThread thread) { if (!VM.runningVM) { - // create primordial thread (in boot image) - int threadSlot = Scheduler.PRIMORDIAL_THREAD_INDEX; - Scheduler.threads[threadSlot] = (ThreadModel)thread; - // note that Scheduler.threadAllocationIndex (search hint) - // is out of date - Scheduler.numActiveThreads ++; - return PRIMORDIAL_THREAD_INDEX; + return bootImageAssignThreadSlot(thread); } else { Scheduler.threadCreationMutex.lock("thread creation mutex"); for (int cnt = threads.length; --cnt >= 1;) { @@ -197,6 +191,16 @@ } } + @UninterruptibleNoWarn("Only called when writing the boot image") + private static int bootImageAssignThreadSlot(RVMThread thread) { + // create primordial thread (in boot image) + int threadSlot = Scheduler.PRIMORDIAL_THREAD_INDEX; + Scheduler.threads[threadSlot] = (ThreadModel)thread; + // note that Scheduler.threadAllocationIndex (search hint) + // is out of date + Scheduler.numActiveThreads ++; + return PRIMORDIAL_THREAD_INDEX; + } /** * Release this thread's threads[] slot. * Assumption: call is guarded by threadCreationMutex. @@ -265,11 +269,13 @@ /** * Schedule another thread */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected abstract void yieldInternal(); /** * Schedule another thread */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void yield() { getScheduler().yieldInternal(); } @@ -318,11 +324,9 @@ getScheduler().bootInternal(); } /** Scheduler specific sysExit shutdown */ - @Interruptible protected abstract void sysExitInternal(); /** Scheduler specific sysExit shutdown */ - @Interruptible public static void sysExit() { getScheduler().sysExitInternal(); } @@ -657,19 +661,22 @@ /** * Dump stack of calling thread, starting at callers frame */ - @LogicallyUninterruptible public static void dumpStack() { if (VM.runningVM) { dumpStack(Magic.getFramePointer()); } else { - StackTraceElement[] elements = - (new Throwable("--traceback from Jikes RVM's Scheduler class--")).getStackTrace(); - for (StackTraceElement element: elements) { - System.err.println(element.toString()); - } + bootImageDumpStack(); } } + @UninterruptibleNoWarn("Only called when writing the boot image") + private static void bootImageDumpStack() { + StackTraceElement[] elements = + (new Throwable("--traceback from Jikes RVM's Scheduler class--")).getStackTrace(); + for (StackTraceElement element: elements) { + System.err.println(element.toString()); + } + } /** * Dump state of a (stopped) thread's stack. * @param fp address of starting frame. first frame output Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/ThinLock.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/ThinLock.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -20,9 +20,9 @@ import org.jikesrvm.runtime.Magic; import org.vmmagic.pragma.Entrypoint; import org.vmmagic.pragma.Inline; -import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; import org.vmmagic.unboxed.Word; @@ -74,6 +74,7 @@ */ @Inline @Entrypoint + @Unpreemptible("Become another thread when lock is contended, don't preempt in other cases") static void inlineLock(Object o, Offset lockOffset) { Word old = Magic.prepareWord(o, lockOffset); if (old.rshl(TL_THREAD_ID_SHIFT).isZero()) { @@ -100,6 +101,7 @@ */ @Inline @Entrypoint + @Unpreemptible("No preemption normally, but may raise exceptions") static void inlineUnlock(Object o, Offset lockOffset) { Word old = Magic.prepareWord(o, lockOffset); Word threadId = Word.fromIntZeroExtend(Processor.getCurrentProcessor().threadId); @@ -121,6 +123,7 @@ * @param lockOffset the offset of the thin lock word in the object. */ @NoInline + @Unpreemptible("Become another thread when lock is contended, don't preempt in other cases") public static void lock(Object o, Offset lockOffset) { major: while (true) { // repeat only if attempt to lock a promoted lock fails @@ -197,6 +200,7 @@ * @param lockOffset the offset of the thin lock word in the object. */ @NoInline + @Unpreemptible("No preemption normally, but may raise exceptions") public static void unlock(Object o, Offset lockOffset) { Magic.sync(); // prevents stale data from being seen by next owner of the lock while (true) { // spurious contention detected @@ -212,7 +216,7 @@ Scheduler.trace("Lock", "unlock error: thin lock word = ", old.toAddress()); Scheduler.trace("Lock", "unlock error: thin lock word = ", Magic.objectAsAddress(o)); // Scheduler.trace("Lock", Thread.getCurrentThread().toString(), 0); - raiseIllegalMonitorStateException("thin unlocking", o); + RVMThread.raiseIllegalMonitorStateException("thin unlocking", o); } if (old.and(TL_LOCK_COUNT_MASK).isZero()) { // get count, 0 is the last lock Word changed = old.and(TL_UNLOCK_MASK); @@ -230,11 +234,6 @@ } } - @LogicallyUninterruptible - private static void raiseIllegalMonitorStateException(String msg, Object o) { - throw new IllegalMonitorStateException(msg + o); - } - //////////////////////////////////////////////////////////////// /// Support for inflating (and deflating) heavy-weight locks /// //////////////////////////////////////////////////////////////// Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenLock.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenLock.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenLock.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -19,8 +19,8 @@ import org.jikesrvm.scheduler.Scheduler; import org.jikesrvm.scheduler.ThinLock; import org.jikesrvm.scheduler.RVMThread; -import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Offset; @Uninterruptible @@ -56,6 +56,7 @@ * @return true, if the lock succeeds; false, otherwise */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public final boolean lockHeavy(Object o) { if (tentativeMicrolocking) { if (!mutex.tryLock()) { @@ -103,7 +104,7 @@ Processor mine = Processor.getCurrentProcessor(); if (ownerId != mine.threadId) { mutex.unlock(); // thread-switching benign - raiseIllegalMonitorStateException("heavy unlocking", o); + RVMThread.raiseIllegalMonitorStateException("heavy unlocking", o); } recursionCount--; if (0 < recursionCount) { @@ -149,11 +150,6 @@ free(this); } - @LogicallyUninterruptible - private static void raiseIllegalMonitorStateException(String msg, Object o) { - throw new IllegalMonitorStateException(msg + o); - } - /** * Is this lock blocking thread t? */ Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenProcessor.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenProcessor.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenProcessor.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -24,16 +24,16 @@ import org.jikesrvm.scheduler.ProcessorLock; import org.jikesrvm.scheduler.Scheduler; import org.vmmagic.pragma.Inline; -import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Offset; /** * Multiplex execution of large number of Threads on small * number of o/s kernel threads. */ -@Uninterruptible +@Uninterruptible("Default to uninterruptibility avoid unforeseen yieldpoints") @NonMoving public final class GreenProcessor extends Processor { @@ -283,6 +283,7 @@ * @param timerTick timer interrupted if true */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public void dispatch(boolean timerTick) { // no processor locks should be held across a thread switch if (VM.VerifyAssertions) checkLockCount(0); @@ -327,6 +328,7 @@ /** * Handle a request from the garbage collector to flush the mutator context. */ + @Unpreemptible("Explicitly schedule other threads, don't preempt at the same time") private void processMutatorFlushRequest() { GreenScheduler.flushMutatorContextsMutex.lock("handling flush request"); /* One context per processor under green threads */ @@ -575,8 +577,7 @@ return true; } - @LogicallyUninterruptible - /* GACK --dave */ + @Unpreemptible public void dumpProcessorState() { VM.sysWrite("Processor "); VM.sysWriteInt(id); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenScheduler.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenScheduler.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenScheduler.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -36,6 +36,7 @@ import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.Uninterruptible; import org.vmmagic.pragma.UninterruptibleNoWarn; +import org.vmmagic.pragma.Unpreemptible; /** * Global variables used to implement virtual machine thread scheduler. @@ -386,6 +387,7 @@ * @see org.jikesrvm.mm.mmtk.Collection */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected void requestMutatorFlushInternal() { flushMutatorContextsMutex.lock("requesting mutator flush"); flushedMutatorCount = 0; @@ -449,6 +451,7 @@ * Dump state of virtual machine. */ @Override + @Unpreemptible public void dumpVirtualMachineInternal() { GreenProcessor processor; VM.sysWrite("\n-- Processors --\n"); @@ -515,7 +518,7 @@ /** Scheduler specific sysExit shutdown */ @Override - @Interruptible + @Uninterruptible protected void sysExitInternal() { Wait.disableIoWait(); // we can't depend on thread switching being enabled } @@ -620,11 +623,13 @@ * Schedule another thread */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected void yieldInternal() { GreenThread.yield(); } @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected void suspendDebuggerThreadInternal() { debugRequested = false; debuggerMutex.lock("debugger queue mutex"); @@ -635,6 +640,7 @@ * Suspend a concurrent worker: it will resume when the garbage collector notifies. */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected void suspendConcurrentCollectorThreadInternal() { concurrentCollectorMutex.lock("suspend concurrent collector thread mutex"); GreenScheduler.getCurrentThread().yield(concurrentCollectorQueue, concurrentCollectorMutex); @@ -645,6 +651,7 @@ * places objects on the finalizer queue and notifies. */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected void suspendFinalizerThreadInternal() { finalizerMutex.lock("suspend finalizer mutex"); GreenScheduler.getCurrentThread().yield(finalizerQueue, finalizerMutex); @@ -655,6 +662,7 @@ * @param lock the lock to allow other thread chance to acquire */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected void yieldToOtherThreadWaitingOnLockInternal(Lock lock) { GreenLock l = (GreenLock)lock; GreenScheduler.getCurrentThread().yield(l.entering, l.mutex); // thread-switching benign Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenThread.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenThread.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/GreenThread.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -30,17 +30,17 @@ import org.jikesrvm.scheduler.Synchronization; import org.jikesrvm.scheduler.RVMThread; import org.vmmagic.pragma.Interruptible; -import org.vmmagic.pragma.LogicallyUninterruptible; import org.vmmagic.pragma.NoInline; import org.vmmagic.pragma.NonMoving; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; import org.vmmagic.unboxed.Address; import org.vmmagic.unboxed.Offset; /** * A green thread's Java execution context */ -@Uninterruptible +@Uninterruptible("Default to uninterruptibility avoid unforeseen yieldpoints") @NonMoving public class GreenThread extends RVMThread { /** Offset of the lock field controlling the suspending of a thread */ @@ -167,6 +167,7 @@ * Precondition: If the queue is global, caller must have the appropriate mutex. * @param q the ThreadQueue on which to enqueue this thread. */ + @Interruptible public final void start(GreenThreadQueue q) { registerThread(); q.enqueue(this); @@ -179,6 +180,7 @@ * Thread is blocked on a heavyweight lock * @see Lock#lockHeavy(Object) */ + @Unpreemptible("Exceptions may possibly cause yields") public final void block(ThreadQueue entering, ProcessorLock mutex) { yield(entering, mutex); } @@ -196,6 +198,7 @@ * May result in threadswitch, depending on state of various control * flags on the processor object. */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void yieldpoint(int whereFrom, Address yieldpointServiceMethodFP) { boolean threadSwitch = false; boolean cbsOverrun = false; @@ -374,6 +377,7 @@ * * @param whereFrom backedge, prologue, epilogue? */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void timerTickYield(int whereFrom) { GreenThread myThread = GreenScheduler.getCurrentThread(); // thread switch @@ -387,6 +391,7 @@ * Suspend execution of current thread, in favor of some other thread. */ @NoInline + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void yield() { GreenThread myThread = GreenScheduler.getCurrentThread(); myThread.beingDispatched = true; @@ -400,6 +405,7 @@ * @param l lock guarding that queue (currently locked) */ @NoInline + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public final void yield(AbstractThreadQueue q, ProcessorLock l) { if (VM.VerifyAssertions) VM._assert(this == GreenScheduler.getCurrentThread()); if (state == State.RUNNABLE) @@ -417,6 +423,7 @@ * @param newState state to change to */ @NoInline + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public final void yield(ProcessorLock l, State newState) { changeThreadState(State.RUNNABLE, newState); beingDispatched = true; @@ -436,6 +443,7 @@ * @param l2 the {@link ProcessorLock} guarding <code>q2</code> (currently locked) */ @NoInline + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") private static void yield(ThreadProxyWaitingQueue q1, ProcessorLock l1, ThreadProxyWakeupQueue q2, ProcessorLock l2) { GreenThread myThread = GreenScheduler.getCurrentThread(); @@ -447,6 +455,7 @@ morph(false); } + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") static void morph() { morph(false); } @@ -455,7 +464,7 @@ * Current thread has been placed onto some queue. Become another thread. * @param timerTick timer interrupted if true */ - @LogicallyUninterruptible + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") static void morph(boolean timerTick) { Magic.sync(); // to ensure beingDispatched flag written out to memory if (trace) Scheduler.trace("GreenThread", "morph "); @@ -480,6 +489,7 @@ * not guarded with a lock) */ @NoInline + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void yield(AbstractThreadQueue q) { GreenThread myThread = GreenScheduler.getCurrentThread(); myThread.beingDispatched = true; @@ -507,6 +517,7 @@ * Uninterruptible portion of going to sleep * @return were we interrupted prior to going to sleep */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") private boolean sleepImpl(ThreadProxy proxy) { if (isInterrupted()) { // we were interrupted before putting this thread to sleep @@ -575,8 +586,9 @@ return t; } /** - * Uninterruptible portion of waiting + * Unpreemptible portion of waiting */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") private Throwable waitImpl(Object o, GreenLock l, boolean hasTimeout, long millis, ThreadProxy proxy) { // Check thread isn't already in interrupted state if (isInterrupted()) { @@ -688,6 +700,7 @@ * @param waitData the wait data specifying the file descriptor(s) * to wait for. */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void ioWaitImpl(ThreadIOWaitData waitData) { GreenThread myThread = GreenScheduler.getCurrentThread(); myThread.waitData = waitData; @@ -702,6 +715,7 @@ * @param process the <code>Process</code> object associated * with the process */ + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public static void processWaitImpl(ThreadProcessWaitData waitData, VMProcess process) { GreenThread myThread = GreenScheduler.getCurrentThread(); myThread.waitData = waitData; @@ -725,6 +739,7 @@ * Thread model dependent part of stopping/interrupting a thread */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected final void killInternal() { // remove this thread from wakeup and/or waiting queue ThreadProxy p = threadProxy; @@ -747,6 +762,7 @@ * Thread model dependent part of thread suspension */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") protected final void suspendInternal() { if(Synchronization.tryCompareAndSwap(this, suspendPendingOffset, 0, 1)) { // successful change from no suspend pending to suspend pending @@ -755,6 +771,7 @@ } if (this == GreenScheduler.getCurrentThread()) yield(); } + /** * Thread model dependent part of thread resumption */ @@ -791,6 +808,7 @@ * Park the thread for OSR. */ @Override + @Unpreemptible("Becoming another thread interrupts the current thread, avoid preemption in the process") public void osrPark() { osrParkLock.lock("locking in osrPark"); if (osrParkingPermit) { @@ -805,6 +823,7 @@ * Unpark the thread from OSR. */ @Override + @Unpreemptible("No preemption normally, but may raise exceptions") public void osrUnpark() { boolean schedule=false; osrParkLock.lock("locking in osrUnpark"); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadEventWaitQueue.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadEventWaitQueue.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadEventWaitQueue.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -17,6 +17,7 @@ import org.jikesrvm.scheduler.RVMThread; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; /** * Queue of threads waiting for a specific kind of event to occur. @@ -204,7 +205,7 @@ /** * Dump state for debugging. */ - @Interruptible + @Unpreemptible void dump() { dump(" "); } @@ -212,7 +213,7 @@ /** * Dump state for debugging. */ - @Interruptible + @Unpreemptible void dump(String prefix) { VM.sysWrite(prefix); for (GreenThread t = head; t != null; t = t.getNext()) { @@ -226,7 +227,7 @@ * Dump description of what given thread is waiting for. * For debugging. */ - @Interruptible + @Unpreemptible abstract void dumpWaitDescription(GreenThread thread); /** Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadIOQueue.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadIOQueue.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadIOQueue.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -17,6 +17,7 @@ import org.jikesrvm.scheduler.ProcessorLock; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; /** * A list of threads waiting for i/o data to become available. @@ -35,12 +36,6 @@ public final class ThreadIOQueue extends ThreadEventWaitQueue implements ThreadEventConstants, ThreadIOConstants { - // Note: this class was modified by David Hovemeyer - // for Extreme Blue 2002 to implement it as a subclass of - // ThreadEventWaitQueue, as part of making a more general - // interface for event notification. It also now supports - // waiting on sets of file descriptors. - /** * Class to safely downcast from <code>ThreadEventWaitData</code> * to <code>ThreadIOWaitData</code>. @@ -49,7 +44,7 @@ * code. */ @Uninterruptible - private static class WaitDataDowncaster extends ThreadEventWaitDataVisitor { + private static final class WaitDataDowncaster extends ThreadEventWaitDataVisitor { private ThreadIOWaitData waitData; @@ -297,11 +292,14 @@ } } + /** Downcaster for dumping */ + private static final WaitDataDowncaster downcaster = new WaitDataDowncaster(); + /** * Dump text description of what given thread is waiting for. * For debugging. */ - @Interruptible + @Unpreemptible @Override void dumpWaitDescription(GreenThread thread) { // Safe downcast from ThreadEventWaitData to ThreadIOWaitData. @@ -309,9 +307,11 @@ // locking (and thus execute concurrently with other methods), do NOT // use the queue's private downcaster object. Instead, create one // from scratch. - WaitDataDowncaster downcaster = new WaitDataDowncaster(); - thread.waitData.accept(downcaster); - ThreadIOWaitData waitData = downcaster.waitData; + ThreadIOWaitData waitData; + synchronized(downcaster) { + thread.waitData.accept(downcaster); + waitData = downcaster.waitData; + } if (VM.VerifyAssertions) VM._assert(waitData == thread.waitData); VM.sysWrite("(R"); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadProcessWaitQueue.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadProcessWaitQueue.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/ThreadProcessWaitQueue.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -18,6 +18,7 @@ import org.jikesrvm.scheduler.ProcessorLock; import org.vmmagic.pragma.Interruptible; import org.vmmagic.pragma.Uninterruptible; +import org.vmmagic.pragma.Unpreemptible; /** * A wait queue for threads that are waiting for a process @@ -61,7 +62,7 @@ * code. */ @Uninterruptible - private static class WaitDataDowncaster extends ThreadEventWaitDataVisitor { + private static final class WaitDataDowncaster extends ThreadEventWaitDataVisitor { public ThreadProcessWaitData waitData; @@ -229,11 +230,14 @@ return ready; } + /** Downcaster for dumping */ + private static final WaitDataDowncaster downcaster = new WaitDataDowncaster(); + /** * Dump text description of what given thread is waiting for. * For debugging. */ - @Interruptible + @Unpreemptible @Override void dumpWaitDescription(GreenThread thread) { // Safe downcast from ThreadEventWaitData to ThreadProcessWaitData. @@ -241,9 +245,11 @@ // locking (and thus execute concurrently with other methods), do NOT // use the queue's private downcaster object. Instead, create one // from scratch. - WaitDataDowncaster downcaster = new WaitDataDowncaster(); - thread.waitData.accept(downcaster); - ThreadProcessWaitData waitData = downcaster.waitData; + ThreadProcessWaitData waitData; + synchronized(downcaster) { + thread.waitData.accept(downcaster); + waitData = downcaster.waitData; + } if (VM.VerifyAssertions) VM._assert(waitData == thread.waitData); VM.sysWrite("pid=", waitData.pid); Modified: rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/Wait.java =================================================================== --- rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/Wait.java 2008-07-24 20:20:47 UTC (rev 14790) +++ rvmroot/trunk/rvm/src/org/jikesrvm/scheduler/greenthreads/Wait.java 2008-07-24 20:24:53 UTC (rev 14791) @@ -15,6 +15,7 @@ import org.jikesrvm.runtime.Time; import org.jikesrvm.scheduler.Processor; import org.jikesrvm.scheduler.Scheduler; +import org.vmmagic.pragma.Uninterruptible; /** * A collection of static methods for waiting on some type of event. @@ -31,6 +32,7 @@ * The reason is that we can't be sure that thread switching * is possible during shutdown. */ + @Uninterruptible public static void disableIoWait() { noIoWait = true; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. ------------------------------------------------------------------------- This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK & win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100&url=/ _______________________________________________ Jikesrvm-commits mailing list Jikesrvm-commits@... https://lists.sourceforge.net/lists/listinfo/jikesrvm-commits |
| Free Forum Powered by Nabble | Forum Help |