summaryrefslogtreecommitdiff
path: root/src/library
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2016-02-12 11:57:21 +1000
committerJason Zaugg <jzaugg@gmail.com>2016-02-12 11:57:21 +1000
commita80f6a00a8519766599e5ca0db61570b7252b584 (patch)
tree9f758cc64badd074f526b040c233a01af49b95b3 /src/library
parent6d09a1ba5fffadd1d886afb66ab4496291fda3dd (diff)
parentdf0d105f90816960b711c35a3289ff460295d1cc (diff)
downloadscala-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.java29
-rw-r--r--src/library/scala/runtime/StructuralCallSite.java43
-rw-r--r--src/library/scala/runtime/SymbolLiteral.java20
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));
+ }
+}