Skip to content

Commit

Permalink
Port StructuralCallSite, LambdaDeserialize to Scala
Browse files Browse the repository at this point in the history
  • Loading branch information
retronym authored and lrytz committed Oct 11, 2018
1 parent 62b310b commit a2e4ec6
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 165 deletions.
62 changes: 0 additions & 62 deletions src/library/scala/runtime/LambdaDeserialize.java

This file was deleted.

44 changes: 44 additions & 0 deletions src/library/scala/runtime/LambdaDeserialize.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.runtime

import java.lang.invoke._
import java.util

import scala.annotation.varargs
import scala.collection.immutable

final class LambdaDeserialize private (lookup: MethodHandles.Lookup, targetMethods: Array[MethodHandle]) {
private val targetMethodMap: util.HashMap[String, MethodHandle] = new util.HashMap[String, MethodHandle](targetMethods.length)

for (targetMethod <- targetMethods) {
val info = lookup.revealDirect(targetMethod)
val key = LambdaDeserialize.nameAndDescriptorKey(info.getName, info.getMethodType.toMethodDescriptorString)
targetMethodMap.put(key, targetMethod)
}

private val cache = new util.HashMap[String, MethodHandle]

def deserializeLambda(serialized: SerializedLambda): AnyRef = LambdaDeserializer.deserializeLambda(lookup, cache, targetMethodMap, serialized)
}

object LambdaDeserialize {
@varargs @throws[Throwable]
def bootstrap(lookup: MethodHandles.Lookup, invokedName: String, invokedType: MethodType, targetMethods: MethodHandle*): CallSite = {
val targetMethodsArray = targetMethods.asInstanceOf[immutable.ArraySeq[_]].unsafeArray.asInstanceOf[Array[MethodHandle]]
val exact = MethodHandleConstants.LAMBDA_DESERIALIZE_DESERIALIZE_LAMBDA.bindTo(new LambdaDeserialize(lookup, targetMethodsArray)).asType(invokedType)
new ConstantCallSite(exact)
}

def nameAndDescriptorKey(name: String, descriptor: String): String = name + descriptor
}
35 changes: 35 additions & 0 deletions src/library/scala/runtime/MethodHandleConstants.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.runtime;

import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.SerializedLambda;

class MethodHandleConstants {
// static final MethodHandles are optimized by the JIT (https://stackoverflow.com/a/14146641/248998)
static final MethodHandle LAMBDA_DESERIALIZE_DESERIALIZE_LAMBDA;

static {
LAMBDA_DESERIALIZE_DESERIALIZE_LAMBDA = lookupDeserialize();
}

private static MethodHandle lookupDeserialize() {
try {
return MethodHandles.lookup().findVirtual(Class.forName("scala.runtime.LambdaDeserialize"), "deserializeLambda", MethodType.methodType(Object.class, SerializedLambda.class));
} catch (NoSuchMethodException | IllegalAccessException | ClassNotFoundException e) {
throw new ExceptionInInitializerError(e);
}
}
}
103 changes: 0 additions & 103 deletions src/library/scala/runtime/StructuralCallSite.java

This file was deleted.

46 changes: 46 additions & 0 deletions src/library/scala/runtime/StructuralCallSite.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* Scala (https://www.scala-lang.org)
*
* Copyright EPFL and Lightbend, Inc.
*
* Licensed under Apache License 2.0
* (http://www.apache.org/licenses/LICENSE-2.0).
*
* See the NOTICE file distributed with this work for
* additional information regarding copyright ownership.
*/

package scala.runtime

import java.lang.invoke._
import java.lang.ref.SoftReference
import java.lang.reflect.Method

final class StructuralCallSite private (callType: MethodType) {
private var cache: SoftReference[MethodCache] = new SoftReference(new EmptyMethodCache)

val parameterTypes: Array[Class[_]] = callType.parameterArray

def get: MethodCache = {
var cache = this.cache.get
if (cache == null) {
cache = new EmptyMethodCache
this.cache = new SoftReference(cache)
}
cache
}

def find(receiver: Class[_]): Method = get.find(receiver)

def add(receiver: Class[_], m: Method): Method = {
cache = new SoftReference(get.add(receiver, m))
m
}
}

object StructuralCallSite {
def bootstrap(lookup: MethodHandles.Lookup, invokedName: String, invokedType: MethodType, reflectiveCallType: MethodType): CallSite = {
val structuralCallSite = new StructuralCallSite(reflectiveCallType)
new ConstantCallSite(MethodHandles.constant(classOf[StructuralCallSite], structuralCallSite))
}
}

0 comments on commit a2e4ec6

Please sign in to comment.