--- old/src/java.base/share/classes/java/lang/Class.java 2018-03-06 15:23:14.000000000 -0800 +++ new/src/java.base/share/classes/java/lang/Class.java 2018-03-06 15:23:14.000000000 -0800 @@ -533,8 +533,8 @@ throws InstantiationException, IllegalAccessException { if (this.isValue()) { - throw new UnsupportedOperationException("newInstance on a value class " - + this.getName()); + throw new IllegalAccessException( + "cannot create new instance of value class " + this.getName()); } SecurityManager sm = System.getSecurityManager(); --- old/src/java.base/share/classes/java/lang/invoke/MemberName.java 2018-03-06 15:23:18.000000000 -0800 +++ new/src/java.base/share/classes/java/lang/invoke/MemberName.java 2018-03-06 15:23:17.000000000 -0800 @@ -447,11 +447,12 @@ // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo // unofficial modifier flags, used by HotSpot: - static final int BRIDGE = 0x00000040; - static final int VARARGS = 0x00000080; - static final int SYNTHETIC = 0x00001000; - static final int ANNOTATION= 0x00002000; - static final int ENUM = 0x00004000; + static final int BRIDGE = 0x00000040; + static final int VARARGS = 0x00000080; + static final int SYNTHETIC = 0x00001000; + static final int ANNOTATION = 0x00002000; + static final int ENUM = 0x00004000; + /** Utility method to query the modifier flags of this member; returns false if the member is not a method. */ public boolean isBridge() { return testAllFlags(IS_METHOD | BRIDGE); @@ -465,6 +466,9 @@ return testAllFlags(SYNTHETIC); } + public boolean isValue() { return clazz.isValue(); } + + static final String CONSTRUCTOR_NAME = ""; // the ever-popular // modifiers exported by the JVM: --- old/src/java.base/share/classes/java/lang/invoke/MethodHandles.java 2018-03-06 15:23:21.000000000 -0800 +++ new/src/java.base/share/classes/java/lang/invoke/MethodHandles.java 2018-03-06 15:23:20.000000000 -0800 @@ -2401,7 +2401,9 @@ } refc = lookupClass(); } - return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(), this.allowedModes == TRUSTED); + // don't allow writing on value type + boolean isWriteAllowedOnFinalFields = this.allowedModes == TRUSTED && !putField.isValue(); + return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(), isWriteAllowedOnFinalFields); } /** Check access and get the requested constructor. */ private MethodHandle getDirectConstructor(Class refc, MemberName ctor) throws IllegalAccessException { --- old/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java 2018-03-06 15:23:24.000000000 -0800 +++ new/src/java.base/share/classes/java/lang/reflect/AccessibleObject.java 2018-03-06 15:23:24.000000000 -0800 @@ -284,14 +284,6 @@ private boolean checkCanSetAccessible(Class caller, Class declaringClass, boolean throwExceptionIfDenied) { - Module callerModule = caller.getModule(); - Module declaringModule = declaringClass.getModule(); - - if (callerModule == declaringModule) return true; - if (callerModule == Object.class.getModule()) return true; - if (!declaringModule.isNamed()) return true; - - String pn = declaringClass.getPackageName(); int modifiers; if (this instanceof Executable) { modifiers = ((Executable) this).getModifiers(); @@ -299,8 +291,23 @@ modifiers = ((Field) this).getModifiers(); } + // does not allow to suppress access check for Value class's + // constructor or field + if (declaringClass.isValue()) { + if (this instanceof Constructor) return false; + if (this instanceof Field && Modifier.isFinal(modifiers)) return false; + } + + Module callerModule = caller.getModule(); + Module declaringModule = declaringClass.getModule(); + + if (callerModule == declaringModule) return true; + if (callerModule == Object.class.getModule()) return true; + if (!declaringModule.isNamed()) return true; + // class is public and package is exported to caller boolean isClassPublic = Modifier.isPublic(declaringClass.getModifiers()); + String pn = declaringClass.getPackageName(); if (isClassPublic && declaringModule.isExported(pn, callerModule)) { // member is public if (Modifier.isPublic(modifiers)) { --- old/src/java.base/share/classes/java/lang/reflect/Constructor.java 2018-03-06 15:23:27.000000000 -0800 +++ new/src/java.base/share/classes/java/lang/reflect/Constructor.java 2018-03-06 15:23:26.000000000 -0800 @@ -181,6 +181,12 @@ @CallerSensitive public void setAccessible(boolean flag) { AccessibleObject.checkPermission(); + + if (clazz.isValue()) { + throw new InaccessibleObjectException( + "Unable to make a value class constructor \"" + this + "\" accessible"); + } + if (flag) { checkCanSetAccessible(Reflection.getCallerClass()); } @@ -474,6 +480,11 @@ throws InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + if (clazz.isValue()) { + throw new IllegalAccessException( + "cannot create new instance of value class " + clazz.getName()); + } + if (!override) { Class caller = Reflection.getCallerClass(); checkAccess(caller, clazz, clazz, modifiers); --- old/src/java.base/share/classes/java/lang/reflect/Field.java 2018-03-06 15:23:30.000000000 -0800 +++ new/src/java.base/share/classes/java/lang/reflect/Field.java 2018-03-06 15:23:29.000000000 -0800 @@ -167,6 +167,12 @@ @CallerSensitive public void setAccessible(boolean flag) { AccessibleObject.checkPermission(); + + if (clazz.isValue() && Modifier.isFinal(modifiers)) { + throw new InaccessibleObjectException( + "Unable to make a value class field \"" + this + "\" accessible"); + } + if (flag) checkCanSetAccessible(Reflection.getCallerClass()); setAccessible0(flag); } --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java 2018-03-06 15:23:33.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessBoolean.java 2018-03-06 15:23:32.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessBoolean + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessBoolean + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean * @run testng/othervm -Diters=20000 VarHandleTestAccessBoolean * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessBoolean @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessBoolean.class, "static_v", boolean.class); vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "boolean_v", boolean.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessBoolean::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -288,6 +301,19 @@ } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + boolean x = (boolean) vh.get(recv); + assertEquals(x, true, "get boolean value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, false); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java 2018-03-06 15:23:36.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessByte.java 2018-03-06 15:23:35.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessByte + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessByte + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessByte * @run testng/othervm -Diters=20000 VarHandleTestAccessByte * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessByte @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessByte.class, "static_v", byte.class); vhArray = MethodHandles.arrayElementVarHandle(byte[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "byte_v", byte.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessByte::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -277,6 +290,19 @@ } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + byte x = (byte) vh.get(recv); + assertEquals(x, (byte)0x01, "get byte value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, (byte)0x23); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java 2018-03-06 15:23:38.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessChar.java 2018-03-06 15:23:37.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessChar + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessChar + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessChar * @run testng/othervm -Diters=20000 VarHandleTestAccessChar * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessChar @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessChar.class, "static_v", char.class); vhArray = MethodHandles.arrayElementVarHandle(char[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "char_v", char.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessChar::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -277,6 +290,19 @@ } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + char x = (char) vh.get(recv); + assertEquals(x, '\u0123', "get char value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, '\u4567'); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java 2018-03-06 15:23:41.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessDouble.java 2018-03-06 15:23:40.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessDouble + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessDouble + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessDouble * @run testng/othervm -Diters=20000 VarHandleTestAccessDouble * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessDouble @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessDouble.class, "static_v", double.class); vhArray = MethodHandles.arrayElementVarHandle(double[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "double_v", double.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessDouble::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -312,6 +325,19 @@ }); } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + double x = (double) vh.get(recv); + assertEquals(x, 1.0d, "get double value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 2.0d); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java 2018-03-06 15:23:44.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessFloat.java 2018-03-06 15:23:43.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessFloat + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessFloat + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessFloat * @run testng/othervm -Diters=20000 VarHandleTestAccessFloat * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessFloat @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessFloat.class, "static_v", float.class); vhArray = MethodHandles.arrayElementVarHandle(float[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "float_v", float.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessFloat::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -312,6 +325,19 @@ }); } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + float x = (float) vh.get(recv); + assertEquals(x, 1.0f, "get float value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 2.0f); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java 2018-03-06 15:23:47.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessInt.java 2018-03-06 15:23:46.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessInt + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessInt + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessInt * @run testng/othervm -Diters=20000 VarHandleTestAccessInt * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessInt @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessInt.class, "static_v", int.class); vhArray = MethodHandles.arrayElementVarHandle(int[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "int_v", int.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessInt::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -277,6 +290,19 @@ } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + int x = (int) vh.get(recv); + assertEquals(x, 0x01234567, "get int value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 0x89ABCDEF); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java 2018-03-06 15:23:50.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessLong.java 2018-03-06 15:23:49.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessLong + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessLong + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessLong * @run testng/othervm -Diters=20000 VarHandleTestAccessLong * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessLong @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessLong.class, "static_v", long.class); vhArray = MethodHandles.arrayElementVarHandle(long[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "long_v", long.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessLong::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -277,6 +290,19 @@ } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + long x = (long) vh.get(recv); + assertEquals(x, 0x0123456789ABCDEFL, "get long value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, 0xCAFEBABECAFEBABEL); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java 2018-03-06 15:23:52.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/VarHandleTestAccessShort.java 2018-03-06 15:23:52.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -23,7 +23,10 @@ /* * @test - * @run testng/othervm -Diters=10 -Xint VarHandleTestAccessShort + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessShort + */ +/* Disabled temporarily for lworld * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessShort * @run testng/othervm -Diters=20000 VarHandleTestAccessShort * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessShort @@ -60,6 +63,8 @@ VarHandle vhArray; + VarHandle vhValueTypeField; + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +80,9 @@ VarHandleTestAccessShort.class, "static_v", short.class); vhArray = MethodHandles.arrayElementVarHandle(short[].class); + + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "short_v", short.class); } @@ -210,6 +218,11 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccessShort::testArrayIndexOutOfBounds, false)); + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -277,6 +290,19 @@ } + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + short x = (short) vh.get(recv); + assertEquals(x, (short)0x0123, "get short value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, (short)0x4567); + }); + } static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template 2018-03-06 15:23:55.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/X-VarHandleTestAccess.java.template 2018-03-06 15:23:54.000000000 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2018, 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 @@ -21,6 +21,18 @@ * questions. */ +#if[Value] +/* + * @test + * @compile -XDenableValueTypes Value.java + * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccess$Type$ + */ +/* Disabled temporarily for lworld + * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccess$Type$ + * @run testng/othervm -Diters=20000 VarHandleTestAccess$Type$ + * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccess$Type$ + */ +#else[Value] /* * @test * @run testng/othervm -Diters=10 -Xint VarHandleTestAccess$Type$ @@ -28,6 +40,7 @@ * @run testng/othervm -Diters=20000 VarHandleTestAccess$Type$ * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccess$Type$ */ +#end[Value] import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -60,6 +73,10 @@ VarHandle vhArray; +#if[Value] + VarHandle vhValueTypeField; +#end[Value] + @BeforeClass public void setup() throws Exception { vhFinalField = MethodHandles.lookup().findVarHandle( @@ -75,6 +92,11 @@ VarHandleTestAccess$Type$.class, "static_v", $type$.class); vhArray = MethodHandles.arrayElementVarHandle($type$[].class); + +#if[Value] + vhValueTypeField = MethodHandles.lookup().findVarHandle( + Value.class, "$type$_v", $type$.class); +#end[Value] } @@ -242,6 +264,13 @@ cases.add(new VarHandleAccessTestCase("Array index out of bounds", vhArray, VarHandleTestAccess$Type$::testArrayIndexOutOfBounds, false)); +#if[Value] + cases.add(new VarHandleAccessTestCase("Value type field", + vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); + cases.add(new VarHandleAccessTestCase("Value type field unsupported", + vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), + false)); +#end[Value] // Work around issue with jtreg summary reporting which truncates // the String result of Object.toString to 30 characters, hence @@ -404,6 +433,21 @@ #end[Bitwise] } +#if[Value] + static void testValueTypeField(Value recv, VarHandle vh) { + // Plain + { + $type$ x = ($type$) vh.get(recv); + assertEquals(x, $value1$, "get $type$ value"); + } + } + + static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { + checkUOE(() -> { + vh.set(recv, $value2$); + }); + } +#end[Value] static void testStaticFinalField(VarHandle vh) { // Plain --- old/test/jdk/java/lang/invoke/VarHandles/generate-vh-tests.sh 2018-03-06 15:23:58.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/generate-vh-tests.sh 2018-03-06 15:23:57.000000000 -0800 @@ -28,6 +28,12 @@ ;; esac + case $type in + boolean|byte|short|char|int|long|float|double) + args="$args -KValue" + ;; + esac + wrong_primitive_type=boolean case $type in --- old/test/jdk/valhalla/valuetypes/Reflection.java 2018-03-06 15:24:02.000000000 -0800 +++ new/test/jdk/valhalla/valuetypes/Reflection.java 2018-03-06 15:24:01.000000000 -0800 @@ -26,7 +26,7 @@ * @test * @summary test reflection on value types * @compile -XDenableValueTypes Point.java - * @run main/othervm -XX:+EnableValhalla Reflection + * @run main/othervm -Xverify:none Reflection */ import java.lang.reflect.*; @@ -35,36 +35,80 @@ public static void main(String... args) throws Exception { Reflection test = new Reflection("Point"); test.newInstance(); + test.constructor(); test.accessField(); + test.setAccessible(); + test.trySetAccessible(); + test.staticField(); } private final Class c; + private final Constructor ctor; + private final Field field; Reflection(String cn) throws Exception { this.c = Class.forName(cn); if (!c.isValue()) { throw new RuntimeException(cn + " is not a value class"); } + + this.ctor = Point.class.getDeclaredConstructor(); + this.field = c.getField("x"); } void accessField() throws Exception { Point o = Point.origin; - Field x = c.getField("x"); - if (x.getInt(o) != o.x) { - throw new RuntimeException("Unexpected Point.x value: " + x.getInt(o)); + if (field.getInt(o) != o.x) { + throw new RuntimeException("Unexpected Point.x value: " + field.getInt(o)); } try { - x.setInt(o, 100); + field.setInt(o, 100); throw new RuntimeException("IllegalAccessException not thrown"); } catch (IllegalAccessException e) {} } void newInstance() throws Exception { - if (c == null) return; - try { Object o = c.newInstance(); throw new RuntimeException("newInstance expected to be unsupported on value class"); - } catch (UnsupportedOperationException e) {} + } catch (IllegalAccessException e) {} + } + + void constructor() throws Exception { + try { + ctor.newInstance(); + throw new RuntimeException("IllegalAccessException not thrown"); + } catch (IllegalAccessException e) { } + } + + void setAccessible() throws Exception { + try { + ctor.setAccessible(true); + throw new RuntimeException("InaccessibleObjectException not thrown"); + } catch (InaccessibleObjectException e) { e.printStackTrace(); } + try { + field.setAccessible(true); + throw new RuntimeException("InaccessibleObjectException not thrown"); + } catch (InaccessibleObjectException e) { e.printStackTrace(); } + } + + void trySetAccessible() throws Exception { + if (ctor.trySetAccessible()) { + throw new RuntimeException("trySetAccessible should not succeed"); + } + if (field.trySetAccessible()) { + throw new RuntimeException("trySetAccessible should not succeed"); + } + } + + void staticField() throws Exception { + Field f = Point.class.getDeclaredField("origin"); + if (f.trySetAccessible()) { + throw new RuntimeException("trySetAccessible should not succeed"); + } + try { + f.setAccessible(true); + throw new RuntimeException("IllegalAccessException not thrown"); + } catch (InaccessibleObjectException e) { } } } --- /dev/null 2018-03-06 15:24:05.000000000 -0800 +++ new/test/jdk/java/lang/invoke/VarHandles/Value.java 2018-03-06 15:24:04.000000000 -0800 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, 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. + */ + +final __ByValue class Value { + static final Value VT = makeValue('\u0123', true, (byte)0x01, 0x01234567, (short)0x0123, 0x0123456789ABCDEFL, 1.0f, 1.0d); + final char char_v; + final byte byte_v; + final boolean boolean_v; + final int int_v; + final short short_v; + final long long_v; + final double double_v; + final float float_v; + Value() { + char_v = 'z'; + boolean_v = true; + byte_v = 0; + int_v = 1; + short_v = 2; + long_v = 3; + float_v = 0.1f; + double_v = 0.2d; + } + static Value makeValue(char c, boolean z, byte b, int x, short y, long l, float f, double d) { + Value v = __MakeDefault Value(); + v.char_v = c; + v.byte_v = b; + v.boolean_v = z; + v.int_v = x; + v.short_v = y; + v.long_v = l; + v.float_v = f; + v.double_v = d; + return v; + } +}