@Uninterruptible public static void dumpRef(ObjectReference ref) { VM.sysWrite("REF="); if (ref.isNull()) { VM.sysWrite("NULL\n"); return; } VM.sysWrite(ref); if (!mappedVMRef(ref)) { VM.sysWrite(" (REF OUTSIDE OF HEAP OR NOT MAPPED)\n"); return; } ObjectModel.dumpHeader(ref); ObjectReference tib = ObjectReference.fromObject(ObjectModel.getTIB(ref)); if (!MemoryManager.mightBeTIB(tib)) { VM.sysWrite(" (INVALID TIB: CLASS NOT ACCESSIBLE)\n"); return; } RVMType type = Magic.getObjectType(ref.toObject()); ObjectReference itype = ObjectReference.fromObject(type); VM.sysWrite(" TYPE="); VM.sysWrite(itype); if (!validType(itype)) { VM.sysWrite(" (INVALID TYPE: CLASS NOT ACCESSIBLE)\n"); return; } VM.sysWrite(" CLASS="); VM.sysWrite(type.getDescriptor()); VM.sysWrite("\n"); }
private static synchronized Throwable fillInStackTrace(Throwable instance) { ObjectReference.fromObject(instance) .toAddress() .add(BACKTRACE_OFFSET) .store( ObjectReference.fromObject( VmThread.getStackTrace(VmProcessor.current().getCurrentThread()))); return instance; }
/** Reference Arrays */ public static void referenceArray(Object object, TransitiveClosure trace) { Address base = Magic.objectAsAddress(object); int length = ObjectModel.getArrayLength(object); for (int i = 0; i < length; i++) { trace.processEdge(ObjectReference.fromObject(object), base.plus(i << LOG_BYTES_IN_ADDRESS)); } }
/** All Scalars */ public static void scalar(Object object, TransitiveClosure trace) { Address base = Magic.objectAsAddress(object); int[] offsets = ObjectModel.getObjectType(object).asClass().getReferenceOffsets(); for (int i = 0; i < offsets.length; i++) { trace.processEdge(ObjectReference.fromObject(object), base.plus(offsets[i])); } }
private static int getStackTraceDepth(Throwable instance) { return ((Object[]) ObjectReference.fromObject(instance) .toAddress() .add(BACKTRACE_OFFSET) .loadObjectReference() .toObject()) .length; }
static int newGlobalRef(Object referent) { if (VM.VerifyAssertions) VM._assert(MemoryManager.validRef(ObjectReference.fromObject(referent))); if (free >= JNIGlobalRefs.length()) { AddressArray newGlobalRefs = AddressArray.create(JNIGlobalRefs.length() * 2); copyAndReplaceGlobalRefs(newGlobalRefs); } JNIGlobalRefs.set(free, Magic.objectAsAddress(referent)); return -free++; }
/** Fallback */ public static void fallback(Object object, TransitiveClosure trace) { ObjectReference objectRef = ObjectReference.fromObject(object); RVMType type = ObjectModel.getObjectType(objectRef.toObject()); if (type.isClassType()) { RVMClass klass = type.asClass(); int[] offsets = klass.getReferenceOffsets(); for (int i = 0; i < offsets.length; i++) { trace.processEdge(objectRef, objectRef.toAddress().plus(offsets[i])); } } else if (type.isArrayType() && type.asArray().getElementType().isReferenceType()) { for (int i = 0; i < ObjectModel.getArrayLength(objectRef.toObject()); i++) { trace.processEdge(objectRef, objectRef.toAddress().plus(i << LOG_BYTES_IN_ADDRESS)); } } }
private static StackTraceElement getStackTraceElement(Throwable instance, int index) { final VmStackFrame frame = (VmStackFrame) ((Object[]) ObjectReference.fromObject(instance) .toAddress() .add(BACKTRACE_OFFSET) .loadObjectReference() .toObject()) [index]; final String location = frame.getLocationInfo(); final int lineNumber = "?".equals(location) ? -1 : Integer.parseInt(location); final VmMethod method = frame.getMethod(); final VmType<?> vmClass = (method == null) ? null : method.getDeclaringClass(); final String fname = (vmClass == null) ? null : vmClass.getSourceFile(); final String cname = (vmClass == null) ? "<unknown class>" : vmClass.getName(); final String mname = (method == null) ? "<unknown method>" : method.getName(); return new StackTraceElement( cname, mname, fname, method == null || method.isNative() ? -2 : lineNumber); }
/** All patterns bottom out here */ @Inline public static void pattern(int pattern, Object object, TransitiveClosure trace) { Address base = Magic.objectAsAddress(object).plus(FIELD_ZERO_OFFSET); if ((pattern & 1) != 0) { trace.processEdge(ObjectReference.fromObject(object), base.plus(0)); } if ((pattern & 2) != 0) { trace.processEdge(ObjectReference.fromObject(object), base.plus(1 << LOG_BYTES_IN_ADDRESS)); } if ((pattern & 4) != 0) { trace.processEdge(ObjectReference.fromObject(object), base.plus(2 << LOG_BYTES_IN_ADDRESS)); } if ((pattern & 8) != 0) { trace.processEdge(ObjectReference.fromObject(object), base.plus(3 << LOG_BYTES_IN_ADDRESS)); } if ((pattern & 16) != 0) { trace.processEdge(ObjectReference.fromObject(object), base.plus(4 << LOG_BYTES_IN_ADDRESS)); } if ((pattern & 32) != 0) { trace.processEdge(ObjectReference.fromObject(object), base.plus(5 << LOG_BYTES_IN_ADDRESS)); } }
@Uninterruptible public static boolean validRef(ObjectReference ref) { if (ref.isNull()) return true; if (!Space.isMappedObject(ref)) { VM.sysWrite("validRef: REF outside heap, ref = "); VM.sysWrite(ref); VM.sysWrite("\n"); Space.printVMMap(); return false; } if (MOVES_OBJECTS) { /* TODO: Work out how to check if forwarded if (Plan.isForwardedOrBeingForwarded(ref)) { // TODO: actually follow forwarding pointer // (need to bound recursion when things are broken!!) return true; } */ } TIB tib = ObjectModel.getTIB(ref); Address tibAddr = Magic.objectAsAddress(tib); if (!Space.isMappedObject(ObjectReference.fromObject(tib))) { VM.sysWrite("validRef: TIB outside heap, ref = "); VM.sysWrite(ref); VM.sysWrite(" tib = "); VM.sysWrite(tibAddr); VM.sysWrite("\n"); ObjectModel.dumpHeader(ref); return false; } if (tibAddr.isZero()) { VM.sysWrite("validRef: TIB is Zero! "); VM.sysWrite(ref); VM.sysWrite("\n"); ObjectModel.dumpHeader(ref); return false; } if (tib.length() == 0) { VM.sysWrite("validRef: TIB length zero, ref = "); VM.sysWrite(ref); VM.sysWrite(" tib = "); VM.sysWrite(tibAddr); VM.sysWrite("\n"); ObjectModel.dumpHeader(ref); return false; } ObjectReference type = ObjectReference.fromObject(tib.getType()); if (!validType(type)) { VM.sysWrite("validRef: invalid TYPE, ref = "); VM.sysWrite(ref); VM.sysWrite(" tib = "); VM.sysWrite(Magic.objectAsAddress(tib)); VM.sysWrite(" type = "); VM.sysWrite(type); VM.sysWrite("\n"); ObjectModel.dumpHeader(ref); return false; } return true; } // validRef
/** * Checks if a reference, its TIB pointer and type pointer are all in the heap. * * @param ref the reference to check * @return {@code true} if and only if the reference refers to a valid object */ @Uninterruptible public static boolean validObject(Object ref) { return validRef(ObjectReference.fromObject(ref)); }