Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8237073: [lworld] Need special handling of jlO constructor invocation #481

Closed
wants to merge 5 commits into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -152,12 +152,14 @@ private static RuntimeException newIAE(String message, Throwable cause) {
return new IllegalArgumentException(message, cause);
}

private static final Function<Object, Object> CREATE_RESERVATION = new Function<>() {
@Override
public Object apply(Object key) {
return new Object();
}
};
private static class CacheHolder {
static final Function<Object, Object> CREATE = new Function<>() {
@Override
public Object apply(Object key) {
return new CacheHolder();
}
};
}

public final S findSpecies(K key) {
// Note: Species instantiation may throw VirtualMachineError because of
@@ -180,12 +182,12 @@ public final S findSpecies(K key) {
// concrete class if ever.
// The concrete class is published via SpeciesData instance
// returned here only after the class and species data are linked together.
Object speciesDataOrReservation = cache.computeIfAbsent(key, CREATE_RESERVATION);
Object speciesDataOrReservation = cache.computeIfAbsent(key, CacheHolder.CREATE);
// Separating the creation of a placeholder SpeciesData instance above
// from the loading and linking a real one below ensures we can never
// accidentally call computeIfAbsent recursively.
S speciesData;
if (speciesDataOrReservation.getClass() == Object.class) {
if (speciesDataOrReservation.getClass() == CacheHolder.class) {
synchronized (speciesDataOrReservation) {
Object existingSpeciesData = cache.get(key);
if (existingSpeciesData == speciesDataOrReservation) { // won the race
@@ -56,6 +56,7 @@
import static com.sun.tools.javac.resources.CompilerProperties.Fragments.DiamondInvalidArgs;
import com.sun.tools.javac.resources.CompilerProperties.Errors;
import com.sun.tools.javac.resources.CompilerProperties.Fragments;
import com.sun.tools.javac.resources.CompilerProperties.Notes;
import com.sun.tools.javac.resources.CompilerProperties.Warnings;
import com.sun.tools.javac.tree.*;
import com.sun.tools.javac.tree.JCTree.*;
@@ -2830,6 +2831,9 @@ public void visitNewClass(final JCNewClass tree) {
clazztype = TreeInfo.isEnumInit(env.tree) ?
attribIdentAsEnumType(env, (JCIdent)clazz) :
attribType(clazz, env);
if (clazztype.tsym == syms.objectType.tsym && cdef == null && !tree.classDeclRemoved()) {
log.note(tree.pos(), Notes.CantInstantiateObjectDirectly);
}
} finally {
env.info.isNewClass = false;
}
@@ -2851,7 +2851,12 @@ public void visitNewClass(JCNewClass tree) {
} else {
tree.clazz = access(c, tree.clazz, enclOp, false);
}
result = tree;
if (tree.clazz.type.tsym == syms.objectType.tsym) {
Assert.check(tree.def == null && tree.encl == null);
result = makeCall(make.Ident(syms.objectsType.tsym), names.newIdentity, List.nil());
} else {
result = tree;
}
}

// Simplify conditionals with known constant controlling expressions.
@@ -3903,3 +3903,6 @@ compiler.warn.declared.using.preview=\

compiler.warn.attempt.to.synchronize.on.instance.of.value.based.class=\
attempt to synchronize on an instance of a value-based class

compiler.note.cant.instantiate.object.directly=\
Object cannot be instantiated directly; a subclass of Object will be instantiated instead, by invoking java.util.Objects.newIdentity()
@@ -40,7 +40,7 @@ public class IntHashTable {
protected int[] ints; // the image set
protected int mask; // used to clip int's into the domain
protected int num_bindings; // the number of mappings (including DELETED)
private static final Object DELETED = new Object();
private static final Object DELETED = new Object() {};

/**
* Construct an Object {@literal ->} int hash table.
@@ -94,6 +94,7 @@ public static Names instance(Context context) {
public final Name init;
public final Name iterator;
public final Name length;
public final Name newIdentity;
public final Name next;
public final Name ordinal;
public final Name provider;
@@ -281,6 +282,7 @@ public Names(Context context) {
iterator = fromString("iterator");
length = fromString("length");
next = fromString("next");
newIdentity = fromString("newIdentity");
ordinal = fromString("ordinal");
provider = fromString("provider");
serialVersionUID = fromString("serialVersionUID");
@@ -208,7 +208,7 @@ public boolean transform(final CompilationService sjavac,

// Prepare compilation calls
List<Callable<CompilationSubResult>> compilationCalls = new ArrayList<>();
final Object lock = new Object();
final Object lock = new Object() {};
for (int i = 0; i < numCompiles; i++) {
CompileChunk cc = compileChunks[i];
if (cc.srcs.isEmpty()) {
@@ -36,10 +36,10 @@
package compiler.escapeAnalysis;

public class TestGetClass {
static Object obj = new Object();
static Object obj = new Object() {};

public static boolean test() {
if (obj.getClass() == Object.class) {
if (obj.getClass().getSuperclass() == Object.class) {
synchronized (obj) {
return true;
}
@@ -30,7 +30,7 @@ public class ForObjectDataProvider {
public static Object[][] forObjectDataProvider() {
return new Object[][]{
{TestHelper.DUMMY_CLASS_INSTANCE.objectField,
"Object[Object@" + TestHelper.DUMMY_CLASS_INSTANCE.objectField.hashCode() + "]"},
"Object[Objects$1@" + TestHelper.DUMMY_CLASS_INSTANCE.objectField.hashCode() + "]"},
{TestHelper.DUMMY_CLASS_INSTANCE.stringField,
"Object[String:\"" + TestHelper.DUMMY_CLASS_INSTANCE.stringField + "\"]"},
{TestHelper.DUMMY_CLASS_INSTANCE.booleanField,
@@ -73,7 +73,7 @@ public static void main(String[] args) throws Throwable {
}

// Try to cast using a different mechanism.
new java.lang.Object().getClass().cast(hiddenClassObj);
new java.lang.Object() {}.getClass().getSuperclass().cast(hiddenClassObj);
}

}
@@ -59,7 +59,7 @@ public static void main(String[] args) throws Throwable {
}

public static void invalidObjectToDerived() {
java.lang.Object instance = new java.lang.Object();
java.lang.Object instance = java.util.Objects.newIdentity();
int left = 23;
int right = 42;
try {
@@ -69,7 +69,7 @@ public static void invalidObjectToDerived() {
throw new RuntimeException("ClassCastException wasn't thrown, test failed.");
} catch (ClassCastException cce) {
System.out.println(cce.toString());
if (!cce.getMessage().contains("class java.lang.Object cannot be cast to class Derived (java.lang.Object is in module java.base of loader 'bootstrap'; Derived is in unnamed module of loader 'app')")) {
if (!cce.getMessage().contains("class java.util.Objects$1 cannot be cast to class Derived (java.util.Objects$1 is in module java.base of loader 'bootstrap'; Derived is in unnamed module of loader 'app')")) {
throw new RuntimeException("Wrong message: " + cce.getMessage());
}
}
@@ -80,7 +80,7 @@ public void run(CommandExecutor executor, String classHistogramArgs, String expa
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.String " + moduleRegex + "\\s*$");

/* Require at least one java.lang.Object */
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.lang.Object " + moduleRegex + "\\s*$");
output.shouldMatch("^\\s+\\d+:\\s+\\d+\\s+\\d+\\s+java.util.Objects\\$1 " + moduleRegex + "\\s*$");

/* Require at exactly one TestClass[] */
output.shouldMatch("^\\s+\\d+:\\s+1\\s+\\d+\\s+" +
@@ -38,8 +38,8 @@

public class WaitNotifyThreadTest {

private Object monitor = new Object();
private final String OBJECT = "a java.lang.Object";
private Object monitor = java.util.Objects.newIdentity();
private final String OBJECT = "a java.util.Objects$1";
private final String OBJECT_WAIT = "java.lang.Object.wait";
private final String RUN_METHOD = "WaitNotifyThreadTest$WaitThread.run";

@@ -179,26 +179,28 @@ public void afterTest() {
this.linker = null;
}

private static class TestObject {}

@Test(dataProvider = "flags")
public void getPropertyTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class);
final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, mt);
Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class);
Assert.assertEquals(cs.getTarget().invoke(new TestObject(), "class"), TestObject.class);
Assert.assertEquals(cs.getTarget().invoke(new Date(), "class"), Date.class);
}

@Test(dataProvider = "flags")
public void getPropertyNegativeTest(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class);
final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, mt);
Assert.assertNull(cs.getTarget().invoke(new Object(), "DOES_NOT_EXIST"));
Assert.assertNull(cs.getTarget().invoke(new TestObject(), "DOES_NOT_EXIST"));
}

@Test(dataProvider = "flags")
public void getPropertyTest2(final boolean publicLookup) throws Throwable {
final MethodType mt = MethodType.methodType(Object.class, Object.class);
final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, "class", mt);
Assert.assertEquals(cs.getTarget().invoke(new Object()), Object.class);
Assert.assertEquals(cs.getTarget().invoke(new TestObject()), TestObject.class);
Assert.assertEquals(cs.getTarget().invoke(new Date()), Date.class);
}

@@ -208,7 +210,7 @@ public void getPropertyNegativeTest2(final boolean publicLookup) throws Throwabl
final CallSite cs = createCallSite(publicLookup, GET_PROPERTY, "DOES_NOT_EXIST", mt);

try {
cs.getTarget().invoke(new Object());
cs.getTarget().invoke(new TestObject());
throw new RuntimeException("Expected NoSuchDynamicMethodException");
} catch (final Throwable th) {
Assert.assertTrue(th instanceof NoSuchDynamicMethodException);
@@ -177,6 +177,8 @@ public void priorityAndFallbackLinkerTest() {
Assert.assertEquals(linkerReachCounter[0], 2);
}

private static class TestObject {}

@Test
public void prelinkTransformerTest() throws Throwable {
final DynamicLinkerFactory factory = newDynamicLinkerFactory(true);
@@ -193,7 +195,7 @@ public void prelinkTransformerTest() throws Throwable {
final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
MethodHandles.publicLookup(), GET_PROPERTY, mt)));
Assert.assertFalse(reachedPrelinkTransformer[0]);
Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class);
Assert.assertEquals(cs.getTarget().invoke(new TestObject(), "class"), TestObject.class);
Assert.assertTrue(reachedPrelinkTransformer[0]);
}

@@ -212,13 +214,13 @@ public void internalObjectsFilterTest() throws Throwable {
final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor(
MethodHandles.publicLookup(), GET_PROPERTY, mt)));
Assert.assertFalse(reachedInternalObjectsFilter[0]);
Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class);
Assert.assertEquals(cs.getTarget().invoke(new TestObject(), "class"), TestObject.class);
Assert.assertTrue(reachedInternalObjectsFilter[0]);
}

@Test
public void autoLoadedLinkerTest() {
testAutoLoadedLinkerInvoked(new Object(), "toString");
testAutoLoadedLinkerInvoked(new TestObject(), "toString");
}

@Test
@@ -51,7 +51,7 @@ public void testTypeInference() {
assertEval("import java.util.ArrayList;");
assertEval("import java.util.Arrays;");

assertType("new Object().getClass().getSuperclass() ", "Class<?>");
assertType("new Object() {}.getClass().getSuperclass().getSuperclass() ", "Class<?>");
assertType("new ArrayList().getClass().getSuperclass()", "Class<?>");
assertType("new ArrayList().getClass()", "Class<? extends ArrayList>");
assertType("ArrayList.class", "Class<ArrayList>");
@@ -509,7 +509,7 @@ public void varDeclRedefNoInit() {
assertVarDeclRedefNoInit("double", "d", "3.1415926", "0.0");
assertVarDeclRedefNoInit("boolean", "n", "true", "false");
assertVarDeclRedefNoInit("char", "c", "'x'", "'\\000'");
assertVarDeclRedefNoInit("Object", "o", "new Object()", IGNORE_VALUE, "null");
assertVarDeclRedefNoInit("Object", "o", "new String()", IGNORE_VALUE, "null");
assertVarDeclRedefNoInit("String", "s", "\"hi\"", "null");
}

@@ -68,7 +68,7 @@ void test(String opt, String expect) throws Exception {

void m(List t) {
// force a note about unchecked usage
t.add(new Object());
t.add(new Object() {});
}

private File testSrc = new File(System.getProperty("test.src", "."));
@@ -16,17 +16,17 @@ public void test() {
// or as a resource in a try-with-resources statement
try {
} catch (Exception exParam1) {
Object exParam1 = new Object();
Object exParam1 = new Object() {};
try (java.io.FileInputStream exParam1 = new java.io.FileInputStream("foo.txt")) {
Object exParam1 = new Object();
Object exParam1 = new Object() {};
} catch (IOException exParam1) {
}
}

// compiler error if resource is redeclared within the try Block as a local var
// or as an exception param of a catch clause in a try statement
try (java.io.FileInputStream exParam2 = new java.io.FileInputStream("bar.txt")) {
Object exParam2 = new Object();
Object exParam2 = new Object() {};
try (BufferedReader br = new BufferedReader(new FileReader("zee.txt"))) {
} catch (IOException exParam2) {
}
@@ -6,7 +6,7 @@
public class TwrForVariable3 implements AutoCloseable {
public static void main(String... args) {
TwrForVariable3 v1 = new TwrForVariable3();
Object v2 = new Object();
Object v2 = new Object() {};
Object v3 = new Object() {
public void close() {
}
@@ -15,7 +15,7 @@ public static void main(String... args) {
}

try (r) {
Object r = new Object();
Object r = new Object() {};
}

try (r) {
@@ -16,5 +16,5 @@ class InvalidRepAnnoOnCast {
@Target(ElementType.TYPE_PARAMETER)
@interface TC { T[] value(); }

String s = (@T(1) @T(2) String) new Object();
String s = (@T(1) @T(2) String) new Object() {};
}
@@ -1,2 +1,3 @@
InvalidRepAnnoOnCast.java:19:17: compiler.err.invalid.repeatable.annotation.not.applicable.in.context: InvalidRepAnnoOnCast.TC
1 error
InvalidRepAnnoOnCast.java:19:37: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.anonymous.class: java.lang.Object, @InvalidRepAnnoOnCast.T(1),@InvalidRepAnnoOnCast.T(2) java.lang.String)
2 errors
@@ -9,7 +9,7 @@
class DeclarationAnnotation {
Object e1 = new @DA int[5];
Object e2 = new @DA String[42];
Object e3 = new @DA Object();
Object e3 = new @DA Object() {};
Object e4 = new @DA Object() { };
}

@@ -0,0 +1,28 @@
/*
* Copyright (c) 2021, 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.
*/

// key: compiler.note.cant.instantiate.object.directly

class CantInstantiateObjectDirectly {
{ new Object(); }
}
@@ -13,7 +13,7 @@
public class UnsoundInference {

public static void main(String[] args) {
Object[] objArray = {new Object()};
Object[] objArray = {new Object() {}};
ArrayList<String> strList = new ArrayList<String>();
transferBug(objArray, strList);
String str = strList.get(0);
@@ -10,7 +10,7 @@

class T8065986a {
T8065986a() {
super(new Object<>());
super(new Object<>() {});
}

T8065986a(boolean b) {
@@ -10,7 +10,7 @@

class T8065986b {
T8065986b() {
this(new Object<>());
this(new Object<>() {});
}

T8065986b(boolean b) {