001/*
002 * Copyright (c) 2015, 2015, Oracle and/or its affiliates. All rights reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation.
008 *
009 * This code is distributed in the hope that it will be useful, but WITHOUT
010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
011 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
012 * version 2 for more details (a copy is included in the LICENSE file that
013 * accompanied this code).
014 *
015 * You should have received a copy of the GNU General Public License version
016 * 2 along with this work; if not, write to the Free Software Foundation,
017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
018 *
019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
020 * or visit www.oracle.com if you need additional information or have any
021 * questions.
022 */
023package com.oracle.graal.compiler.test;
024
025import org.junit.*;
026
027import com.oracle.graal.compiler.common.util.*;
028
029public class TypeWriterTest extends GraalCompilerTest {
030
031    private static void putValue(TypeWriter writer, long value) {
032        if (TypeConversion.isS1(value)) {
033            writer.putS1(value);
034        }
035        if (TypeConversion.isU1(value)) {
036            writer.putU1(value);
037        }
038        if (TypeConversion.isS2(value)) {
039            writer.putS2(value);
040        }
041        if (TypeConversion.isU2(value)) {
042            writer.putU2(value);
043        }
044        if (TypeConversion.isS4(value)) {
045            writer.putS4(value);
046        }
047        if (TypeConversion.isU4(value)) {
048            writer.putU4(value);
049        }
050        writer.putS8(value);
051        writer.putSV(value);
052        if (value >= 0) {
053            writer.putUV(value);
054        }
055    }
056
057    private static void checkValue(TypeReader reader, long value) {
058        if (TypeConversion.isS1(value)) {
059            Assert.assertEquals(value, reader.getS1());
060        }
061        if (TypeConversion.isU1(value)) {
062            Assert.assertEquals(value, reader.getU1());
063        }
064        if (TypeConversion.isS2(value)) {
065            Assert.assertEquals(value, reader.getS2());
066        }
067        if (TypeConversion.isU2(value)) {
068            Assert.assertEquals(value, reader.getU2());
069        }
070        if (TypeConversion.isS4(value)) {
071            Assert.assertEquals(value, reader.getS4());
072        }
073        if (TypeConversion.isU4(value)) {
074            Assert.assertEquals(value, reader.getU4());
075        }
076        Assert.assertEquals(value, reader.getS8());
077        Assert.assertEquals(value, reader.getSV());
078        if (value >= 0) {
079            Assert.assertEquals(value, reader.getUV());
080        }
081    }
082
083    private static void putValues(TypeWriter writer) {
084        for (int i = 0; i < 64; i++) {
085            long value = 1L << i;
086            putValue(writer, value - 2);
087            putValue(writer, value - 1);
088            putValue(writer, value);
089            putValue(writer, value + 1);
090            putValue(writer, value + 2);
091
092            putValue(writer, -value - 2);
093            putValue(writer, -value - 1);
094            putValue(writer, -value);
095            putValue(writer, -value + 1);
096            putValue(writer, -value + 2);
097        }
098    }
099
100    private static void checkValues(TypeReader reader) {
101        for (int i = 0; i < 64; i++) {
102            long value = 1L << i;
103            checkValue(reader, value - 2);
104            checkValue(reader, value - 1);
105            checkValue(reader, value);
106            checkValue(reader, value + 1);
107            checkValue(reader, value + 2);
108
109            checkValue(reader, -value - 2);
110            checkValue(reader, -value - 1);
111            checkValue(reader, -value);
112            checkValue(reader, -value + 1);
113            checkValue(reader, -value + 2);
114        }
115    }
116
117    private static void test01(boolean supportsUnalignedMemoryAccess) {
118        UnsafeArrayTypeWriter writer = UnsafeArrayTypeWriter.create(supportsUnalignedMemoryAccess);
119        putValues(writer);
120
121        byte[] array = new byte[(int) writer.getBytesWritten()];
122        writer.toArray(array);
123        UnsafeArrayTypeReader reader = UnsafeArrayTypeReader.create(array, 0, supportsUnalignedMemoryAccess);
124        checkValues(reader);
125    }
126
127    @Test
128    public void test01a() {
129        test01(getTarget().arch.supportsUnalignedMemoryAccess());
130    }
131
132    @Test
133    public void test01b() {
134        test01(false);
135    }
136
137    private static void checkSignedSize(TypeWriter writer, long value, int expectedSize) {
138        long sizeBefore = writer.getBytesWritten();
139        writer.putSV(value);
140        Assert.assertEquals(expectedSize, writer.getBytesWritten() - sizeBefore);
141    }
142
143    private static void checkUnsignedSize(TypeWriter writer, long value, int expectedSize) {
144        long sizeBefore = writer.getBytesWritten();
145        writer.putUV(value);
146        Assert.assertEquals(expectedSize, writer.getBytesWritten() - sizeBefore);
147    }
148
149    private static void checkSizes(TypeWriter writer) {
150        checkSignedSize(writer, 0, 1);
151        checkSignedSize(writer, 63, 1);
152        checkSignedSize(writer, -64, 1);
153        checkSignedSize(writer, 64, 2);
154        checkSignedSize(writer, -65, 2);
155        checkSignedSize(writer, 8191, 2);
156        checkSignedSize(writer, -8192, 2);
157        checkSignedSize(writer, 8192, 3);
158        checkSignedSize(writer, -8193, 3);
159        checkSignedSize(writer, Long.MAX_VALUE, 10);
160        checkSignedSize(writer, Long.MIN_VALUE, 10);
161
162        checkUnsignedSize(writer, 0, 1);
163        checkUnsignedSize(writer, 127, 1);
164        checkUnsignedSize(writer, 128, 2);
165        checkUnsignedSize(writer, 16383, 2);
166        checkUnsignedSize(writer, 16384, 3);
167        checkUnsignedSize(writer, Long.MAX_VALUE, 9);
168    }
169
170    @Test
171    public void test02a() {
172        checkSizes(UnsafeArrayTypeWriter.create(getTarget().arch.supportsUnalignedMemoryAccess()));
173    }
174
175    @Test
176    public void test02b() {
177        checkSizes(UnsafeArrayTypeWriter.create(false));
178    }
179}