Compile Time Extraction of Line and Column Numbers, Class Name, Method Names as Opposed to Stack Walking
Remi Forax
forax at univ-mlv.fr
Tue Jan 12 08:24:35 UTC 2021
> De: "Suminda Sirinath Salpitikorala Dharmasena" <sirinath1978m at gmail.com>
> À: "compiler-dev" <compiler-dev at openjdk.java.net>
> Envoyé: Mardi 12 Janvier 2021 07:20:44
> Objet: Compile Time Extraction of Line and Column Numbers, Class Name, Method
> Names as Opposed to Stack Walking
> Hello,
Hello
> With all the up coming changes in Java is it possible to give a way to extract
> static meta data in a program for logging like line numbers, method details,
> class name, etc. without resorting to stack walking.
> Also stack walking can be optimised to be more efficient.
StackWalker is not that bad, especially if you call it once.
Here is an example of how to extract all the stack information efficiently, by calling the StackWalker only once and caching the result.
public class MetaDataTest {
private static final MetaData<StackWalker.StackFrame> META_DATA = MetaData.create(StackWalker.getInstance(), frames -> frames.findFirst().orElseThrow());
@Test
public void create() {
System.out.println(META_DATA.get()); // it's a constant for the JIT !
}
}
> Suminda
regards,
Rémi
---
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.invoke.MutableCallSite;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.stream.Stream;
@FunctionalInterface
public interface MetaData<T> {
T get();
@SuppressWarnings("unchecked")
static <T> MetaData<T> create(StackWalker stackWalker, Function<? super Stream<StackWalker.StackFrame>, ? extends T> fun) {
Objects.requireNonNull(stackWalker);
Objects.requireNonNull(fun);
var target = createMH(() -> stackWalker.walk(fun.compose(frames -> frames.skip(3))));
return () -> {
try {
return (T) target.invokeExact();
} catch (RuntimeException | Error e) {
throw e;
} catch(Throwable t) {
throw new UndeclaredThrowableException(t);
}
};
}
private static MethodHandle createMH(Supplier<?> supplier) {
return new MostlyConstant(supplier).dynamicInvoker();
}
/*private*/ final class MostlyConstant extends MutableCallSite {
private final Supplier<?> supplier;
private MostlyConstant(Supplier<?> supplier) {
super(MethodType.methodType(Object.class));
this.supplier = supplier;
setTarget(FALLBACK.bindTo(this));
}
private Object fallback() {
var value = supplier.get();
setTarget(MethodHandles.constant(Object.class, value));
return value;
}
static final MethodHandle FALLBACK;
static {
var lookup = MethodHandles.lookup();
try {
FALLBACK = lookup.findVirtual(MostlyConstant.class, "fallback", MethodType.methodType(Object.class));
} catch (NoSuchMethodException | IllegalAccessException e) {
throw new AssertionError(e);
}
}
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20210112/a038d9f5/attachment.htm>
More information about the compiler-dev
mailing list