1 /*
   2  * Copyright (c) 2013, 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 package org.graalvm.compiler.hotspot.test;
  25 
  26 import java.util.ArrayDeque;
  27 import java.util.ArrayList;
  28 import java.util.Arrays;
  29 import java.util.Collections;
  30 import java.util.HashMap;
  31 import java.util.List;
  32 import java.util.concurrent.atomic.AtomicReference;
  33 
  34 import org.junit.Assert;
  35 import org.junit.Test;
  36 
  37 import org.graalvm.compiler.core.test.GraalCompilerTest;
  38 
  39 import jdk.vm.ci.hotspot.HotSpotInstalledCode;
  40 import jdk.vm.ci.meta.ResolvedJavaMethod;
  41 
  42 /**
  43  * The following tests perform object/array equality and assignments in various ways. The selected
  44  * cases have been the problematic ones while implementing the Compressed Oops support.
  45  */
  46 public class CompressedOopTest extends GraalCompilerTest {
  47 
  48     private HotSpotInstalledCode getInstalledCode(String name, Class<?>... parameterTypes) throws Exception {
  49         final ResolvedJavaMethod javaMethod = getResolvedJavaMethod(getClass(), name, parameterTypes);
  50         final HotSpotInstalledCode installedBenchmarkCode = (HotSpotInstalledCode) getCode(javaMethod);
  51         return installedBenchmarkCode;
  52     }
  53 
  54     @Test
  55     public void test() throws Exception {
  56         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("fieldTest", Object.class);
  57         Container c1 = new Container();
  58         Assert.assertEquals(c1.b, installedBenchmarkCode.executeVarargs(c1));
  59     }
  60 
  61     public static Object fieldTest(Object c1) {
  62         ((Container) c1).a = ((Container) c1).b;
  63         return ((Container) c1).a;
  64     }
  65 
  66     @Test
  67     public void test1() throws Exception {
  68         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("arrayTest", Object.class, Object.class, Object.class);
  69         ArrayContainer ac = new ArrayContainer();
  70         Assert.assertEquals(ac.a[9], installedBenchmarkCode.executeVarargs(ac.a, 0, 9));
  71         Assert.assertEquals(ac.a[8], installedBenchmarkCode.executeVarargs(ac.a, 1, 8));
  72         Assert.assertEquals(ac.a[7], installedBenchmarkCode.executeVarargs(ac.a, 2, 7));
  73         Assert.assertEquals(ac.a[6], installedBenchmarkCode.executeVarargs(ac.a, 3, 6));
  74         Assert.assertEquals(ac.a[5], installedBenchmarkCode.executeVarargs(ac.a, 4, 5));
  75         Assert.assertEquals(ac.a[4], installedBenchmarkCode.executeVarargs(ac.a, 5, 4));
  76         Assert.assertEquals(ac.a[3], installedBenchmarkCode.executeVarargs(ac.a, 6, 3));
  77         Assert.assertEquals(ac.a[2], installedBenchmarkCode.executeVarargs(ac.a, 7, 2));
  78         Assert.assertEquals(ac.a[1], installedBenchmarkCode.executeVarargs(ac.a, 8, 1));
  79         Assert.assertEquals(ac.a[0], installedBenchmarkCode.executeVarargs(ac.a, 9, 0));
  80     }
  81 
  82     public static Object arrayTest(Object c1, Object c2, Object c3) {
  83         Object[] array = (Object[]) c1;
  84         int initialIndex = ((Integer) c2).intValue();
  85         int replacingIndex = ((Integer) c3).intValue();
  86         array[initialIndex] = array[replacingIndex];
  87         return array[initialIndex];
  88     }
  89 
  90     @Test
  91     public void test2() throws Exception {
  92         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("arrayCopyTest", Object.class, Object.class);
  93         ArrayContainer source = new ArrayContainer();
  94         ArrayContainer destination = new ArrayContainer();
  95         Assert.assertEquals(source.a.length, destination.a.length);
  96         Assert.assertFalse(Arrays.equals(source.a, destination.a));
  97         installedBenchmarkCode.executeVarargs(source.a, destination.a);
  98         Assert.assertArrayEquals(source.a, destination.a);
  99     }
 100 
 101     public static void arrayCopyTest(Object c1, Object c2) {
 102         Object[] source = (Object[]) c1;
 103         Object[] destination = (Object[]) c2;
 104         System.arraycopy(source, 0, destination, 0, source.length);
 105     }
 106 
 107     @Test
 108     public void test3() throws Exception {
 109         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("compareAndSwapTest", Object.class, Object.class, Object.class);
 110         Object initial = new Object();
 111         Object replacement = new Object();
 112         AtomicReference<Object> cas = new AtomicReference<>();
 113         Assert.assertEquals(cas.get(), null);
 114         installedBenchmarkCode.executeVarargs(cas, null, initial);
 115         Assert.assertEquals(cas.get(), initial);
 116         installedBenchmarkCode.executeVarargs(cas, initial, replacement);
 117         Assert.assertEquals(cas.get(), replacement);
 118     }
 119 
 120     @SuppressWarnings("unchecked")
 121     public static void compareAndSwapTest(Object c1, Object c2, Object c3) throws ClassCastException {
 122         AtomicReference<Object> cas = (AtomicReference<Object>) c1;
 123         cas.compareAndSet(c2, c3);
 124     }
 125 
 126     @Test
 127     public void test4() throws Exception {
 128         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("charArrayCopyTest", Object.class, Object.class, Object.class);
 129         StringContainer1 source1 = new StringContainer1();
 130         StringContainer2 source2 = new StringContainer2();
 131         char[] result = new char[source1.value.length + source2.value.length];
 132         installedBenchmarkCode.executeVarargs(source1.value, source2.value, result);
 133         Assert.assertArrayEquals(new char[]{'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'}, result);
 134     }
 135 
 136     public static char[] charArrayCopyTest(Object c1, Object c2, Object c3) {
 137         char[] source1 = (char[]) c1;
 138         char[] source2 = (char[]) c2;
 139         char[] result = (char[]) c3;
 140         for (int i = 0; i < source1.length; i++) {
 141             result[i] = source1[i];
 142         }
 143 
 144         for (int i = 0; i < source2.length; i++) {
 145             result[source1.length + i] = source2[i];
 146         }
 147         return result;
 148     }
 149 
 150     @Test
 151     public void test5() throws Exception {
 152         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("charContainerArrayCopyTest", Object.class, Object.class, Object.class);
 153         StringContainer1 source1 = new StringContainer1();
 154         StringContainer2 source2 = new StringContainer2();
 155         char[] result = new char[source1.value.length + source2.value.length];
 156         installedBenchmarkCode.executeVarargs(source1, source2, result);
 157         Assert.assertArrayEquals(new char[]{'T', 'e', 's', 't', ' ', 'S', 't', 'r', 'i', 'n', 'g'}, result);
 158     }
 159 
 160     public static char[] charContainerArrayCopyTest(Object c1, Object c2, Object c3) {
 161         char[] source1 = ((StringContainer1) c1).value;
 162         char[] source2 = ((StringContainer2) c2).value;
 163         char[] result = (char[]) c3;
 164         for (int i = 0; i < source1.length; i++) {
 165             result[i] = source1[i];
 166         }
 167         for (int i = 0; i < source2.length; i++) {
 168             result[source1.length + i] = source2[i];
 169         }
 170         return result;
 171     }
 172 
 173     @Test
 174     public void test6() throws Exception {
 175         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringCopyTest", Object.class, Object.class);
 176         String a = new String("Test ");
 177         String b = new String("String");
 178         String c = (String) installedBenchmarkCode.executeVarargs(a, b);
 179         Assert.assertTrue(c.equals("Test String"));
 180     }
 181 
 182     public static String stringCopyTest(Object c1, Object c2) {
 183         String source = (String) c1;
 184         String destination = (String) c2;
 185         return source + destination;
 186     }
 187 
 188     @Test
 189     public void test7() throws Exception {
 190         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("queueTest", Object.class, Object.class);
 191         ArrayDeque<Object> q = new ArrayDeque<>();
 192         Object[] objects = new Object[512];
 193         for (int i = 0; i < objects.length; i++) {
 194             objects[i] = new Object();
 195         }
 196         int j = 0;
 197         while (j < objects.length) {
 198             if (!installedBenchmarkCode.isValid()) {
 199                 // This can get invalidated due to lack of MDO update
 200                 installedBenchmarkCode = getInstalledCode("queueTest", Object.class, Object.class);
 201             }
 202             installedBenchmarkCode.executeVarargs(q, objects[j]);
 203             j++;
 204         }
 205 
 206         System.gc();
 207         Assert.assertTrue(q.size() == objects.length);
 208         Assert.assertTrue(!q.isEmpty());
 209         j = 0;
 210         while (j < objects.length) {
 211             Assert.assertTrue(objects[j] == q.remove());
 212             j++;
 213         }
 214 
 215         Assert.assertTrue(q.size() == 0);
 216         Assert.assertTrue(q.isEmpty());
 217     }
 218 
 219     @SuppressWarnings("unchecked")
 220     public static void queueTest(Object c1, Object c2) {
 221         ArrayDeque<Object> queue = (ArrayDeque<Object>) c1;
 222         queue.add(c2);
 223     }
 224 
 225     @Test
 226     public void test8() throws Exception {
 227         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("unmodListTest", Object.class);
 228         List<Object> list = new ArrayList<>();
 229         for (int i = 0; i < 512; i++) {
 230             list.add(new Object());
 231         }
 232         Object[] array = (Object[]) installedBenchmarkCode.executeVarargs(list);
 233         Assert.assertTrue(list.size() == array.length);
 234         int i = 0;
 235         for (Object obj : list) {
 236             Assert.assertTrue(obj == array[i]);
 237             i++;
 238         }
 239     }
 240 
 241     @SuppressWarnings("unchecked")
 242     public static Object[] unmodListTest(Object c1) {
 243         List<Object> queue = (ArrayList<Object>) c1;
 244         Object[] result = Collections.unmodifiableCollection(queue).toArray(new Object[queue.size()]);
 245         return result;
 246     }
 247 
 248     @Test
 249     public void test9() throws Exception {
 250         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("unmodListTest", Object.class);
 251         List<Object> list = new ArrayList<>();
 252         Object[] array = (Object[]) installedBenchmarkCode.executeVarargs(list);
 253         Assert.assertTrue(list.size() == array.length);
 254     }
 255 
 256     public void test10() throws Exception {
 257         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("constantTest", Object.class);
 258         Container c = new Container();
 259         Assert.assertFalse((boolean) installedBenchmarkCode.executeVarargs(c));
 260     }
 261 
 262     public static Boolean constantTest(Object c1) {
 263         ConstantContainer container = (ConstantContainer) c1;
 264         return container.a.equals(container.b);
 265     }
 266 
 267     @Test
 268     public void test11() throws Exception {
 269         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringEqualsTest", Object.class, Object.class);
 270         String s1 = new String("Test");
 271         String s2 = new String("Test");
 272         boolean result = ((Boolean) (installedBenchmarkCode.executeVarargs(s1, s2))).booleanValue();
 273         Assert.assertTrue(result);
 274     }
 275 
 276     public static Boolean stringEqualsTest(Object c1, Object c2) {
 277         return ((String) c1).equals(c2);
 278     }
 279 
 280     @Test
 281     public void test12() throws Exception {
 282         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringConstantEqualsTest", Object.class);
 283         String s1 = new String("Test");
 284         boolean result = ((Boolean) (installedBenchmarkCode.executeVarargs(s1))).booleanValue();
 285         Assert.assertTrue(result);
 286     }
 287 
 288     public static Boolean stringConstantEqualsTest(Object c1) {
 289         return "Test".equals(c1);
 290     }
 291 
 292     @SuppressWarnings("unchecked")
 293     public static Object[] unmodListTestByte(Object c1) {
 294         List<Byte> queue = (ArrayList<Byte>) c1;
 295         Byte[] result = Collections.unmodifiableCollection(queue).toArray(new Byte[queue.size()]);
 296         return result;
 297     }
 298 
 299     @Test
 300     public void test13() throws Exception {
 301         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("unmodListTestByte", Object.class);
 302         List<Byte> list = new ArrayList<>();
 303         Byte[] array = (Byte[]) installedBenchmarkCode.executeVarargs(list);
 304         Assert.assertTrue(list.size() == array.length);
 305     }
 306 
 307     @Test
 308     public void test14() throws Exception {
 309         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBuilderTest", Object.class, Object.class);
 310         StringBuilder buffer = new StringBuilder("TestTestTestTestTestTestTest");
 311         Assert.assertTrue(buffer.length() == 28);
 312         String a = new String("TestTestTestTestTestTestTest");
 313         installedBenchmarkCode.executeVarargs(buffer, a.toCharArray());
 314         Assert.assertTrue(buffer.length() == 56);
 315         Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
 316     }
 317 
 318     public static void stringBuilderTest(Object c1, Object c2) {
 319         StringBuilder source = (StringBuilder) c1;
 320         char[] add = (char[]) c2;
 321         for (int i = 0; i < add.length; i++) {
 322             source.append(add[i]);
 323         }
 324     }
 325 
 326     @Test
 327     public void test15() throws Exception {
 328         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBuilderTestIn");
 329         installedBenchmarkCode.executeVarargs();
 330     }
 331 
 332     public static void stringBuilderTestIn() {
 333         StringBuilder buffer = new StringBuilder("TestTestTestTestTestTestTest");
 334         Assert.assertTrue(buffer.length() == 28);
 335         String a = new String("TestTestTestTestTestTestTest");
 336         char[] add = a.toCharArray();
 337         for (int i = 0; i < add.length; i++) {
 338             buffer.append(add[i]);
 339         }
 340         Assert.assertTrue(buffer.length() == 56);
 341         Assert.assertTrue(buffer.toString().equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
 342     }
 343 
 344     @Test
 345     public void test16() throws Exception {
 346         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBuilderArrayCopy");
 347         installedBenchmarkCode.executeVarargs();
 348     }
 349 
 350     public static void stringBuilderArrayCopy() {
 351         StringBuilder buffer = new StringBuilder("TestTestTestTestTestTestTest");
 352         Assert.assertTrue(buffer.length() == 28);
 353         String a = new String("TestTestTestTestTestTestTest");
 354         char[] dst = new char[buffer.length() * 2];
 355         System.arraycopy(buffer.toString().toCharArray(), 0, dst, 0, buffer.length());
 356         System.arraycopy(a.toCharArray(), 0, dst, buffer.length(), buffer.length());
 357         Assert.assertTrue(dst.length == 56);
 358         Assert.assertTrue(new String(dst).equals("TestTestTestTestTestTestTestTestTestTestTestTestTestTest"));
 359     }
 360 
 361     @Test
 362     public void test17() throws Exception {
 363         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringFormat");
 364         installedBenchmarkCode.executeVarargs();
 365     }
 366 
 367     public static void stringFormat() {
 368         String.format("Hello %d", 0);
 369         String.format("Hello %d", -11);
 370         String.format("Hello %d", -2147483648);
 371     }
 372 
 373     @Test
 374     public void test18() throws Exception {
 375         HotSpotInstalledCode installedBenchmarkCode = getInstalledCode("stringBuilder");
 376         StringBuilder b = (StringBuilder) installedBenchmarkCode.executeVarargs();
 377         Assert.assertTrue(b.capacity() == 16);
 378         Assert.assertTrue(b.length() == 0);
 379     }
 380 
 381     public static Object stringBuilder() {
 382         return new StringBuilder();
 383     }
 384 
 385     static class Container {
 386 
 387         public Object a = new Object();
 388         public Object b = new Object();
 389     }
 390 
 391     static class ArrayContainer {
 392 
 393         public Object[] a = new Object[10];
 394 
 395         ArrayContainer() {
 396             for (int i = 0; i < 10; i++) {
 397                 a[i] = new Object();
 398             }
 399         }
 400     }
 401 
 402     static class HashMapContainer {
 403 
 404         public HashMap<Object, Object> a = new HashMap<>();
 405 
 406         HashMapContainer() {
 407             for (int i = 0; i < 10; i++) {
 408                 a.put(new Object(), new Object());
 409             }
 410         }
 411     }
 412 
 413     static class StringContainer1 {
 414 
 415         public char[] value = new char[5];
 416 
 417         StringContainer1() {
 418             value[0] = 'T';
 419             value[1] = 'e';
 420             value[2] = 's';
 421             value[3] = 't';
 422             value[4] = ' ';
 423 
 424         }
 425     }
 426 
 427     static class StringContainer2 {
 428 
 429         public char[] value = new char[6];
 430 
 431         StringContainer2() {
 432             value[0] = 'S';
 433             value[1] = 't';
 434             value[2] = 'r';
 435             value[3] = 'i';
 436             value[4] = 'n';
 437             value[5] = 'g';
 438         }
 439     }
 440 
 441     static class ConstantContainer {
 442 
 443         public final Object a = new Object();
 444         public final Object b = new Object();
 445 
 446         ConstantContainer() {
 447 
 448         }
 449     }
 450 }