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
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
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();
123 assert(speciesSig.equals("L"));
124 names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig);
125
126 LambdaForm delegate = makeDelegateFor(methodTypes[i]);
127 forms.add(delegate);
128 names.add(delegate.kind.defaultLambdaName);
129 }
130 }
131 return generateCodeBytesForLFs(className,
132 names.toArray(new String[0]),
133 forms.toArray(new LambdaForm[0]));
134 }
135
136 static byte[] generateInvokersHolderClassBytes(String className,
137 MethodType[] methodTypes) {
138
139 HashSet<MethodType> dedupSet = new HashSet<>();
140 ArrayList<LambdaForm> forms = new ArrayList<>();
141 ArrayList<String> names = new ArrayList<>();
142 int[] types = {
188 g.addMethod();
189 }
190
191 private static LambdaForm makeReinvokerFor(MethodType type) {
192 MethodHandle emptyHandle = MethodHandles.empty(type);
193 return DelegatingMethodHandle.makeReinvokerForm(emptyHandle,
194 MethodTypeForm.LF_REBIND,
195 BoundMethodHandle.speciesData_L(),
196 BoundMethodHandle.speciesData_L().getterFunction(0));
197 }
198
199 private static LambdaForm makeDelegateFor(MethodType type) {
200 MethodHandle handle = MethodHandles.empty(type);
201 return DelegatingMethodHandle.makeReinvokerForm(
202 handle,
203 MethodTypeForm.LF_DELEGATE,
204 DelegatingMethodHandle.class,
205 DelegatingMethodHandle.NF_getTarget);
206 }
207
208 static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(
209 final String types) {
210 for (char c : types.toCharArray()) {
211 if ("LIJFD".indexOf(c) < 0) {
212 throw new IllegalArgumentException("All characters must "
213 + "correspond to a basic field type: LIJFD");
214 }
215 }
216 String shortTypes = LambdaForm.shortenSignature(types);
217 final String className =
218 BoundMethodHandle.Factory.speciesInternalClassName(shortTypes);
219 return Map.entry(className,
220 BoundMethodHandle.Factory.generateConcreteBMHClassBytes(
221 shortTypes, types, className));
222 }
223
224 }
|
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
26 package java.lang.invoke;
27
28 import jdk.internal.org.objectweb.asm.ClassWriter;
29 import jdk.internal.org.objectweb.asm.Opcodes;
30 import sun.invoke.util.Wrapper;
31
32 import java.util.ArrayList;
33 import java.util.HashSet;
34 import java.util.List;
35 import java.util.Map;
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
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.speciesDataFor(reinvoker).key();
122 assert(speciesSig.equals("L"));
123 names.add(reinvoker.kind.defaultLambdaName + "_" + speciesSig);
124
125 LambdaForm delegate = makeDelegateFor(methodTypes[i]);
126 forms.add(delegate);
127 names.add(delegate.kind.defaultLambdaName);
128 }
129 }
130 return generateCodeBytesForLFs(className,
131 names.toArray(new String[0]),
132 forms.toArray(new LambdaForm[0]));
133 }
134
135 static byte[] generateInvokersHolderClassBytes(String className,
136 MethodType[] methodTypes) {
137
138 HashSet<MethodType> dedupSet = new HashSet<>();
139 ArrayList<LambdaForm> forms = new ArrayList<>();
140 ArrayList<String> names = new ArrayList<>();
141 int[] types = {
187 g.addMethod();
188 }
189
190 private static LambdaForm makeReinvokerFor(MethodType type) {
191 MethodHandle emptyHandle = MethodHandles.empty(type);
192 return DelegatingMethodHandle.makeReinvokerForm(emptyHandle,
193 MethodTypeForm.LF_REBIND,
194 BoundMethodHandle.speciesData_L(),
195 BoundMethodHandle.speciesData_L().getterFunction(0));
196 }
197
198 private static LambdaForm makeDelegateFor(MethodType type) {
199 MethodHandle handle = MethodHandles.empty(type);
200 return DelegatingMethodHandle.makeReinvokerForm(
201 handle,
202 MethodTypeForm.LF_DELEGATE,
203 DelegatingMethodHandle.class,
204 DelegatingMethodHandle.NF_getTarget);
205 }
206
207 @SuppressWarnings({"rawtypes", "unchecked"})
208 static Map.Entry<String, byte[]> generateConcreteBMHClassBytes(final String types) {
209 for (char c : types.toCharArray()) {
210 if ("LIJFD".indexOf(c) < 0) {
211 throw new IllegalArgumentException("All characters must "
212 + "correspond to a basic field type: LIJFD");
213 }
214 }
215 final BoundMethodHandle.SpeciesData species = BoundMethodHandle.SPECIALIZER.findSpecies(types);
216 final String className = species.speciesCode().getName();
217 final ClassSpecializer.Factory factory = BoundMethodHandle.SPECIALIZER.factory();
218 final byte[] code = factory.generateConcreteSpeciesCodeFile(className, species);
219 return Map.entry(className.replace('.', '/'), code);
220 }
221
222 }
|