use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.
the class RuntimeEntrypoints method athrow.
// ---------------------------------------------------------------//
// Exception Handling. //
// ---------------------------------------------------------------//
/**
* Deliver a software exception to current java thread.
* @param exceptionObject exception object to deliver
* (null --> deliver NullPointerException).
* does not return
* (stack is unwound and execution resumes in a catch block)
*
* This method is public so that it can be invoked by java.lang.VMClass.
*/
@NoInline
@Entrypoint
@Unpreemptible("Deliver exception possibly from unpreemptible code")
public static void athrow(Throwable exceptionObject) {
if (traceAthrow) {
VM.sysWriteln("in athrow.");
RVMThread.dumpStack();
}
RVMThread myThread = RVMThread.getCurrentThread();
AbstractRegisters exceptionRegisters = myThread.getExceptionRegisters();
// VM.enableGC() is called when the exception is delivered.
VM.disableGC();
Magic.saveThreadState(exceptionRegisters);
exceptionRegisters.setInUse(true);
deliverException(exceptionObject, exceptionRegisters);
}
use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.
the class RuntimeEntrypoints method deliverHardwareException.
/**
* Deliver a hardware exception to current java thread.
* <p>
* Does not return.
* (stack is unwound, starting at trap site, and
* execution resumes in a catch block somewhere up the stack)
* /or/ execution resumes at instruction following trap
* (for TRAP_STACK_OVERFLOW)
*
* <p> Note: Control reaches here by the actions of an
* external "C" signal handler
* which saves the register state of the trap site into the
* "exceptionRegisters" field of the current
* Thread object.
* The signal handler also inserts a <hardware trap> frame
* onto the stack immediately above this frame, for use by
* HardwareTrapGCMapIterator during garbage collection.
*
* @param trapCode code indicating kind of exception that was trapped
* (see TRAP_xxx, above)
* @param trapInfo array subscript (for array bounds trap, only), marker
* (for stack overflow traps on PPC) or
*/
@Entrypoint
@UnpreemptibleNoWarn
static void deliverHardwareException(int trapCode, Word trapInfo) {
if (VM.verboseSignalHandling)
VM.sysWriteln("delivering hardware exception");
RVMThread myThread = RVMThread.getCurrentThread();
if (VM.verboseSignalHandling)
VM.sysWriteln("we have a thread = ", Magic.objectAsAddress(myThread));
if (VM.verboseSignalHandling)
VM.sysWriteln("it's in state = ", myThread.getExecStatus());
AbstractRegisters exceptionRegisters = myThread.getExceptionRegisters();
if (VM.verboseSignalHandling)
VM.sysWriteln("we have exception registers = ", Magic.objectAsAddress(exceptionRegisters));
if ((trapCode == TRAP_STACK_OVERFLOW || trapCode == TRAP_JNI_STACK) && myThread.getStack().length < (StackFrameLayout.getMaxStackSize() >> LOG_BYTES_IN_ADDRESS) && !myThread.hasNativeStackFrame()) {
// (C trap handler has set register.ip to the instruction following the trap).
if (trapCode == TRAP_JNI_STACK) {
RVMThread.resizeCurrentStack(myThread.getStackLength() + StackFrameLayout.getJNIStackGrowthSize(), exceptionRegisters);
} else {
RVMThread.resizeCurrentStack(myThread.getStackLength() + StackFrameLayout.getStackGrowthSize(), exceptionRegisters);
}
if (VM.VerifyAssertions)
VM._assert(exceptionRegisters.getInUse());
exceptionRegisters.setInUse(false);
Magic.restoreHardwareExceptionState(exceptionRegisters);
if (VM.VerifyAssertions)
VM._assert(NOT_REACHED);
}
// GC stress testing
if (canForceGC()) {
// VM.sysWriteln("FORCING GC: in deliverHardwareException");
System.gc();
}
// Hardware traps in uninterruptible code should be considered hard failures.
if (!VM.sysFailInProgress()) {
Address fp = exceptionRegisters.getInnermostFramePointer();
int compiledMethodId = Magic.getCompiledMethodID(fp);
if (compiledMethodId != StackFrameLayout.getInvisibleMethodID()) {
CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(compiledMethodId);
Address ip = exceptionRegisters.getInnermostInstructionAddress();
Offset instructionOffset = compiledMethod.getInstructionOffset(ip);
if (compiledMethod.isWithinUninterruptibleCode(instructionOffset)) {
VM.sysWriteln();
switch(trapCode) {
case TRAP_NULL_POINTER:
VM.sysWriteln("Fatal error: NullPointerException within uninterruptible region.");
break;
case TRAP_ARRAY_BOUNDS:
VM.sysWriteln("Fatal error: ArrayIndexOutOfBoundsException within uninterruptible region (index was ", trapInfo.toInt(), ").");
break;
case TRAP_DIVIDE_BY_ZERO:
VM.sysWriteln("Fatal error: DivideByZero within uninterruptible region.");
break;
case TRAP_STACK_OVERFLOW:
case TRAP_JNI_STACK:
VM.sysWriteln("Fatal error: StackOverflowError within uninterruptible region.");
break;
case TRAP_CHECKCAST:
VM.sysWriteln("Fatal error: ClassCastException within uninterruptible region.");
break;
case TRAP_MUST_IMPLEMENT:
VM.sysWriteln("Fatal error: IncompatibleClassChangeError within uninterruptible region.");
break;
case TRAP_STORE_CHECK:
VM.sysWriteln("Fatal error: ArrayStoreException within uninterruptible region.");
break;
case TRAP_UNREACHABLE_BYTECODE:
VM.sysWriteln("Fatal error: Reached a bytecode that was determined to be unreachable within uninterruptible region.");
break;
default:
VM.sysWriteln("Fatal error: Unknown hardware trap within uninterruptible region.");
break;
}
VM.sysWriteln("trapCode = ", trapCode);
VM.sysWriteln("trapInfo = ", trapInfo.toAddress());
VM.sysFail("Exiting virtual machine due to uninterruptibility violation.");
}
}
}
Throwable exceptionObject;
switch(trapCode) {
case TRAP_NULL_POINTER:
exceptionObject = new java.lang.NullPointerException();
break;
case TRAP_ARRAY_BOUNDS:
exceptionObject = new java.lang.ArrayIndexOutOfBoundsException(trapInfo.toInt());
break;
case TRAP_DIVIDE_BY_ZERO:
exceptionObject = new java.lang.ArithmeticException();
break;
case TRAP_STACK_OVERFLOW:
case TRAP_JNI_STACK:
exceptionObject = new java.lang.StackOverflowError();
break;
case TRAP_CHECKCAST:
exceptionObject = new java.lang.ClassCastException();
break;
case TRAP_MUST_IMPLEMENT:
exceptionObject = new java.lang.IncompatibleClassChangeError();
break;
case TRAP_STORE_CHECK:
exceptionObject = new java.lang.ArrayStoreException();
break;
case TRAP_UNREACHABLE_BYTECODE:
exceptionObject = new java.lang.InternalError(UNREACHABLE_BC_MESSAGE);
break;
default:
exceptionObject = new java.lang.UnknownError();
RVMThread.traceback("UNKNOWN ERROR");
break;
}
// VM.enableGC() is called when the exception is delivered.
VM.disableGC();
deliverException(exceptionObject, exceptionRegisters);
}
use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.
the class StackTrace method countFramesUninterruptible.
/**
* Walk the stack counting the number of stack frames encountered.
* The stack being walked is our stack, so code is Uninterruptible to stop the
* stack moving.
*
* @param stackTraceThread the thread whose stack is walked
* @return number of stack frames encountered
*/
@Uninterruptible
@NoInline
private int countFramesUninterruptible(RVMThread stackTraceThread) {
int stackFrameCount = 0;
Address fp;
/* Stack trace for the thread */
if (stackTraceThread == RVMThread.getCurrentThread()) {
fp = Magic.getFramePointer();
} else {
AbstractRegisters contextRegisters = stackTraceThread.getContextRegisters();
fp = contextRegisters.getInnermostFramePointer();
}
fp = Magic.getCallerFramePointer(fp);
while (Magic.getCallerFramePointer(fp).NE(StackFrameLayout.getStackFrameSentinelFP())) {
int compiledMethodId = Magic.getCompiledMethodID(fp);
if (compiledMethodId != StackFrameLayout.getInvisibleMethodID()) {
CompiledMethod compiledMethod = CompiledMethods.getCompiledMethod(compiledMethodId);
if ((compiledMethod.getCompilerType() != CompiledMethod.TRAP) && compiledMethod.hasBridgeFromNativeAnnotation()) {
// skip native frames, stopping at last native frame preceeding the
// Java To C transition frame
fp = RuntimeEntrypoints.unwindNativeStackFrame(fp);
}
}
stackFrameCount++;
fp = Magic.getCallerFramePointer(fp);
}
// VM.sysWriteln("stack frame count = ",stackFrameCount);
return stackFrameCount;
}
use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.
the class ScanThread method scanThread.
/**
*********************************************************************
*
* Thread scanning
*/
/**
* Scan a thread, placing the addresses of pointers into supplied buffers.
*
* @param thread The thread to be scanned
* @param trace The trace instance to use for reporting references.
* @param processCodeLocations Should code locations be processed?
* @param newRootsSufficient Is a partial stack scan sufficient, or must we do a full scan?
*/
public static void scanThread(RVMThread thread, TraceLocal trace, boolean processCodeLocations, boolean newRootsSufficient) {
if (DEFAULT_VERBOSITY >= 1) {
VM.sysWriteln("scanning ", thread.getThreadSlot());
}
/* get the gprs associated with this thread */
AbstractRegisters regs = thread.getContextRegisters();
Address gprs = Magic.objectAsAddress(regs.getGPRs());
Address ip = regs.getInnermostInstructionAddress();
Address fp = regs.getInnermostFramePointer();
regs.clear();
regs.setInnermost(ip, fp);
scanThread(thread, trace, processCodeLocations, gprs, Address.zero(), newRootsSufficient);
}
use of org.jikesrvm.architecture.AbstractRegisters in project JikesRVM by JikesRVM.
the class ScanThread method getHWExceptionRegisters.
/**
* When an exception occurs, registers are saved temporarily. If
* the stack being scanned is in this state, we need to scan those
* registers for code pointers. If the codeLocations deque is null,
* then scanning for code pointers is not required, so we don't need
* to do anything. (SB: Why only code pointers?).
* <p>
* Dave G: The contents of the GPRs of the exceptionRegisters
* are handled during normal stack scanning
* (@see org.jikesrvm.runtime.compilers.common.HardwareTrapCompiledMethod.
* It looks to me like the main goal of this method is to ensure that the
* method in which the trap happened isn't treated as dead code and collected
* (if it's been marked as obsolete, we are setting its activeOnStackFlag below).
*/
private void getHWExceptionRegisters() {
AbstractRegisters exReg = thread.getExceptionRegisters();
if (processCodeLocations && exReg.getInUse()) {
Address ip = exReg.getIP();
CompiledMethod compiledMethod = CompiledMethods.findMethodForInstruction(ip);
if (VM.VerifyAssertions) {
VM._assert(compiledMethod != null);
VM._assert(compiledMethod.containsReturnAddress(ip));
}
compiledMethod.setActiveOnStack();
ObjectReference code = ObjectReference.fromObject(compiledMethod.getEntryCodeArray());
Address ipLoc = exReg.getIPLocation();
if (VM.VerifyAssertions)
VM._assert(ip.EQ(ipLoc.loadAddress()));
processCodeLocation(code, ipLoc);
}
}
Aggregations