Search in sources :

Example 6 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class VMThreadMXBeanImpl method getThreadInfoForId.

/**
 * Returns a {@link java.lang.management.ThreadInfo}
 * object for the given thread id with a stack trace to
 * the given depth (0 for empty, Integer.MAX_VALUE for
 * full).
 *
 * @param id the id of the thread whose info should be returned.
 * @param maxDepth the depth of the stack trace.
 * @return a {@link java.lang.management.ThreadInfo} instance.
 */
static ThreadInfo getThreadInfoForId(long id, int maxDepth) {
    Thread thread = getThreadForId(id);
    Constructor<ThreadInfo> cons = null;
    try {
        // ensure class is at least resolved
        Class.forName("java.lang.management.ThreadInfo");
        cons = ThreadInfo.class.getDeclaredConstructor(Long.TYPE, String.class, Thread.State.class, Long.TYPE, Long.TYPE, String.class, Long.TYPE, String.class, Long.TYPE, Long.TYPE, Boolean.TYPE, Boolean.TYPE, StackTraceElement[].class, MonitorInfo[].class, LockInfo[].class);
        cons.setAccessible(true);
        RVMThread rvmThread = JikesRVMSupport.getThread(thread);
        // TODO number of times blocked for Java monitors
        long blockedCount = 0;
        // TODO total time blocked for Java monitors
        long blockedTime = 0;
        long waitingCount = JMXSupport.getWaitingCount(rvmThread);
        long waitingTime = JMXSupport.getWaitingTime(rvmThread);
        boolean inNative = JMXSupport.isInNative(rvmThread);
        boolean suspended = JMXSupport.isSuspended(rvmThread);
        StackTraceElement[] stackTrace;
        if (maxDepth == 0) {
            stackTrace = null;
        } else {
            stackTrace = JMXSupport.getStackTraceForThread(rvmThread);
            int newMax = Math.min(stackTrace.length, maxDepth);
            StackTraceElement[] reducedStackTrace = new StackTraceElement[newMax];
            int srcPos = stackTrace.length - newMax;
            System.arraycopy(stackTrace, srcPos, reducedStackTrace, 0, newMax);
            stackTrace = reducedStackTrace;
        }
        MonitorInfo[] emptyMonitorInfo = new MonitorInfo[0];
        LockInfo[] emptyLockInfo = new LockInfo[0];
        return cons.newInstance(id, thread.getName(), thread.getState(), blockedCount, blockedTime, null, -1, null, waitingCount, waitingTime, inNative, suspended, stackTrace, emptyMonitorInfo, emptyLockInfo);
    } catch (NoSuchMethodException e) {
        throw (Error) new InternalError("Couldn't get ThreadInfo constructor").initCause(e);
    } catch (InstantiationException e) {
        throw (Error) new InternalError("Couldn't create ThreadInfo").initCause(e);
    } catch (IllegalAccessException e) {
        throw (Error) new InternalError("Couldn't access ThreadInfo").initCause(e);
    } catch (InvocationTargetException e) {
        throw (Error) new InternalError("ThreadInfo's constructor threw an exception").initCause(e);
    } catch (ClassNotFoundException e) {
        throw (Error) new InternalError("Problem resolving ThreadInfo").initCause(e);
    }
}
Also used : MonitorInfo(java.lang.management.MonitorInfo) RVMThread(org.jikesrvm.scheduler.RVMThread) InvocationTargetException(java.lang.reflect.InvocationTargetException) RVMThread(org.jikesrvm.scheduler.RVMThread) ThreadInfo(java.lang.management.ThreadInfo) LockInfo(java.lang.management.LockInfo)

Example 7 with RVMThread

use of org.jikesrvm.scheduler.RVMThread 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 --&gt; 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);
}
Also used : RVMThread(org.jikesrvm.scheduler.RVMThread) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters) Unpreemptible(org.vmmagic.pragma.Unpreemptible) Entrypoint(org.vmmagic.pragma.Entrypoint) NoInline(org.vmmagic.pragma.NoInline)

Example 8 with RVMThread

use of org.jikesrvm.scheduler.RVMThread 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 &lt;hardware trap&gt; 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);
}
Also used : Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) AbstractRegisters(org.jikesrvm.architecture.AbstractRegisters) Entrypoint(org.vmmagic.pragma.Entrypoint) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset) Entrypoint(org.vmmagic.pragma.Entrypoint) UnpreemptibleNoWarn(org.vmmagic.pragma.UnpreemptibleNoWarn)

Example 9 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class CodeInstaller method install.

public static boolean install(ExecutionState state, CompiledMethod cm) {
    RVMThread thread = state.getThread();
    byte[] stack = thread.getStack();
    Offset tsfromFPOffset = state.getTSFPOffset();
    Offset fooFPOffset = state.getFPOffset();
    int foomid = Magic.getIntAtOffset(stack, fooFPOffset.plus(STACKFRAME_METHOD_ID_OFFSET));
    CompiledMethod foo = CompiledMethods.getCompiledMethod(foomid);
    int cType = foo.getCompilerType();
    // this offset is used to adjust SP to FP right after return
    // from a call. 1 stack slot for return address and
    // 1 stack slot for saved FP of tsfrom.
    Offset sp2fpOffset = fooFPOffset.minus(tsfromFPOffset).minus(2 * BYTES_IN_STACKSLOT);
    // should given an estimated length, and print the instructions
    // for debugging
    Assembler asm = new Assembler(50, VM.TraceOnStackReplacement);
    // 1. generate bridge instructions to recover saved registers
    if (cType == CompiledMethod.BASELINE) {
        // unwind stack pointer, SP is FP now
        if (VM.BuildFor32Addr) {
            asm.emitADD_Reg_Imm(SP, sp2fpOffset.toInt());
        } else {
            asm.emitADD_Reg_Imm_Quad(SP, sp2fpOffset.toInt());
        }
        asm.generateJTOCloadWord(S0, cm.getOsrJTOCoffset());
        // restore saved EDI
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_RegDisp(EDI, SP, EDI_SAVE_OFFSET);
        } else {
            asm.emitMOV_Reg_RegDisp_Quad(EDI, SP, EDI_SAVE_OFFSET);
        }
        // restore saved EBX
        if (VM.BuildFor32Addr) {
            asm.emitMOV_Reg_RegDisp(EBX, SP, EBX_SAVE_OFFSET);
        } else {
            asm.emitMOV_Reg_RegDisp_Quad(EBX, SP, EBX_SAVE_OFFSET);
        }
        // restore frame pointer
        asm.emitPOP_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
        // do not pop return address and parameters,
        // we make a faked call to newly compiled method
        asm.emitJMP_Reg(S0);
    } else if (cType == CompiledMethod.OPT) {
        // /////////////////////////////////////////////////
        // recover saved registers from foo's stack frame
        // /////////////////////////////////////////////////
        OptCompiledMethod fooOpt = (OptCompiledMethod) foo;
        // foo definitely not save volatile
        boolean saveVolatile = fooOpt.isSaveVolatile();
        if (VM.VerifyAssertions) {
            VM._assert(!saveVolatile);
        }
        // assume SP is on foo's stack frame,
        int firstNonVolatile = fooOpt.getFirstNonVolatileGPR();
        int nonVolatiles = fooOpt.getNumberOfNonvolatileGPRs();
        int nonVolatileOffset = fooOpt.getUnsignedNonVolatileOffset();
        for (int i = firstNonVolatile; i < firstNonVolatile + nonVolatiles; i++) {
            if (VM.BuildFor32Addr) {
                asm.emitMOV_Reg_RegDisp(NONVOLATILE_GPRS[i], SP, sp2fpOffset.minus(nonVolatileOffset));
            } else {
                asm.emitMOV_Reg_RegDisp_Quad(NONVOLATILE_GPRS[i], SP, sp2fpOffset.minus(nonVolatileOffset));
            }
            nonVolatileOffset += BYTES_IN_STACKSLOT;
        }
        // adjust SP to frame pointer
        if (VM.BuildFor32Addr) {
            asm.emitADD_Reg_Imm(SP, sp2fpOffset.toInt());
        } else {
            asm.emitADD_Reg_Imm_Quad(SP, sp2fpOffset.toInt());
        }
        // restore frame pointer
        asm.emitPOP_RegDisp(TR, ArchEntrypoints.framePointerField.getOffset());
        // branch to the newly compiled instructions
        asm.generateJTOCjmp(cm.getOsrJTOCoffset());
    }
    if (VM.TraceOnStackReplacement) {
        VM.sysWrite("new CM instr addr ");
        VM.sysWriteHex(Statics.getSlotContentsAsAddress(cm.getOsrJTOCoffset()));
        VM.sysWriteln();
        VM.sysWrite("JTOC register ");
        VM.sysWriteHex(Magic.getTocPointer());
        VM.sysWriteln();
        VM.sysWrite("Thread register ");
        VM.sysWriteHex(Magic.objectAsAddress(Magic.getThreadRegister()));
        VM.sysWriteln();
        VM.sysWriteln("tsfromFPOffset ", tsfromFPOffset);
        VM.sysWriteln("fooFPOffset ", fooFPOffset);
        VM.sysWriteln("SP + ", sp2fpOffset.plus(BYTES_IN_STACKSLOT));
    }
    // 3. set thread flags
    thread.isWaitingForOsr = true;
    thread.bridgeInstructions = asm.getMachineCodes();
    thread.fooFPOffset = fooFPOffset;
    thread.tsFPOffset = tsfromFPOffset;
    Address bridgeaddr = Magic.objectAsAddress(thread.bridgeInstructions);
    Memory.sync(bridgeaddr, thread.bridgeInstructions.length() << LG_INSTRUCTION_WIDTH);
    AOSLogging.logger.logOsrEvent("OSR code installation succeeded");
    return true;
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) Assembler(org.jikesrvm.compilers.common.assembler.ia32.Assembler) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Example 10 with RVMThread

use of org.jikesrvm.scheduler.RVMThread in project JikesRVM by JikesRVM.

the class DynamicLibrary method load.

/**
 * Load a dynamic library
 * @param libName the name of the library to load.
 * @return 0 on failure, 1 on success
 */
public static synchronized int load(String libName) {
    DynamicLibrary dl = dynamicLibraries.get(libName);
    if (dl != null) {
        // success: already loaded
        return 1;
    } else {
        // Convert file name from unicode to filesystem character set.
        // (Assume file name is ASCII, for now).
        // 
        byte[] asciiName = StringUtilities.stringToBytesNullTerminated(libName);
        // make sure we have enough stack to load the library.
        // This operation has been known to require more than 20K of stack.
        RVMThread myThread = RVMThread.getCurrentThread();
        Offset remaining = Magic.getFramePointer().diff(myThread.stackLimit);
        int stackNeededInBytes = StackFrameLayout.getStackSizeDLOpen() - remaining.toInt();
        if (stackNeededInBytes > 0) {
            if (myThread.hasNativeStackFrame()) {
                throw new java.lang.StackOverflowError("Not enough space to open shared library");
            } else {
                RVMThread.resizeCurrentStack(myThread.getStackLength() + stackNeededInBytes, null);
            }
        }
        Address libHandler = SysCall.sysCall.sysDlopen(asciiName);
        if (!libHandler.isZero()) {
            dynamicLibraries.put(libName, new DynamicLibrary(libName, libHandler));
            return 1;
        } else {
            // fail; file does not exist
            return 0;
        }
    }
}
Also used : Address(org.vmmagic.unboxed.Address) RVMThread(org.jikesrvm.scheduler.RVMThread) Offset(org.vmmagic.unboxed.Offset)

Aggregations

RVMThread (org.jikesrvm.scheduler.RVMThread)22 Unpreemptible (org.vmmagic.pragma.Unpreemptible)7 Address (org.vmmagic.unboxed.Address)7 Entrypoint (org.vmmagic.pragma.Entrypoint)6 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)5 Offset (org.vmmagic.unboxed.Offset)5 NoInline (org.vmmagic.pragma.NoInline)4 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)3 AbstractRegisters (org.jikesrvm.architecture.AbstractRegisters)2 Test (org.junit.Test)2 Inline (org.vmmagic.pragma.Inline)2 UnpreemptibleNoWarn (org.vmmagic.pragma.UnpreemptibleNoWarn)2 LockInfo (java.lang.management.LockInfo)1 MonitorInfo (java.lang.management.MonitorInfo)1 ThreadInfo (java.lang.management.ThreadInfo)1 InvocationTargetException (java.lang.reflect.InvocationTargetException)1 RVMMethod (org.jikesrvm.classloader.RVMMethod)1 RVMType (org.jikesrvm.classloader.RVMType)1 ArchBaselineCompiledMethod (org.jikesrvm.compilers.baseline.ppc.ArchBaselineCompiledMethod)1 Assembler (org.jikesrvm.compilers.common.assembler.ia32.Assembler)1