Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openjdk-aarch32-jdk8u
Path: blob/jdk8u272-b10-aarch32-20201026/jdk/test/java/lang/invoke/lambda/LambdaAsm.java
48795 views
1
/*
2
* Copyright (c) 2013, 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 8027232
27
* @summary ensures that j.l.i.InvokerByteCodeGenerator and ASM visitMethodInsn
28
* generate bytecodes with correct constant pool references
29
* @compile -XDignore.symbol.file LambdaAsm.java LUtils.java
30
* @run main/othervm LambdaAsm
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.ConstantPool;
36
import com.sun.tools.classfile.ConstantPool.CPInfo;
37
import com.sun.tools.classfile.Instruction;
38
import com.sun.tools.classfile.Method;
39
import java.io.ByteArrayInputStream;
40
import java.io.File;
41
import java.util.ArrayList;
42
import java.nio.file.DirectoryStream;
43
import java.nio.file.Path;
44
import jdk.internal.org.objectweb.asm.ClassWriter;
45
import jdk.internal.org.objectweb.asm.MethodVisitor;
46
47
import static java.nio.file.Files.*;
48
import static jdk.internal.org.objectweb.asm.Opcodes.*;
49
50
public class LambdaAsm {
51
52
static final File TestFile = new File("A.java");
53
54
static void init() {
55
emitCode();
56
LUtils.compile(TestFile.getName());
57
LUtils.TestResult tr = LUtils.doExec(LUtils.JAVA_CMD.getAbsolutePath(),
58
"-Djdk.internal.lambda.dumpProxyClasses=.",
59
"-cp", ".", "A");
60
if (tr.exitValue != 0) {
61
System.out.println("Error: " + tr.toString());
62
throw new RuntimeException("could not create proxy classes");
63
}
64
}
65
66
static void emitCode() {
67
ArrayList<String> scratch = new ArrayList<>();
68
scratch.add("import java.util.function.*;");
69
scratch.add("class A {");
70
scratch.add(" interface I {");
71
scratch.add(" default Supplier<Integer> a() { return () -> 1; }");
72
scratch.add(" default Supplier<Integer> b(int i) { return () -> i; }");
73
scratch.add(" default Supplier<Integer> c(int i) { return () -> m(i); }");
74
scratch.add(" int m(int i);");
75
scratch.add(" static Integer d() { return 0; }");
76
scratch.add(" }");
77
scratch.add(" static class C implements I {");
78
scratch.add(" public int m(int i) { return i;}");
79
scratch.add(" }");
80
scratch.add(" public static void main(String[] args) {");
81
scratch.add(" I i = new C();");
82
scratch.add(" i.a();");
83
scratch.add(" i.b(1);");
84
scratch.add(" i.c(1);");
85
scratch.add(" I.d();");
86
scratch.add(" }");
87
scratch.add("}");
88
LUtils.createFile(TestFile, scratch);
89
}
90
91
static void checkMethod(String cname, String mname, ConstantPool cp,
92
Code_attribute code) throws ConstantPool.InvalidIndex {
93
for (Instruction i : code.getInstructions()) {
94
String iname = i.getMnemonic();
95
if ("invokespecial".equals(iname)
96
|| "invokestatic".equals(iname)) {
97
int idx = i.getByte(2);
98
System.out.println("Verifying " + cname + ":" + mname +
99
" instruction:" + iname + " index @" + idx);
100
CPInfo cpinfo = cp.get(idx);
101
if (cpinfo instanceof ConstantPool.CONSTANT_Methodref_info) {
102
throw new RuntimeException("unexpected CP type expected "
103
+ "InterfaceMethodRef, got MethodRef, " + cname
104
+ ", " + mname);
105
}
106
}
107
}
108
}
109
110
static int checkMethod(ClassFile cf, String mthd) throws Exception {
111
if (cf.major_version < 52) {
112
throw new RuntimeException("unexpected class file version, in "
113
+ cf.getName() + "expected 52, got " + cf.major_version);
114
}
115
int count = 0;
116
for (Method m : cf.methods) {
117
String mname = m.getName(cf.constant_pool);
118
if (mname.equals(mthd)) {
119
for (Attribute a : m.attributes) {
120
if ("Code".equals(a.getName(cf.constant_pool))) {
121
count++;
122
checkMethod(cf.getName(), mname, cf.constant_pool,
123
(Code_attribute) a);
124
}
125
}
126
}
127
}
128
return count;
129
}
130
131
static void verifyInvokerBytecodeGenerator() throws Exception {
132
int count = 0;
133
int mcount = 0;
134
try (DirectoryStream<Path> ds = newDirectoryStream(new File(".").toPath(),
135
// filter in lambda proxy classes
136
"A$I$$Lambda$?.class")) {
137
for (Path p : ds) {
138
System.out.println(p.toFile());
139
ClassFile cf = ClassFile.read(p.toFile());
140
// Check those methods implementing Supplier.get
141
mcount += checkMethod(cf, "get");
142
count++;
143
}
144
}
145
if (count < 3) {
146
throw new RuntimeException("unexpected number of files, "
147
+ "expected atleast 3 files, but got only " + count);
148
}
149
if (mcount < 3) {
150
throw new RuntimeException("unexpected number of methods, "
151
+ "expected atleast 3 methods, but got only " + mcount);
152
}
153
}
154
155
static void verifyASM() throws Exception {
156
ClassWriter cw = new ClassWriter(0);
157
cw.visit(V1_8, ACC_PUBLIC, "X", null, "java/lang/Object", null);
158
MethodVisitor mv = cw.visitMethod(ACC_STATIC, "foo",
159
"()V", null, null);
160
mv.visitMaxs(2, 1);
161
mv.visitMethodInsn(INVOKESTATIC,
162
"java/util/function/Function.class",
163
"identity", "()Ljava/util/function/Function;", true);
164
mv.visitInsn(RETURN);
165
cw.visitEnd();
166
byte[] carray = cw.toByteArray();
167
// for debugging
168
// write((new File("X.class")).toPath(), carray, CREATE, TRUNCATE_EXISTING);
169
170
// verify using javap/classfile reader
171
ClassFile cf = ClassFile.read(new ByteArrayInputStream(carray));
172
int mcount = checkMethod(cf, "foo");
173
if (mcount < 1) {
174
throw new RuntimeException("unexpected method count, expected 1" +
175
"but got " + mcount);
176
}
177
}
178
179
public static void main(String... args) throws Exception {
180
init();
181
verifyInvokerBytecodeGenerator();
182
verifyASM();
183
}
184
}
185
186