diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2016-02-12 11:57:21 +1000 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2016-02-12 11:57:21 +1000 |
commit | a80f6a00a8519766599e5ca0db61570b7252b584 (patch) | |
tree | 9f758cc64badd074f526b040c233a01af49b95b3 /src/library | |
parent | 6d09a1ba5fffadd1d886afb66ab4496291fda3dd (diff) | |
parent | df0d105f90816960b711c35a3289ff460295d1cc (diff) | |
download | scala-a80f6a00a8519766599e5ca0db61570b7252b584.tar.gz scala-a80f6a00a8519766599e5ca0db61570b7252b584.tar.bz2 scala-a80f6a00a8519766599e5ca0db61570b7252b584.zip |
Merge pull request #4896 from retronym/topic/indy-all-the-things
Use invokedynamic for structural calls, symbol literals, lambda ser.
Diffstat (limited to 'src/library')
-rw-r--r-- | src/library/scala/runtime/LambdaDeserialize.java | 29 | ||||
-rw-r--r-- | src/library/scala/runtime/StructuralCallSite.java | 43 | ||||
-rw-r--r-- | src/library/scala/runtime/SymbolLiteral.java | 20 |
3 files changed, 92 insertions, 0 deletions
diff --git a/src/library/scala/runtime/LambdaDeserialize.java b/src/library/scala/runtime/LambdaDeserialize.java new file mode 100644 index 0000000000..e239debf25 --- /dev/null +++ b/src/library/scala/runtime/LambdaDeserialize.java @@ -0,0 +1,29 @@ +package scala.runtime; + + +import java.lang.invoke.*; +import java.util.Arrays; +import java.util.HashMap; + +public final class LambdaDeserialize { + + private MethodHandles.Lookup lookup; + private final HashMap<String, MethodHandle> cache = new HashMap<>(); + private final LambdaDeserializer$ l = LambdaDeserializer$.MODULE$; + + private LambdaDeserialize(MethodHandles.Lookup lookup) { + this.lookup = lookup; + } + + public Object deserializeLambda(SerializedLambda serialized) { + return l.deserializeLambda(lookup, cache, serialized); + } + + public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName, + MethodType invokedType) throws Throwable { + MethodType type = MethodType.fromMethodDescriptorString("(Ljava/lang/invoke/SerializedLambda;)Ljava/lang/Object;", lookup.getClass().getClassLoader()); + MethodHandle deserializeLambda = lookup.findVirtual(LambdaDeserialize.class, "deserializeLambda", type); + MethodHandle exact = deserializeLambda.bindTo(new LambdaDeserialize(lookup)).asType(invokedType); + return new ConstantCallSite(exact); + } +} diff --git a/src/library/scala/runtime/StructuralCallSite.java b/src/library/scala/runtime/StructuralCallSite.java new file mode 100644 index 0000000000..f73b4f08e6 --- /dev/null +++ b/src/library/scala/runtime/StructuralCallSite.java @@ -0,0 +1,43 @@ +package scala.runtime; + + +import java.lang.invoke.*; +import java.lang.ref.SoftReference; +import java.lang.reflect.Method; + +public final class StructuralCallSite { + + private Class<?>[] parameterTypes; + private SoftReference<MethodCache> cache = new SoftReference<>(new EmptyMethodCache()); + + private StructuralCallSite(MethodType callType) { + parameterTypes = callType.parameterArray(); + } + + public MethodCache get() { + MethodCache cache = this.cache.get(); + if (cache == null) { + cache = new EmptyMethodCache(); + this.cache = new SoftReference<>(cache); + } + return cache; + } + + public Method find(Class<?> receiver) { + return get().find(receiver); + } + + public Method add(Class<?> receiver, Method m) { + cache = new SoftReference<MethodCache>(get().add(receiver, m)); + return m; + } + public Class<?>[] parameterTypes() { + return parameterTypes; + } + + public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName, + MethodType invokedType, MethodType reflectiveCallType) throws Throwable { + StructuralCallSite structuralCallSite = new StructuralCallSite(reflectiveCallType); + return new ConstantCallSite(MethodHandles.constant(StructuralCallSite.class, structuralCallSite)); + } +} diff --git a/src/library/scala/runtime/SymbolLiteral.java b/src/library/scala/runtime/SymbolLiteral.java new file mode 100644 index 0000000000..09a66c83d5 --- /dev/null +++ b/src/library/scala/runtime/SymbolLiteral.java @@ -0,0 +1,20 @@ +package scala.runtime; + +import java.lang.invoke.*; +import java.util.regex.Pattern; + +public final class SymbolLiteral { + private SymbolLiteral() { + } + + public static CallSite bootstrap(MethodHandles.Lookup lookup, String invokedName, + MethodType invokedType, + String value) throws Throwable { + ClassLoader classLoader = lookup.lookupClass().getClassLoader(); + MethodType type = MethodType.fromMethodDescriptorString("(Ljava/lang/Object;)Ljava/lang/Object;", classLoader); + Class<?> symbolClass = Class.forName("scala.Symbol", false, classLoader); + MethodHandle factoryMethod = lookup.findStatic(symbolClass, "apply", type); + Object symbolValue = factoryMethod.invokeWithArguments(value); + return new ConstantCallSite(MethodHandles.constant(symbolClass, symbolValue)); + } +} |