blob: 93186def698f976cb3431f2531ec09d9a90278ba [file] [log] [blame]
/*
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.replacements.test;
import java.util.HashMap;
import org.junit.Assert;
import org.junit.Test;
import org.graalvm.compiler.core.test.GraalCompilerTest;
/**
* Tests the implementation of {@code NEW}.
*/
public class NewInstanceTest extends GraalCompilerTest {
@Override
protected void assertDeepEquals(Object expected, Object actual) {
Assert.assertTrue(expected != null);
Assert.assertTrue(actual != null);
super.assertDeepEquals(expected.getClass(), actual.getClass());
if (expected instanceof Object[]) {
Assert.assertTrue(actual instanceof Object[]);
Object[] eArr = (Object[]) expected;
Object[] aArr = (Object[]) actual;
Assert.assertTrue(eArr.length == aArr.length);
for (int i = 0; i < eArr.length; i++) {
assertDeepEquals(eArr[i], aArr[i]);
}
} else if (expected.getClass() != Object.class) {
try {
expected.getClass().getDeclaredMethod("equals", Object.class);
super.assertDeepEquals(expected, actual);
} catch (Exception e) {
}
}
}
@Test
public void test1() {
test("newObject");
}
@Test
public void test2() {
test("newObjectTwice");
}
public static Object newObject() {
return new Object();
}
@Test
public void test3() {
test("newObjectLoop", 100);
}
@Test
public void test4() {
test("newBigObject");
}
@Test
public void test5() {
test("newSomeObject");
}
@Test
public void test6() {
test("newEmptyString");
}
@Test
public void test7() {
test("newString", "value");
}
@Test
public void test8() {
test("newHashMap", 31);
}
@Test
public void test9() {
test("newRegression", true);
}
public static Object[] newObjectTwice() {
Object[] res = {new Object(), new Object()};
return res;
}
public static Object[] newObjectLoop(int n) {
Object[] res = new Object[n];
for (int i = 0; i < n; i++) {
res[i] = new Object();
}
return res;
}
public static BigObject newBigObject() {
return new BigObject();
}
public static SomeObject newSomeObject() {
return new SomeObject();
}
public static String newEmptyString() {
return new String();
}
public static String newString(String value) {
return new String(value);
}
public static HashMap<?, ?> newHashMap(int initialCapacity) {
return new HashMap<>(initialCapacity);
}
static class SomeObject {
String name = "o1";
HashMap<String, Object> map = new HashMap<>();
SomeObject() {
map.put(name, this.getClass());
}
@Override
public boolean equals(Object obj) {
if (obj instanceof SomeObject) {
SomeObject so = (SomeObject) obj;
return so.name.equals(name) && so.map.equals(map);
}
return false;
}
@Override
public int hashCode() {
return name.hashCode();
}
}
static class BigObject {
Object f01;
Object f02;
Object f03;
Object f04;
Object f05;
Object f06;
Object f07;
Object f08;
Object f09;
Object f10;
Object f12;
Object f13;
Object f14;
Object f15;
Object f16;
Object f17;
Object f18;
Object f19;
Object f20;
Object f21;
Object f22;
Object f23;
Object f24;
Object f25;
Object f26;
Object f27;
Object f28;
Object f29;
Object f30;
Object f31;
Object f32;
Object f33;
Object f34;
Object f35;
Object f36;
Object f37;
Object f38;
Object f39;
Object f40;
Object f41;
Object f42;
Object f43;
Object f44;
Object f45;
}
/**
* Tests that an earlier bug does not occur. The issue was that the loading of the TLAB 'top'
* and 'end' values was being GVN'ed from each branch of the 'if' statement. This meant that the
* allocated B object in the true branch overwrote the allocated array. The cause is that
* RegisterNode was a floating node and the reads from it were UnsafeLoads which are also
* floating. The fix was to make RegisterNode a fixed node (which it should have been in the
* first place).
*/
public static Object newRegression(boolean condition) {
Object result;
if (condition) {
Object[] arr = {0, 1, 2, 3, 4, 5};
result = new B();
for (int i = 0; i < arr.length; ++i) {
// If the bug exists, the values of arr will now be deadbeef values
// and the virtual dispatch will cause a segfault. This can result in
// either a VM crash or a spurious NullPointerException.
if (arr[i].equals(Integer.valueOf(i))) {
return false;
}
}
} else {
result = new B();
}
return result;
}
static class B {
long f1 = 0xdeadbeefdeadbe01L;
long f2 = 0xdeadbeefdeadbe02L;
long f3 = 0xdeadbeefdeadbe03L;
long f4 = 0xdeadbeefdeadbe04L;
long f5 = 0xdeadbeefdeadbe05L;
}
}