Skip to content

Instantly share code, notes, and snippets.

@forax
Created February 18, 2018 21:32
Show Gist options
  • Save forax/b0fee828c2440dfa7f9a900e6fb288cb to your computer and use it in GitHub Desktop.
Save forax/b0fee828c2440dfa7f9a900e6fb288cb to your computer and use it in GitHub Desktop.
How to create a constant for the VM (JIT) that can change
package fr.umlv.inside.almostconst;
import java.util.function.Supplier;
public class Main {
private static final MostlyConstant<String> FOO = new MostlyConstant<>("HELL");
private static final Supplier<String> FOO_GETTER = FOO.getter();
private static int test(int max, int change) {
int sum = 0;
for(int i = 0; i < max; i++) {
if (i == change) {
FOO.set("BAR");
}
sum += FOO_GETTER.get().length();
}
return sum;
}
private static int SINK;
public static void main(String[] args) {
SINK += test(10, 5);
SINK += test(10, 5);
SINK += test(10, 5);
FOO.set("HELL");
System.out.println(test(10_000_000, 5_000_000));
}
}
package fr.umlv.inside.almostconst;
import static java.lang.invoke.MethodHandles.constant;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MutableCallSite;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.function.Supplier;
public class MostlyConstant<T> {
private final MutableCallSite callSite;
private final MethodHandle invoker;
public MostlyConstant(T constant) {
MutableCallSite callSite = new MutableCallSite(constant(Object.class, constant));
this.callSite = callSite;
this.invoker = callSite.dynamicInvoker();
}
public void set(T constant) {
callSite.setTarget(constant(Object.class, constant));
}
public Supplier<T> getter() {
MethodHandle invoker = this.invoker;
return () -> {
try {
return (T)invoker.invokeExact();
} catch (Throwable e) {
throw rethrow(e);
}
};
}
static UndeclaredThrowableException rethrow(Throwable t) {
if (t instanceof RuntimeException) {
throw (RuntimeException)t;
}
if (t instanceof Error) {
throw (Error)t;
}
return new UndeclaredThrowableException(t);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment