1 /*
   2  * Copyright (c) 2007, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.hotspot.test;
  24 
  25 import java.io.DataInputStream;
  26 import java.io.InputStream;
  27 import java.nio.ByteBuffer;
  28 import java.util.zip.Checksum;
  29 
  30 import java.lang.invoke.MethodHandle;
  31 import java.lang.invoke.MethodHandles;
  32 import java.lang.invoke.MethodType;
  33 
  34 import org.graalvm.compiler.test.GraalTest;
  35 import org.graalvm.compiler.core.test.GraalCompilerTest;
  36 
  37 import org.junit.Test;
  38 
  39 import static org.junit.Assume.assumeFalse;
  40 
  41 /**
  42  * Tests compiled calls to {@link java.util.zip.CRC32C}.
  43  */
  44 @SuppressWarnings("javadoc")
  45 public class CRC32CSubstitutionsTest extends GraalCompilerTest {
  46 
  47     public static long updateBytes(byte[] input, int offset, int end) throws Throwable {
  48         Class<?> crcClass = Class.forName("java.util.zip.CRC32C");
  49         MethodHandle newMH = MethodHandles.publicLookup().findConstructor(crcClass, MethodType.methodType(void.class));
  50         Checksum crc = (Checksum) newMH.invoke();
  51         crc.update(input, offset, end);
  52         return crc.getValue();
  53     }
  54 
  55     @Test
  56     public void test1() throws Throwable {
  57         assumeFalse(GraalTest.Java8OrEarlier);
  58         String classfileName = CRC32CSubstitutionsTest.class.getSimpleName().replace('.', '/') + ".class";
  59         InputStream s = CRC32CSubstitutionsTest.class.getResourceAsStream(classfileName);
  60         byte[] buf = new byte[s.available()];
  61         new DataInputStream(s).readFully(buf);
  62         int end = buf.length;
  63         for (int offset = 0; offset < buf.length; offset++) {
  64             test("updateBytes", buf, offset, end);
  65         }
  66     }
  67 
  68     public static long updateByteBuffer(ByteBuffer buffer) throws Throwable {
  69         Class<?> crcClass = Class.forName("java.util.zip.CRC32C");
  70         MethodHandle newMH = MethodHandles.publicLookup().findConstructor(crcClass, MethodType.methodType(void.class));
  71         MethodHandle updateMH = MethodHandles.publicLookup().findVirtual(crcClass, "update", MethodType.methodType(void.class, ByteBuffer.class));
  72         Checksum crc = (Checksum) newMH.invoke();
  73         buffer.rewind();
  74         updateMH.invokeExact(crc, buffer); // Checksum.update(ByteBuffer) is also available since 9
  75         return crc.getValue();
  76     }
  77 
  78     @Test
  79     public void test2() throws Throwable {
  80         assumeFalse(GraalTest.Java8OrEarlier);
  81         String classfileName = CRC32CSubstitutionsTest.class.getSimpleName().replace('.', '/') + ".class";
  82         InputStream s = CRC32CSubstitutionsTest.class.getResourceAsStream(classfileName);
  83         byte[] buf = new byte[s.available()];
  84         new DataInputStream(s).readFully(buf);
  85 
  86         ByteBuffer directBuf = ByteBuffer.allocateDirect(buf.length);
  87         directBuf.put(buf);
  88         ByteBuffer heapBuf = ByteBuffer.wrap(buf);
  89 
  90         test("updateByteBuffer", directBuf);
  91         test("updateByteBuffer", heapBuf);
  92     }
  93 
  94 }