< prev index next >

src/java.logging/share/classes/java/util/logging/LogRecord.java

Print this page
rev 13118 : [mq]: backout-stackw

@@ -28,12 +28,13 @@
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicLong;
 import java.io.*;
 import java.time.Clock;
-import java.util.function.Predicate;
 
+import jdk.internal.misc.JavaLangAccess;
+import jdk.internal.misc.SharedSecrets;
 import static jdk.internal.logger.SimpleConsoleLogger.skipLoggingFrame;
 
 /**
  * LogRecord objects are used to pass logging requests between
  * the logging framework and individual log Handlers.

@@ -658,60 +659,44 @@
     // This property is not standard, implementation specific, and yet
     // undocumented (and thus subject to changes without notice).
     //
     private void inferCaller() {
         needToInferCaller = false;
+        JavaLangAccess access = SharedSecrets.getJavaLangAccess();
+        Throwable throwable = new Throwable();
+        int depth = access.getStackTraceDepth(throwable);
+
+        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();
+            boolean isLoggerImpl = isLoggerImplFrame(cname);
+            if (lookingForLogger) {
         // Skip all frames until we have found the first logger frame.
-        Optional<StackWalker.StackFrame> frame = new CallerFinder().get();
-        frame.ifPresent(f -> {
-            setSourceClassName(f.getClassName());
-            setSourceMethodName(f.getMethodName());
-        });
-
-        // We haven't found a suitable frame, so just punt.  This is
-        // OK as we are only committed to making a "best effort" here.
+                if (isLoggerImpl) {
+                    lookingForLogger = false;
     }
-
-    /*
-     * CallerFinder is a stateful predicate.
-     */
-    static final class CallerFinder implements Predicate<StackWalker.StackFrame> {
-        static final StackWalker WALKER = StackWalker.getInstance();
-
-        /**
-         * Returns StackFrame of the caller's frame.
-         * @return StackFrame of the caller's frame.
-         */
-        Optional<StackWalker.StackFrame> get() {
-            return WALKER.walk((s) -> s.filter(this).findFirst());
+            } else {
+                if (!isLoggerImpl) {
+                    // skip logging/logger infrastructure and reflection calls
+                    if (!skipLoggingFrame(cname)) {
+                       // We've found the relevant frame.
+                       setSourceClassName(cname);
+                       setSourceMethodName(frame.getMethodName());
+                       return;
         }
-
-        private boolean lookingForLogger = true;
-        /**
-         * Returns true if we have found the caller's frame, false if the frame
-         * must be skipped.
-         *
-         * @param t The frame info.
-         * @return true if we have found the caller's frame, false if the frame
-         * must be skipped.
-         */
-        @Override
-        public boolean test(StackWalker.StackFrame t) {
-            final String cname = t.getClassName();
-            // We should skip all frames until we have found the logger,
-            // because these frames could be frames introduced by e.g. custom
-            // sub classes of Handler.
-            if (lookingForLogger) {
-                // the log record could be created for a platform logger
-                lookingForLogger = !isLoggerImplFrame(cname);
-                return false;
             }
-            // skip logging/logger infrastructure and reflection calls
-            return !skipLoggingFrame(cname);
+            }
+        }
+        // We haven't found a suitable frame, so just punt.  This is
+        // OK as we are only committed to making a "best effort" here.
         }
 
         private boolean isLoggerImplFrame(String cname) {
+        // the log record could be created for a platform logger
             return (cname.equals("java.util.logging.Logger") ||
                     cname.startsWith("sun.util.logging.PlatformLogger"));
         }
-    }
 }
< prev index next >