jdk/src/java.base/share/classes/java/lang/StackFrameInfo.java
author rriggs
Tue, 16 Feb 2016 11:36:20 -0500
changeset 35978 752d505da547
parent 34362 3396ae214e7d
child 36511 9d0388c6b336
permissions -rw-r--r--
8148775: Spec for j.l.ProcessBuilder.Redirect.DISCARD need to be improved Reviewed-by: martin
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
34362
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     1
/*
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     2
 * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     4
 *
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    10
 *
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    15
 * accompanied this code).
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    16
 *
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    20
 *
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    23
 * questions.
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    24
 */
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    25
package java.lang;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    26
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    27
import jdk.internal.misc.JavaLangInvokeAccess;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    28
import jdk.internal.misc.SharedSecrets;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    29
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    30
import static java.lang.StackWalker.Option.*;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    31
import java.lang.StackWalker.StackFrame;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    32
import java.util.Optional;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    33
import java.util.OptionalInt;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    34
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    35
class StackFrameInfo implements StackFrame {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    36
    private final static JavaLangInvokeAccess jlInvokeAccess =
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    37
        SharedSecrets.getJavaLangInvokeAccess();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    38
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    39
    // -XX:+MemberNameInStackFrame will initialize MemberName and all other fields;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    40
    // otherwise, VM will set the hidden fields (injected by the VM).
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    41
    // -XX:+MemberNameInStackFrame is temporary to enable performance measurement
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    42
    //
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    43
    // Footprint improvement: MemberName::clazz and MemberName::name
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    44
    // can replace StackFrameInfo::declaringClass and StackFrameInfo::methodName
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    45
    // Currently VM sets StackFrameInfo::methodName instead of expanding MemberName::name
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    46
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    47
    final StackWalker walker;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    48
    final Class<?> declaringClass;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    49
    final Object memberName;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    50
    final int bci;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    51
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    52
    // methodName, fileName, and lineNumber will be lazily set by the VM
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    53
    // when first requested.
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    54
    private String methodName;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    55
    private String fileName = null;     // default for unavailable filename
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    56
    private int    lineNumber = -1;     // default for unavailable lineNumber
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    57
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    58
    /*
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    59
     * Create StackFrameInfo for StackFrameTraverser and LiveStackFrameTraverser
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    60
     * to use
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    61
     */
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    62
    StackFrameInfo(StackWalker walker) {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    63
        this.walker = walker;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    64
        this.declaringClass = null;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    65
        this.bci = -1;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    66
        this.memberName = jlInvokeAccess.newMemberName();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    67
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    68
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    69
    @Override
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    70
    public String getClassName() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    71
        return declaringClass.getName();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    72
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    73
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    74
    @Override
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    75
    public Class<?> getDeclaringClass() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    76
        walker.ensureAccessEnabled(RETAIN_CLASS_REFERENCE);
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    77
        return declaringClass;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    78
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    79
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    80
    // Call the VM to set methodName, lineNumber, and fileName
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    81
    private synchronized void ensureMethodInfoInitialized() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    82
        if (methodName == null) {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    83
            setMethodInfo();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    84
        }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    85
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    86
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    87
    @Override
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    88
    public String getMethodName() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    89
        ensureMethodInfoInitialized();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    90
        return methodName;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    91
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    92
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    93
    @Override
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    94
    public Optional<String> getFileName() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    95
        ensureMethodInfoInitialized();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    96
        return fileName != null ? Optional.of(fileName) : Optional.empty();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    97
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    98
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
    99
    @Override
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   100
    public OptionalInt getLineNumber() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   101
        ensureMethodInfoInitialized();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   102
        return lineNumber > 0 ? OptionalInt.of(lineNumber) : OptionalInt.empty();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   103
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   104
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   105
    @Override
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   106
    public boolean isNativeMethod() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   107
        ensureMethodInfoInitialized();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   108
        return lineNumber == -2;
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   109
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   110
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   111
    @Override
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   112
    public String toString() {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   113
        ensureMethodInfoInitialized();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   114
        // similar format as StackTraceElement::toString
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   115
        if (isNativeMethod()) {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   116
            return getClassName() + "." + getMethodName() + "(Native Method)";
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   117
        } else {
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   118
            // avoid allocating Optional objects
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   119
            return getClassName() + "." + getMethodName() +
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   120
                "(" + (fileName != null ? fileName : "Unknown Source") +
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   121
                      (lineNumber > 0 ? ":" + lineNumber : " bci:" + bci) + ")";
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   122
        }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   123
    }
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   124
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   125
    /**
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   126
     * Lazily initialize method name, file name, line number
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   127
     */
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   128
    private native void setMethodInfo();
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   129
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   130
    /**
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   131
     * Fill in source file name and line number of the given StackFrame array.
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   132
     */
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   133
    static native void fillInStackFrames(int startIndex,
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   134
                                         Object[] stackframes,
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   135
                                         int fromIndex, int toIndex);
3396ae214e7d 8140450: Implement JEP 259: Stack-Walking API
mchung
parents:
diff changeset
   136
}