am 0c29232f: Merge "Replaced usages of Unsafe in UnsignedBytes with standard Java"

* commit '0c29232f9e0a18dc064d9f2859f7bff889729002':
  Replaced usages of Unsafe in UnsignedBytes with standard Java
diff --git a/guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java b/guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java
index 19511fc..9b1cac2 100644
--- a/guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java
+++ b/guava-tests/benchmark/com/google/common/primitives/UnsignedBytesBenchmark.java
@@ -36,7 +36,6 @@
   private byte[] ba3;
   private byte[] ba4;
   private Comparator<byte[]> javaImpl;
-  private Comparator<byte[]> unsafeImpl;
 
   // 4, 8, 64, 1K, 1M, 1M (unaligned), 64M, 64M (unaligned)
   //@Param({"4", "8", "64", "1024", "1048576", "1048577", "6710884", "6710883"})
@@ -56,8 +55,6 @@
     ba4[ba1.length - 1] = (byte) 42;
 
     javaImpl = UnsignedBytes.lexicographicalComparatorJavaImpl();
-    unsafeImpl =
-        UnsignedBytes.LexicographicalComparatorHolder.UnsafeComparator.INSTANCE;
   }
 
   @Benchmark void longEqualJava(int reps) {
@@ -68,14 +65,6 @@
     }
   }
 
-  @Benchmark void longEqualUnsafe(int reps) {
-    for (int i = 0; i < reps; ++i) {
-      if (unsafeImpl.compare(ba1, ba2) != 0) {
-        throw new Error(); // deoptimization
-      }
-    }
-  }
-
   @Benchmark void diffLastJava(int reps) {
     for (int i = 0; i < reps; ++i) {
       if (javaImpl.compare(ba3, ba4) == 0) {
@@ -84,14 +73,6 @@
     }
   }
 
-  @Benchmark void diffLastUnsafe(int reps) {
-    for (int i = 0; i < reps; ++i) {
-      if (unsafeImpl.compare(ba3, ba4) == 0) {
-        throw new Error(); // deoptimization
-      }
-    }
-  }
-
   /*
   try {
     UnsignedBytesBenchmark bench = new UnsignedBytesBenchmark();
diff --git a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
index 575eb7e..c74e8a2 100644
--- a/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
+++ b/guava-tests/test/com/google/common/primitives/UnsignedBytesTest.java
@@ -226,9 +226,9 @@
   public void testLexicographicalComparatorDefaultChoice() {
     Comparator<byte[]> defaultComparator =
         UnsignedBytes.lexicographicalComparator();
-    Comparator<byte[]> unsafeComparator =
-        UnsignedBytes.LexicographicalComparatorHolder.UnsafeComparator.INSTANCE;
-    assertSame(defaultComparator, unsafeComparator);
+    Comparator<byte[]> pureJavaComparator =
+        UnsignedBytes.LexicographicalComparatorHolder.PureJavaComparator.INSTANCE;
+    assertSame(defaultComparator, pureJavaComparator);
   }
 
   public void testLexicographicalComparator() {
diff --git a/guava/src/com/google/common/primitives/UnsignedBytes.java b/guava/src/com/google/common/primitives/UnsignedBytes.java
index cc16b0c..6177043 100644
--- a/guava/src/com/google/common/primitives/UnsignedBytes.java
+++ b/guava/src/com/google/common/primitives/UnsignedBytes.java
@@ -22,9 +22,6 @@
 import com.google.common.annotations.Beta;
 import com.google.common.annotations.VisibleForTesting;
 
-import sun.misc.Unsafe;
-
-import java.nio.ByteOrder;
 import java.util.Comparator;
 
 /**
@@ -281,130 +278,12 @@
   }
 
   /**
-   * Provides a lexicographical comparator implementation; either a Java
-   * implementation or a faster implementation based on {@link Unsafe}.
-   *
-   * <p>Uses reflection to gracefully fall back to the Java implementation if
-   * {@code Unsafe} isn't available.
+   * Provides a pure Java lexicographical comparator implementation.
    */
   @VisibleForTesting
   static class LexicographicalComparatorHolder {
-    static final String UNSAFE_COMPARATOR_NAME =
-        LexicographicalComparatorHolder.class.getName() + "$UnsafeComparator";
 
-    static final Comparator<byte[]> BEST_COMPARATOR = getBestComparator();
-
-    @VisibleForTesting
-    enum UnsafeComparator implements Comparator<byte[]> {
-      INSTANCE;
-
-      static final boolean BIG_ENDIAN =
-          ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
-
-      /*
-       * The following static final fields exist for performance reasons.
-       *
-       * In UnsignedBytesBenchmark, accessing the following objects via static
-       * final fields is the fastest (more than twice as fast as the Java
-       * implementation, vs ~1.5x with non-final static fields, on x86_32)
-       * under the Hotspot server compiler. The reason is obviously that the
-       * non-final fields need to be reloaded inside the loop.
-       *
-       * And, no, defining (final or not) local variables out of the loop still
-       * isn't as good because the null check on the theUnsafe object remains
-       * inside the loop and BYTE_ARRAY_BASE_OFFSET doesn't get
-       * constant-folded.
-       *
-       * The compiler can treat static final fields as compile-time constants
-       * and can constant-fold them while (final or not) local variables are
-       * run time values.
-       */
-
-      static final Unsafe theUnsafe;
-
-      /** The offset to the first element in a byte array. */
-      static final int BYTE_ARRAY_BASE_OFFSET;
-
-      static {
-        theUnsafe = getUnsafe();
-
-        BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
-
-        // sanity check - this should never fail
-        if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
-          throw new AssertionError();
-        }
-      }
-      
-      /**
-       * Returns a sun.misc.Unsafe.  Suitable for use in a 3rd party package.
-       * Replace with a simple call to Unsafe.getUnsafe when integrating
-       * into a jdk.
-       *
-       * @return a sun.misc.Unsafe
-       */
-      private static sun.misc.Unsafe getUnsafe() {
-          try {
-              return sun.misc.Unsafe.getUnsafe();
-          } catch (SecurityException tryReflectionInstead) {}
-          try {
-              return java.security.AccessController.doPrivileged
-              (new java.security.PrivilegedExceptionAction<sun.misc.Unsafe>() {
-                  public sun.misc.Unsafe run() throws Exception {
-                      Class<sun.misc.Unsafe> k = sun.misc.Unsafe.class;
-                      for (java.lang.reflect.Field f : k.getDeclaredFields()) {
-                          f.setAccessible(true);
-                          Object x = f.get(null);
-                          if (k.isInstance(x))
-                              return k.cast(x);
-                      }
-                      throw new NoSuchFieldError("the Unsafe");
-                  }});
-          } catch (java.security.PrivilegedActionException e) {
-              throw new RuntimeException("Could not initialize intrinsics",
-                                         e.getCause());
-          }
-      }
-
-      @Override public int compare(byte[] left, byte[] right) {
-        int minLength = Math.min(left.length, right.length);
-        int minWords = minLength / Longs.BYTES;
-
-        /*
-         * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a
-         * time is no slower than comparing 4 bytes at a time even on 32-bit.
-         * On the other hand, it is substantially faster on 64-bit.
-         */
-        for (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) {
-          long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i);
-          long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i);
-          if (lw != rw) {
-            if (BIG_ENDIAN) {
-              return UnsignedLongs.compare(lw, rw);
-            }
-
-            /*
-             * We want to compare only the first index where left[index] != right[index].
-             * This corresponds to the least significant nonzero byte in lw ^ rw, since lw
-             * and rw are little-endian.  Long.numberOfTrailingZeros(diff) tells us the least 
-             * significant nonzero bit, and zeroing out the first three bits of L.nTZ gives us the 
-             * shift to get that least significant nonzero byte.
-             */
-            int n = Long.numberOfTrailingZeros(lw ^ rw) & ~0x7;
-            return (int) (((lw >>> n) & UNSIGNED_MASK) - ((rw >>> n) & UNSIGNED_MASK));
-          }
-        }
-
-        // The epilogue to cover the last (minLength % 8) elements.
-        for (int i = minWords * Longs.BYTES; i < minLength; i++) {
-          int result = UnsignedBytes.compare(left[i], right[i]);
-          if (result != 0) {
-            return result;
-          }
-        }
-        return left.length - right.length;
-      }
-    }
+    static final Comparator<byte[]> BEST_COMPARATOR = lexicographicalComparatorJavaImpl();
 
     enum PureJavaComparator implements Comparator<byte[]> {
       INSTANCE;
@@ -420,23 +299,5 @@
         return left.length - right.length;
       }
     }
-
-    /**
-     * Returns the Unsafe-using Comparator, or falls back to the pure-Java
-     * implementation if unable to do so.
-     */
-    static Comparator<byte[]> getBestComparator() {
-      try {
-        Class<?> theClass = Class.forName(UNSAFE_COMPARATOR_NAME);
-
-        // yes, UnsafeComparator does implement Comparator<byte[]>
-        @SuppressWarnings("unchecked")
-        Comparator<byte[]> comparator =
-            (Comparator<byte[]>) theClass.getEnumConstants()[0];
-        return comparator;
-      } catch (Throwable t) { // ensure we really catch *everything*
-        return lexicographicalComparatorJavaImpl();
-      }
-    }
   }
 }