Skip to content

Commit ff187e2

Browse files
cpovirkGoogle Java Core Libraries
authored andcommitted
Use java.util.zip.CRC32C directly when available instead of using it through MethodHandle.
This became possible with #6549. See #6549 (comment) and the next couple posts. We still use reflection in `Crc32CSupplier.pickFunction()` to determine whether to use enter this `ChecksumType.CRC_32C` code path or to instead use `ABSTRACT_HASH_FUNCTION`. RELNOTES=n/a PiperOrigin-RevId: 793810002
1 parent 6a5ca21 commit ff187e2

File tree

1 file changed

+5
-50
lines changed

1 file changed

+5
-50
lines changed

guava/src/com/google/common/hash/Hashing.java

Lines changed: 5 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,9 @@
1616

1717
import static com.google.common.base.Preconditions.checkArgument;
1818
import static com.google.common.base.Preconditions.checkNotNull;
19-
import static com.google.common.hash.SneakyThrows.sneakyThrow;
20-
import static java.lang.invoke.MethodType.methodType;
2119

2220
import com.google.errorprone.annotations.Immutable;
2321
import com.google.j2objc.annotations.J2ObjCIncompatible;
24-
import java.lang.invoke.MethodHandle;
25-
import java.lang.invoke.MethodHandles;
2622
import java.security.Key;
2723
import java.util.ArrayList;
2824
import java.util.Arrays;
@@ -31,6 +27,7 @@
3127
import java.util.List;
3228
import java.util.zip.Adler32;
3329
import java.util.zip.CRC32;
30+
import java.util.zip.CRC32C;
3431
import java.util.zip.Checksum;
3532
import javax.crypto.spec.SecretKeySpec;
3633
import org.jspecify.annotations.Nullable;
@@ -495,9 +492,12 @@ public Checksum get() {
495492
},
496493
@J2ObjCIncompatible
497494
CRC_32C("Hashing.crc32c()") {
495+
// Crc32CSupplier.pickFunction uses this only when it finds that CRC32C is available.
496+
@SuppressWarnings("Java8ApiChecker")
497+
@IgnoreJRERequirement
498498
@Override
499499
public Checksum get() {
500-
return Crc32cMethodHandles.newCrc32c();
500+
return new CRC32C();
501501
}
502502
},
503503
ADLER_32("Hashing.adler32()") {
@@ -514,51 +514,6 @@ public Checksum get() {
514514
}
515515
}
516516

517-
@J2ObjCIncompatible
518-
@SuppressWarnings("unused")
519-
private static final class Crc32cMethodHandles {
520-
private static final MethodHandle CONSTRUCTOR = crc32cConstructor();
521-
522-
@IgnoreJRERequirement // https://github.com/mojohaus/animal-sniffer/issues/67
523-
static Checksum newCrc32c() {
524-
try {
525-
return (Checksum) CONSTRUCTOR.invokeExact();
526-
} catch (Throwable e) {
527-
// The constructor has no `throws` clause.
528-
throw sneakyThrow(e);
529-
}
530-
}
531-
532-
private static MethodHandle crc32cConstructor() {
533-
try {
534-
Class<?> clazz = Class.forName("java.util.zip.CRC32C");
535-
/*
536-
* We can't cast to CRC32C at the call site because we support building with Java 8
537-
* (https://github.com/google/guava/issues/6549). So we have to use asType() to change from
538-
* CRC32C to Checksum. This may carry some performance cost
539-
* (https://stackoverflow.com/a/22321671/28465), but I'd have to benchmark more carefully to
540-
* even detect it.
541-
*/
542-
return MethodHandles.lookup()
543-
.findConstructor(clazz, methodType(void.class))
544-
.asType(methodType(Checksum.class));
545-
} catch (ClassNotFoundException e) {
546-
// We check that the class is available before calling this method.
547-
throw new AssertionError(e);
548-
} catch (IllegalAccessException e) {
549-
// That API is public.
550-
throw newLinkageError(e);
551-
} catch (NoSuchMethodException e) {
552-
// That constructor exists.
553-
throw newLinkageError(e);
554-
}
555-
}
556-
557-
private static LinkageError newLinkageError(Throwable cause) {
558-
return new LinkageError(cause.toString(), cause);
559-
}
560-
}
561-
562517
/**
563518
* Returns a hash function implementing FarmHash's Fingerprint64, an open-source algorithm.
564519
*

0 commit comments

Comments
 (0)