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 jdk.experimental.value;
27
28 import jdk.experimental.bytecode.BasicClassBuilder.BasicPoolHelper;
29 import jdk.experimental.bytecode.BasicClassBuilder.BasicTypeHelper;
30 import jdk.experimental.bytecode.ClassBuilder;
31 import jdk.experimental.bytecode.CodeBuilder;
32 import jdk.experimental.bytecode.Flag;
33 import jdk.experimental.bytecode.MethodBuilder;
34 import jdk.experimental.bytecode.PoolHelper;
35 import jdk.experimental.bytecode.TypeHelper;
36 import jdk.experimental.bytecode.TypeTag;
37 import jdk.experimental.bytecode.TypedCodeBuilder;
38 import jdk.experimental.value.MethodHandleBuilder.IsolatedMethodBuilder.IsolatedMethodPoolHelper;
39 import jdk.internal.misc.Unsafe;
40 import sun.security.action.GetBooleanAction;
41 import valhalla.shady.MinimalValueTypes_1_0;
42
43 import java.lang.invoke.MethodHandle;
44 import java.lang.invoke.MethodHandles.Lookup;
45 import java.lang.invoke.MethodType;
46 import java.security.AccessController;
47 import java.util.HashMap;
48 import java.util.Iterator;
49 import java.util.Map;
50 import java.util.PropertyPermission;
51 import java.util.function.Consumer;
52 import java.util.function.Function;
53
54 /**
55 * Utility class for building method handles.
56 */
57 public class MethodHandleBuilder {
58
59 static final Unsafe UNSAFE = Unsafe.getUnsafe();
60
61 static final boolean ENABLE_POOL_PATCHES;
62
63 static {
64 final String key = "valhalla.enablePoolPatches";
65 ENABLE_POOL_PATCHES = key == null ? false :
66 AccessController.doPrivileged(
67 new GetBooleanAction(key), null,
68 new PropertyPermission(key , "read"));
69 }
70
71 public static MethodHandle loadCode(Lookup lookup, String name, MethodType type, Consumer<? super MethodHandleCodeBuilder> builder) {
72 return loadCode(lookup, name, type.toMethodDescriptorString(), builder);
73 }
74
75 public static MethodHandle loadCode(Lookup lookup, String name, String type, Consumer<? super MethodHandleCodeBuilder> builder) {
76 return loadCode(lookup, name, name, type, MethodHandleCodeBuilder::new,
77 clazz -> {
78 try {
79 return lookup.findStatic(clazz, name, MethodType.fromMethodDescriptorString(type, lookup.lookupClass().getClassLoader()));
80 } catch (ReflectiveOperationException ex) {
81 throw new IllegalStateException(ex);
82 }
83 },
84 builder);
85 }
86
87 protected static <Z, C extends CodeBuilder<Class<?>, String, byte[], ?>> Z loadCode(
88 Lookup lookup, String className, String methodName, String type,
197 @Override
198 public String commonSupertype(String t1, String t2) {
199 return basicTypeHelper.commonSupertype(t1, t2);
200 }
201
202 @Override
203 public String nullType() {
204 return basicTypeHelper.nullType();
205 }
206 }
207
208 static class IsolatedMethodPoolHelper implements PoolHelper<Class<?>, String, byte[]> {
209 BasicPoolHelper basicPoolHelper = new BasicPoolHelper();
210 String clazz;
211
212 IsolatedMethodPoolHelper(String clazz) {
213 this.clazz = clazz;
214 }
215
216 String from(Class<?> c) {
217 String name = c == THIS_CLASS ? clazz : c.getName();
218 return name.replaceAll("\\.", "/");
219 }
220
221 @Override
222 public int putClass(Class<?> symbol) {
223 return basicPoolHelper.putClass(from(symbol));
224 }
225
226 @Override
227 public int putFieldRef(Class<?> owner, CharSequence name, String type) {
228 return basicPoolHelper.putFieldRef(from(owner), name, type);
229 }
230
231 @Override
232 public int putMethodRef(Class<?> owner, CharSequence name, String type, boolean isInterface) {
233 return basicPoolHelper.putMethodRef(from(owner), name, type, isInterface);
234 }
235
236 @Override
237 public int putUtf8(CharSequence s) {
|
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 jdk.experimental.value;
27
28 import jdk.experimental.bytecode.BasicClassBuilder.BasicPoolHelper;
29 import jdk.experimental.bytecode.BasicClassBuilder.BasicTypeHelper;
30 import jdk.experimental.bytecode.ClassBuilder;
31 import jdk.experimental.bytecode.CodeBuilder;
32 import jdk.experimental.bytecode.Flag;
33 import jdk.experimental.bytecode.MethodBuilder;
34 import jdk.experimental.bytecode.PoolHelper;
35 import jdk.experimental.bytecode.TypeHelper;
36 import jdk.experimental.bytecode.TypeTag;
37 import jdk.experimental.bytecode.TypedCodeBuilder;
38 import jdk.experimental.value.MethodHandleBuilder.IsolatedMethodBuilder.IsolatedMethodPoolHelper;
39 import jdk.internal.misc.Unsafe;
40 import sun.security.action.GetPropertyAction;
41 import valhalla.shady.MinimalValueTypes_1_0;
42
43 import java.lang.invoke.MethodHandle;
44 import java.lang.invoke.MethodHandles.Lookup;
45 import java.lang.invoke.MethodType;
46 import java.util.*;
47 import java.util.function.Consumer;
48 import java.util.function.Function;
49
50 /**
51 * Utility class for building method handles.
52 */
53 public class MethodHandleBuilder {
54
55 static final Unsafe UNSAFE = Unsafe.getUnsafe();
56
57 static final boolean ENABLE_POOL_PATCHES;
58 static final boolean MANGLE_CLASS_INFO;
59
60 static {
61 Properties props = GetPropertyAction.privilegedGetProperties();
62 ENABLE_POOL_PATCHES = Boolean.parseBoolean(
63 props.getProperty("valhalla.enablePoolPatches"));
64 MANGLE_CLASS_INFO = Boolean.parseBoolean(
65 props.getProperty("valhalla.mangleClassInfo"));
66 }
67
68 public static MethodHandle loadCode(Lookup lookup, String name, MethodType type, Consumer<? super MethodHandleCodeBuilder> builder) {
69 return loadCode(lookup, name, type.toMethodDescriptorString(), builder);
70 }
71
72 public static MethodHandle loadCode(Lookup lookup, String name, String type, Consumer<? super MethodHandleCodeBuilder> builder) {
73 return loadCode(lookup, name, name, type, MethodHandleCodeBuilder::new,
74 clazz -> {
75 try {
76 return lookup.findStatic(clazz, name, MethodType.fromMethodDescriptorString(type, lookup.lookupClass().getClassLoader()));
77 } catch (ReflectiveOperationException ex) {
78 throw new IllegalStateException(ex);
79 }
80 },
81 builder);
82 }
83
84 protected static <Z, C extends CodeBuilder<Class<?>, String, byte[], ?>> Z loadCode(
85 Lookup lookup, String className, String methodName, String type,
194 @Override
195 public String commonSupertype(String t1, String t2) {
196 return basicTypeHelper.commonSupertype(t1, t2);
197 }
198
199 @Override
200 public String nullType() {
201 return basicTypeHelper.nullType();
202 }
203 }
204
205 static class IsolatedMethodPoolHelper implements PoolHelper<Class<?>, String, byte[]> {
206 BasicPoolHelper basicPoolHelper = new BasicPoolHelper();
207 String clazz;
208
209 IsolatedMethodPoolHelper(String clazz) {
210 this.clazz = clazz;
211 }
212
213 String from(Class<?> c) {
214 String name;
215 boolean isValue = MinimalValueTypes_1_0.isValueType(c);
216 if (c == THIS_CLASS) {
217 //THIS_CLASS cannot be a DVT (by construction) - never mangle
218 name = clazz;
219 } else {
220 name = (isValue && MANGLE_CLASS_INFO) ?
221 ";Q" + c.getName() + ";" : //mangle DVT name
222 c.getName();
223 }
224 return name.replaceAll("\\.", "/");
225 }
226
227 @Override
228 public int putClass(Class<?> symbol) {
229 return basicPoolHelper.putClass(from(symbol));
230 }
231
232 @Override
233 public int putFieldRef(Class<?> owner, CharSequence name, String type) {
234 return basicPoolHelper.putFieldRef(from(owner), name, type);
235 }
236
237 @Override
238 public int putMethodRef(Class<?> owner, CharSequence name, String type, boolean isInterface) {
239 return basicPoolHelper.putMethodRef(from(owner), name, type, isInterface);
240 }
241
242 @Override
243 public int putUtf8(CharSequence s) {
|