Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/lang/StackWalker/TestBCI.java
41149 views
1
/*
2
* Copyright (c) 2016, 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.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
/*
25
* @test
26
* @bug 8140450
27
* @summary Basic test for the StackWalker::getByteCodeIndex method
28
* @modules jdk.jdeps/com.sun.tools.classfile
29
* @run main TestBCI
30
*/
31
32
import com.sun.tools.classfile.Attribute;
33
import com.sun.tools.classfile.ClassFile;
34
import com.sun.tools.classfile.Code_attribute;
35
import com.sun.tools.classfile.ConstantPoolException;
36
import com.sun.tools.classfile.Descriptor;
37
import com.sun.tools.classfile.LineNumberTable_attribute;
38
import com.sun.tools.classfile.Method;
39
40
import java.lang.StackWalker.StackFrame;
41
import java.io.IOException;
42
import java.io.InputStream;
43
import java.util.Arrays;
44
import java.util.Comparator;
45
import java.util.HashMap;
46
import java.util.Map;
47
import java.util.Optional;
48
import java.util.SortedSet;
49
import java.util.TreeSet;
50
import java.util.function.Function;
51
import java.util.stream.Collectors;
52
53
import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE;
54
55
public class TestBCI {
56
public static void main(String... args) throws Exception {
57
TestBCI test = new TestBCI(Walker.class);
58
System.out.println("Line number table:");
59
test.methods.values().stream()
60
.sorted(Comparator.comparing(MethodInfo::name).reversed())
61
.forEach(System.out::println);
62
63
// walk the stack
64
test.walk();
65
}
66
67
private final Map<String, MethodInfo> methods;
68
private final Class<?> clazz;
69
TestBCI(Class<?> c) throws ConstantPoolException, IOException {
70
Map<String, MethodInfo> methods;
71
String filename = c.getName().replace('.', '/') + ".class";
72
try (InputStream in = c.getResourceAsStream(filename)) {
73
ClassFile cf = ClassFile.read(in);
74
methods = Arrays.stream(cf.methods)
75
.map(m -> new MethodInfo(cf, m))
76
.collect(Collectors.toMap(MethodInfo::name, Function.identity()));
77
}
78
this.clazz = c;
79
this.methods = methods;
80
}
81
82
void walk() {
83
Walker walker = new Walker();
84
walker.m1();
85
}
86
87
void verify(StackFrame frame) {
88
if (frame.getDeclaringClass() != clazz)
89
return;
90
91
int bci = frame.getByteCodeIndex();
92
int lineNumber = frame.getLineNumber();
93
System.out.format("%s.%s bci %d (%s:%d)%n",
94
frame.getClassName(), frame.getMethodName(), bci,
95
frame.getFileName(), lineNumber);
96
97
MethodInfo method = methods.get(frame.getMethodName());
98
SortedSet<Integer> values = method.findLineNumbers(bci).get();
99
if (!values.contains(lineNumber)) {
100
throw new RuntimeException("line number for bci: " + bci + " "
101
+ lineNumber + " not matched line number table: " + values);
102
}
103
}
104
105
/*
106
* BCIs in the execution stack when StackWalker::forEach is invoked
107
* will cover BCI range in the line number table.
108
*/
109
class Walker {
110
final StackWalker walker = StackWalker.getInstance(RETAIN_CLASS_REFERENCE);
111
void m1() {
112
int i = (int)Math.random()+2;
113
m2(i*2);
114
}
115
116
void m2(int i) {
117
i++;
118
m3(i);
119
}
120
121
void m3(int i) {
122
i++; m4(i++);
123
}
124
125
int m4(int i) {
126
walker.forEach(TestBCI.this::verify);
127
return i;
128
}
129
}
130
131
static class MethodInfo {
132
final Method method;
133
final String name;
134
final String paramTypes;
135
final String returnType;
136
final Map<Integer, SortedSet<Integer>> bciToLineNumbers = new HashMap<>();
137
MethodInfo(ClassFile cf, Method m) {
138
this.method = m;
139
140
String name;
141
String paramTypes;
142
String returnType;
143
LineNumberTable_attribute.Entry[] lineNumberTable;
144
try {
145
// method name
146
name = m.getName(cf.constant_pool);
147
// signature
148
paramTypes = m.descriptor.getParameterTypes(cf.constant_pool);
149
returnType = m.descriptor.getReturnType(cf.constant_pool);
150
Code_attribute codeAttr = (Code_attribute)
151
m.attributes.get(Attribute.Code);
152
lineNumberTable = ((LineNumberTable_attribute)
153
codeAttr.attributes.get(Attribute.LineNumberTable)).line_number_table;
154
} catch (ConstantPoolException|Descriptor.InvalidDescriptor e) {
155
throw new RuntimeException(e);
156
}
157
this.name = name;
158
this.paramTypes = paramTypes;
159
this.returnType = returnType;
160
Arrays.stream(lineNumberTable).forEach(entry ->
161
bciToLineNumbers.computeIfAbsent(entry.start_pc, _n -> new TreeSet<>())
162
.add(entry.line_number));
163
}
164
165
String name() {
166
return name;
167
}
168
169
Optional<SortedSet<Integer>> findLineNumbers(int value) {
170
return bciToLineNumbers.entrySet().stream()
171
.sorted(Map.Entry.comparingByKey(Comparator.reverseOrder()))
172
.filter(e -> e.getKey().intValue() <= value)
173
.map(Map.Entry::getValue)
174
.findFirst();
175
}
176
177
@Override
178
public String toString() {
179
StringBuilder sb = new StringBuilder();
180
sb.append(name);
181
sb.append(paramTypes).append(returnType).append(" ");
182
bciToLineNumbers.entrySet().stream()
183
.sorted(Map.Entry.comparingByKey())
184
.forEach(entry -> sb.append("bci:").append(entry.getKey()).append(" ")
185
.append(entry.getValue()).append(" "));
186
return sb.toString();
187
}
188
}
189
190
}
191
192