changeset 58573:452fbc77bc54 records

records: review comments - move ObjectMethods to j.l.runtime
author chegar
date Sat, 26 Oct 2019 11:30:28 +0100
parents 51ffd9d65d2a
children 6161b40dcfcd
files src/java.base/share/classes/java/lang/runtime/ObjectMethods.java src/java.base/share/classes/java/lang/runtime/package-info.java src/java.base/share/classes/module-info.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java test/jdk/java/lang/invoke/ObjectMethodsTest.java test/jdk/java/lang/invoke/empty_security.policy test/jdk/java/lang/runtime/ObjectMethodsTest.java test/jdk/java/lang/runtime/empty.policy
diffstat 9 files changed, 238 insertions(+), 199 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java	Sat Oct 26 11:22:59 2019 +0100
+++ b/src/java.base/share/classes/java/lang/runtime/ObjectMethods.java	Sat Oct 26 11:30:28 2019 +0100
@@ -23,8 +23,13 @@
  * questions.
  */
 
-package java.lang.invoke;
+package java.lang.runtime;
 
+import java.lang.invoke.ConstantCallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.TypeDescriptor;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.Arrays;
@@ -80,7 +85,7 @@
             @SuppressWarnings("preview")
             Class<ObjectMethods> OBJECT_METHODS_CLASS = ObjectMethods.class;
             MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
-            MethodHandles.Lookup lookup = MethodHandles.Lookup.IMPL_LOOKUP;
+            MethodHandles.Lookup lookup = MethodHandles.lookup();
 
             ClassLoader loader = AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
                 @Override public ClassLoader run() { return ClassLoader.getPlatformClassLoader(); }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/java.base/share/classes/java/lang/runtime/package-info.java	Sat Oct 26 11:30:28 2019 +0100
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019, 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.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+/**
+ * The {@code java.lang.runtime} package provides low-level runtime support
+ * for the Java language.
+ *
+ * @since 14
+ */
+
+package java.lang.runtime;
\ No newline at end of file
--- a/src/java.base/share/classes/module-info.java	Sat Oct 26 11:22:59 2019 +0100
+++ b/src/java.base/share/classes/module-info.java	Sat Oct 26 11:30:28 2019 +0100
@@ -84,6 +84,7 @@
     exports java.lang.module;
     exports java.lang.ref;
     exports java.lang.reflect;
+    exports java.lang.runtime;
     exports java.math;
     exports java.net;
     exports java.net.spi;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Sat Oct 26 11:22:59 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Sat Oct 26 11:30:28 2019 +0100
@@ -515,7 +515,7 @@
 
         // Enter predefined classes. All are assumed to be in the java.base module.
         objectType = enterClass("java.lang.Object");
-        objectMethodsType = enterClass("java.lang.invoke.ObjectMethods");
+        objectMethodsType = enterClass("java.lang.runtime.ObjectMethods");
         objectsType = enterClass("java.util.Objects");
         classType = enterClass("java.lang.Class");
         stringType = enterClass("java.lang.String");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Sat Oct 26 11:22:59 2019 +0100
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Sat Oct 26 11:30:28 2019 +0100
@@ -199,7 +199,7 @@
     public final Name makeConcatWithConstants;
 
     // record related
-    // members of java.lang.invoke.ObjectMethods
+    // members of java.lang.runtime.ObjectMethods
     public final Name bootstrap;
 
     public final Name record;
--- a/test/jdk/java/lang/invoke/ObjectMethodsTest.java	Sat Oct 26 11:22:59 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,169 +0,0 @@
-/*
- * Copyright (c) 2019, 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.
- */
-
-/*
- * @test
- * @summary Basic tests for ObjectMethods
- * @compile --enable-preview -source 14 ObjectMethodsTest.java
- * @run testng/othervm --enable-preview ObjectMethodsTest
- * @run testng/othervm/java.security.policy=empty_security.policy --enable-preview ObjectMethodsTest
- */
-
-import java.lang.invoke.CallSite;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
-import java.lang.invoke.MethodType;
-import java.lang.invoke.ObjectMethods;
-import org.testng.annotations.Test;
-import static java.lang.invoke.MethodType.methodType;
-import static org.testng.Assert.assertEquals;
-import static org.testng.Assert.assertThrows;
-import static org.testng.Assert.assertFalse;
-import static org.testng.Assert.assertTrue;
-
-@Test
-public class ObjectMethodsTest {
-
-    public static class C {
-        static final MethodType EQUALS_DESC = methodType(boolean.class, C.class, Object.class);
-        static final MethodType HASHCODE_DESC = methodType(int.class, C.class);
-        static final MethodType TO_STRING_DESC = methodType(String.class, C.class);
-
-        static final MethodHandle[] ACCESSORS = accessors();
-        static final String NAME_LIST = "x;y";
-        private static MethodHandle[] accessors() {
-            try {
-                return  new MethodHandle[]{
-                        MethodHandles.lookup().findGetter(C.class, "x", int.class),
-                        MethodHandles.lookup().findGetter(C.class, "y", int.class),
-                };
-            } catch (Exception e) {
-                throw new AssertionError(e);
-            }
-        }
-
-        private final int x;
-        private final int y;
-        C (int x, int y) { this.x = x; this.y = y; }
-        public int x() { return x; }
-        public int y() { return y; }
-    }
-
-    static class Empty {
-        static final MethodType EQUALS_DESC = methodType(boolean.class, Empty.class, Object.class);
-        static final MethodType HASHCODE_DESC = methodType(int.class, Empty.class);
-        static final MethodType TO_STRING_DESC = methodType(String.class, Empty.class);
-        static final MethodHandle[] ACCESSORS = new MethodHandle[] { };
-        static final String NAME_LIST = "";
-        Empty () {  }
-    }
-
-    static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
-
-    public void testEqualsC() throws Throwable {
-        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS);
-        MethodHandle handle = cs.dynamicInvoker();
-        C c = new C(5, 5);
-        assertTrue((boolean)handle.invokeExact(c, (Object)c));
-        assertTrue((boolean)handle.invokeExact(c, (Object)new C(5, 5)));
-        assertFalse((boolean)handle.invokeExact(c, (Object)new C(5, 4)));
-        assertFalse((boolean)handle.invokeExact(c, (Object)new C(4, 5)));
-        assertFalse((boolean)handle.invokeExact(c, (Object)null));
-        assertFalse((boolean)handle.invokeExact(c, new Object()));
-    }
-
-    public void testEqualsEmpty() throws Throwable {
-        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", Empty.EQUALS_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS);
-        MethodHandle handle = cs.dynamicInvoker();
-        Empty e = new Empty();
-        assertTrue((boolean)handle.invokeExact(e, (Object)e));
-        assertTrue((boolean)handle.invokeExact(e, (Object)new Empty()));
-        assertFalse((boolean)handle.invokeExact(e, (Object)null));
-        assertFalse((boolean)handle.invokeExact(e, new Object()));
-    }
-
-    public void testHashCodeC() throws Throwable {
-        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", C.HASHCODE_DESC, C.class, null, C.ACCESSORS);
-        MethodHandle handle = cs.dynamicInvoker();
-        C c = new C(6, 7);
-        int hc = (int)handle.invokeExact(c);
-        assertEquals(hc, hashCombiner(c.x(), c.y()));
-
-        assertEquals((int)handle.invokeExact(new C(100, 1)),  hashCombiner(100, 1));
-        assertEquals((int)handle.invokeExact(new C(0, 0)),    hashCombiner(0, 0));
-        assertEquals((int)handle.invokeExact(new C(-1, 100)), hashCombiner(-1, 100));
-        assertEquals((int)handle.invokeExact(new C(100, 1)),  hashCombiner(100, 1));
-        assertEquals((int)handle.invokeExact(new C(100, -1)), hashCombiner(100, -1));
-    }
-
-    public void testHashCodeEmpty() throws Throwable {
-        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", Empty.HASHCODE_DESC, Empty.class, "", Empty.ACCESSORS);
-        MethodHandle handle = cs.dynamicInvoker();
-        Empty e = new Empty();
-        assertEquals((int)handle.invokeExact(e), 0);
-    }
-
-    public void testToStringC() throws Throwable {
-        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, C.NAME_LIST, C.ACCESSORS);
-        MethodHandle handle = cs.dynamicInvoker();
-        assertEquals((String)handle.invokeExact(new C(8, 9)),    "C[x=8, y=9]"   );
-        assertEquals((String)handle.invokeExact(new C(10, 11)),  "C[x=10, y=11]" );
-        assertEquals((String)handle.invokeExact(new C(100, -9)), "C[x=100, y=-9]");
-        assertEquals((String)handle.invokeExact(new C(0, 0)),    "C[x=0, y=0]"   );
-    }
-
-    public void testToStringEmpty() throws Throwable {
-        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", Empty.TO_STRING_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS);
-        MethodHandle handle = cs.dynamicInvoker();
-        assertEquals((String)handle.invokeExact(new Empty()),    "Empty[]");
-    }
-
-    Class<NullPointerException> NPE = NullPointerException.class;
-    Class<IllegalArgumentException> IAE = IllegalArgumentException.class;
-
-    public void exceptions()  {
-        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "badName",  C.EQUALS_DESC,    C.class,         C.NAME_LIST, C.ACCESSORS));
-        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class,         "x;y;z",     C.ACCESSORS));
-        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class,         "x;y",       new MethodHandle[]{}));
-        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, this.getClass(), "x;y",       C.ACCESSORS));
-
-        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.EQUALS_DESC,    C.class, "x;y", C.ACCESSORS));
-        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "hashCode", C.TO_STRING_DESC, C.class, "x;y", C.ACCESSORS));
-        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "equals",   C.HASHCODE_DESC,  C.class, "x;y", C.ACCESSORS));
-
-        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, "x;y", null)       );
-        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, null,  C.ACCESSORS));
-        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, null,    "x;y", C.ACCESSORS));
-        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "equals",   C.EQUALS_DESC,    null,    "x;y", C.ACCESSORS));
-        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "hashCode", C.HASHCODE_DESC,  null,    "x;y", C.ACCESSORS));
-
-        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", null,             C.class, "x;y", C.ACCESSORS));
-        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, null,       C.TO_STRING_DESC, C.class, "x;y", C.ACCESSORS));
-      //assertThrows(NPE, () -> ObjectMethods.bootstrap(null,   "toString", C.TO_STRING_DESC, C.class, "x;y", C.ACCESSORS));
-    }
-
-    // Based on the ObjectMethods internal implementation
-    private static int hashCombiner(int x, int y) {
-        return x*31 + y;
-    }
-}
--- a/test/jdk/java/lang/invoke/empty_security.policy	Sat Oct 26 11:22:59 2019 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,26 +0,0 @@
-//
-// Copyright (c) 2019, 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.
-//
-
-// This policy is used by tests not requiring permissions, to assert that the
-// JDK implementation has the correct privileged blocks.
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/runtime/ObjectMethodsTest.java	Sat Oct 26 11:30:28 2019 +0100
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2019, 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.
+ */
+
+/*
+ * @test
+ * @summary Basic tests for ObjectMethods
+ * @compile --enable-preview -source 14 ObjectMethodsTest.java
+ * @run testng/othervm --enable-preview ObjectMethodsTest
+ * @run testng/othervm/java.security.policy=empty.policy --enable-preview ObjectMethodsTest
+ */
+
+import java.lang.invoke.CallSite;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.ObjectMethods;
+import org.testng.annotations.Test;
+import static java.lang.invoke.MethodType.methodType;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertThrows;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+@Test
+public class ObjectMethodsTest {
+
+    public static class C {
+        static final MethodType EQUALS_DESC = methodType(boolean.class, C.class, Object.class);
+        static final MethodType HASHCODE_DESC = methodType(int.class, C.class);
+        static final MethodType TO_STRING_DESC = methodType(String.class, C.class);
+
+        static final MethodHandle[] ACCESSORS = accessors();
+        static final String NAME_LIST = "x;y";
+        private static MethodHandle[] accessors() {
+            try {
+                return  new MethodHandle[]{
+                        MethodHandles.lookup().findGetter(C.class, "x", int.class),
+                        MethodHandles.lookup().findGetter(C.class, "y", int.class),
+                };
+            } catch (Exception e) {
+                throw new AssertionError(e);
+            }
+        }
+
+        private final int x;
+        private final int y;
+        C (int x, int y) { this.x = x; this.y = y; }
+        public int x() { return x; }
+        public int y() { return y; }
+    }
+
+    static class Empty {
+        static final MethodType EQUALS_DESC = methodType(boolean.class, Empty.class, Object.class);
+        static final MethodType HASHCODE_DESC = methodType(int.class, Empty.class);
+        static final MethodType TO_STRING_DESC = methodType(String.class, Empty.class);
+        static final MethodHandle[] ACCESSORS = new MethodHandle[] { };
+        static final String NAME_LIST = "";
+        Empty () {  }
+    }
+
+    static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+    public void testEqualsC() throws Throwable {
+        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", C.EQUALS_DESC, C.class, C.NAME_LIST, C.ACCESSORS);
+        MethodHandle handle = cs.dynamicInvoker();
+        C c = new C(5, 5);
+        assertTrue((boolean)handle.invokeExact(c, (Object)c));
+        assertTrue((boolean)handle.invokeExact(c, (Object)new C(5, 5)));
+        assertFalse((boolean)handle.invokeExact(c, (Object)new C(5, 4)));
+        assertFalse((boolean)handle.invokeExact(c, (Object)new C(4, 5)));
+        assertFalse((boolean)handle.invokeExact(c, (Object)null));
+        assertFalse((boolean)handle.invokeExact(c, new Object()));
+    }
+
+    public void testEqualsEmpty() throws Throwable {
+        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "equals", Empty.EQUALS_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS);
+        MethodHandle handle = cs.dynamicInvoker();
+        Empty e = new Empty();
+        assertTrue((boolean)handle.invokeExact(e, (Object)e));
+        assertTrue((boolean)handle.invokeExact(e, (Object)new Empty()));
+        assertFalse((boolean)handle.invokeExact(e, (Object)null));
+        assertFalse((boolean)handle.invokeExact(e, new Object()));
+    }
+
+    public void testHashCodeC() throws Throwable {
+        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", C.HASHCODE_DESC, C.class, null, C.ACCESSORS);
+        MethodHandle handle = cs.dynamicInvoker();
+        C c = new C(6, 7);
+        int hc = (int)handle.invokeExact(c);
+        assertEquals(hc, hashCombiner(c.x(), c.y()));
+
+        assertEquals((int)handle.invokeExact(new C(100, 1)),  hashCombiner(100, 1));
+        assertEquals((int)handle.invokeExact(new C(0, 0)),    hashCombiner(0, 0));
+        assertEquals((int)handle.invokeExact(new C(-1, 100)), hashCombiner(-1, 100));
+        assertEquals((int)handle.invokeExact(new C(100, 1)),  hashCombiner(100, 1));
+        assertEquals((int)handle.invokeExact(new C(100, -1)), hashCombiner(100, -1));
+    }
+
+    public void testHashCodeEmpty() throws Throwable {
+        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "hashCode", Empty.HASHCODE_DESC, Empty.class, "", Empty.ACCESSORS);
+        MethodHandle handle = cs.dynamicInvoker();
+        Empty e = new Empty();
+        assertEquals((int)handle.invokeExact(e), 0);
+    }
+
+    public void testToStringC() throws Throwable {
+        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, C.NAME_LIST, C.ACCESSORS);
+        MethodHandle handle = cs.dynamicInvoker();
+        assertEquals((String)handle.invokeExact(new C(8, 9)),    "C[x=8, y=9]"   );
+        assertEquals((String)handle.invokeExact(new C(10, 11)),  "C[x=10, y=11]" );
+        assertEquals((String)handle.invokeExact(new C(100, -9)), "C[x=100, y=-9]");
+        assertEquals((String)handle.invokeExact(new C(0, 0)),    "C[x=0, y=0]"   );
+    }
+
+    public void testToStringEmpty() throws Throwable {
+        CallSite cs = (CallSite)ObjectMethods.bootstrap(LOOKUP, "toString", Empty.TO_STRING_DESC, Empty.class, Empty.NAME_LIST, Empty.ACCESSORS);
+        MethodHandle handle = cs.dynamicInvoker();
+        assertEquals((String)handle.invokeExact(new Empty()),    "Empty[]");
+    }
+
+    Class<NullPointerException> NPE = NullPointerException.class;
+    Class<IllegalArgumentException> IAE = IllegalArgumentException.class;
+
+    public void exceptions()  {
+        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "badName",  C.EQUALS_DESC,    C.class,         C.NAME_LIST, C.ACCESSORS));
+        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class,         "x;y;z",     C.ACCESSORS));
+        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class,         "x;y",       new MethodHandle[]{}));
+        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, this.getClass(), "x;y",       C.ACCESSORS));
+
+        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.EQUALS_DESC,    C.class, "x;y", C.ACCESSORS));
+        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "hashCode", C.TO_STRING_DESC, C.class, "x;y", C.ACCESSORS));
+        assertThrows(IAE, () -> ObjectMethods.bootstrap(LOOKUP, "equals",   C.HASHCODE_DESC,  C.class, "x;y", C.ACCESSORS));
+
+        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, "x;y", null)       );
+        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, C.class, null,  C.ACCESSORS));
+        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", C.TO_STRING_DESC, null,    "x;y", C.ACCESSORS));
+        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "equals",   C.EQUALS_DESC,    null,    "x;y", C.ACCESSORS));
+        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "hashCode", C.HASHCODE_DESC,  null,    "x;y", C.ACCESSORS));
+
+        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, "toString", null,             C.class, "x;y", C.ACCESSORS));
+        assertThrows(NPE, () -> ObjectMethods.bootstrap(LOOKUP, null,       C.TO_STRING_DESC, C.class, "x;y", C.ACCESSORS));
+      //assertThrows(NPE, () -> ObjectMethods.bootstrap(null,   "toString", C.TO_STRING_DESC, C.class, "x;y", C.ACCESSORS));
+    }
+
+    // Based on the ObjectMethods internal implementation
+    private static int hashCombiner(int x, int y) {
+        return x*31 + y;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/jdk/java/lang/runtime/empty.policy	Sat Oct 26 11:30:28 2019 +0100
@@ -0,0 +1,26 @@
+//
+// Copyright (c) 2019, 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.
+//
+
+// This policy is used by tests not requiring permissions, to assert that the
+// JDK implementation has the correct privileged blocks.
+