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
26 package java.lang.invoke;
27
28 import java.util.Map;
29 import jdk.internal.org.objectweb.asm.ClassWriter;
30 import jdk.internal.org.objectweb.asm.Opcodes;
31
32 import java.util.ArrayList;
33 import java.util.HashSet;
34
35 /**
36 * Helper class to assist the GenerateJLIClassesPlugin to get access to
37 * generate classes ahead of time.
38 */
39 class GenerateJLIClassesHelper {
40
41 static byte[] generateBasicFormsClassBytes(String className) {
42 ArrayList<LambdaForm> forms = new ArrayList<>();
43 ArrayList<String> names = new ArrayList<>();
44 HashSet<String> dedupSet = new HashSet<>();
45 for (LambdaForm.BasicType type : LambdaForm.BasicType.values()) {
46 LambdaForm zero = LambdaForm.zeroForm(type);
47 String name = zero.kind.defaultLambdaName
48 + "_" + zero.returnType().basicTypeChar();
49 if (dedupSet.add(name)) {
50 names.add(name);
51 forms.add(zero);
52 }
53
54 LambdaForm identity = LambdaForm.identityForm(type);
55 name = identity.kind.defaultLambdaName
56 + "_" + identity.returnType().basicTypeChar();
57 if (dedupSet.add(name)) {
58 names.add(name);
59 forms.add(identity);
60 }
61 }
62 return generateCodeBytesForLFs(className,
63 names.toArray(new String[0]),
64 forms.toArray(new LambdaForm[0]));
65 }
66
67 static byte[] generateDirectMethodHandleHolderClassBytes(String className,
68 MethodType[] methodTypes, int[] types) {
69 LambdaForm[] forms = new LambdaForm[methodTypes.length];
70 String[] names = new String[methodTypes.length];
71 for (int i = 0; i < forms.length; i++) {
72 forms[i] = DirectMethodHandle.makePreparedLambdaForm(methodTypes[i],
73 types[i]);
74 names[i] = forms[i].kind.defaultLambdaName;
75 }
76 return generateCodeBytesForLFs(className, names, forms);
77 }
78
79 static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
80 MethodType[] methodTypes) {
81
82 HashSet<MethodType> dedupSet = new HashSet<>();
83 ArrayList<LambdaForm> forms = new ArrayList<>();
84 ArrayList<String> names = new ArrayList<>();
85 for (int i = 0; i < methodTypes.length; i++) {
86 // generate methods representing the DelegatingMethodHandle
87 if (dedupSet.add(methodTypes[i])) {
88 // reinvokers are variant with the associated SpeciesData
89 // and shape of the target LF, but we can easily pregenerate
90 // the basic reinvokers associated with Species_L. Ultimately we
91 // may want to consider pregenerating more of these, which will
92 // require an even more complex naming scheme
93 LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]);
94 forms.add(reinvoker);
95 String speciesSig = BoundMethodHandle
96 .speciesData(reinvoker).fieldSignature();
149 MethodTypeForm.LF_DELEGATE,
150 DelegatingMethodHandle.class,
151 DelegatingMethodHandle.NF_getTarget);
152 }
153
154 static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
155 final String types) {
156 for (char c : types.toCharArray()) {
157 if ("LIJFD".indexOf(c) < 0) {
158 throw new IllegalArgumentException("All characters must "
159 + "correspond to a basic field type: LIJFD");
160 }
161 }
162 String shortTypes = LambdaForm.shortenSignature(types);
163 final String className =
164 BoundMethodHandle.Factory.speciesInternalClassName(shortTypes);
165 return Map.entry(className,
166 BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
167 shortTypes, types, className));
168 }
169 }
|
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
26 package java.lang.invoke;
27
28 import java.util.Map;
29 import jdk.internal.org.objectweb.asm.ClassWriter;
30 import jdk.internal.org.objectweb.asm.Opcodes;
31 import java.util.ArrayList;
32 import java.util.HashSet;
33 import sun.invoke.util.Wrapper;
34
35 import static java.lang.invoke.MethodHandleNatives.Constants.*;
36
37 /**
38 * Helper class to assist the GenerateJLIClassesPlugin to get access to
39 * generate classes ahead of time.
40 */
41 class GenerateJLIClassesHelper {
42
43 static byte[] generateBasicFormsClassBytes(String className) {
44 ArrayList<LambdaForm> forms = new ArrayList<>();
45 ArrayList<String> names = new ArrayList<>();
46 HashSet<String> dedupSet = new HashSet<>();
47 for (LambdaForm.BasicType type : LambdaForm.BasicType.values()) {
48 LambdaForm zero = LambdaForm.zeroForm(type);
49 String name = zero.kind.defaultLambdaName
50 + "_" + zero.returnType().basicTypeChar();
51 if (dedupSet.add(name)) {
52 names.add(name);
53 forms.add(zero);
54 }
55
56 LambdaForm identity = LambdaForm.identityForm(type);
57 name = identity.kind.defaultLambdaName
58 + "_" + identity.returnType().basicTypeChar();
59 if (dedupSet.add(name)) {
60 names.add(name);
61 forms.add(identity);
62 }
63 }
64 return generateCodeBytesForLFs(className,
65 names.toArray(new String[0]),
66 forms.toArray(new LambdaForm[0]));
67 }
68
69 static byte[] generateDirectMethodHandleHolderClassBytes(String className,
70 MethodType[] methodTypes, int[] types) {
71 ArrayList<LambdaForm> forms = new ArrayList<>();
72 ArrayList<String> names = new ArrayList<>();
73 for (int i = 0; i < methodTypes.length; i++) {
74 LambdaForm form = DirectMethodHandle
75 .makePreparedLambdaForm(methodTypes[i], types[i]);
76 forms.add(form);
77 names.add(form.kind.defaultLambdaName);
78 }
79 for (Wrapper wrapper : Wrapper.values()) {
80 if (wrapper == Wrapper.VOID) {
81 continue;
82 }
83 for (byte b = DirectMethodHandle.AF_GETFIELD; b < DirectMethodHandle.AF_LIMIT; b++) {
84 int ftype = DirectMethodHandle.ftypeKind(wrapper.primitiveType());
85 LambdaForm form = DirectMethodHandle
86 .makePreparedFieldLambdaForm(b, /*isVolatile*/false, ftype);
87 if (form.kind != LambdaForm.Kind.GENERIC) {
88 forms.add(form);
89 names.add(form.kind.defaultLambdaName);
90 }
91 // volatile
92 form = DirectMethodHandle
93 .makePreparedFieldLambdaForm(b, /*isVolatile*/true, ftype);
94 if (form.kind != LambdaForm.Kind.GENERIC) {
95 forms.add(form);
96 names.add(form.kind.defaultLambdaName);
97 }
98 }
99 }
100 return generateCodeBytesForLFs(className,
101 names.toArray(new String[0]),
102 forms.toArray(new LambdaForm[0]));
103 }
104
105 static byte[] generateDelegatingMethodHandleHolderClassBytes(String className,
106 MethodType[] methodTypes) {
107
108 HashSet<MethodType> dedupSet = new HashSet<>();
109 ArrayList<LambdaForm> forms = new ArrayList<>();
110 ArrayList<String> names = new ArrayList<>();
111 for (int i = 0; i < methodTypes.length; i++) {
112 // generate methods representing the DelegatingMethodHandle
113 if (dedupSet.add(methodTypes[i])) {
114 // reinvokers are variant with the associated SpeciesData
115 // and shape of the target LF, but we can easily pregenerate
116 // the basic reinvokers associated with Species_L. Ultimately we
117 // may want to consider pregenerating more of these, which will
118 // require an even more complex naming scheme
119 LambdaForm reinvoker = makeReinvokerFor(methodTypes[i]);
120 forms.add(reinvoker);
121 String speciesSig = BoundMethodHandle
122 .speciesData(reinvoker).fieldSignature();
175 MethodTypeForm.LF_DELEGATE,
176 DelegatingMethodHandle.class,
177 DelegatingMethodHandle.NF_getTarget);
178 }
179
180 static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
181 final String types) {
182 for (char c : types.toCharArray()) {
183 if ("LIJFD".indexOf(c) < 0) {
184 throw new IllegalArgumentException("All characters must "
185 + "correspond to a basic field type: LIJFD");
186 }
187 }
188 String shortTypes = LambdaForm.shortenSignature(types);
189 final String className =
190 BoundMethodHandle.Factory.speciesInternalClassName(shortTypes);
191 return Map.entry(className,
192 BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
193 shortTypes, types, className));
194 }
195
196 }
|