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