• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2015, 2019, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package java.lang;
26 
27 
28 import java.lang.StackWalker.StackFrame;
29 import java.lang.invoke.MethodType;
30 
31 class StackFrameInfo implements StackFrame {
32 
33     // Android-removed: libcore doesn't have JavaLangInvokeAccess yet.
34     // private static final JavaLangInvokeAccess JLIA =
35     //     SharedSecrets.getJavaLangInvokeAccess();
36 
37     private final boolean retainClassRef;
38     // Android-removed: Unused internal fields.
39     // private final Object memberName;    // MemberName initialized by VM
40     private int bci;                    // initialized by VM to >= 0
41     private volatile StackTraceElement ste;
42 
43     // Android-added: Add Android-specific internal fields.
44     private Class<?> declaringClass; // initialized by VM
45     private MethodType methodType; // initialized by VM
46     private String methodName; // initialized by VM
47     private String fileName; // initialized by VM
48     private int lineNumber; // initialized by VM
49 
50     /*
51      * Construct an empty StackFrameInfo object that will be filled by the VM
52      * during stack walking.
53      *
54      * @see StackStreamFactory.AbstractStackWalker#callStackWalk
55      * @see StackStreamFactory.AbstractStackWalker#fetchStackFrames
56      */
StackFrameInfo(StackWalker walker)57     StackFrameInfo(StackWalker walker) {
58         this.retainClassRef = walker.retainClassRef;
59         // Android-removed: Unused internal fields.
60         // this.memberName = JLIA.newMemberName();
61     }
62 
63     // Android-added: Additional constructor
StackFrameInfo(boolean retainClassRef)64     StackFrameInfo(boolean retainClassRef) {
65         this.retainClassRef = retainClassRef;
66     }
67 
68 
69     // package-private called by StackStreamFactory to skip
70     // the capability check
declaringClass()71     Class<?> declaringClass() {
72         // Android-changed: Android own implementation.
73         // return JLIA.getDeclaringClass(memberName);
74         return declaringClass;
75     }
76 
77     // ----- implementation of StackFrame methods
78 
79     @Override
getClassName()80     public String getClassName() {
81         return declaringClass().getName();
82     }
83 
84     @Override
getDeclaringClass()85     public Class<?> getDeclaringClass() {
86         ensureRetainClassRefEnabled();
87         return declaringClass();
88     }
89 
90     @Override
getMethodName()91     public String getMethodName() {
92         // Android-changed: Android own implementation.
93         // return JLIA.getName(memberName);
94         return methodName;
95     }
96 
97     @Override
getMethodType()98     public MethodType getMethodType() {
99         ensureRetainClassRefEnabled();
100         // Android-changed: Android own implementation.
101         // return JLIA.getMethodType(memberName);
102         return methodType;
103     }
104 
105     @Override
getDescriptor()106     public String getDescriptor() {
107         // Android-changed: Android own implementation.
108         // return JLIA.getMethodDescriptor(memberName);
109         return methodType.toMethodDescriptorString();
110     }
111 
112     @Override
getByteCodeIndex()113     public int getByteCodeIndex() {
114         // bci not available for native methods
115         if (isNativeMethod())
116             return -1;
117 
118         return bci;
119     }
120 
121     @Override
getFileName()122     public String getFileName() {
123         // Android-changed: Android own implementation.
124         // return toStackTraceElement().getFileName();
125         return fileName;
126     }
127 
128     @Override
getLineNumber()129     public int getLineNumber() {
130         // line number not available for native methods
131         if (isNativeMethod())
132             return -2;
133 
134         // Android-changed: Android own implementation.
135         // return toStackTraceElement().getLineNumber();
136         return lineNumber;
137     }
138 
139 
140     @Override
isNativeMethod()141     public boolean isNativeMethod() {
142         // Android-changed: Android own implementation.
143         // return JLIA.isNative(memberName);
144         // StackTraceElement.isNativeMethod() uses -2 in line number to indicate native method.
145         return lineNumber == -2;
146     }
147 
148     @Override
toString()149     public String toString() {
150         return toStackTraceElement().toString();
151     }
152 
153     @Override
toStackTraceElement()154     public StackTraceElement toStackTraceElement() {
155         StackTraceElement s = ste;
156         if (s == null) {
157             synchronized (this) {
158                 s = ste;
159                 if (s == null) {
160                     ste = s = StackTraceElement.of(this);
161                 }
162             }
163         }
164         return s;
165     }
166 
ensureRetainClassRefEnabled()167     private void ensureRetainClassRefEnabled() {
168         if (!retainClassRef) {
169             throw new UnsupportedOperationException("No access to RETAIN_CLASS_REFERENCE");
170         }
171     }
172 }
173