提交 c5dde42c 编写于 作者: M martin

6511515: poor performance of LogRecord.inferCaller depending on...

6511515: poor performance of LogRecord.inferCaller depending on java.lang.Throwable.getStackTraceElement
Summary: Allow random access to stack trace elements; retrieve only needed ones
Reviewed-by: swamyv
Contributed-by: jeremymanson@google.com
上级 d120bfcc
......@@ -1174,6 +1174,12 @@ public final class System {
public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
Shutdown.add(slot, registerShutdownInProgress, hook);
}
public int getStackTraceDepth(Throwable t) {
return t.getStackTraceDepth();
}
public StackTraceElement getStackTraceElement(Throwable t, int i) {
return t.getStackTraceElement(i);
}
});
}
......
......@@ -645,17 +645,21 @@ public class Throwable implements Serializable {
/**
* Returns the number of elements in the stack trace (or 0 if the stack
* trace is unavailable).
*
* package-protection for use by SharedSecrets.
*/
private native int getStackTraceDepth();
native int getStackTraceDepth();
/**
* Returns the specified element of the stack trace.
*
* package-protection for use by SharedSecrets.
*
* @param index index of the element to return.
* @throws IndexOutOfBoundsException if <tt>index &lt; 0 ||
* index &gt;= getStackTraceDepth() </tt>
*/
private native StackTraceElement getStackTraceElement(int index);
native StackTraceElement getStackTraceElement(int index);
private synchronized void writeObject(java.io.ObjectOutputStream s)
throws IOException
......
......@@ -29,6 +29,9 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.io.*;
import sun.misc.JavaLangAccess;
import sun.misc.SharedSecrets;
/**
* LogRecord objects are used to pass logging requests between
* the logging framework and individual log Handlers.
......@@ -522,29 +525,31 @@ public class LogRecord implements java.io.Serializable {
// Private method to infer the caller's class and method names
private void inferCaller() {
needToInferCaller = false;
// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace();
// First, search back to a method in the Logger class.
int ix = 0;
while (ix < stack.length) {
StackTraceElement frame = stack[ix];
JavaLangAccess access = SharedSecrets.getJavaLangAccess();
Throwable throwable = new Throwable();
int depth = access.getStackTraceDepth(throwable);
String logClassName = "java.util.logging.Logger";
boolean lookingForLogger = true;
for (int ix = 0; ix < depth; ix++) {
// Calling getStackTraceElement directly prevents the VM
// from paying the cost of building the entire stack frame.
StackTraceElement frame =
access.getStackTraceElement(throwable, ix);
String cname = frame.getClassName();
if (cname.equals("java.util.logging.Logger")) {
break;
}
ix++;
}
// Now search for the first frame before the "Logger" class.
while (ix < stack.length) {
StackTraceElement frame = stack[ix];
String cname = frame.getClassName();
if (!cname.equals("java.util.logging.Logger")) {
// We've found the relevant frame.
setSourceClassName(cname);
setSourceMethodName(frame.getMethodName());
return;
if (lookingForLogger) {
// Skip all frames until we have found the first logger frame.
if (cname.equals(logClassName)) {
lookingForLogger = false;
}
} else {
if (!cname.equals(logClassName)) {
// We've found the relevant frame.
setSourceClassName(cname);
setSourceMethodName(frame.getMethodName());
return;
}
}
ix++;
}
// We haven't found a suitable frame, so just punt. This is
// OK as we are only committed to making a "best effort" here.
......
......@@ -73,4 +73,14 @@ public interface JavaLangAccess {
* the slot is not valid to register.
*/
void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook);
/**
* Returns the number of stack frames represented by the given throwable.
*/
int getStackTraceDepth(Throwable t);
/**
* Returns the ith StackTraceElement for the given throwable.
*/
StackTraceElement getStackTraceElement(Throwable t, int i);
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册