Skip to content

Instantly share code, notes, and snippets.

@forax
Last active July 23, 2016 15:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save forax/2ea146eacaf5608cec93e8066e9ae665 to your computer and use it in GitHub Desktop.
Save forax/2ea146eacaf5608cec93e8066e9ae665 to your computer and use it in GitHub Desktop.
same PIC but the test code is slighly altered
package java.lang.invoke;
import java.lang.invoke.MethodHandles.Lookup;
import java.net.URI;
import java.net.URISyntaxException;
// compile with:
// /usr/jdk/jdk-9/bin/javac -Xmodule:java.base -d ../classes java/lang/invoke/FunPIC.java
// execute with:
// /usr/jdk/jdk-9/bin/java -Xpatch:java.base=../classes -m java.base/java.lang.invoke.FunPIC
public class FunPIC {
@jdk.internal.vm.annotation.Stable static MethodHandle[] GUARDS = new MethodHandle[2];
@jdk.internal.vm.annotation.Stable static MethodHandle[] TARGETS = new MethodHandle[2];
@jdk.internal.vm.annotation.ForceInline
private static int m(Object o) throws Throwable {
if (GUARDS[0] == null) {
return deopt(o, 0);
}
if ((boolean)GUARDS[0].invokeExact(o)) {
return (int)TARGETS[0].invokeExact(o);
}
if (GUARDS[1] == null) {
return deopt(o, 1);
}
if ((boolean)GUARDS[1].invokeExact(o)) {
return (int)TARGETS[1].invokeExact(o);
}
return deopt(o, -1);
}
public static int test(Object o) {
try {
return m(o);
} catch (Throwable e) {
throw new AssertionError(e);
}
}
public static int test2(Object o) {
try {
return m(o);
} catch (Throwable e) {
throw new AssertionError(e);
}
}
public static int loop(Object o, Object o2) {
int sum = 0;
for(int i = 0; i < 100_000; i++) {
sum += test(o);
sum += test2(o2);
}
return sum;
}
public static void main(String[] args) throws URISyntaxException {
Object[] array = { "hello", new URI("http://hello/") /*, 4.5*/ };
Object[] array2 = { "hello", "2" /*, 4.5*/ };
int sum = 0;
for(int i = 0; i < array.length; i++) {
sum += loop(array[i], array2[i]);
}
System.out.println(sum);
}
@jdk.internal.vm.annotation.DontInline
private static int deopt(Object receiver, int i) throws Throwable {
System.out.println("deopt " + i);
if (i == -1) {
throw new UnsupportedOperationException("we are morons");
}
Class<?> receiverClass = receiver.getClass();
MethodHandle guard = MethodHandles.insertArguments(TYPE_CHECK, 1, receiverClass);
MethodHandle target;
try {
target = LOOKUP.findStatic(FunPIC.class, "impl", MethodType.methodType(int.class, receiverClass));
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new AssertionError(e);
}
target = target.asType(MethodType.methodType(int.class, Object.class));
GUARDS[i] = guard;
TARGETS[i] = target;
return (int) target.invokeExact(receiver);
}
private static final Lookup LOOKUP = MethodHandles.Lookup.IMPL_LOOKUP;
private static final MethodHandle TYPE_CHECK;
static {
try {
TYPE_CHECK = LOOKUP.findStatic(FunPIC.class, "typeCheck", MethodType.methodType(boolean.class, Object.class, Class.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new AssertionError(e);
}
}
private static boolean typeCheck(Object o, Class<?> type) {
return o.getClass() == type;
}
private static int ONE = 1;
private static int TWO = 2;
private static int impl(String s) {
/*int sum = 0;
for(int c: s.toCharArray()) {
sum += c;
}
return sum;*/
return ONE;
}
private static int impl(URI u) {
/*
int sum = 0;
for(int c: u.toASCIIString().toCharArray()) {
sum += c;
}
return sum;
*/
return TWO;
}
private static int impl(Integer i) {
return ((Integer)i.intValue()).intValue();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment