Search in sources :

Example 71 with Offset

use of org.vmmagic.unboxed.Offset 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 72 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class StackTrace method countFrames.

/**
 * Count number of stack frames including those inlined by the opt compiler
 * @param first the first compiled method to look from
 * @param last the last compiled method to look to
 * @return the number of stack frames
 */
private int countFrames(int first, int last) {
    int numElements = 0;
    if (!VM.BuildForOptCompiler) {
        numElements = last - first + 1;
    } else {
        for (int i = first; i <= last; i++) {
            CompiledMethod compiledMethod = getCompiledMethod(i);
            if ((compiledMethod == null) || (compiledMethod.getCompilerType() != CompiledMethod.OPT)) {
                // Invisible or non-opt compiled method
                numElements++;
            } else {
                Offset instructionOffset = Offset.fromIntSignExtend(instructionOffsets[i]);
                OptCompiledMethod optInfo = (OptCompiledMethod) compiledMethod;
                OptMachineCodeMap map = optInfo.getMCMap();
                int iei = map.getInlineEncodingForMCOffset(instructionOffset);
                if (iei < 0) {
                    numElements++;
                } else {
                    int[] inlineEncoding = map.inlineEncoding;
                    for (; iei >= 0; iei = OptEncodedCallSiteTree.getParent(iei, inlineEncoding)) {
                        numElements++;
                    }
                }
            }
        }
    }
    return numElements;
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) OptMachineCodeMap(org.jikesrvm.compilers.opt.runtimesupport.OptMachineCodeMap) BaselineCompiledMethod(org.jikesrvm.compilers.baseline.BaselineCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) Offset(org.vmmagic.unboxed.Offset)

Example 73 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class Statics method findOrCreateObjectLiteral.

/**
 * Find or allocate a slot in the JTOC for an object literal.
 * @param       literal value
 * @return offset of slot that was allocated
 * Side effect: literal value is stored into JTOC
 */
public static int findOrCreateObjectLiteral(Object literal) {
    int off = findObjectLiteral(literal);
    if (off != 0) {
        return off;
    } else {
        Offset newOff = allocateReferenceSlot(false);
        setSlotContents(newOff, literal);
        synchronized (objectLiterals) {
            objectLiterals.put(literal, newOff.toInt());
        }
        return newOff.toInt();
    }
}
Also used : Offset(org.vmmagic.unboxed.Offset)

Example 74 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class Statics method findOrCreate16ByteSizeLiteral.

/**
 * Find the given literal in the 16byte like literal map, if not found
 * create a slot for the literal and place an entry in the map
 * @param literal_high the high part of the literal value to find or create
 * @param literal_low the low part of the literal value to find or create
 * @return the offset in the JTOC of the literal
 */
public static int findOrCreate16ByteSizeLiteral(long literal_high, long literal_low) {
    final int bottom = getLowestInUseSlot();
    final int top = middleOfTable & 0xFFFFFFFC;
    for (int i = top; i >= bottom; i -= 4) {
        Offset off = slotAsOffset(i);
        if ((getSlotContentsAsLong(off) == literal_low) && (getSlotContentsAsLong(off.plus(8)) == literal_high) && !numericFieldVector.get(i) && !(numericFieldVector.get(i + 1)) && !numericFieldVector.get(i + 2) && !(numericFieldVector.get(i + 3)) && (i != numericSlotHole) && (i + 1 != numericSlotHole) && (i + 2 != numericSlotHole) && (i + 3 != numericSlotHole)) {
            return slotAsOffset(i).toInt();
        }
    }
    Offset newOff = allocateNumericSlot(16, false);
    setSlotContents(newOff, literal_low);
    setSlotContents(newOff.plus(8), literal_high);
    return newOff.toInt();
}
Also used : Offset(org.vmmagic.unboxed.Offset)

Example 75 with Offset

use of org.vmmagic.unboxed.Offset in project JikesRVM by JikesRVM.

the class BaselineExecutionStateExtractor method extractState.

/**
 * Implements ExecutionStateExtractor.extractState.
 *
 * @param thread : the suspended thread, the registers and stack frames are used.
 * @param osrFPoff : the osr method's stack frame offset
 * @param methFPoff : the real method's stack frame offset
 * @param cmid   : the top application method ( system calls are unwounded ).
 *
 * return a ExecutionStateExtractor object.
 */
@Override
public ExecutionState extractState(RVMThread thread, Offset osrFPoff, Offset methFPoff, int cmid) {
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("BASE execStateExtractor starting ...");
    }
    byte[] stack = thread.getStack();
    if (VM.VerifyAssertions) {
        int fooCmid = Magic.getIntAtOffset(stack, methFPoff.plus(STACKFRAME_METHOD_ID_OFFSET));
        if (VM.TraceOnStackReplacement) {
            VM.sysWriteln("fooCmid = " + fooCmid);
            VM.sysWriteln("   cmid = " + cmid);
        }
        VM._assert(fooCmid == cmid);
    }
    ArchBaselineCompiledMethod fooCM = (ArchBaselineCompiledMethod) CompiledMethods.getCompiledMethod(cmid);
    NormalMethod fooM = (NormalMethod) fooCM.getMethod();
    VM.disableGC();
    Address rowIP = Magic.objectAsAddress(stack).loadAddress(osrFPoff.plus(STACKFRAME_RETURN_ADDRESS_OFFSET));
    Offset ipOffset = fooCM.getInstructionOffset(rowIP);
    VM.enableGC();
    // CAUTION: IP Offset should point to next instruction
    int bcIndex = fooCM.findBytecodeIndexForInstruction(ipOffset.plus(INSTRUCTION_WIDTH));
    // assertions
    if (VM.VerifyAssertions) {
        if (bcIndex == -1) {
            VM.sysWriteln("osrFPoff = ", osrFPoff);
            VM.sysWriteln("instr_beg = ", Magic.objectAsAddress(fooCM.getEntryCodeArray()));
            for (int i = (osrFPoff.toInt()) - 10; i < (osrFPoff.toInt()) + 10; i++) {
                VM.sysWriteln("  stack[" + i + "] = " + stack[i]);
            }
            Offset ipIndex = ipOffset.toWord().rsha(LG_INSTRUCTION_WIDTH).toOffset();
            VM.sysWriteln("ipIndex : ", ipIndex);
            VM.sysWriteln("bcIndex : " + bcIndex);
        }
        VM._assert(bcIndex != -1);
    }
    // create execution state object
    ExecutionState state = new ExecutionState(thread, methFPoff, cmid, bcIndex, osrFPoff);
    /* extract values for local and stack, but first of all
     * we need to get type information for current PC.
     */
    BytecodeTraverser typer = new BytecodeTraverser();
    typer.computeLocalStackTypes(fooM, bcIndex);
    byte[] localTypes = typer.getLocalTypes();
    byte[] stackTypes = typer.getStackTypes();
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("BC Index : " + bcIndex);
        VM.sysWrite("Local Types :");
        for (byte localType : localTypes) {
            VM.sysWrite(" " + (char) localType);
        }
        VM.sysWriteln();
        VM.sysWrite("Stack Types :");
        for (byte stackType : stackTypes) {
            VM.sysWrite(" " + (char) stackType);
        }
        VM.sysWriteln();
    }
    // type. We should remove non-reference type
    for (int i = 0, n = localTypes.length; i < n; i++) {
        // then set the localType to uninitialized, see VM spec, bytecode verifier
        if (localTypes[i] == ClassTypeCode) {
            if (!fooCM.referenceMaps.isLocalRefType(fooM, ipOffset.plus(1 << LG_INSTRUCTION_WIDTH), i)) {
                localTypes[i] = VoidTypeCode;
                if (VM.TraceOnStackReplacement) {
                    VM.sysWriteln("GC maps disagrees with type matcher at " + i + "th local");
                    VM.sysWriteln();
                }
            }
        }
    }
    // go through the stack frame and extract values
    // In the variable value list, we keep the order as follows:
    // L0, L1, ..., S0, S1, ....
    // adjust local offset and stack offset
    // NOTE: do not call BaselineCompilerImpl.getFirstLocalOffset(method)
    Offset startLocalOffset = methFPoff.plus(BaselineCompilerImpl.locationToOffset(fooCM.getGeneralLocalLocation(0)));
    Offset stackOffset = methFPoff.plus(fooCM.getEmptyStackOffset());
    // for locals
    getVariableValue(stack, startLocalOffset, localTypes, fooCM, LOCAL, state);
    // for stacks
    getVariableValue(stack, stackOffset, stackTypes, fooCM, STACK, state);
    if (VM.TraceOnStackReplacement) {
        state.printState();
    }
    if (VM.TraceOnStackReplacement) {
        VM.sysWriteln("BASE executionStateExtractor done ");
    }
    return state;
}
Also used : ArchBaselineCompiledMethod(org.jikesrvm.compilers.baseline.ia32.ArchBaselineCompiledMethod) ExecutionState(org.jikesrvm.osr.ExecutionState) Address(org.vmmagic.unboxed.Address) NormalMethod(org.jikesrvm.classloader.NormalMethod) BytecodeTraverser(org.jikesrvm.osr.BytecodeTraverser) Offset(org.vmmagic.unboxed.Offset)

Aggregations

Offset (org.vmmagic.unboxed.Offset)215 Address (org.vmmagic.unboxed.Address)48 Inline (org.vmmagic.pragma.Inline)38 Entrypoint (org.vmmagic.pragma.Entrypoint)32 ObjectReference (org.vmmagic.unboxed.ObjectReference)21 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)20 TypeReference (org.jikesrvm.classloader.TypeReference)17 RVMField (org.jikesrvm.classloader.RVMField)14 ForwardReference (org.jikesrvm.compilers.common.assembler.ForwardReference)13 OptCompiledMethod (org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod)13 NoInline (org.vmmagic.pragma.NoInline)13 RVMMethod (org.jikesrvm.classloader.RVMMethod)11 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)10 Word (org.vmmagic.unboxed.Word)10 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)9 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)9 RVMType (org.jikesrvm.classloader.RVMType)8 Register (org.jikesrvm.compilers.opt.ir.Register)8 RVMClass (org.jikesrvm.classloader.RVMClass)7 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)7