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