private ExtendedStackTraceElement getStackTraceElement(int i) { int skipChunks = i / TRACE_CHUNK_SIZE; int j = i % TRACE_CHUNK_SIZE; Object chunk = getBacktrace(t); while (chunk != null && skipChunks > 0) { chunk = getNext(chunk); skipChunks--; } return getStackTraceElement(getStackTraceElement0(i), chunk, j); }
private ExtendedStackTraceElement getStackTraceElement(StackTraceElement ste, Object chunk, int j) { return new HotSpotExtendedStackTraceElement(ste, getDeclaringClass(chunk, j), getMethod(chunk, j), getBci(chunk, j)); }
@Override public ExtendedStackTraceElement[] get() { synchronized (this) { if (est == null) { est = new ExtendedStackTraceElement[getStackTraceDepth()]; int i = 0; for (ExtendedStackTraceElement e : this) est[i++] = e; } return est; } }
private int getStackTraceDepth() { Object chunk = getBacktrace(t); int depth = 0; if (chunk != null) { // Iterate over chunks and count full ones while (true) { Object next = getNext(chunk); if (next == null) break; depth += TRACE_CHUNK_SIZE; chunk = next; } // Count element in remaining partial chunk. NULL value for mirror // marks the end of the stack trace elements that are saved. for (int j = 0; j < TRACE_CHUNK_SIZE; j++) { Class<?> c = getDeclaringClass(chunk, j); if (c == null) break; depth++; } } assert depth == getStackTraceDepth0(); return depth; }
@Override protected Member getMethod(ExtendedStackTraceElement este) { final HotSpotExtendedStackTraceElement heste = (HotSpotExtendedStackTraceElement) este; Member[] ms = getMethods(heste.getDeclaringClass()); for (Member m : ms) { if (heste.methodSlot == getSlot(m)) return m; } return null; }
private static void sanityCheck() { Throwable t = new Throwable(); Object[] chunk = (Object[]) getBacktrace(t); if (((Object[]) chunk[TRACE_CLASSES_OFFSET]).length != TRACE_CHUNK_SIZE) throw new IllegalStateException(); if (((short[]) chunk[TRACE_METHOD_OFFSET]).length != TRACE_CHUNK_SIZE) throw new IllegalStateException(); if (((int[]) chunk[TRACE_BCIS_OFFSET]).length != TRACE_CHUNK_SIZE) throw new IllegalStateException(); final Object[] nextChunk = (Object[]) getNext(chunk); if (nextChunk != null && nextChunk.length != chunk.length) throw new IllegalStateException(); } }
public static ExtendedStackTrace here() { try { return new ExtendedStackTraceHotSpot(new Throwable()); } catch (Throwable e) { return new ExtendedStackTraceClassContext(); } }
private static long guessBacktraceFieldOffset() { Field[] fs = Throwable.class.getDeclaredFields(); Field second = null; for (Field f : fs) { if (getSlot(f) == 2) { second = f; break; } } if (second == null) throw new IllegalStateException(); long secondOffest = UNSAFE.objectFieldOffset(second); if (secondOffest == 16) return 12; // compressed oops if (secondOffest == 24) return 16; // no compressed oops else throw new IllegalStateException("secondOffset: " + secondOffest); // unfamiliar }
public static ExtendedStackTrace of(Throwable t) { try { return new ExtendedStackTraceHotSpot(t); } catch (Throwable e) { return new ExtendedStackTrace(t); } }