Skip to content

Commit 01368fe

Browse files
bokkenbo8979
and
bo8979
authored
internal: use LambdaMetafactory to generate java.util.zip.CRC32C instances (#595)
currently we have written a lambda (turns into anonymous class) which invokes a MethodHandle for the java.util.zip.CRC32C constructor as the Supplier<Checksum> implementation. This has 2 layers of misdirection. The Supplier implementation spun up by the jvm calls the anonymous lambda class, which then calls the MethodHandle invoke. This leads to stack traces like: use LambdaMetafactory to generate a Supplier<Checksum> which calls the java.util.zip.CRC32C Co-authored-by: bo8979 <bo8979@cerner.com>
1 parent 341377b commit 01368fe

File tree

1 file changed

+22
-15
lines changed

1 file changed

+22
-15
lines changed

src/main/java/org/xerial/snappy/SnappyFramed.java

+22-15
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package org.xerial.snappy;
55

66
import java.io.IOException;
7+
import java.lang.invoke.LambdaMetafactory;
78
import java.lang.invoke.MethodHandle;
89
import java.lang.invoke.MethodHandles;
910
import java.lang.invoke.MethodType;
@@ -37,21 +38,27 @@ final class SnappyFramed
3738
Supplier<Checksum> supplier = null;
3839
try
3940
{
40-
final Class crc32cClazz = Class.forName("java.util.zip.CRC32C");
41-
final MethodHandles.Lookup lookup = MethodHandles.publicLookup();
42-
43-
final MethodHandle conHandle = lookup.findConstructor(crc32cClazz, MethodType.methodType(void.class))
44-
.asType(MethodType.methodType(Checksum.class));
45-
supplier = () -> {
46-
try
47-
{
48-
return (Checksum) conHandle.invokeExact();
49-
}
50-
catch (Throwable e)
51-
{
52-
throw new IllegalStateException(e);
53-
}
54-
};
41+
final Class<?> crc32cClazz = Class.forName("java.util.zip.CRC32C");
42+
// using LambdaMetafactory requires a caller sensitive lookup
43+
final MethodHandles.Lookup lookup = MethodHandles.lookup();
44+
final MethodHandle conHandle = lookup.findConstructor(crc32cClazz, MethodType.methodType(void.class));
45+
46+
// use LambdaMetafactory to generate an implementation of Supplier<Checksum> which invokes
47+
// the java.util.zip.CRC32C default constructor
48+
supplier = (Supplier<Checksum>) LambdaMetafactory.metafactory(lookup,
49+
// method name on Supplier
50+
"get",
51+
// functional interface to be created by factory
52+
MethodType.methodType(Supplier.class),
53+
// type of the functional interface
54+
// uses a generic, so erasure to Object
55+
MethodType.methodType(Object.class),
56+
// the method handle to call
57+
conHandle,
58+
// type as used at call site
59+
MethodType.methodType(Checksum.class))
60+
.getTarget()
61+
.invoke();
5562
}
5663
catch(Throwable t)
5764
{

0 commit comments

Comments
 (0)