1 /*
   2  * Copyright (c) 2015, 2019, 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 
  24 
  25 package org.graalvm.compiler.core.test;
  26 
  27 import org.junit.Assert;
  28 import org.junit.Test;
  29 
  30 import org.graalvm.compiler.core.common.util.TypeConversion;
  31 import org.graalvm.compiler.core.common.util.TypeReader;
  32 import org.graalvm.compiler.core.common.util.TypeWriter;
  33 import org.graalvm.compiler.core.common.util.UnsafeArrayTypeReader;
  34 import org.graalvm.compiler.core.common.util.UnsafeArrayTypeWriter;
  35 
  36 public class TypeWriterTest extends GraalCompilerTest {
  37 
  38     private static void putValue(TypeWriter writer, long value) {
  39         if (TypeConversion.isS1(value)) {
  40             writer.putS1(value);
  41         }
  42         if (TypeConversion.isU1(value)) {
  43             writer.putU1(value);
  44         }
  45         if (TypeConversion.isS2(value)) {
  46             writer.putS2(value);
  47         }
  48         if (TypeConversion.isU2(value)) {
  49             writer.putU2(value);
  50         }
  51         if (TypeConversion.isS4(value)) {
  52             writer.putS4(value);
  53         }
  54         if (TypeConversion.isU4(value)) {
  55             writer.putU4(value);
  56         }
  57         writer.putS8(value);
  58         writer.putSV(value);
  59         if (value >= 0) {
  60             writer.putUV(value);
  61         }
  62     }
  63 
  64     private static void checkValue(TypeReader reader, long value) {
  65         if (TypeConversion.isS1(value)) {
  66             Assert.assertEquals(value, reader.getS1());
  67         }
  68         if (TypeConversion.isU1(value)) {
  69             Assert.assertEquals(value, reader.getU1());
  70         }
  71         if (TypeConversion.isS2(value)) {
  72             Assert.assertEquals(value, reader.getS2());
  73         }
  74         if (TypeConversion.isU2(value)) {
  75             Assert.assertEquals(value, reader.getU2());
  76         }
  77         if (TypeConversion.isS4(value)) {
  78             Assert.assertEquals(value, reader.getS4());
  79         }
  80         if (TypeConversion.isU4(value)) {
  81             Assert.assertEquals(value, reader.getU4());
  82         }
  83         Assert.assertEquals(value, reader.getS8());
  84         Assert.assertEquals(value, reader.getSV());
  85         if (value >= 0) {
  86             Assert.assertEquals(value, reader.getUV());
  87         }
  88     }
  89 
  90     private static void putValues(TypeWriter writer) {
  91         for (int i = 0; i < 64; i++) {
  92             long value = 1L << i;
  93             putValue(writer, value - 2);
  94             putValue(writer, value - 1);
  95             putValue(writer, value);
  96             putValue(writer, value + 1);
  97             putValue(writer, value + 2);
  98 
  99             putValue(writer, -value - 2);
 100             putValue(writer, -value - 1);
 101             putValue(writer, -value);
 102             putValue(writer, -value + 1);
 103             putValue(writer, -value + 2);
 104         }
 105     }
 106 
 107     private static void checkValues(TypeReader reader) {
 108         for (int i = 0; i < 64; i++) {
 109             long value = 1L << i;
 110             checkValue(reader, value - 2);
 111             checkValue(reader, value - 1);
 112             checkValue(reader, value);
 113             checkValue(reader, value + 1);
 114             checkValue(reader, value + 2);
 115 
 116             checkValue(reader, -value - 2);
 117             checkValue(reader, -value - 1);
 118             checkValue(reader, -value);
 119             checkValue(reader, -value + 1);
 120             checkValue(reader, -value + 2);
 121         }
 122     }
 123 
 124     private static void test01(boolean supportsUnalignedMemoryAccess) {
 125         UnsafeArrayTypeWriter writer = UnsafeArrayTypeWriter.create(supportsUnalignedMemoryAccess);
 126         putValues(writer);
 127 
 128         byte[] array = new byte[TypeConversion.asU4(writer.getBytesWritten())];
 129         writer.toArray(array);
 130         UnsafeArrayTypeReader reader = UnsafeArrayTypeReader.create(array, 0, supportsUnalignedMemoryAccess);
 131         checkValues(reader);
 132     }
 133 
 134     @Test
 135     public void test01a() {
 136         test01(getTarget().arch.supportsUnalignedMemoryAccess());
 137     }
 138 
 139     @Test
 140     public void test01b() {
 141         test01(false);
 142     }
 143 
 144     private static void checkSignedSize(TypeWriter writer, long value, long expectedSize) {
 145         long sizeBefore = writer.getBytesWritten();
 146         writer.putSV(value);
 147         Assert.assertEquals(expectedSize, writer.getBytesWritten() - sizeBefore);
 148     }
 149 
 150     private static void checkUnsignedSize(TypeWriter writer, long value, long expectedSize) {
 151         long sizeBefore = writer.getBytesWritten();
 152         writer.putUV(value);
 153         Assert.assertEquals(expectedSize, writer.getBytesWritten() - sizeBefore);
 154     }
 155 
 156     private static void checkSizes(TypeWriter writer) {
 157         checkSignedSize(writer, 0, 1);
 158         checkSignedSize(writer, 95, 1);
 159         checkSignedSize(writer, -96, 1);
 160         checkSignedSize(writer, 96, 2);
 161         checkSignedSize(writer, -97, 2);
 162         checkSignedSize(writer, 6239, 2);
 163         checkSignedSize(writer, -6240, 2);
 164         checkSignedSize(writer, 8192, 3);
 165         checkSignedSize(writer, -8193, 3);
 166         checkSignedSize(writer, Long.MAX_VALUE, UnsafeArrayTypeWriter.MAX_BYTES);
 167         checkSignedSize(writer, Long.MIN_VALUE, UnsafeArrayTypeWriter.MAX_BYTES);
 168 
 169         checkUnsignedSize(writer, 0, 1);
 170         checkUnsignedSize(writer, 191, 1);
 171         checkUnsignedSize(writer, 192, 2);
 172         checkUnsignedSize(writer, 12479, 2);
 173         checkUnsignedSize(writer, 12480, 3);
 174         checkUnsignedSize(writer, Long.MAX_VALUE, UnsafeArrayTypeWriter.MAX_BYTES);
 175         checkUnsignedSize(writer, Long.MIN_VALUE, UnsafeArrayTypeWriter.MAX_BYTES);
 176     }
 177 
 178     @Test
 179     public void test02a() {
 180         checkSizes(UnsafeArrayTypeWriter.create(getTarget().arch.supportsUnalignedMemoryAccess()));
 181     }
 182 
 183     @Test
 184     public void test02b() {
 185         checkSizes(UnsafeArrayTypeWriter.create(false));
 186     }
 187 }