changeset 47253:4bded5db79fd mvt

import changes from mvt/langtools
author dsimms
date Tue, 26 Sep 2017 16:13:34 +0200
parents e99c25c2f4a6
children d4fe87089809
files src/java.compiler/share/classes/javax/lang/model/element/Modifier.java src/jdk.compiler/share/classes/com/sun/source/tree/NewClassTree.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ValueCapableClassAttr.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ByteCodes.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/AccessFlags.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/Descriptor.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/Opcode.java src/jdk.jdeps/share/classes/com/sun/tools/classfile/Signature.java src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java test/langtools/tools/javac/diags/CheckResourceKeys.java test/langtools/tools/javac/diags/examples.not-yet.txt test/langtools/tools/javac/diags/examples/ValueTypesDisabled.java test/langtools/tools/javac/processing/model/TestSymtabItems.java test/langtools/tools/javac/valhalla/minimalvalues/CheckClone.java test/langtools/tools/javac/valhalla/minimalvalues/CheckClone.out test/langtools/tools/javac/valhalla/minimalvalues/CheckCyclicMembership.java test/langtools/tools/javac/valhalla/minimalvalues/CheckCyclicMembership.out test/langtools/tools/javac/valhalla/minimalvalues/CheckEquals.java test/langtools/tools/javac/valhalla/minimalvalues/CheckEquals.out test/langtools/tools/javac/valhalla/minimalvalues/CheckExtends.java test/langtools/tools/javac/valhalla/minimalvalues/CheckExtends.out test/langtools/tools/javac/valhalla/minimalvalues/CheckFinal.java test/langtools/tools/javac/valhalla/minimalvalues/CheckFinal.out test/langtools/tools/javac/valhalla/minimalvalues/CheckFinalize.java test/langtools/tools/javac/valhalla/minimalvalues/CheckFinalize.out test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash.java test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash.out test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash01.java test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash01.out test/langtools/tools/javac/valhalla/minimalvalues/CheckNullAssign.java test/langtools/tools/javac/valhalla/minimalvalues/CheckNullAssign.out test/langtools/tools/javac/valhalla/minimalvalues/CheckNullCastable.java test/langtools/tools/javac/valhalla/minimalvalues/CheckNullCastable.out test/langtools/tools/javac/valhalla/minimalvalues/CheckSync.java test/langtools/tools/javac/valhalla/minimalvalues/CheckSync.out test/langtools/tools/javac/valhalla/minimalvalues/CheckSynchronized.java test/langtools/tools/javac/valhalla/minimalvalues/CheckSynchronized.out test/langtools/tools/javac/valhalla/minimalvalues/ClassFileReaderTest.java test/langtools/tools/javac/valhalla/minimalvalues/ClassFileReaderTest.out test/langtools/tools/javac/valhalla/minimalvalues/Point.java test/langtools/tools/javac/valhalla/values/CheckClone.java test/langtools/tools/javac/valhalla/values/CheckClone.out test/langtools/tools/javac/valhalla/values/CheckCyclicMembership.java test/langtools/tools/javac/valhalla/values/CheckCyclicMembership.out test/langtools/tools/javac/valhalla/values/CheckEquals.java test/langtools/tools/javac/valhalla/values/CheckEquals.out test/langtools/tools/javac/valhalla/values/CheckExtends.java test/langtools/tools/javac/valhalla/values/CheckExtends.out test/langtools/tools/javac/valhalla/values/CheckFinal.java test/langtools/tools/javac/valhalla/values/CheckFinal.out test/langtools/tools/javac/valhalla/values/CheckFinalize.java test/langtools/tools/javac/valhalla/values/CheckFinalize.out test/langtools/tools/javac/valhalla/values/CheckFlags.java test/langtools/tools/javac/valhalla/values/CheckIdentityHash.java test/langtools/tools/javac/valhalla/values/CheckIdentityHash.out test/langtools/tools/javac/valhalla/values/CheckIdentityHash01.java test/langtools/tools/javac/valhalla/values/CheckIdentityHash01.out test/langtools/tools/javac/valhalla/values/CheckMakeDefault.java test/langtools/tools/javac/valhalla/values/CheckMakeDefault.out test/langtools/tools/javac/valhalla/values/CheckNoInvokeDirect.java test/langtools/tools/javac/valhalla/values/CheckNullAssign.java test/langtools/tools/javac/valhalla/values/CheckNullAssign.out test/langtools/tools/javac/valhalla/values/CheckNullCastable.java test/langtools/tools/javac/valhalla/values/CheckNullCastable.out test/langtools/tools/javac/valhalla/values/CheckStaticValueFactory.java test/langtools/tools/javac/valhalla/values/CheckStaticValueFactory.out test/langtools/tools/javac/valhalla/values/CheckSuper.java test/langtools/tools/javac/valhalla/values/CheckSuperCompileOnly.java test/langtools/tools/javac/valhalla/values/CheckSync.java test/langtools/tools/javac/valhalla/values/CheckSync.out test/langtools/tools/javac/valhalla/values/CheckSynchronized.java test/langtools/tools/javac/valhalla/values/CheckSynchronized.out test/langtools/tools/javac/valhalla/values/CheckValueFactoryWithReference.java test/langtools/tools/javac/valhalla/values/CheckValueFactoryWithReference.out test/langtools/tools/javac/valhalla/values/CheckValueModifier.java test/langtools/tools/javac/valhalla/values/CheckValueModifier.out test/langtools/tools/javac/valhalla/values/Point.java test/langtools/tools/javac/valhalla/values/VOpcodeTest.java test/langtools/tools/javac/valhalla/values/ValueCreationTest.java
diffstat 102 files changed, 2316 insertions(+), 95 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/java.compiler/share/classes/javax/lang/model/element/Modifier.java	Tue Sep 26 16:13:34 2017 +0200
@@ -58,6 +58,17 @@
      * @since 1.8
      */
      DEFAULT,
+    /**
+     * The modifier {@code __ByValue}
+     * @since 1.9
+     */
+    VALUE,
+    /**
+     * The modifier {@code __ValueFactory}
+     * @since 1.9
+     */
+    STATICVALUEFACTORY,
+
     /** The modifier {@code static} */          STATIC,
     /** The modifier {@code final} */           FINAL,
     /** The modifier {@code transient} */       TRANSIENT,
--- a/src/jdk.compiler/share/classes/com/sun/source/tree/NewClassTree.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/source/tree/NewClassTree.java	Tue Sep 26 16:13:34 2017 +0200
@@ -49,6 +49,18 @@
  * @since 1.6
  */
 public interface NewClassTree extends ExpressionTree {
+
+    /**
+     * There are two kinds of new class trees: (i) references (new String("Foo"))
+     * (ii) default values (__MakeDefault Point())
+     */
+    public enum CreationMode {
+        /** enum constant for reference creation. */
+        NEW,
+        /** enum constant for default value creation. */
+        DEFAULT_VALUE,
+    }
+
     /**
      * Returns the enclosing expression, or {@code null} if none.
      * @return the enclosing expression
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Flags.java	Tue Sep 26 16:13:34 2017 +0200
@@ -91,6 +91,9 @@
     /** Flag that marks attribute interfaces, added in classfile v49.0. */
     public static final int ANNOTATION   = 1<<13;
 
+    /** Flag to mark value factory methods. (vminit methods as opposed to static value factory methods) */
+    public static final int VALUEFACTORY = 1<<13;
+
     /** An enumeration type or an enumeration constant, added in
      *  classfile v49.0. */
     public static final int ENUM         = 1<<14;
@@ -98,6 +101,9 @@
     /** Added in SE8, represents constructs implicitly declared in source. */
     public static final int MANDATED     = 1<<15;
 
+    /** Marks a type as a value-type */
+    public static final int VALUE        = 1<<16;
+
     public static final int StandardFlags = 0x0fff;
 
     // Because the following access flags are overloaded with other
@@ -107,6 +113,7 @@
     public static final int ACC_SUPER    = 0x0020;
     public static final int ACC_BRIDGE   = 0x0040;
     public static final int ACC_VARARGS  = 0x0080;
+    public static final int ACC_VALUE    = 0x0100;
     public static final int ACC_MODULE   = 0x8000;
 
     /*****************************************
@@ -122,6 +129,11 @@
      */
     public static final int HASINIT          = 1<<18;
 
+    /** Flag is set for a method symbol that acts as a static factory method for a value type
+     *  (contrast with vminit methods flagged as STATICVALUEFACTORY)
+     */
+    public static final int STATICVALUEFACTORY = 1<<19;
+
     /** Flag is set for compiler-generated anonymous method symbols
      *  that `own' an initializer block.
      */
@@ -220,7 +232,7 @@
      */
     public static final long UNION = 1L<<39;
 
-    // Flag bit (1L << 40) is available.
+    public static final long VALUE_CAPABLE = 1L<<40;
 
     /**
      * Flag that marks an 'effectively final' local variable.
@@ -317,7 +329,7 @@
      */
     public static final int
         AccessFlags           = PUBLIC | PROTECTED | PRIVATE,
-        LocalClassFlags       = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC,
+        LocalClassFlags       = FINAL | ABSTRACT | STRICTFP | ENUM | SYNTHETIC | VALUE,
         MemberClassFlags      = LocalClassFlags | INTERFACE | AccessFlags,
         ClassFlags            = LocalClassFlags | INTERFACE | PUBLIC | ANNOTATION,
         InterfaceVarFlags     = FINAL | STATIC | PUBLIC,
@@ -326,9 +338,9 @@
         ConstructorFlags      = AccessFlags,
         InterfaceMethodFlags  = ABSTRACT | PUBLIC,
         MethodFlags           = AccessFlags | ABSTRACT | STATIC | NATIVE |
-                                SYNCHRONIZED | FINAL | STRICTFP;
+                                SYNCHRONIZED | FINAL | STRICTFP | VALUEFACTORY | STATICVALUEFACTORY;
     public static final long
-        ExtendedStandardFlags       = (long)StandardFlags | DEFAULT,
+        ExtendedStandardFlags       = (long)StandardFlags | DEFAULT | VALUE | STATICVALUEFACTORY,
         ModifierFlags               = ((long)StandardFlags & ~INTERFACE) | DEFAULT,
         InterfaceMethodMask         = ABSTRACT | PRIVATE | STATIC | PUBLIC | STRICTFP | DEFAULT,
         AnnotationTypeElementMask   = ABSTRACT | PUBLIC,
@@ -353,6 +365,8 @@
             if (0 != (flags & NATIVE))    modifiers.add(Modifier.NATIVE);
             if (0 != (flags & STRICTFP))  modifiers.add(Modifier.STRICTFP);
             if (0 != (flags & DEFAULT))   modifiers.add(Modifier.DEFAULT);
+            if (0 != (flags & VALUE))     modifiers.add(Modifier.VALUE);
+            if (0 != (flags & STATICVALUEFACTORY))     modifiers.add(Modifier.STATICVALUEFACTORY);
             modifiers = Collections.unmodifiableSet(modifiers);
             modifierSets.put(flags, modifiers);
         }
@@ -394,9 +408,12 @@
         ANNOTATION(Flags.ANNOTATION),
         DEPRECATED(Flags.DEPRECATED),
         HASINIT(Flags.HASINIT),
+        STATICVALUEFACTORY(Flags.STATICVALUEFACTORY),
         BLOCK(Flags.BLOCK),
         ENUM(Flags.ENUM),
         MANDATED(Flags.MANDATED),
+        VALUE(Flags.VALUE),
+        VALUECAPABLE(Flags.VALUE_CAPABLE),
         NOOUTERTHIS(Flags.NOOUTERTHIS),
         EXISTS(Flags.EXISTS),
         COMPOUND(Flags.COMPOUND),
@@ -422,6 +439,7 @@
         THROWS(Flags.THROWS),
         LAMBDA_METHOD(Flags.LAMBDA_METHOD),
         TYPE_TRANSLATED(Flags.TYPE_TRANSLATED),
+        VALUEFACTORY(Flags.VALUEFACTORY),
         MODULE(Flags.MODULE),
         AUTOMATIC_MODULE(Flags.AUTOMATIC_MODULE),
         SYSTEM_MODULE(Flags.SYSTEM_MODULE),
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java	Tue Sep 26 16:13:34 2017 +0200
@@ -285,6 +285,11 @@
         UNCHECKED("unchecked"),
 
         /**
+         * Warn about value incompatible/unfriendly operations on value capable types.
+         */
+        VALUES("values"),
+
+        /**
          * Warn about potentially unsafe vararg methods
          */
         VARARGS("varargs");
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symbol.java	Tue Sep 26 16:13:34 2017 +0200
@@ -425,6 +425,13 @@
         return name == name.table.names.init;
     }
 
+    /**
+     * Is this a value capable class ?
+    */
+    public boolean isValueCapable() {
+        return (flags() & VALUE_CAPABLE) != 0;
+    }
+
     /** The fully qualified name of this symbol.
      *  This is the same as the symbol's name except for class symbols,
      *  which are handled separately.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Symtab.java	Tue Sep 26 16:13:34 2017 +0200
@@ -154,10 +154,12 @@
     /** A symbol for the java.base module.
      */
     public final ModuleSymbol java_base;
+    public final ModuleSymbol jdk_incubator_mvt;
 
     /** Predefined types.
      */
     public final Type objectType;
+    public final Type valueClassType;
     public final Type objectsType;
     public final Type classType;
     public final Type classLoaderType;
@@ -210,6 +212,7 @@
     public final Type documentedType;
     public final Type elementTypeType;
     public final Type functionalInterfaceType;
+    public final Type valueCapableClass;
 
     /** The symbol representing the length field of an array.
      */
@@ -294,6 +297,60 @@
         };
     }
 
+    public void synthesizeDeriveValueTypeIfMissing(final Type type) {
+        final Completer completer = type.tsym.completer;
+        type.tsym.completer = new Completer() {
+            public void complete(Symbol sym) throws CompletionFailure {
+                try {
+                    completer.complete(sym);
+                } catch (CompletionFailure e) {
+                    ClassType ctype = (ClassType) type;
+                    sym.flags_field = PUBLIC|ACYCLIC|ANNOTATION|INTERFACE;
+                    sym.erasure_field = ctype;
+                    ((ClassSymbol) sym).members_field = WriteableScope.create(sym);
+                    ctype.typarams_field = List.nil();
+                    ctype.allparams_field = List.nil();
+                    ctype.supertype_field = annotationType;
+                    ctype.interfaces_field = List.nil();
+                }
+            }
+
+            @Override
+            public boolean isTerminal() {
+                return completer.isTerminal();
+            }
+        };
+    }
+
+    public void synthesizeJavaLangValueClassIfMissing(final Type type) {
+        final Completer completer = type.tsym.completer;
+        type.tsym.completer = new Completer() {
+            public void complete(Symbol sym) throws CompletionFailure {
+                try {
+                    completer.complete(sym);
+                } catch (CompletionFailure e) {
+                    sym.flags_field |= (PUBLIC | VALUE);
+                    ((ClassType) sym.type).supertype_field = Type.noType;
+                    ((ClassSymbol) sym).members_field = WriteableScope.create(sym);
+                    sym.members().enter(new MethodSymbol(PUBLIC, names.init,
+                            new MethodType(List.<Type>nil(), voidType, List.<Type>nil(), methodClass), sym));
+                    sym.members().enter(new MethodSymbol(PUBLIC, names.hashCode,
+                            new MethodType(List.<Type>nil(), intType, List.<Type>nil(), methodClass), sym));
+                    sym.members().enter(new MethodSymbol(PUBLIC, names.toString,
+                            new MethodType(List.<Type>nil(), stringType, List.<Type>nil(), methodClass), sym));
+                    sym.members().enter(new MethodSymbol(PUBLIC, names.equals,
+                            new MethodType(List.<Type>of(objectType), booleanType, List.<Type>nil(), methodClass), sym));
+                }
+            }
+
+            @Override
+            public boolean isTerminal() {
+                return completer.isTerminal();
+            }
+        };
+    }
+
+
     public void synthesizeBoxTypeIfMissing(final Type type) {
         ClassSymbol sym = enterClass(java_base, boxedName[type.getTag().ordinal()]);
         final Completer completer = sym.completer;
@@ -473,8 +530,13 @@
             //avoid completing java.base during the Symtab initialization
             java_base.completer = Completer.NULL_COMPLETER;
             java_base.visiblePackages = Collections.emptyMap();
+
+            jdk_incubator_mvt = enterModule(names.fromString("jdk.incubator.mvt"));
+            jdk_incubator_mvt.completer = Completer.NULL_COMPLETER;
+            jdk_incubator_mvt.visiblePackages = Collections.emptyMap();
         } else {
             java_base = noModule;
+            jdk_incubator_mvt = noModule;
         }
 
         // Get the initial completer for ModuleSymbols from Modules
@@ -483,6 +545,7 @@
         // Enter predefined classes. All are assumed to be in the java.base module.
         objectType = enterClass("java.lang.Object");
         objectsType = enterClass("java.util.Objects");
+        valueClassType = enterClass("java.lang.__Value");
         classType = enterClass("java.lang.Class");
         stringType = enterClass("java.lang.String");
         stringBufferType = enterClass("java.lang.StringBuffer");
@@ -544,6 +607,9 @@
         stringConcatFactory = enterClass("java.lang.invoke.StringConcatFactory");
         functionalInterfaceType = enterClass("java.lang.FunctionalInterface");
 
+        Name vccName = names.fromString("jdk.incubator.mvt.ValueCapableClass");
+        valueCapableClass = enterClass(jdk_incubator_mvt, vccName).type;
+
         synthesizeEmptyInterfaceIfMissing(autoCloseableType);
         synthesizeEmptyInterfaceIfMissing(cloneableType);
         synthesizeEmptyInterfaceIfMissing(serializableType);
@@ -553,6 +619,8 @@
         synthesizeBoxTypeIfMissing(doubleType);
         synthesizeBoxTypeIfMissing(floatType);
         synthesizeBoxTypeIfMissing(voidType);
+        synthesizeJavaLangValueClassIfMissing(valueClassType);
+        synthesizeDeriveValueTypeIfMissing(valueCapableClass);
 
         // Enter a synthetic class that is used to mark internal
         // proprietary classes in ct.sym.  This class does not have a
@@ -586,8 +654,10 @@
             arrayClass);
         arrayClass.members().enter(arrayCloneMethod);
 
-        if (java_base != noModule)
+        if (java_base != noModule) {
             java_base.completer = moduleCompleter::complete; //bootstrap issues
+            jdk_incubator_mvt.completer = moduleCompleter::complete; //bootstrap issues
+        }
 
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java	Tue Sep 26 16:13:34 2017 +0200
@@ -686,6 +686,15 @@
        }
     }
 
+    public boolean isValue(Type t) {
+        return t.tsym != null && (t.tsym.flags_field & Flags.VALUE) != 0;
+    }
+
+    public boolean isValueCapable(Type t) {
+        return t != null && t.tsym != null && t.tsym.isValueCapable();
+    }
+
+
     // <editor-fold defaultstate="collapsed" desc="isSubtype">
     /**
      * Is t an unchecked subtype of s?
@@ -806,7 +815,7 @@
                      return isSubtypeNoCapture(t.getUpperBound(), s);
                  case BOT:
                      return
-                         s.hasTag(BOT) || s.hasTag(CLASS) ||
+                         s.hasTag(BOT) || (s.hasTag(CLASS) && !isValue(s)) ||
                          s.hasTag(ARRAY) || s.hasTag(TYPEVAR);
                  case WILDCARD: //we shouldn't be here - avoids crash (see 7034495)
                  case NONE:
@@ -1447,7 +1456,7 @@
 
             @Override
             public Boolean visitClassType(ClassType t, Type s) {
-                if (s.hasTag(ERROR) || s.hasTag(BOT))
+                if (s.hasTag(ERROR) || s.hasTag(BOT) && !isValue(t))
                     return true;
 
                 if (s.hasTag(TYPEVAR)) {
@@ -4813,7 +4822,10 @@
                     append('V');
                     break;
                 case CLASS:
-                    append('L');
+                    if (types.isValue(type))
+                        append('Q');
+                    else
+                        append('L');
                     assembleClassSig(type);
                     append(';');
                     break;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Tue Sep 26 16:13:34 2017 +0200
@@ -33,6 +33,7 @@
 import com.sun.source.tree.IdentifierTree;
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 import com.sun.source.tree.MemberSelectTree;
+import com.sun.source.tree.NewClassTree.CreationMode;
 import com.sun.source.tree.TreeVisitor;
 import com.sun.source.util.SimpleTreeVisitor;
 import com.sun.tools.javac.code.*;
@@ -113,6 +114,7 @@
     final Dependencies dependencies;
     final Annotate annotate;
     final ArgumentAttr argumentAttr;
+    private final ValueCapableClassAttr valueCapableClassAttr;
 
     public static Attr instance(Context context) {
         Attr instance = context.get(attrKey);
@@ -148,6 +150,7 @@
         typeEnvs = TypeEnvs.instance(context);
         dependencies = Dependencies.instance(context);
         argumentAttr = ArgumentAttr.instance(context);
+        valueCapableClassAttr = ValueCapableClassAttr.instance(context);
 
         Options options = Options.instance(context);
 
@@ -295,7 +298,19 @@
             if (v.isResourceVariable()) { //TWR resource
                 log.error(pos, Errors.TryResourceMayNotBeAssigned(v));
             } else {
-                log.error(pos, Errors.CantAssignValToFinalVar(v));
+                boolean complain = true;
+                /* Allow updates to blank final fields inside value factories.
+                   This really results in copy on write and not mutation of the
+                   final field
+                */
+                if (v.getKind() == ElementKind.FIELD && (v.flags() & HASINIT) == 0) {
+                    if (env.enclMethod != null && (env.enclMethod.mods.flags & STATICVALUEFACTORY) != 0) {
+                        if (v.owner == env.enclMethod.sym.owner)
+                            complain = false;
+                    }
+                }
+                if (complain)
+                    log.error(pos, Errors.CantAssignValToFinalVar(v));
             }
         }
     }
@@ -1063,8 +1078,8 @@
             } else {
                 // Add an implicit super() call unless an explicit call to
                 // super(...) or this(...) is given
-                // or we are compiling class java.lang.Object.
-                if (tree.name == names.init && owner.type != syms.objectType) {
+                // or we are compiling class java.lang.{Object, Value}.
+                if (tree.name == names.init && owner.type != syms.objectType && owner.type != syms.valueClassType) {
                     JCBlock body = tree.body;
                     if (body.stats.isEmpty() ||
                             !TreeInfo.isSelfCall(body.stats.head)) {
@@ -1121,6 +1136,9 @@
                 annotate.queueScanTreeAndTypeAnnotate(tree.init, env, tree.sym, tree.pos());
                 annotate.flush();
             }
+            if (types.isValue(tree.sym.owner.type) && (tree.mods.flags & (Flags.FINAL | Flags.STATIC)) == 0) {
+                log.error(tree.pos(), "value.field.must.be.final");
+            }
         }
 
         VarSymbol v = tree.sym;
@@ -1920,7 +1938,12 @@
             Symbol msym = TreeInfo.symbol(tree.meth);
             restype = adjustMethodReturnType(msym, qualifier, methName, argtypes, restype);
 
-            chk.checkRefTypes(tree.typeargs, typeargtypes);
+            // identity hash code is uncomputable for value instances.
+            final Symbol symbol = TreeInfo.symbol(tree.meth);
+            if (symbol != null && symbol.name == names.identityHashCode && symbol.owner.flatName() == names.java_lang_System) {
+                if (tree.args.length() == 1 && types.isValue(tree.args.head.type))
+                    log.error(tree.pos(), "value.does.not.support", "identityHashCode");
+            }
 
             // Check that value of resulting type is admissible in the
             // current context.  Also, capture the return type
@@ -2106,6 +2129,10 @@
                  ((JCVariableDecl) env.tree).init != tree))
                 log.error(tree.pos(), Errors.EnumCantBeInstantiated);
 
+            if (tree.creationMode == CreationMode.NEW && types.isValue(clazztype)) {
+                log.error(tree.pos(), Errors.GarbledValueReferenceInstantiation);
+            }
+
             boolean isSpeculativeDiamondInferenceRound = TreeInfo.isDiamond(tree) &&
                     resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
             boolean skipNonDiamondPath = false;
@@ -2206,6 +2233,22 @@
                         tree.constructorType = instantiatedContext.asInstType(tree.constructorType);
                     });
         }
+        if (tree.creationMode == CreationMode.DEFAULT_VALUE) {
+            if (tree.constructor != null && tree.constructor.isConstructor()) {
+                final List<Type> parameterTypes = tree.constructorType.getParameterTypes();
+                if (!parameterTypes.isEmpty()) {
+                    log.error(tree.pos, "invalid.arguments.to.make.default");
+                }
+                if (!types.isValue(TreeInfo.symbol(tree.clazz).type)) {
+                    log.error(tree.pos, "make.default.with.nonvalue");
+                } else if (env.enclMethod != null && env.enclMethod.sym.owner != TreeInfo.symbol(tree.clazz)) {
+                    log.error(tree.pos, "make.default.with.wrong.value.type", TreeInfo.symbol(tree.clazz));
+                }
+            }
+            if (env.enclMethod != null && (env.enclMethod.mods.flags & STATICVALUEFACTORY) == 0) {
+                log.error(tree.pos, "make.default.in.nonfactory");
+            }
+        }
         chk.validate(tree.typeargs, localEnv);
     }
 
@@ -3313,6 +3356,9 @@
                 if (!types.isCastable(left, right, new Warner(tree.pos()))) {
                     log.error(tree.pos(), Errors.IncomparableTypes(left, right));
                 }
+                if (types.isValue(left) || types.isValue(right)) {
+                    log.error(tree.pos(), "value.does.not.support", tree.operator.name.toString());
+                }
             }
 
             chk.checkDivZero(tree.rhs.pos(), operator, right);
@@ -4437,6 +4483,9 @@
         try {
             annotate.flush();
             attribClass(c);
+            final Env<AttrContext> env = typeEnvs.get(c);
+            if (c.owner.kind == PCK && env != null && env.info.lint != null && env.info.lint.isEnabled(LintCategory.VALUES))
+                valueCapableClassAttr.translate(env.tree);
         } catch (CompletionFailure ex) {
             chk.completionError(pos, ex);
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Check.java	Tue Sep 26 16:13:34 2017 +0200
@@ -754,7 +754,7 @@
      *  @param t             The type to be checked.
      */
     Type checkRefType(DiagnosticPosition pos, Type t) {
-        if (t.isReference())
+        if (t.isReference() && !types.isValue(t))
             return t;
         else
             return typeTagError(pos,
@@ -1168,7 +1168,9 @@
                     mask = implicit = InterfaceMethodFlags;
                 }
             } else {
-                mask = MethodFlags;
+                // instance methods of value types do not have a monitor associated with their `this'
+                mask = ((sym.owner.flags_field & VALUE) != 0 && (flags & Flags.STATIC) == 0) ?
+                        MethodFlags & ~SYNCHRONIZED : MethodFlags;
             }
             // Imply STRICTFP if owner has STRICTFP set.
             if (((flags|implicit) & Flags.ABSTRACT) == 0 ||
@@ -1197,8 +1199,8 @@
             if ((flags & INTERFACE) != 0) implicit |= ABSTRACT;
 
             if ((flags & ENUM) != 0) {
-                // enums can't be declared abstract or final
-                mask &= ~(ABSTRACT | FINAL);
+                // enums can't be declared abstract or final or value type
+                mask &= ~(ABSTRACT | FINAL | VALUE);
                 implicit |= implicitEnumFinalFlag(tree);
             }
             // Imply STRICTFP if owner has STRICTFP set.
@@ -1231,7 +1233,7 @@
                  &&
                  checkDisjoint(pos, flags,
                                ABSTRACT | INTERFACE,
-                               FINAL | NATIVE | SYNCHRONIZED)
+                               FINAL | NATIVE | SYNCHRONIZED | VALUE)
                  &&
                  checkDisjoint(pos, flags,
                                PUBLIC,
@@ -2169,6 +2171,52 @@
         }
     }
 
+    // A value class cannot contain a field of its own type either or indirectly.
+    void checkNonCyclicMembership(JCClassDecl tree) {
+        Assert.check((tree.sym.flags_field & LOCKED) == 0);
+        try {
+            tree.sym.flags_field |= LOCKED;
+            for (List<? extends JCTree> l = tree.defs; l.nonEmpty(); l = l.tail) {
+                if (l.head.hasTag(VARDEF)) {
+                    JCVariableDecl field = (JCVariableDecl) l.head;
+                    if (!field.sym.isStatic()) {
+                        Type fieldType = field.sym.type;
+                        if (types.isValue(fieldType) || types.isValueCapable(fieldType)) {
+                            checkNonCyclicMembership((ClassSymbol) fieldType.tsym, field.pos());
+                        }
+                    }
+                }
+            }
+        } finally {
+            tree.sym.flags_field &= ~LOCKED;
+        }
+
+    }
+    // where
+    private void checkNonCyclicMembership(ClassSymbol c, DiagnosticPosition pos) {
+        if ((c.flags_field & LOCKED) != 0) {
+            if (c.isValueCapable()) {
+                if (lint.isEnabled(LintCategory.VALUES)) {
+                    log.warning(LintCategory.VALUES, pos, Warnings.CyclicValueTypeMembership(c));
+                }
+            } else {
+                log.error(pos, Errors.CyclicValueTypeMembership(c));
+            }
+            return;
+        }
+        try {
+            c.flags_field |= LOCKED;
+            for (Symbol fld : c.members().getSymbols(s -> s.kind == VAR &&
+                    !s.isStatic() &&
+                    (types.isValue(s.type) || types.isValueCapable(s.type)), NON_RECURSIVE)) {
+                checkNonCyclicMembership((ClassSymbol) fld.type.tsym, pos);
+            }
+        } finally {
+            c.flags_field &= ~LOCKED;
+        }
+    }
+
+
     void checkNonCyclicDecl(JCClassDecl tree) {
         CycleChecker cc = new CycleChecker();
         cc.scan(tree);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java	Tue Sep 26 16:13:34 2017 +0200
@@ -41,6 +41,8 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.JCTree.*;
 
+import javax.lang.model.element.ElementKind;
+
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Flags.BLOCK;
 import static com.sun.tools.javac.code.Kinds.Kind.*;
@@ -1538,6 +1540,7 @@
         }
 
         private boolean isInitialConstructor = false;
+        private JCMethodDecl enclMethod = null;
 
         @Override
         protected void markDead() {
@@ -1623,7 +1626,15 @@
                 }
                 inits.incl(sym.adr);
             } else if ((sym.flags() & FINAL) != 0) {
-                log.error(pos, Errors.VarMightAlreadyBeAssigned(sym));
+                boolean complain = true;
+                if (sym.getKind() == ElementKind.FIELD && (sym.flags() & HASINIT) == 0) {
+                    if (enclMethod != null && (enclMethod.mods.flags & STATICVALUEFACTORY) != 0) {
+                        if (sym.owner == enclMethod.sym.owner)
+                            complain = false;
+                    }
+                }
+                if (complain)
+                    log.error(pos, Errors.VarMightAlreadyBeAssigned(sym));
             }
         }
         //where
@@ -1863,8 +1874,10 @@
 
                 Assert.check(pendingExits.isEmpty());
                 boolean lastInitialConstructor = isInitialConstructor;
+                JCMethodDecl lastEnclMethod = enclMethod;
                 try {
                     isInitialConstructor = TreeInfo.isInitialConstructor(tree);
+                    enclMethod = tree;
 
                     if (!isInitialConstructor) {
                         firstadr = nextadr;
@@ -1920,6 +1933,7 @@
                     firstadr = firstadrPrev;
                     returnadr = returnadrPrev;
                     isInitialConstructor = lastInitialConstructor;
+                    enclMethod = lastEnclMethod;
                 }
             } finally {
                 lint = lintPrev;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Tue Sep 26 16:13:34 2017 +0200
@@ -228,6 +228,16 @@
             m.defaultValue = annotate.unfinishedDefaultValue(); // set it to temporary sentinel for now
             annotate.annotateDefaultValueLater(tree.defaultValue, localEnv, m, tree.pos());
         }
+
+        if ((tree.mods.flags & STATICVALUEFACTORY) != 0) {
+            if ((tree.mods.flags & STATIC) == 0) {
+                log.error(tree.pos(), "value.factory.must.be.static");
+            }
+            final Type returnType = m.getReturnType();
+            if (returnType != null && returnType.tsym != m.owner) {
+                log.error(tree.restype != null ? tree.restype.pos() : tree.pos(), "type.found.req", returnType.tsym, m.owner);
+            }
+        }
     }
 
     /** Create a fresh environment for method bodies.
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java	Tue Sep 26 16:13:34 2017 +0200
@@ -2311,7 +2311,10 @@
             else bestSoFar = bestOf(bestSoFar, sym);
 
             sym = findGlobalType(env, env.toplevel.starImportScope, name, starImportScopeRecovery);
-            if (sym.exists()) return sym;
+            if (sym.exists()) {
+                return sym;
+            } else if (name.contentEquals("__Value"))
+                return syms.valueClassType.tsym; // hack, not sure why it is not getting synthesized.
             else bestSoFar = bestOf(bestSoFar, sym);
         }
 
@@ -3801,6 +3804,28 @@
             if (name == names.error)
                 return null;
 
+            /* If this is an ill conceived attempt to invoke jlO methods not available on value types,
+               issue a distinct message that spells out the programmer's error.
+            */
+            if (kind == ABSENT_MTH && types.isValue(site)) {
+                int argSize = argtypes.size();
+                switch (name.toString()) {
+                    case "wait":
+                        if (argSize == 0
+                                || (types.isConvertible(argtypes.head, syms.longType) &&
+                                (argSize == 1 || (argSize == 2 && types.isConvertible(argtypes.tail.head, syms.intType))))) {
+                            return diags.create(dkind, log.currentSource(), pos,
+                                    "value.does.not.support", name);
+                        }
+                        break;
+                    case "notify":
+                    case "notifyAll":
+                    case "clone":
+                    case "finalize":
+                        return diags.create(dkind, log.currentSource(), pos,
+                                "value.does.not.support", name);
+                }
+            }
             boolean hasLocation = false;
             if (location == null) {
                 location = site.tsym;
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/TypeEnter.java	Tue Sep 26 16:13:34 2017 +0200
@@ -664,8 +664,11 @@
             // Determine supertype.
             Type supertype;
             JCExpression extending;
+            final boolean isValueType = (tree.mods.flags & Flags.VALUE) != 0;
 
             if (tree.extending != null) {
+                if (isValueType)
+                    log.error(tree.pos(), "value.may.not.extend");
                 extending = clearTypeParams(tree.extending);
                 supertype = attr.attribBase(extending, baseEnv, true, false, true);
             } else {
@@ -673,9 +676,9 @@
                 supertype = ((tree.mods.flags & Flags.ENUM) != 0)
                 ? attr.attribBase(enumBase(tree.pos, sym), baseEnv,
                                   true, false, false)
-                : (sym.fullname == names.java_lang_Object)
-                ? Type.noType
-                : syms.objectType;
+                : (sym.fullname == names.java_lang_Object || sym.fullname == names.java_lang_Value)
+                        ? Type.noType
+                        : isValueType ? syms.valueClassType : syms.objectType;
             }
             ct.supertype_field = modelMissingTypes(baseEnv, supertype, extending, false);
 
@@ -838,6 +841,9 @@
                 !env.toplevel.sourcefile.isNameCompatible(sym.name.toString(),JavaFileObject.Kind.SOURCE)) {
                 sym.flags_field |= AUXILIARY;
             }
+            if ((tree.mods.flags & Flags.VALUE) != 0 && (tree.mods.flags & Flags.FINAL) == 0) {
+                log.error(tree.pos(), "value.must.be.final");
+            }
         }
     }
 
@@ -935,6 +941,9 @@
                 typeAnnotations.organizeTypeAnnotationsSignatures(env, (JCClassDecl)env.tree);
                 typeAnnotations.validateTypeAnnotationsSignatures(env, (JCClassDecl)env.tree);
             }
+            if (types.isValue(tree.sym.type)) {
+                chk.checkNonCyclicMembership(tree);
+            }
         }
 
         /** Enter members for a class.
@@ -1043,7 +1052,7 @@
                 argtypes, based);
         List<JCVariableDecl> params = make.Params(argtypes, init);
         List<JCStatement> stats = List.nil();
-        if (c.type != syms.objectType) {
+        if (c.type != syms.objectType && c.type != syms.valueClassType) {
             stats = stats.prepend(SuperCall(make, typarams, params, based));
         }
         result = make.MethodDef(init, make.Block(0, stats));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/ValueCapableClassAttr.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,267 @@
+/*
+ * Copyright (c) 2017, 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.
+ */
+
+package com.sun.tools.javac.comp;
+
+import com.sun.tools.javac.code.*;
+
+import static com.sun.tools.javac.code.Flags.asFlagSet;
+import static com.sun.tools.javac.code.Kinds.Kind.*;
+import com.sun.tools.javac.code.Lint.LintCategory;
+import com.sun.tools.javac.code.Symbol.MethodSymbol;
+import com.sun.tools.javac.code.Symbol.OperatorSymbol;
+import com.sun.tools.javac.code.Symbol.TypeSymbol;
+import com.sun.tools.javac.jvm.ByteCodes;
+import com.sun.tools.javac.tree.*;
+import com.sun.tools.javac.tree.JCTree.*;
+import com.sun.tools.javac.util.*;
+
+/**
+ * Support for "Minimal Value Types" : Process classes annotated with @ValueCapableClass -
+ * All semantic checks are centralized in this place so that we can blow them all away when
+ * moving to "Maximal Value Types".
+ *
+ * see: http://cr.openjdk.java.net/~jrose/values/shady-values.html
+ *
+ */
+
+public class ValueCapableClassAttr extends TreeTranslator {
+
+    protected static final Context.Key<ValueCapableClassAttr> valueCapableClassAttr = new Context.Key<>();
+    private JCMethodDecl currentMethod;
+    private Log log;
+    private Names names;
+    private Symtab syms;
+    private final JCDiagnostic.Factory diags;
+    private final Types types;
+    private final Check chk;
+    private boolean inValue = false;
+
+    public static ValueCapableClassAttr instance(Context context) {
+        ValueCapableClassAttr instance = context.get(valueCapableClassAttr);
+        if (instance == null)
+            instance = new ValueCapableClassAttr(context);
+        return instance;
+    }
+
+    protected ValueCapableClassAttr(Context context) {
+        context.put(valueCapableClassAttr, this);
+        log = Log.instance(context);
+        names = Names.instance(context);
+        syms = Symtab.instance(context);
+        diags = JCDiagnostic.Factory.instance(context);
+        types = Types.instance(context);
+        chk = Check.instance(context);
+    }
+
+    public void visitClassDef(JCClassDecl tree) {
+        boolean oldInValue = inValue;
+        try {
+            inValue = false;
+            for (List<JCAnnotation> al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
+                JCAnnotation a = al.head;
+                if (a.annotationType.type == syms.valueCapableClass && a.args.isEmpty()) {
+                    inValue = true;
+                    tree.sym.flags_field |= Flags.VALUE_CAPABLE;
+                    break;
+                }
+            }
+            if (inValue) {
+                if (tree.extending != null) {
+                    log.warning(LintCategory.VALUES, tree.pos(), "value.may.not.extend");
+                }
+                if ((tree.mods.flags & Flags.FINAL) == 0) {
+                    log.warning(LintCategory.VALUES, tree.pos(), "value.must.be.final");
+                }
+                chk.checkNonCyclicMembership(tree);
+            }
+            super.visitClassDef(tree);
+        } finally {
+            inValue = oldInValue;
+        }
+    }
+
+    public void visitMethodDef(JCMethodDecl tree) {
+        JCMethodDecl previousMethod = currentMethod;
+        try {
+            currentMethod = tree;
+            if (tree.sym != null && tree.sym.owner.isValueCapable()) {
+                if ((tree.sym.flags() & (Flags.SYNCHRONIZED | Flags.STATIC)) == Flags.SYNCHRONIZED) {
+                    log.warning(LintCategory.VALUES, tree.pos(), "mod.not.allowed.here", asFlagSet(Flags.SYNCHRONIZED));
+                }
+                if (tree.sym.attribute(syms.overrideType.tsym) != null) {
+                    MethodSymbol m = tree.sym;
+                    TypeSymbol owner = (TypeSymbol)m.owner;
+                    for (Type sup : types.closure(owner.type)) {
+                        if (sup == owner.type)
+                            continue; // skip "this"
+                        Scope scope = sup.tsym.members();
+                        for (Symbol sym : scope.getSymbolsByName(m.name)) {
+                            if (!sym.isStatic() && m.overrides(sym, owner, types, true)) {
+                                switch (sym.name.toString()) {
+                                    case "hashCode":
+                                    case "equals":
+                                    case "toString":
+                                        break;
+                                    default:
+                                        log.warning(LintCategory.VALUES, tree.pos(), "value.does.not.support", "overriding java.lang.Object's method: " + sym.name.toString());
+                                        break;
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+            super.visitMethodDef(tree);
+        } finally {
+            currentMethod = previousMethod;
+        }
+
+    }
+
+    public void visitVarDef(JCVariableDecl tree) {
+        if (tree.sym != null && tree.sym.owner.kind == TYP && tree.sym.owner.isValueCapable()) {
+            if ((tree.mods.flags & (Flags.FINAL | Flags.STATIC)) == 0) {
+                log.warning(LintCategory.VALUES, tree.pos(), "value.field.must.be.final");
+            }
+        }
+        if (tree.init != null && tree.init.type != null && tree.init.type.hasTag(TypeTag.BOT)) {
+            if (types.isValueCapable(tree.vartype.type))
+                log.warning(LintCategory.VALUES, tree.init.pos(), "prob.found.req", diags.fragment("inconvertible.types", syms.botType, tree.vartype.type));
+        }
+        super.visitVarDef(tree);
+    }
+
+    @Override
+    public void visitAssign(JCAssign tree) {
+        if (tree.rhs.type != null && tree.rhs.type.hasTag(TypeTag.BOT)) {
+            Type lType = tree.lhs.type;
+            if (lType != null && types.isValueCapable(lType)) {
+                log.warning(LintCategory.VALUES, tree.rhs.pos(), "prob.found.req", diags.fragment("inconvertible.types", syms.botType, lType));
+            }
+        }
+        super.visitAssign(tree);
+    }
+
+    @Override
+    public void visitReturn(JCReturn tree) {
+        if (currentMethod != null && tree.expr != null && tree.expr.type != null && tree.expr.type.hasTag(TypeTag.BOT)) {
+            if (currentMethod.restype != null && types.isValueCapable(currentMethod.restype.type)) {
+                log.warning(LintCategory.VALUES, tree.expr.pos(), "prob.found.req", diags.fragment("inconvertible.types", syms.botType, currentMethod.restype.type));
+            }
+        }
+        super.visitReturn(tree);
+    }
+
+    @Override
+    public void visitTypeTest(JCInstanceOf tree) {
+        if (tree.expr.type.hasTag(TypeTag.BOT)) {
+            if (types.isValueCapable(tree.clazz.type)) {
+                log.warning(LintCategory.VALUES, tree.expr.pos(), "prob.found.req", diags.fragment("inconvertible.types", syms.botType, tree.clazz.type));
+            }
+        }
+        super.visitTypeTest(tree);
+    }
+
+    @Override
+    public void visitTypeCast(JCTypeCast tree) {
+        if (tree.expr.type != null && tree.expr.type.hasTag(TypeTag.BOT) &&
+                tree.clazz.type != null && types.isValueCapable(tree.clazz.type)) {
+            log.warning(LintCategory.VALUES, tree.expr.pos(), "prob.found.req", diags.fragment("inconvertible.types", syms.botType, tree.clazz.type));
+        }
+        super.visitTypeCast(tree);
+    }
+
+    public void visitBinary(JCBinary tree) {
+        Type left = tree.lhs.type;
+        Type right = tree.rhs.type;
+        Symbol operator = tree.operator;
+
+        if (operator != null && operator.kind == MTH &&
+                left != null && !left.isErroneous() &&
+                right != null && !right.isErroneous()) {
+            int opc = ((OperatorSymbol)operator).opcode;
+            if ((opc == ByteCodes.if_acmpeq || opc == ByteCodes.if_acmpne)) {
+                if ((left.hasTag(TypeTag.BOT) && types.isValueCapable(right)) ||
+                        (right.hasTag(TypeTag.BOT) && types.isValueCapable(left))) {
+                    log.warning(LintCategory.VALUES, tree.pos(), "incomparable.types", left, right);
+                }
+            }
+            // this is likely to change.
+            if (operator.name.contentEquals("==") || operator.name.contentEquals("!=")) {
+                if (types.isValueCapable(tree.lhs.type) ||
+                        types.isValueCapable(tree.rhs.type))
+                    log.warning(LintCategory.VALUES, tree.pos(), "value.does.not.support", tree.operator.name.toString());
+            }
+        }
+        super.visitBinary(tree);
+    }
+
+    @Override
+    public void visitSynchronized(JCSynchronized tree) {
+        if (types.isValueCapable(tree.lock.type)) {
+            log.warning(LintCategory.VALUES, tree.pos(), "type.found.req", tree.lock.type, diags.fragment("type.req.ref"));
+        }
+        super.visitSynchronized(tree);
+    }
+
+    public void visitApply(JCMethodInvocation tree) {
+        final Symbol method = TreeInfo.symbolFor(tree);
+        if (method != null && method.kind != ERR) {
+            if (method.name.contentEquals("identityHashCode") && method.owner.type == syms.systemType) {
+                if ((tree.args.length() == 1) && types.isValueCapable(tree.args.head.type))
+                    log.warning(LintCategory.VALUES, tree.pos(), "value.does.not.support", "identityHashCode");
+            }
+
+            if (method.name != names.init && method.name != names.getClass && method.owner.type == syms.objectType) {
+                boolean receiverIsValue = false;
+                switch (tree.meth.getTag()) {
+                    case IDENT:
+                        receiverIsValue = inValue;
+                        break;
+                    case SELECT:
+                        final Symbol symbol = TreeInfo.symbol(((JCFieldAccess)tree.meth).selected);
+                        receiverIsValue = symbol != null &&
+                                (symbol.name == names._super ? inValue : types.isValueCapable(symbol.type));
+                        break;
+                }
+                if (receiverIsValue) {
+                    log.warning(LintCategory.VALUES, tree.pos(), "value.does.not.support", "calling java.lang.Object's method: " + method.name.toString());
+                }
+            }
+            final List<Type> parameterTypes = method.type.getParameterTypes();
+            for (int i = 0; i < tree.args.size(); i++) {
+                final JCExpression arg = tree.args.get(i);
+                if (arg.type != null && arg.type.hasTag(TypeTag.BOT)) {
+                    Type param = i < parameterTypes.size() ? parameterTypes.get(i) :
+                            types.elemtype(parameterTypes.get(parameterTypes.size() - 1));
+                    if (types.isValueCapable(param))
+                        log.warning(LintCategory.VALUES, arg.pos(), "prob.found.req", diags.fragment("inconvertible.types", syms.botType, param));
+                }
+            }
+        }
+        super.visitApply(tree);
+    }
+}
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ByteCodes.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ByteCodes.java	Tue Sep 26 16:13:34 2017 +0200
@@ -242,7 +242,17 @@
         goto_w          = 200,
         jsr_w           = 201,
         breakpoint      = 202,
-        ByteCodeCount   = 203;
+
+        // value-type bytecodes
+        vload           = 203,
+        vstore          = 204,
+        vaload          = 205,
+        vastore         = 206,
+        vreturn         = 207,
+        vdefault       =  208,
+        vwithfield     =  209,
+
+        ByteCodeCount   = 210;
 
     /** Virtual instruction codes; used for constant folding.
      */
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Tue Sep 26 16:13:34 2017 +0200
@@ -508,13 +508,30 @@
         int index =  poolIdx[i];
         int len = getChar(index + 1);
         int start = index + 3;
-        Assert.check(buf[start] == '[' || buf[start + len - 1] != ';');
-        // by the above assertion, the following test can be
-        // simplified to (buf[start] == '[')
-        return (buf[start] == '[' || buf[start + len - 1] == ';')
-            ? (Object)sigToType(buf, start, len)
-            : (Object)enterClass(names.fromUtf(internalize(buf, start,
-                                                           len)));
+        if (buf[start + len - 1] == ';') {
+            //this is a type sig
+            int offset = -1;
+            boolean needsSymbol = true;
+            switch (buf[start]) {
+                case ';':
+                    //value
+                    offset = 1;
+                    break;
+                case '[':
+                    //array
+                    needsSymbol = false;
+                    offset = 0;
+                    break;
+                default:
+                    Assert.error();
+            }
+            Type t = sigToType(buf, start + offset, len);
+            return needsSymbol ? t.tsym : t;
+        } else {
+            //this is a class name
+            Assert.check(buf[start] != ';' && buf[start] != '[');
+            return enterClass(names.fromUtf(internalize(buf, start, len)));
+        }
     }
 
     /** Read signature and convert to type parameters.
@@ -703,6 +720,7 @@
             sigp++;
             return syms.longType;
         case 'L':
+        case 'Q':
             {
                 // int oldsigp = sigp;
                 Type t = classSigToType();
@@ -763,7 +781,7 @@
     /** Convert class signature to type, where signature is implicit.
      */
     Type classSigToType() {
-        if (signature[sigp] != 'L')
+        if (signature[sigp] != 'L' && signature[sigp] != 'Q')
             throw badClassFile("bad.class.signature",
                                Convert.utf2string(signature, sigp, 10));
         sigp++;
@@ -1596,6 +1614,8 @@
                         target = proxy;
                     } else if (proxy.type.tsym == syms.repeatableType.tsym) {
                         repeatable = proxy;
+                    } else if (sym.kind == TYP && proxy.type.tsym == syms.valueCapableClass.tsym) {
+                        sym.flags_field |= VALUE_CAPABLE;
                     } else if (proxy.type.tsym == syms.deprecatedType.tsym) {
                         sym.flags_field |= (DEPRECATED | DEPRECATED_ANNOTATION);
                         for (Pair<Name, Attribute> v : proxy.values) {
@@ -2838,6 +2858,8 @@
             flags &= ~ACC_MODULE;
             flags |= MODULE;
         }
+        if ((flags & ACC_VALUE) != 0)
+            flags = (flags ^ ACC_VALUE) | VALUE;
         return flags & ~ACC_SUPER; // SUPER and SYNCHRONIZED bits overloaded
     }
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Tue Sep 26 16:13:34 2017 +0200
@@ -26,6 +26,7 @@
 package com.sun.tools.javac.jvm;
 
 import java.io.*;
+import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Set;
@@ -434,7 +435,13 @@
                 if (c.type.hasTag(ARRAY)) {
                     poolbuf.appendChar(pool.put(typeSig(c.type)));
                 } else {
-                    poolbuf.appendChar(pool.put(names.fromUtf(externalize(c.flatname))));
+                    Name className = names.fromUtf(externalize(c.flatname));
+                    if (types.isValue(c.type)) {
+                        className = names.fromString(";Q")
+                                .append(className)
+                                .append(names.fromString(";"));
+                    }
+                    poolbuf.appendChar(pool.put(className));
                     enterInner(c);
                 }
             } else if (value instanceof NameAndType) {
@@ -1716,6 +1723,8 @@
             flags = adjustFlags(c.flags() & ~DEFAULT);
             if ((flags & PROTECTED) != 0) flags |= PUBLIC;
             flags = flags & ClassFlags & ~STRICTFP;
+            if ((flags & VALUE) != 0) flags |= ACC_VALUE;
+            flags = flags & ~VALUE;
             if ((flags & INTERFACE) == 0) flags |= ACC_SUPER;
         }
 
@@ -1816,7 +1825,11 @@
 
         poolbuf.appendInt(JAVA_MAGIC);
 
-        if (c.owner.kind == MDL) {
+        if (types.isValue(c.type)) {
+            //fixup classfile version for value capable classes
+            poolbuf.appendChar(1);
+            poolbuf.appendChar(53);
+        } else if (c.owner.kind == MDL) {
             // temporarily overide to force use of v53 for module-info.class
             poolbuf.appendChar(0);
             poolbuf.appendChar(53);
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Code.java	Tue Sep 26 16:13:34 2017 +0200
@@ -495,6 +495,7 @@
         emitop(op);
         if (!alive) return;
         switch (op) {
+        case vaload:
         case aaload: {
             state.pop(1);// index
             Type a = state.stack[state.stacksize-1];
@@ -601,6 +602,7 @@
         case lushr:
             state.pop(1);
             break;
+        case vreturn:
         case areturn:
         case ireturn:
         case freturn:
@@ -655,6 +657,7 @@
             // state.pop(1);
             // state.push(syms.intType);
             break;
+        case vastore:
         case aastore:
             state.pop(3);
             break;
@@ -956,6 +959,7 @@
             state.push(syms.doubleType);
             break;
         case aload:
+        case vload:
             state.push(lvar[od].sym.type);
             break;
         case lstore:
@@ -965,6 +969,7 @@
         case istore:
         case fstore:
         case astore:
+        case vstore:
             state.pop(1);
             break;
         case ret:
@@ -1024,6 +1029,17 @@
             }
             state.push(uninitializedObject(sym.erasure(types), cp-3));
             break;
+        case vdefault:
+            if (pool.pool[od] instanceof UniqueType) {
+                // Required by change in Gen.makeRef to allow
+                // annotated types.
+                // TODO: is this needed anywhere else?
+                sym = ((UniqueType)(pool.pool[od])).type.tsym;
+            } else {
+                sym = (Symbol)(pool.pool[od]);
+            }
+            state.push(sym.erasure(types));
+            break;
         case sipush:
             state.push(syms.intType);
             break;
@@ -1050,6 +1066,9 @@
         case goto_:
             markDead();
             break;
+        case vwithfield:
+            state.pop(((Symbol)(pool.pool[od])).erasure(types));
+            break;
         case putfield:
             state.pop(((Symbol)(pool.pool[od])).erasure(types));
             state.pop(1); // object ref
@@ -2427,6 +2446,13 @@
             mnem[goto_w] = "goto_w";
             mnem[jsr_w] = "jsr_w";
             mnem[breakpoint] = "breakpoint";
+            mnem[vload] = "vload";
+            mnem[vstore] = "vstore";
+            mnem[vaload] = "vaload";
+            mnem[vastore] = "vastore";
+            mnem[vreturn] = "vreturn";
+            mnem[vdefault] = "vdefault";
+            mnem[vwithfield] = "vwithfield";
         }
     }
 }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java	Tue Sep 26 16:13:34 2017 +0200
@@ -25,6 +25,7 @@
 
 package com.sun.tools.javac.jvm;
 
+import com.sun.source.tree.NewClassTree.CreationMode;
 import com.sun.tools.javac.tree.TreeInfo.PosKind;
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
@@ -1603,6 +1604,7 @@
     public void visitReturn(JCReturn tree) {
         int limit = code.nextreg;
         final Env<GenContext> targetEnv;
+        final Type returnType = env.enclMethod.sym.getReturnType();
 
         /* Save and then restore the location of the return in case a finally
          * is expanded (with unwind()) in the middle of our bytecodes.
@@ -1618,7 +1620,7 @@
             targetEnv = unwind(env.enclMethod, env);
             code.pendingStatPos = tmpPos;
             r.load();
-            code.emitop0(ireturn + Code.truncate(Code.typecode(pt)));
+            code.emitop0(types.isValue(returnType) ? vreturn : ireturn + Code.truncate(Code.typecode(pt)));
         } else {
             targetEnv = unwind(env.enclMethod, env);
             code.pendingStatPos = tmpPos;
@@ -1728,15 +1730,23 @@
         Assert.check(tree.encl == null && tree.def == null);
         setTypeAnnotationPositions(tree.pos);
 
-        code.emitop2(new_, makeRef(tree.pos(), tree.type));
-        code.emitop0(dup);
+        Type newType = tree.type;
 
-        // Generate code for all arguments, where the expected types are
-        // the parameters of the constructor's external type (that is,
-        // any implicit outer instance appears as first parameter).
-        genArgs(tree.args, tree.constructor.externalType(types).getParameterTypes());
+        if (types.isValue(newType)) {
+            Assert.check(tree.creationMode == CreationMode.DEFAULT_VALUE);
+            Assert.check(tree.constructorType.getParameterTypes().isEmpty());
+            code.emitop2(vdefault, makeRef(tree.pos(), newType));
+        } else {
+            code.emitop2(new_, makeRef(tree.pos(), tree.type));
+            code.emitop0(dup);
 
-        items.makeMemberItem(tree.constructor, true).invoke();
+            // Generate code for all arguments, where the expected types are
+            // the parameters of the constructor's external type (that is,
+            // any implicit outer instance appears as first parameter).
+            genArgs(tree.args, tree.constructor.externalType(types).getParameterTypes());
+
+            items.makeMemberItem(tree.constructor, true).invoke();
+        }
         result = items.makeStackItem(tree.type);
     }
 
@@ -2033,9 +2043,14 @@
     public void visitIdent(JCIdent tree) {
         Symbol sym = tree.sym;
         if (tree.name == names._this || tree.name == names._super) {
-            Item res = tree.name == names._this
-                ? items.makeThisItem()
-                : items.makeSuperItem();
+            Item res;
+            if (tree.name == names._this) {
+                res = items.makeThisItem(env.enclClass.sym.type);
+            } else {
+                Symbol superSym = sym.kind == MTH ?
+                        tree.sym.owner : tree.type.tsym;
+                res = items.makeSuperItem(types.asSuper(env.enclClass.sym.type, superSym));
+            }
             if (sym.kind == MTH) {
                 // Generate code to address the constructor.
                 res.load();
@@ -2051,7 +2066,7 @@
                 sym = binaryQualifier(sym, env.enclClass.type);
             result = items.makeStaticItem(sym);
         } else {
-            items.makeThisItem().load();
+            items.makeThisItem(env.enclClass.sym.type).load();
             sym = binaryQualifier(sym, env.enclClass.type);
             result = items.makeMemberItem(sym, (sym.flags() & PRIVATE) != 0);
         }
@@ -2076,9 +2091,14 @@
         // resulting from a qualified super?
         boolean accessSuper = isAccessSuper(env.enclMethod);
 
-        Item base = (selectSuper)
-            ? items.makeSuperItem()
-            : genExpr(tree.selected, tree.selected.type);
+        Item base;
+        if (selectSuper) {
+            Type selType = tree.selected.type;
+            Type superType = types.asSuper(env.enclClass.type.tsym.type, selType.tsym);
+            base = items.makeSuperItem(superType == null ? selType : superType);
+        } else {
+            base = genExpr(tree.selected, tree.selected.type);
+        }
 
         if (sym.kind == VAR && ((VarSymbol) sym).getConstValue() != null) {
             // We are seeing a variable that is constant but its selecting
@@ -2111,10 +2131,17 @@
                     code.emitop0(arraylength);
                     result = items.makeStackItem(syms.intType);
                 } else {
+                    boolean requireCopyOnWrite = false;
+                    if (sym.kind == VAR && (sym.flags() & FINAL) != 0) {
+                        if ((env.enclMethod.mods.flags & STATICVALUEFACTORY) != 0) {
+                            if (sym.owner == env.enclClass.sym)
+                                requireCopyOnWrite = true;
+                        }
+                    }
                     result = items.
                         makeMemberItem(sym,
                                        (sym.flags() & PRIVATE) != 0 ||
-                                       selectSuper || accessSuper);
+                                       selectSuper || accessSuper, (requireCopyOnWrite ? base : null));
                 }
             }
         }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Items.java	Tue Sep 26 16:13:34 2017 +0200
@@ -68,8 +68,6 @@
     /** Items that exist only once (flyweight pattern).
      */
     private final Item voidItem;
-    private final Item thisItem;
-    private final Item superItem;
     private final Item[] stackItem = new Item[TypeCodeCount];
 
     public Items(Pool pool, Code code, Symtab syms, Types types) {
@@ -79,8 +77,6 @@
         voidItem = new Item(VOIDcode) {
                 public String toString() { return "void"; }
             };
-        thisItem = new SelfItem(false);
-        superItem = new SelfItem(true);
         for (int i = 0; i < VOIDcode; i++) stackItem[i] = new StackItem(i);
         stackItem[VOIDcode] = voidItem;
         this.syms = syms;
@@ -93,14 +89,14 @@
     }
     /** Make an item representing `this'.
      */
-    Item makeThisItem() {
-        return thisItem;
+    Item makeThisItem(Type thisType) {
+        return new SelfItem(thisType, false);
     }
 
     /** Make an item representing `super'.
      */
-    Item makeSuperItem() {
-        return superItem;
+    Item makeSuperItem(Type superType) {
+        return new SelfItem(superType, true);
     }
 
     /** Make an item representing a value on stack.
@@ -150,9 +146,19 @@
      *  @param member       The represented symbol.
      *  @param nonvirtual   Is the reference not virtual? (true for constructors
      *                      and private members).
+     *  @param baseToCopyOnWrite Updates to fields imply copy on write to this receiver
+     */
+    Item makeMemberItem(Symbol member, boolean nonvirtual, Item baseToCopyOnWrite) {
+        return  baseToCopyOnWrite != null ? new CopyOnWriteMemberItem(baseToCopyOnWrite, member) : new MemberItem(member, nonvirtual);
+    }
+
+    /** Make an item representing an instance variable or method.
+     *  @param member       The represented symbol.
+     *  @param nonvirtual   Is the reference not virtual? (true for constructors
+     *                      and private members).
      */
     Item makeMemberItem(Symbol member, boolean nonvirtual) {
-        return new MemberItem(member, nonvirtual);
+        return makeMemberItem(member, nonvirtual, null);
     }
 
     /** Make an item representing a literal.
@@ -315,18 +321,26 @@
     /** An item representing an indexed expression.
      */
     class IndexedItem extends Item {
+        Type type;
 
         IndexedItem(Type type) {
             super(Code.typecode(type));
+            this.type = type;
         }
 
         Item load() {
-            code.emitop0(iaload + typecode);
+            if (types.isValue(type))
+                code.emitop0(vaload);
+            else
+                code.emitop0(iaload + typecode);
             return stackItem[typecode];
         }
 
         void store() {
-            code.emitop0(iastore + typecode);
+            if (types.isValue(type))
+                code.emitop0(vastore);
+            else
+                code.emitop0(iastore + typecode);
         }
 
         void duplicate() {
@@ -357,14 +371,20 @@
         /** Flag which determines whether this item represents `this' or `super'.
          */
         boolean isSuper;
+        Type type;
 
-        SelfItem(boolean isSuper) {
+        SelfItem(Type type, boolean isSuper) {
             super(OBJECTcode);
+            this.type = type;
             this.isSuper = isSuper;
         }
 
         Item load() {
-            code.emitop0(aload_0);
+            if (types.isValue(type)) {
+                code.emitop1w(vload, 0);
+            } else {
+                code.emitop0(aload_0);
+            }
             return stackItem[typecode];
         }
 
@@ -393,18 +413,26 @@
         }
 
         Item load() {
-            if (reg <= 3)
-                code.emitop0(iload_0 + Code.truncate(typecode) * 4 + reg);
-            else
-                code.emitop1w(iload + Code.truncate(typecode), reg);
+            if (types.isValue(type)) {
+                code.emitop1w(vload, reg);
+            } else {
+                if (reg <= 3)
+                    code.emitop0(iload_0 + Code.truncate(typecode) * 4 + reg);
+                else
+                    code.emitop1w(iload + Code.truncate(typecode), reg);
+            }
             return stackItem[typecode];
         }
 
         void store() {
-            if (reg <= 3)
-                code.emitop0(istore_0 + Code.truncate(typecode) * 4 + reg);
-            else
-                code.emitop1w(istore + Code.truncate(typecode), reg);
+            if (types.isValue(type)) {
+                code.emitop1w(vstore, reg);
+            } else {
+                if (reg <= 3)
+                    code.emitop0(istore_0 + Code.truncate(typecode) * 4 + reg);
+                else
+                    code.emitop1w(istore + Code.truncate(typecode), reg);
+            }
             code.setDefined(reg);
         }
 
@@ -554,6 +582,21 @@
         }
     }
 
+    class CopyOnWriteMemberItem extends MemberItem {
+
+        Item rcvItem;
+
+        CopyOnWriteMemberItem(Item rcvItem, Symbol member) {
+            super(member, false);
+            this.rcvItem = rcvItem;
+        }
+
+        void store() {
+            code.emitop2(vwithfield, pool.put(member));
+            rcvItem.store();
+        }
+    }
+
     /** An item representing a literal.
      */
     class ImmediateItem extends Item {
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java	Tue Sep 26 16:13:34 2017 +0200
@@ -31,6 +31,7 @@
 import com.sun.source.tree.MemberReferenceTree.ReferenceMode;
 import com.sun.source.tree.ModuleTree.ModuleKind;
 
+import com.sun.source.tree.NewClassTree.CreationMode;
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.parser.Tokens.*;
 import com.sun.tools.javac.parser.Tokens.Comment.CommentStyle;
@@ -185,6 +186,7 @@
         this.keepLineMap = keepLineMap;
         this.errorTree = F.Erroneous();
         endPosTable = newEndPosTable(keepEndPositions);
+        this.allowValueClasses = fac.options.isSet("enableValueTypes");
     }
 
     protected AbstractEndPosTable newEndPosTable(boolean keepEndPositions) {
@@ -233,6 +235,11 @@
      */
     boolean allowDefaultMethods;
 
+    /** Switch: should we allow value classes ?
+     */
+    boolean allowValueClasses;
+
+
     /** Switch: should we allow static methods in interfaces?
      */
     boolean allowStaticInterfaceMethods;
@@ -421,6 +428,7 @@
                 case THIS:
                 case SUPER:
                 case NEW:
+                case VDEFAULT:
                     if (stopAtStatement)
                         return;
                     break;
@@ -1210,12 +1218,14 @@
             } else return illegal();
             break;
         case NEW:
+        case VDEFAULT:
             if (typeArgs != null) return illegal();
             if ((mode & EXPR) != 0) {
                 mode = EXPR;
+                CreationMode creationMode = getCreationMode(token);
                 nextToken();
                 if (token.kind == LT) typeArgs = typeArguments(false);
-                t = creator(pos, typeArgs);
+                t = creator(pos, creationMode, typeArgs);
                 typeArgs = null;
             } else return illegal();
             break;
@@ -1331,9 +1341,10 @@
                                 if (typeArgs != null) return illegal();
                                 mode = EXPR;
                                 int pos1 = token.pos;
+                                CreationMode creationMode = getCreationMode(token);
                                 nextToken();
                                 if (token.kind == LT) typeArgs = typeArguments(false);
-                                t = innerCreator(pos1, typeArgs, t);
+                                t = innerCreator(pos1, creationMode, typeArgs, t);
                                 typeArgs = null;
                                 break loop;
                             }
@@ -1425,6 +1436,10 @@
         return term3Rest(t, typeArgs);
     }
 
+    private CreationMode getCreationMode(Token token) {
+        return token.kind == NEW ? CreationMode.NEW : CreationMode.DEFAULT_VALUE;
+    }
+
     JCExpression term3Rest(JCExpression t, List<JCExpression> typeArgs) {
         if (typeArgs != null) illegal();
         while (true) {
@@ -1466,13 +1481,14 @@
                     nextToken();
                     t = arguments(typeArgs, t);
                     typeArgs = null;
-                } else if (token.kind == NEW && (mode & EXPR) != 0) {
+                } else if ((token.kind == NEW || token.kind == VDEFAULT) && (mode & EXPR) != 0) {
                     if (typeArgs != null) return illegal();
                     mode = EXPR;
                     int pos2 = token.pos;
+                    CreationMode creationMode = getCreationMode(token);
                     nextToken();
                     if (token.kind == LT) typeArgs = typeArguments(false);
-                    t = innerCreator(pos2, typeArgs, t);
+                    t = innerCreator(pos2, creationMode, typeArgs, t);
                     typeArgs = null;
                 } else {
                     List<JCAnnotation> tyannos = null;
@@ -1626,7 +1642,7 @@
                         case INTLITERAL: case LONGLITERAL: case FLOATLITERAL:
                         case DOUBLELITERAL: case CHARLITERAL: case STRINGLITERAL:
                         case TRUE: case FALSE: case NULL:
-                        case NEW: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
+                        case NEW: case VDEFAULT: case IDENTIFIER: case ASSERT: case ENUM: case UNDERSCORE:
                         case BYTE: case SHORT: case CHAR: case INT:
                         case LONG: case FLOAT: case DOUBLE: case BOOLEAN: case VOID:
                             return ParensResult.CAST;
@@ -2054,8 +2070,8 @@
         }
         Name refName;
         ReferenceMode refMode;
-        if (token.kind == NEW) {
-            refMode = ReferenceMode.NEW;
+        if (token.kind == NEW || token.kind == VDEFAULT) {
+            refMode = ReferenceMode.NEW; // TODO(Srikanth): What is the right thing to do here ?
             refName = names.init;
             nextToken();
         } else {
@@ -2067,7 +2083,7 @@
 
     /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
      */
-    JCExpression creator(int newpos, List<JCExpression> typeArgs) {
+    JCExpression creator(int newpos, CreationMode creationMode, List<JCExpression> typeArgs) {
         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
 
         switch (token.kind) {
@@ -2141,7 +2157,7 @@
             }
             return e;
         } else if (token.kind == LPAREN) {
-            JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
+            JCNewClass newClass = classCreatorRest(newpos, creationMode, null, typeArgs, t);
             if (newClass.def != null) {
                 assert newClass.def.mods.annotations.isEmpty();
                 if (newAnnotations.nonEmpty()) {
@@ -2170,7 +2186,7 @@
 
     /** InnerCreator = [Annotations] Ident [TypeArguments] ClassCreatorRest
      */
-    JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) {
+    JCExpression innerCreator(int newpos, CreationMode creationMode, List<JCExpression> typeArgs, JCExpression encl) {
         List<JCAnnotation> newAnnotations = typeAnnotationsOpt();
 
         JCExpression t = toP(F.at(token.pos).Ident(ident()));
@@ -2184,7 +2200,7 @@
             t = typeArguments(t, true);
             mode = oldmode;
         }
-        return classCreatorRest(newpos, encl, typeArgs, t);
+        return classCreatorRest(newpos, creationMode, encl, typeArgs, t);
     }
 
     /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
@@ -2264,6 +2280,7 @@
     /** ClassCreatorRest = Arguments [ClassBody]
      */
     JCNewClass classCreatorRest(int newpos,
+                                CreationMode creationMode,
                                   JCExpression encl,
                                   List<JCExpression> typeArgs,
                                   JCExpression t)
@@ -2276,7 +2293,9 @@
             JCModifiers mods = F.at(Position.NOPOS).Modifiers(0);
             body = toP(F.at(pos).AnonymousClassDef(mods, defs));
         }
-        return toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
+        JCNewClass newClass = toP(F.at(newpos).NewClass(encl, typeArgs, t, args, body));
+        newClass.creationMode = creationMode;
+        return newClass;
     }
 
     /** ArrayInitializer = "{" [VariableInitializer {"," VariableInitializer}] [","] "}"
@@ -2417,6 +2436,7 @@
         case ASSERT:
             return List.of(parseSimpleStatement());
         case MONKEYS_AT:
+        case VALUE:
         case FINAL: {
             Comment dc = token.comment(CommentStyle.JAVADOC);
             JCModifiers mods = modifiersOpt();
@@ -2854,6 +2874,8 @@
             case STRICTFP    : flag = Flags.STRICTFP; break;
             case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
             case DEFAULT     : checkDefaultMethods(); flag = Flags.DEFAULT; break;
+            case VALUE       : checkValueClasses(); flag = Flags.VALUE; break;
+            case STATICVALUEFACTORY: flag = Flags.STATICVALUEFACTORY; break;
             case ERROR       : flag = 0; nextToken(); break;
             default: break loop;
             }
@@ -4193,6 +4215,13 @@
             log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.DefaultMethodsNotSupportedInSource(source.name));
         }
     }
+
+    void checkValueClasses() {
+        if (!allowValueClasses) {
+            log.error(token.pos, "value.types.disabled");
+        }
+    }
+
     void checkIntersectionTypesInCast() {
         if (!allowIntersectionTypesInCast) {
             log.error(DiagnosticFlag.SOURCE_LEVEL, token.pos, Errors.IntersectionTypesInCastNotSupportedInSource(source.name));
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/Tokens.java	Tue Sep 26 16:13:34 2017 +0200
@@ -163,6 +163,9 @@
         THROWS("throws"),
         TRANSIENT("transient"),
         TRY("try"),
+        VALUE("__ByValue"),
+        STATICVALUEFACTORY("__ValueFactory"),
+        VDEFAULT("__MakeDefault"),
         VOID("void", Tag.NAMED),
         VOLATILE("volatile"),
         WHILE("while"),
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties	Tue Sep 26 16:13:34 2017 +0200
@@ -353,6 +353,10 @@
     cyclic inheritance involving {0}
 
 # 0: symbol
+compiler.err.cyclic.value.type.membership=\
+    cyclic value type membership involving {0}
+
+# 0: symbol
 compiler.err.cyclic.annotation.element=\
     type of element {0} is cyclic
 
@@ -3131,3 +3135,68 @@
 # 0: string, 1: string
 compiler.err.illegal.argument.for.option=\
     illegal argument for {0}: {1}
+
+compiler.err.garbled.value.reference.instantiation=\
+    Mismatched instantiation syntax between value and reference types.
+
+# 0: name (of method)
+compiler.err.value.does.not.support=\
+    value types do not support {0}
+
+compiler.err.value.must.be.final=\
+    value type must be declared final
+
+compiler.err.value.field.must.be.final=\
+    value-type field must be declared final
+
+compiler.err.value.factory.must.be.static=\
+    Value factory must be a static method
+
+compiler.err.invalid.arguments.to.make.default=\
+    Superfluous arguments to default value creation
+
+compiler.err.make.default.in.nonfactory=\
+    Illegal attempt to create a default value outside of value factory
+
+compiler.err.make.default.with.nonvalue=\
+    Default value creation requires a value type
+
+# 0: symbol
+compiler.err.make.default.with.wrong.value.type=\
+    This value factory cannot create values of type {0}
+
+compiler.err.value.may.not.extend=\
+    value type may not extend another value or class
+
+compiler.err.value.types.disabled=\
+    value classes allowed only with -XDenableValueTypes option to the compiler
+
+# 0: name (of method)
+compiler.warn.value.does.not.support=\
+    value types do not support {0}
+
+compiler.warn.value.must.be.final=\
+    value type must be declared final
+
+compiler.warn.value.field.must.be.final=\
+    value-type field must be declared final
+
+compiler.warn.value.may.not.extend=\
+    value type may not extend another value or class
+
+compiler.warn.mod.not.allowed.here=\
+    modifier {0} not allowed here
+
+# 0: message segment or type, 1: message segment
+compiler.warn.type.found.req=\
+    unexpected type\n\
+    required: {1}\n\
+    found:    {0}
+
+# 0: type, 1: type
+compiler.warn.incomparable.types=\
+    incomparable types: {0} and {1}
+
+# 0: symbol
+compiler.warn.cyclic.value.type.membership=\
+    cyclic value type membership involving {0}
\ No newline at end of file
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/javac.properties	Tue Sep 26 16:13:34 2017 +0200
@@ -249,6 +249,9 @@
 javac.opt.Xlint.desc.unchecked=\
     Warn about unchecked operations.
 
+javac.opt.Xlint.desc.values=\
+    Warn about value types related issues.
+
 javac.opt.Xlint.desc.varargs=\
     Warn about potentially unsafe vararg methods
 
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/JCTree.java	Tue Sep 26 16:13:34 2017 +0200
@@ -1663,6 +1663,7 @@
         public JCExpression clazz;
         public List<JCExpression> args;
         public JCClassDecl def;
+        public CreationMode creationMode;    // <- temporary
         public Symbol constructor;
         public Type varargsElement;
         public Type constructorType;
@@ -1678,6 +1679,7 @@
             this.clazz = clazz;
             this.args = args;
             this.def = def;
+            this.creationMode = CreationMode.NEW;    // <- temporary
         }
         @Override
         public void accept(Visitor v) { v.visitNewClass(this); }
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/util/Names.java	Tue Sep 26 16:13:34 2017 +0200
@@ -98,6 +98,7 @@
     public final Name getMessage;
     public final Name hasNext;
     public final Name hashCode;
+    public final Name identityHashCode;
     public final Name init;
     public final Name initCause;
     public final Name iterator;
@@ -119,6 +120,8 @@
     public final Name java_lang_Enum;
     public final Name java_lang_Object;
     public final Name java_lang_invoke_MethodHandle;
+    public final Name java_lang_System;
+    public final Name java_lang_Value;
 
     // names of builtin classes
     public final Name Array;
@@ -259,6 +262,7 @@
         getMessage = fromString("getMessage");
         hasNext = fromString("hasNext");
         hashCode = fromString("hashCode");
+        identityHashCode = fromString("identityHashCode");
         init = fromString("<init>");
         initCause = fromString("initCause");
         iterator = fromString("iterator");
@@ -281,6 +285,9 @@
         java_lang_Enum = fromString("java.lang.Enum");
         java_lang_Object = fromString("java.lang.Object");
         java_lang_invoke_MethodHandle = fromString("java.lang.invoke.MethodHandle");
+        java_lang_System = fromString("java.lang.System");
+        java_lang_Value = fromString("java.lang.__Value");
+
 
         // names of builtin classes
         Array = fromString("Array");
--- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java	Tue Sep 26 16:13:34 2017 +0200
@@ -2894,7 +2894,7 @@
     }
 
     public boolean isValue(DocTree doctree) {
-        return isKind(doctree, VALUE);
+        return isKind(doctree, Kind.VALUE);
     }
 
     public boolean isVersion(DocTree doctree) {
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/AccessFlags.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/AccessFlags.java	Tue Sep 26 16:13:34 2017 +0200
@@ -49,6 +49,7 @@
     public static final int ACC_BRIDGE        = 0x0040; //                      method
     public static final int ACC_TRANSIENT     = 0x0080; //               field
     public static final int ACC_VARARGS       = 0x0080; //                      method
+    public static final int ACC_VALUE         = 0x0100; // class
     public static final int ACC_NATIVE        = 0x0100; //                      method
     public static final int ACC_INTERFACE     = 0x0200; // class, inner
     public static final int ACC_ABSTRACT      = 0x0400; // class, inner,        method
@@ -82,12 +83,12 @@
     }
 
     private static final int[] classModifiers = {
-        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT
+        ACC_PUBLIC, ACC_FINAL, ACC_ABSTRACT, ACC_VALUE
     };
 
     private static final int[] classFlags = {
         ACC_PUBLIC, ACC_FINAL, ACC_SUPER, ACC_INTERFACE, ACC_ABSTRACT,
-        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE
+        ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_MODULE, ACC_VALUE
     };
 
     public Set<String> getClassModifiers() {
@@ -101,12 +102,12 @@
 
     private static final int[] innerClassModifiers = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL,
-        ACC_ABSTRACT
+        ACC_ABSTRACT, ACC_VALUE
     };
 
     private static final int[] innerClassFlags = {
         ACC_PUBLIC, ACC_PRIVATE, ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_SUPER,
-        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM
+        ACC_INTERFACE, ACC_ABSTRACT, ACC_SYNTHETIC, ACC_ANNOTATION, ACC_ENUM, ACC_VALUE
     };
 
     public Set<String> getInnerClassModifiers() {
@@ -203,8 +204,8 @@
                 return (t == Kind.Field ? "transient" : null);
             case ACC_VOLATILE:
                 return "volatile";
-            case ACC_NATIVE:
-                return "native";
+            case 0x100:
+                return (t == Kind.Class ? "value" : "native");
             case ACC_ABSTRACT:
                 return "abstract";
             case ACC_STRICT:
@@ -234,8 +235,8 @@
             return (t == Kind.Field ? "ACC_VOLATILE" : "ACC_BRIDGE");
         case 0x80:
             return (t == Kind.Field ? "ACC_TRANSIENT" : "ACC_VARARGS");
-        case ACC_NATIVE:
-            return "ACC_NATIVE";
+        case 0x100:
+            return (t == Kind.Class ? "ACC_VALUE" : "ACC_NATIVE");
         case ACC_INTERFACE:
             return "ACC_INTERFACE";
         case ACC_ABSTRACT:
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Descriptor.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Descriptor.java	Tue Sep 26 16:13:34 2017 +0200
@@ -158,6 +158,7 @@
                     break;
 
                 case 'L':
+                case 'Q':
                     int sep = desc.indexOf(';', p);
                     if (sep == -1)
                         throw new InvalidDescriptor(desc, p - 1);
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Opcode.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Opcode.java	Tue Sep 26 16:13:34 2017 +0200
@@ -242,6 +242,19 @@
     IFNONNULL(0xc7, BRANCH),
     GOTO_W(0xc8, BRANCH_W),
     JSR_W(0xc9, BRANCH_W),
+
+    VLOAD(203, LOCAL),
+    VSTORE(204, LOCAL),
+    VALOAD(205),
+    VASTORE(206),
+    VRETURN(207),
+
+    VDEFAULT(208, CPREF_W),
+    VWITHFIELD(209, CPREF_W),
+
+    VBOX(210, CPREF_W),
+    VUNBOX(211, CPREF_W),
+
     // impdep 0xfe: PicoJava nonpriv
     // impdep 0xff: Picojava priv
 
--- a/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Signature.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.jdeps/share/classes/com/sun/tools/classfile/Signature.java	Tue Sep 26 16:13:34 2017 +0200
@@ -143,6 +143,7 @@
                 return new SimpleType("long");
 
             case 'L':
+            case 'Q':
                 return parseClassTypeSignature();
 
             case 'S':
@@ -191,7 +192,7 @@
     }
 
     private Type parseClassTypeSignature() {
-        assert sig.charAt(sigp) == 'L';
+        assert sig.charAt(sigp) == 'L' || sig.charAt(sigp) == 'Q';
         sigp++;
         return parseClassTypeSignatureRest();
     }
--- a/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/src/jdk.jshell/share/classes/jdk/jshell/CompletenessAnalyzer.java	Tue Sep 26 16:13:34 2017 +0200
@@ -191,6 +191,9 @@
         ERROR(TokenKind.ERROR, XERRO),  //
         IDENTIFIER(TokenKind.IDENTIFIER, XEXPR1|XDECL1|XTERM),  //
         UNDERSCORE(TokenKind.UNDERSCORE, XERRO),  //  _
+        VALUE(TokenKind.VALUE, XEXPR1|XDECL1|XTERM),  //  "__ByValue"
+        VALUEFACTORY(TokenKind.STATICVALUEFACTORY, XDECL1),  //  "__ValueFactory" (a la public)
+        VDEFAULT(TokenKind.VDEFAULT, XEXPR1|XDECL1|XTERM),  //  "__MakeDefault" a la __Make
         CLASS(TokenKind.CLASS, XEXPR|XDECL1|XBRACESNEEDED),  //  class decl (MAPPED: DOTCLASS)
         MONKEYS_AT(TokenKind.MONKEYS_AT, XEXPR|XDECL1),  //  @
         IMPORT(TokenKind.IMPORT, XDECL1|XSTART),  //  import -- consider declaration
--- a/test/langtools/tools/javac/diags/CheckResourceKeys.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/test/langtools/tools/javac/diags/CheckResourceKeys.java	Tue Sep 26 16:13:34 2017 +0200
@@ -307,7 +307,10 @@
             "java.",
             "javac.",
             "verbose.",
-            "locn."
+            "locn.",
+            // annotation for minimal value types.
+            "jvm.internal.value.ValueCapableClass",
+            "java.lang.__Value"
     ));
 
     /**
--- a/test/langtools/tools/javac/diags/examples.not-yet.txt	Tue Sep 26 16:13:10 2017 +0200
+++ b/test/langtools/tools/javac/diags/examples.not-yet.txt	Tue Sep 26 16:13:34 2017 +0200
@@ -152,3 +152,22 @@
 compiler.err.locn.module-info.not.allowed.on.patch.path
 compiler.misc.cant.resolve.modules
 compiler.misc.file.does.not.contain.module
+compiler.err.cyclic.value.type.membership
+compiler.err.garbled.value.reference.instantiation
+compiler.err.value.does.not.support
+compiler.err.value.factory.must.be.static
+compiler.err.value.field.must.be.final
+compiler.err.value.must.be.final
+compiler.err.invalid.arguments.to.make.default
+compiler.err.make.default.in.nonfactory
+compiler.err.make.default.with.nonvalue
+compiler.err.make.default.with.wrong.value.type
+compiler.err.value.may.not.extend
+compiler.warn.cyclic.value.type.membership
+compiler.warn.incomparable.types
+compiler.warn.mod.not.allowed.here
+compiler.warn.type.found.req
+compiler.warn.value.does.not.support
+compiler.warn.value.field.must.be.final
+compiler.warn.value.may.not.extend
+compiler.warn.value.must.be.final
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/diags/examples/ValueTypesDisabled.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2017, 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.err.value.types.disabled
+
+__ByValue final class ValueTypesDisabled {
+}
--- a/test/langtools/tools/javac/processing/model/TestSymtabItems.java	Tue Sep 26 16:13:10 2017 +0200
+++ b/test/langtools/tools/javac/processing/model/TestSymtabItems.java	Tue Sep 26 16:13:34 2017 +0200
@@ -47,6 +47,8 @@
 import javax.lang.model.util.*;
 
 import com.sun.tools.javac.code.Symbol.ClassSymbol;
+import com.sun.tools.javac.code.Symbol.Completer;
+import com.sun.tools.javac.code.Symbol.ModuleSymbol;
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.file.JavacFileManager;
 import com.sun.tools.javac.main.JavaCompiler;
@@ -127,7 +129,12 @@
         public Void visitModule(ModuleElement e, Void p) {
             show("module", e);
             indent(+1);
-            super.visitModule(e, p);
+            if (e.getQualifiedName().contentEquals("jdk.incubator.mvt")) {
+                //completion of a module with 'requires' directive will fail at this stage.
+                ((ModuleSymbol) e).completer = Completer.NULL_COMPLETER;
+            } else {
+                super.visitModule(e, p);
+            }
             indent(-1);
             return null;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckClone.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support clone
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckClone.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values CheckClone.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckClone {
+    @jdk.incubator.mvt.ValueCapableClass
+    final class InnerValue {
+        void foo(InnerValue iv) {
+            iv.clone(); // <-- error
+        }
+    }
+    @Override
+    protected Object clone() { return null; } // <-- error
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckClone.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,6 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckClone.java:12:21: compiler.warn.value.does.not.support: calling java.lang.Object's method: clone
+CheckClone.java:16:22: compiler.warn.value.does.not.support: overriding java.lang.Object's method: clone
+1 error
+3 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckCyclicMembership.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types may not declare fields of its own type either directly or indirectly.
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckCyclicMembership.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values CheckCyclicMembership.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckCyclicMembership {
+    class InnerRef {
+        CheckCyclicMembership ccm;
+    }
+    @jdk.incubator.mvt.ValueCapableClass final class InnerValue {
+        final CheckCyclicMembership ccm = new CheckCyclicMembership(); // Error.
+    }
+    final CheckCyclicMembership ccm = new CheckCyclicMembership(); // Error.
+    final int i = 10;
+    final String s = "blah";
+    final InnerRef ir = new InnerRef(); // OK.
+    final InnerValue iv = new InnerValue(); // Error.
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckCyclicMembership.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,7 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckCyclicMembership.java:15:33: compiler.warn.cyclic.value.type.membership: CheckCyclicMembership
+CheckCyclicMembership.java:13:37: compiler.warn.cyclic.value.type.membership: CheckCyclicMembership.InnerValue
+CheckCyclicMembership.java:13:37: compiler.warn.cyclic.value.type.membership: CheckCyclicMembership
+1 error
+4 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckEquals.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support == or !=
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckEquals.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror  -Xlint:values CheckEquals.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckEquals {
+    boolean foo(CheckEquals a, CheckEquals b) {
+        return (a == b) || (a != b);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckEquals.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,6 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckEquals.java:10:19: compiler.warn.value.does.not.support: ==
+CheckEquals.java:10:31: compiler.warn.value.does.not.support: !=
+1 error
+3 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckExtends.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,9 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Values may not extend
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckExtends.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror  -Xlint:values CheckExtends.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckExtends extends Object {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckExtends.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,5 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckExtends.java:8:7: compiler.warn.value.may.not.extend
+1 error
+2 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckFinal.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types and their instance fields must be final
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckFinal.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values CheckFinal.java
+ */
+
+@jdk.incubator.mvt.ValueCapableClass
+class CheckFinal {  // <- error
+    int x;          // <- error
+    void f(int x) { // <- ok
+        int y;      // <- ok
+        @jdk.incubator.mvt.ValueCapableClass
+        final class CheckLocalFinal {
+            int x; // <- error.
+        }
+    }
+    final Object o = new Object() { int i; }; // <- ok
+    static int xs; // OK.
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckFinal.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,7 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckFinal.java:9:1: compiler.warn.value.must.be.final
+CheckFinal.java:10:9: compiler.warn.value.field.must.be.final
+CheckFinal.java:15:17: compiler.warn.value.field.must.be.final
+1 error
+4 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckFinalize.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support finalize
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckFinalize.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values  CheckFinalize.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckFinalize {
+    @Override
+    protected void finalize() {} // <-- error
+
+    @jdk.incubator.mvt.ValueCapableClass
+    final class CheckFinalizeInner {}
+
+    void foo(CheckFinalizeInner cfi, CheckFinalize cf) {
+        cfi.finalize();          // Error
+        cf.finalize();           // OK.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckFinalize.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,9 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckFinalize.java:16:12: compiler.err.report.access: finalize(), protected, java.lang.Object
+CheckFinalize.java:10:20: compiler.warn.value.does.not.support: overriding java.lang.Object's method: finalize
+CheckFinalize.java:16:21: compiler.warn.value.does.not.support: calling java.lang.Object's method: finalize
+- compiler.note.deprecated.filename: CheckFinalize.java
+- compiler.note.deprecated.recompile
+2 errors
+3 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support identityHashCode
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckIdentityHash.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values  CheckIdentityHash.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckIdentityHash {
+    int identityHashCode(CheckIdentityHash x) {
+        return 0;
+    }
+    void test(CheckIdentityHash v) {
+        this.identityHashCode(v);      // <- ok
+        System.identityHashCode(v);    // <- error
+        System.identityHashCode(this); // <- error
+        java.lang.System.identityHashCode(v);    // <- error
+        java.lang.System.identityHashCode(this); // <- error
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,8 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckIdentityHash.java:14:32: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash.java:15:32: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash.java:16:42: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash.java:17:42: compiler.warn.value.does.not.support: identityHashCode
+1 error
+5 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash01.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support identityHashCode
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckIdentityHash01.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values  CheckIdentityHash01.java
+ */
+
+import static java.lang.System.*;
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckIdentityHash01 {
+    void test(CheckIdentityHash01 v) {
+
+        identityHashCode(v);      // <- error
+        identityHashCode(this);   // <- error
+
+        System system = null;
+        system.identityHashCode(v);      // <- error
+        system.identityHashCode(this);   // <- error
+
+        System.identityHashCode(v);      // <- error
+        System.identityHashCode(this);   // <- error
+
+        java.lang.System.identityHashCode(v);    // <- error
+        java.lang.System.identityHashCode(this); // <- error
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckIdentityHash01.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,12 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckIdentityHash01.java:13:25: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:14:25: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:17:32: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:18:32: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:20:32: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:21:32: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:23:42: compiler.warn.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:24:42: compiler.warn.value.does.not.support: identityHashCode
+1 error
+9 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckNullAssign.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,17 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Assignment of null to value types should be disallowed.
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckNullAssign.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values CheckNullAssign.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckNullAssign {
+    CheckNullAssign foo(CheckNullAssign cna) {
+        // All of the below involve subtype/assignability checks and should be rejected.
+        CheckNullAssign cnal = null;
+        cna = null;
+        foo(null);
+        if (null instanceof CheckNullAssign) {}
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckNullAssign.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,9 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckNullAssign.java:11:32: compiler.warn.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+CheckNullAssign.java:12:15: compiler.warn.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+CheckNullAssign.java:13:13: compiler.warn.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+CheckNullAssign.java:14:13: compiler.warn.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+CheckNullAssign.java:15:16: compiler.warn.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+1 error
+6 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckNullCastable.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary null cannot be casted to and compared with value types.
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckNullCastable.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror  -Xlint:values  CheckNullCastable.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckNullCastable {
+    void foo(CheckNullCastable cnc) {
+        CheckNullCastable cncl = (CheckNullCastable) null;
+        if (cnc != null) {};
+        if (null != cnc) {};
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckNullCastable.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,9 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckNullCastable.java:10:54: compiler.warn.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullCastable)
+CheckNullCastable.java:11:17: compiler.warn.incomparable.types: CheckNullCastable, compiler.misc.type.null
+CheckNullCastable.java:11:17: compiler.warn.value.does.not.support: !=
+CheckNullCastable.java:12:18: compiler.warn.incomparable.types: compiler.misc.type.null, CheckNullCastable
+CheckNullCastable.java:12:18: compiler.warn.value.does.not.support: !=
+1 error
+6 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckSync.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary May not synchronize on value types
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckSync.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values  CheckSync.java
+ */
+
+/* Note: ATM, value types do not have jlO in their lineage. So they anyway
+   cannot synchronize using the methods declared on jlO.
+*/
+@jdk.incubator.mvt.ValueCapableClass
+public final class CheckSync {
+    @jdk.incubator.mvt.ValueCapableClass
+    final class Val {
+
+        void foo() {
+            // All calls below are bad.
+            wait();
+            wait(10);
+            wait(10, 10);
+            notify();
+            notifyAll();
+            finalize();
+            clone();
+        }
+    }
+
+    final Val val = new Val();
+
+    void test() throws InterruptedException {
+        // All calls below are bad.
+        val.wait();
+        val.wait(10);
+        val.wait(new Integer(10));
+        val.wait(new Long(10));
+        val.wait(10L);
+        val.wait(10L, 10);
+        val.wait("Hello");
+        val.notify();
+        val.notifyAll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckSync.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,22 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckSync.java:38:12: compiler.err.cant.apply.symbols: kindname.method, wait, java.lang.String,{(compiler.misc.inapplicable.method: kindname.method, java.lang.Object, wait(long), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.String, long))),(compiler.misc.inapplicable.method: kindname.method, java.lang.Object, wait(long,int), (compiler.misc.arg.length.mismatch)),(compiler.misc.inapplicable.method: kindname.method, java.lang.Object, wait(), (compiler.misc.arg.length.mismatch))}
+CheckSync.java:18:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:19:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:20:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:21:19: compiler.warn.value.does.not.support: calling java.lang.Object's method: notify
+CheckSync.java:22:22: compiler.warn.value.does.not.support: calling java.lang.Object's method: notifyAll
+CheckSync.java:23:21: compiler.warn.value.does.not.support: calling java.lang.Object's method: finalize
+CheckSync.java:24:18: compiler.warn.value.does.not.support: calling java.lang.Object's method: clone
+CheckSync.java:32:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:33:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:34:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:35:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:36:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:37:17: compiler.warn.value.does.not.support: calling java.lang.Object's method: wait
+CheckSync.java:39:19: compiler.warn.value.does.not.support: calling java.lang.Object's method: notify
+CheckSync.java:40:22: compiler.warn.value.does.not.support: calling java.lang.Object's method: notifyAll
+- compiler.note.deprecated.filename: CheckSync.java
+- compiler.note.deprecated.recompile
+2 errors
+16 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckSynchronized.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Check behavior of synzhronized key word on value instances and methods.
+ * @modules jdk.incubator.mvt
+ * @compile/fail/ref=CheckSynchronized.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values  CheckSynchronized.java
+ */
+@jdk.incubator.mvt.ValueCapableClass
+final class CheckSynchronized {
+    synchronized void foo() { // <<-- ERROR, no monitor associated with `this'
+    }
+    void goo() {
+        synchronized(this) {} // <<-- ERROR, no monitor associated with `this'
+    }
+    synchronized static void zoo(CheckSynchronized cs) { // OK, static method.
+        synchronized(cs) {    // <<-- ERROR, no monitor associated with value instance.
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/CheckSynchronized.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,7 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+CheckSynchronized.java:9:23: compiler.warn.mod.not.allowed.here: synchronized
+CheckSynchronized.java:12:9: compiler.warn.type.found.req: CheckSynchronized, (compiler.misc.type.req.ref)
+CheckSynchronized.java:15:9: compiler.warn.type.found.req: CheckSynchronized, (compiler.misc.type.req.ref)
+1 error
+4 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/ClassFileReaderTest.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,11 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Verify that the class reader flags Value capable classes appropriately.
+ * @modules jdk.incubator.mvt
+ * @compile Point.java
+ * @compile/fail/ref=ClassFileReaderTest.out --should-stop:ifError=PARSE -XDrawDiagnostics -Werror -Xlint:values  ClassFileReaderTest.java
+ */
+
+public class ClassFileReaderTest {
+    Point point = null;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/ClassFileReaderTest.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,5 @@
+- compiler.warn.incubating.modules: jdk.incubator.mvt
+- compiler.err.warnings.and.werror
+ClassFileReaderTest.java:10:19: compiler.warn.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, Point)
+1 error
+2 warnings
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/minimalvalues/Point.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2016, 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.
+ */
+
+@jdk.incubator.mvt.ValueCapableClass
+final class Point {
+    final int x = 0;
+    final int y = 0;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckClone.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support clone
+ *
+ * @compile/fail/ref=CheckClone.out -XDenableValueTypes -XDrawDiagnostics CheckClone.java
+ */
+
+final __ByValue class CheckClone {
+    final __ByValue class InnerValue {
+        void foo(InnerValue iv) {
+            iv.clone();
+        }
+    }
+    @Override
+    protected Object clone() { return null; } // <-- error
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckClone.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,3 @@
+CheckClone.java:11:15: compiler.err.value.does.not.support: clone
+CheckClone.java:14:5: compiler.err.method.does.not.override.superclass
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckCyclicMembership.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,20 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types may not declare fields of its own type either directly or indirectly.
+ *
+ * @compile/fail/ref=CheckCyclicMembership.out -XDenableValueTypes -XDrawDiagnostics CheckCyclicMembership.java
+ */
+
+final __ByValue class CheckCyclicMembership {
+    class InnerRef {
+        CheckCyclicMembership ccm;
+    }
+    __ByValue final class InnerValue {
+        final CheckCyclicMembership ccm = __MakeDefault CheckCyclicMembership(); // Error.
+    }
+    final CheckCyclicMembership ccm = __MakeDefault CheckCyclicMembership(); // Error.
+    final int i = 10;
+    final String s = "blah";
+    final InnerRef ir = new InnerRef(); // OK.
+    final InnerValue iv = __MakeDefault InnerValue(); // Error. Some Order dependancy hides this. FIXME.
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckCyclicMembership.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,3 @@
+CheckCyclicMembership.java:15:33: compiler.err.cyclic.value.type.membership: CheckCyclicMembership
+CheckCyclicMembership.java:13:37: compiler.err.cyclic.value.type.membership: CheckCyclicMembership.InnerValue
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckEquals.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support == or !=
+ *
+ * @compile/fail/ref=CheckEquals.out -XDenableValueTypes -XDrawDiagnostics CheckEquals.java
+ */
+
+final __ByValue class CheckEquals {
+    boolean foo(CheckEquals a, CheckEquals b) {
+        return (a == b) || (a != b);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckEquals.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,3 @@
+CheckEquals.java:10:19: compiler.err.value.does.not.support: ==
+CheckEquals.java:10:31: compiler.err.value.does.not.support: !=
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckExtends.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,9 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Values may not extend
+ *
+ * @compile/fail/ref=CheckExtends.out -XDenableValueTypes -XDrawDiagnostics CheckExtends.java
+ */
+
+final __ByValue class CheckExtends extends Object {
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckExtends.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,2 @@
+CheckExtends.java:8:17: compiler.err.value.may.not.extend
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckFinal.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types and their instance fields must be final
+ *
+ * @compile/fail/ref=CheckFinal.out -XDenableValueTypes -XDrawDiagnostics CheckFinal.java
+ */
+
+__ByValue class CheckFinal {  // <- error
+    int x;          // <- error
+    void f(int x) { // <- ok
+        int y;      // <- ok
+        __ByValue final class CheckLocalFinal {
+            int x; // <- error.
+        }
+    }
+    final Object o = new Object() { int i; }; // <- ok
+    static int xs; // OK.
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckFinal.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,4 @@
+CheckFinal.java:8:11: compiler.err.value.must.be.final
+CheckFinal.java:9:9: compiler.err.value.field.must.be.final
+CheckFinal.java:13:17: compiler.err.value.field.must.be.final
+3 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckFinalize.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support finalize
+ *
+ * @compile/fail/ref=CheckFinalize.out -XDenableValueTypes -XDrawDiagnostics CheckFinalize.java
+ */
+
+final __ByValue class CheckFinalize {
+    @Override
+    protected void finalize() {} // <-- error
+
+    final __ByValue class CheckFinalizeInner {}
+
+    void foo(CheckFinalizeInner cfi, CheckFinalize cf) {
+        cfi.finalize();          // Error
+        cf.finalize();           // OK.
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckFinalize.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,3 @@
+CheckFinalize.java:9:5: compiler.err.method.does.not.override.superclass
+CheckFinalize.java:15:12: compiler.err.value.does.not.support: finalize
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckFlags.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/*
+ * @test
+ * @summary Check value flag in class file
+ * @modules jdk.jdeps/com.sun.tools.classfile
+ * @compile -XDenableValueTypes Point.java
+ * @compile -XDenableValueTypes CheckFlags.java
+ * @run main CheckFlags
+ */
+
+import com.sun.tools.classfile.*;
+
+public class CheckFlags {
+    public static void main(String[] args) throws Exception {
+        ClassFile cls = ClassFile.read(CheckFlags.class.getResourceAsStream("Point.class"));
+
+        if (!cls.access_flags.is(AccessFlags.ACC_VALUE))
+            throw new Exception("Value flag not set");
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckIdentityHash.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,19 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support identityHashCode
+ *
+ * @compile/fail/ref=CheckIdentityHash.out -XDenableValueTypes -XDrawDiagnostics CheckIdentityHash.java
+ */
+
+final __ByValue class CheckIdentityHash {
+    int identityHashCode(CheckIdentityHash x) {
+        return 0;
+    }
+    void test(CheckIdentityHash v) {
+        this.identityHashCode(v);      // <- ok
+        System.identityHashCode(v);    // <- error
+        System.identityHashCode(this); // <- error
+        java.lang.System.identityHashCode(v);    // <- error
+        java.lang.System.identityHashCode(this); // <- error
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckIdentityHash.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,5 @@
+CheckIdentityHash.java:14:32: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash.java:15:32: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash.java:16:42: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash.java:17:42: compiler.err.value.does.not.support: identityHashCode
+4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckIdentityHash01.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,26 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Value types do not support identityHashCode
+ *
+ * @compile/fail/ref=CheckIdentityHash01.out -XDenableValueTypes -XDrawDiagnostics CheckIdentityHash01.java
+ */
+
+import static java.lang.System.*;
+
+final __ByValue class CheckIdentityHash01 {
+    void test(CheckIdentityHash01 v) {
+
+        identityHashCode(v);      // <- error
+        identityHashCode(this);   // <- error
+
+        System system = null;
+        system.identityHashCode(v);      // <- error
+        system.identityHashCode(this);   // <- error
+
+        System.identityHashCode(v);      // <- error
+        System.identityHashCode(this);   // <- error
+
+        java.lang.System.identityHashCode(v);    // <- error
+        java.lang.System.identityHashCode(this); // <- error
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckIdentityHash01.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,9 @@
+CheckIdentityHash01.java:13:25: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:14:25: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:17:32: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:18:32: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:20:32: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:21:32: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:23:42: compiler.err.value.does.not.support: identityHashCode
+CheckIdentityHash01.java:24:42: compiler.err.value.does.not.support: identityHashCode
+8 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckMakeDefault.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Check various semantic constraints on value creation via __MakeDefault
+ *
+ * @compile/fail/ref=CheckMakeDefault.out -XDenableValueTypes -XDrawDiagnostics CheckMakeDefault.java
+ */
+__ByValue final class Point {
+
+    static final class Sinner {
+        __ValueFactory static Sinner make() {
+            return __MakeDefault Sinner(); // NO: Sinner is not a value class.
+        }
+    }
+
+    __ByValue static final class SinnerValue {
+        __ValueFactory static SinnerValue make() {
+            return __MakeDefault SinnerValue(); // OK.
+        }
+    }
+
+    final int x;
+    final int y;
+
+    Point() {}
+    Point (int x, int y) {}
+
+    Point badFactory(int x, int y) {
+        return __MakeDefault Point(); // NO: Value created in a non-factory.
+    }
+
+    __ValueFactory static Point make(int x, int y) {
+       Point p = __MakeDefault Point(10, 20); // NO arguments to default value creation
+       String s = __MakeDefault String(); // NO: String cannot be produced in this factory.
+       __MakeDefault SinnerValue(); // NO: Wrong factory.
+       p = __MakeDefault Point();
+       p.x = x;
+       p.y = y;
+       return p;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckMakeDefault.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,6 @@
+CheckMakeDefault.java:11:20: compiler.err.make.default.with.nonvalue
+CheckMakeDefault.java:28:16: compiler.err.make.default.in.nonfactory
+CheckMakeDefault.java:32:18: compiler.err.invalid.arguments.to.make.default
+CheckMakeDefault.java:33:19: compiler.err.make.default.with.nonvalue
+CheckMakeDefault.java:34:8: compiler.err.make.default.with.wrong.value.type: Point.SinnerValue
+5 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckNoInvokeDirect.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2016, 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 Check that javac emits invokedirect instruction for method calls on values
+ * @modules jdk.compiler/com.sun.tools.javac.util
+ *          jdk.jdeps/com.sun.tools.javap
+ * @compile -XDenableValueTypes -g CheckNoInvokeDirect.java
+ * @run main/othervm -Xverify:none -XX:+EnableValhalla CheckNoInvokeDirect
+ */
+
+import com.sun.tools.javac.util.Assert;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Paths;
+
+public class CheckNoInvokeDirect {
+
+    interface I {
+        default void foo() {}
+        default void goo() {}
+    }
+
+    static final __ByValue class Value implements I {
+
+        static void soo() {}
+        public void foo() {}
+        void boo() {}
+
+        void test() {
+            soo();  // static method.
+            foo();  // invokedirect, overridden.
+            goo();  // invokedirect inherited.
+            boo();  // invokedirect fresh instance method
+        }
+    }
+
+    public static void main(String[] args) {
+        new CheckNoInvokeDirect().run();
+    }
+
+    void run() {
+        String [] params = new String [] { "-v",
+                                            Paths.get(System.getProperty("test.classes"),
+                                                "CheckNoInvokeDirect$Value.class").toString() };
+        runCheck(params, new String [] {
+
+           "#1 = Methodref          #7.#24         // \";Qjava/lang/__Value;\".\"<init>\":()V",
+           "#2 = Methodref          #6.#25         // \";QCheckNoInvokeDirect$Value;\".soo:()V",
+           "#3 = Methodref          #6.#26         // \";QCheckNoInvokeDirect$Value;\".foo:()V",
+           "#4 = Methodref          #6.#27         // \";QCheckNoInvokeDirect$Value;\".goo:()V",
+           "#5 = Methodref          #6.#28         // \";QCheckNoInvokeDirect$Value;\".boo:()V",
+
+           "0: vload         0",
+           "2: invokespecial #1                  // Method \";Qjava/lang/__Value;\".\"<init>\":()V",
+           "5: return",
+
+
+           "0: invokestatic  #2                  // Method soo:()V",
+           "3: vload         0",
+           "5: invokevirtual #3                  // Method foo:()V",
+           "8: vload         0",
+          "10: invokevirtual #4                  // Method goo:()V",
+          "13: vload         0",
+          "15: invokevirtual #5                  // Method boo:()V",
+          "18: return"
+                         });
+
+     }
+
+     void runCheck(String [] params, String [] expectedOut) {
+        StringWriter s;
+        String out;
+
+        try (PrintWriter pw = new PrintWriter(s = new StringWriter())) {
+            com.sun.tools.javap.Main.run(params, pw);
+            out = s.toString();
+        }
+        int errors = 0;
+        for (String eo: expectedOut) {
+            if (!out.contains(eo)) {
+                System.err.println("Match not found for string: " + eo);
+                errors++;
+            }
+        }
+         if (errors > 0) {
+             throw new AssertionError("Unexpected javap output: " + out);
+         }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckNullAssign.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,16 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Assignment of null to value types should be disallowed.
+ *
+ * @compile/fail/ref=CheckNullAssign.out -XDenableValueTypes -XDrawDiagnostics CheckNullAssign.java
+ */
+
+final __ByValue class CheckNullAssign {
+    CheckNullAssign foo(CheckNullAssign cna) {
+        // All of the below involve subtype/assignability checks and should be rejected.
+        cna = null;
+        foo(null);
+        if (null instanceof CheckNullAssign) {}
+        return null;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckNullAssign.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,5 @@
+CheckNullAssign.java:11:15: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+CheckNullAssign.java:12:9: compiler.err.cant.apply.symbol: kindname.method, foo, CheckNullAssign, compiler.misc.type.null, kindname.class, CheckNullAssign, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign))
+CheckNullAssign.java:13:13: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+CheckNullAssign.java:14:16: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullAssign)
+4 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckNullCastable.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,14 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary null cannot be casted to and compared with value types.
+ *
+ * @compile/fail/ref=CheckNullCastable.out -XDenableValueTypes -XDrawDiagnostics CheckNullCastable.java
+ */
+
+__ByValue final class CheckNullCastable {
+    void foo(CheckNullCastable cnc) {
+        CheckNullCastable cncl = (CheckNullCastable) null;
+        if (cnc != null) {};
+        if (null != cnc) {};
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckNullCastable.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,4 @@
+CheckNullCastable.java:10:54: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: compiler.misc.type.null, CheckNullCastable)
+CheckNullCastable.java:11:17: compiler.err.incomparable.types: CheckNullCastable, compiler.misc.type.null
+CheckNullCastable.java:12:18: compiler.err.incomparable.types: compiler.misc.type.null, CheckNullCastable
+3 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckStaticValueFactory.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,53 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Check various semantic constraints on static value factory method
+ *
+ * @compile/fail/ref=CheckStaticValueFactory.out -XDenableValueTypes -XDrawDiagnostics CheckStaticValueFactory.java
+ */
+__ByValue __ValueFactory final class Point { // NO: A type cannot be __ValueFactory
+
+    static class Sinner {
+        final int x;
+    }
+
+    interface I {
+        default __ValueFactory I foo() { // No: an interface method cannot be value factory
+            return null;
+        }
+    }
+
+    __ValueFactory final int x; // NO: A field cannot be value factory
+
+    final int y;
+    final int z = 0;
+
+    __ValueFactory Point() { // NO: A constructor cannot be value factory
+    }
+
+    __ValueFactory Point badFactory(int x, int y) { // No: factory must be a static method
+        return __MakeDefault Point();
+    }
+
+    __ValueFactory static String makeString(int x, int y) { // NO: bad return type for factory
+        String s = __MakeDefault String(); // NO: String is not a value type
+        return s;
+    }
+
+    __ValueFactory static Point make(int x, int y, int z) {
+       Point p = __MakeDefault Point();
+       p.x = x; // OK: allow update to blank final field via copy on write`
+       p.y = y; // OK: allow update to blank final field via copy on write`
+       p.z = z; // !OK, do not allow update to a non blank final even in a value factory.
+       Sinner s = new Sinner();
+       s.x = 10; // NO: No write to final field.
+       return p;
+    }
+
+    static Point nonFactory(int x, int y, int z) {
+       Point p = __MakeDefault Point(); // NO: cannot create default value in non-factory
+       p.x = x; // Error: No write to final field.
+       p.y = y; // Error: No write to final field.
+       p.z = z; // Error: No write to final field.
+       return p;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckStaticValueFactory.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,14 @@
+CheckStaticValueFactory.java:7:32: compiler.err.mod.not.allowed.here: staticvaluefactory
+CheckStaticValueFactory.java:19:30: compiler.err.mod.not.allowed.here: staticvaluefactory
+CheckStaticValueFactory.java:24:20: compiler.err.mod.not.allowed.here: staticvaluefactory
+CheckStaticValueFactory.java:27:26: compiler.err.value.factory.must.be.static
+CheckStaticValueFactory.java:31:27: compiler.err.type.found.req: java.lang.String, Point
+CheckStaticValueFactory.java:14:34: compiler.err.mod.not.allowed.here: staticvaluefactory
+CheckStaticValueFactory.java:32:20: compiler.err.make.default.with.nonvalue
+CheckStaticValueFactory.java:40:9: compiler.err.cant.assign.val.to.final.var: z
+CheckStaticValueFactory.java:42:9: compiler.err.cant.assign.val.to.final.var: x
+CheckStaticValueFactory.java:47:18: compiler.err.make.default.in.nonfactory
+CheckStaticValueFactory.java:48:9: compiler.err.cant.assign.val.to.final.var: x
+CheckStaticValueFactory.java:49:9: compiler.err.cant.assign.val.to.final.var: y
+CheckStaticValueFactory.java:50:9: compiler.err.cant.assign.val.to.final.var: z
+13 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckSuper.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2014, 2015 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.
+ */
+
+/*
+ * @test
+ * @ignore
+ * @summary Check super type
+ *
+ * @compile -XDenableValueTypes Point.java
+ * @compile -XDenableValueTypes CheckSuper.java
+ * @run main CheckSuper
+ */
+
+public class CheckSuper {
+    public static void main(String... args) {
+        final Point p = __Make Point(0,0);
+        // in the prototype, all values extend java.lang.__Value
+        __Value v = (__Value)p;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckSuperCompileOnly.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 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.
+ */
+
+/*
+ * @test
+ * @summary Check that value types have their super types wired to be j.l.__Value
+ *
+ * @compile -XDenableValueTypes Point.java
+ * @compile -XDenableValueTypes CheckSuperCompileOnly.java
+ */
+
+public class CheckSuperCompileOnly {
+    public static void main(String... args) {
+        final Point p = Point.makePoint(100, 200);
+        // in the prototype, all values extend java.lang.__Value
+        __Value v = (__Value)p;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckSync.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,42 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary May not synchronize on value types
+ *
+ * @compile/fail/ref=CheckSync.out -XDenableValueTypes -XDrawDiagnostics CheckSync.java
+ */
+
+/* Note: ATM, value types do not have jlO in their lineage. So they anyway
+   cannot synchronize using the methods declared on jlO.
+*/
+
+public final __ByValue class CheckSync {
+
+    final __ByValue class Val {
+
+        void foo() {
+            // All calls below are bad.
+            wait();
+            wait(10);
+            wait(10, 10);
+            notify();
+            notifyAll();
+            finalize();
+            clone();
+        }
+    }
+
+    final Val val = __MakeDefault Val();
+
+    void test() throws InterruptedException {
+        // All calls below are bad.
+        val.wait();
+        val.wait(10);
+        val.wait(new Integer(10));
+        val.wait(new Long(10));
+        val.wait(10L);
+        val.wait(10L, 10);
+        val.wait("Hello");
+        val.notify();
+        val.notifyAll();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckSync.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,19 @@
+CheckSync.java:18:13: compiler.err.value.does.not.support: wait
+CheckSync.java:19:13: compiler.err.value.does.not.support: wait
+CheckSync.java:20:13: compiler.err.value.does.not.support: wait
+CheckSync.java:21:13: compiler.err.value.does.not.support: notify
+CheckSync.java:22:13: compiler.err.value.does.not.support: notifyAll
+CheckSync.java:23:13: compiler.err.value.does.not.support: finalize
+CheckSync.java:24:13: compiler.err.value.does.not.support: clone
+CheckSync.java:32:12: compiler.err.value.does.not.support: wait
+CheckSync.java:33:12: compiler.err.value.does.not.support: wait
+CheckSync.java:34:12: compiler.err.value.does.not.support: wait
+CheckSync.java:35:12: compiler.err.value.does.not.support: wait
+CheckSync.java:36:12: compiler.err.value.does.not.support: wait
+CheckSync.java:37:12: compiler.err.value.does.not.support: wait
+CheckSync.java:38:12: compiler.err.cant.resolve.location.args: kindname.method, wait, , java.lang.String, (compiler.misc.location.1: kindname.variable, val, CheckSync.Val)
+CheckSync.java:39:12: compiler.err.value.does.not.support: notify
+CheckSync.java:40:12: compiler.err.value.does.not.support: notifyAll
+- compiler.note.deprecated.filename: CheckSync.java
+- compiler.note.deprecated.recompile
+16 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckSynchronized.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,18 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Check behavior of synzhronized key word on value instances and methods.
+ *
+ * @compile/fail/ref=CheckSynchronized.out -XDenableValueTypes -XDrawDiagnostics CheckSynchronized.java
+ */
+
+__ByValue final class CheckSynchronized {
+    synchronized void foo() { // <<-- ERROR, no monitor associated with `this'
+    }
+    void goo() {
+        synchronized(this) {} // <<-- ERROR, no monitor associated with `this'
+    }
+    synchronized static void zoo(CheckSynchronized cs) { // OK, static method.
+        synchronized(cs) {    // <<-- ERROR, no monitor associated with value instance.
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckSynchronized.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,4 @@
+CheckSynchronized.java:9:23: compiler.err.mod.not.allowed.here: synchronized
+CheckSynchronized.java:12:9: compiler.err.type.found.req: CheckSynchronized, (compiler.misc.type.req.ref)
+CheckSynchronized.java:15:9: compiler.err.type.found.req: CheckSynchronized, (compiler.misc.type.req.ref)
+3 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckValueFactoryWithReference.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,12 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Do not allow mismatched instantiation syntax between value & reference types.
+ *
+ * @compile/fail/ref=CheckValueFactoryWithReference.out -XDenableValueTypes -XDrawDiagnostics CheckValueFactoryWithReference.java
+ */
+
+final class CheckValueFactoryWithReference {
+    final Object o = __MakeDefault Object();
+    __ByValue final class Point {}
+    Point p = new Point();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckValueFactoryWithReference.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,3 @@
+CheckValueFactoryWithReference.java:9:22: compiler.err.make.default.with.nonvalue
+CheckValueFactoryWithReference.java:11:15: compiler.err.garbled.value.reference.instantiation
+2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckValueModifier.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,23 @@
+/*
+ * @test /nodynamiccopyright/
+ * @summary Compiler should reject value modifier when it features in illegal contexts.
+ *
+ * @compile/fail/ref=CheckValueModifier.out -XDenableValueTypes -XDrawDiagnostics CheckValueModifier.java
+ */
+
+/* Note: __ByValue as a modifier will be rejected by the parser if it features as a
+   modifier of a (a) catch parameter, (b) resource variable, (c) for loop's init section
+   declarators and (d) formal parameters. We test here only for the other illegal places.
+
+   All uses of __ByValue below should trigger errors.
+*/
+class CheckValueModifier {
+   __ByValue int x;
+   __ByValue int foo() {
+       __ByValue String local;
+   }
+   __ByValue interface IFace {}
+   __ByValue @interface Annot {}
+   __ByValue enum Enum {}
+   __ByValue abstract class Inner {}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/CheckValueModifier.out	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,8 @@
+CheckValueModifier.java:19:14: compiler.err.illegal.combination.of.modifiers: interface, value
+CheckValueModifier.java:20:15: compiler.err.illegal.combination.of.modifiers: interface, value
+CheckValueModifier.java:21:14: compiler.err.mod.not.allowed.here: value
+CheckValueModifier.java:22:23: compiler.err.illegal.combination.of.modifiers: abstract, value
+CheckValueModifier.java:15:18: compiler.err.mod.not.allowed.here: value
+CheckValueModifier.java:16:18: compiler.err.mod.not.allowed.here: value
+CheckValueModifier.java:17:25: compiler.err.mod.not.allowed.here: value
+7 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/Point.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014, 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.
+ */
+
+/*
+ * @test
+ * @summary Test basic syntax of values
+ *
+ * @compile -XDenableValueTypes Point.java
+ */
+
+final __ByValue class Point {
+    static final Point origin = makePoint(10, 20);
+    final int x;
+    final int y;
+    Point () {
+        x = 10;
+        y = 20;
+    }
+    __ValueFactory static Point makePoint(int x, int y) {
+        Point p = __MakeDefault Point();
+        p.x = x;
+        p.y = y;
+        return p;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/VOpcodeTest.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2017, 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 Check that javac emits vopcodes.
+ * @modules jdk.compiler jdk.jdeps/com.sun.tools.javap
+ * @compile -XDenableValueTypes VOpcodeTest.java
+ * @run main/othervm -Xverify:none -XX:+EnableValhalla VOpcodeTest
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Paths;
+
+public class VOpcodeTest {
+
+    public static __ByValue final class InnerValue {
+    }
+
+    public static __ByValue final class Value {
+
+        final InnerValue iv = __MakeDefault InnerValue();
+
+        Value foo() {
+            return foo();
+        }
+
+        Value goo(Value [] va) {
+            Value v = foo();
+            foo();
+            foo().iv.hashCode();
+            va[0] = va[1];
+            return foo();
+        }
+    }
+
+    public static void main(String[] args) {
+        new VOpcodeTest().run();
+    }
+
+    void run() {
+        String [] params =
+                new String [] { "-v",
+                                Paths.get(System.getProperty("test.classes"),
+                               "VOpcodeTest$Value.class").toString() };
+
+        runCheck(params, new String [] {
+               // goo's code:
+               "0: vload         0",
+               "2: invokevirtual #4                  // Method foo:()QVOpcodeTest$Value;",
+               "5: vstore        2",   // Store directly into v without buffering
+
+               "7: vload         0",
+               "9: invokevirtual #4                  // Method foo:()QVOpcodeTest$Value;",
+              "12: pop",               // Don't buffer what is being discarded.
+
+              "13: vload         0",
+              "15: invokevirtual #4                  // Method foo:()QVOpcodeTest$Value;",
+              "18: getfield      #3                  // Field iv:QVOpcodeTest$InnerValue;",
+              "21: invokevirtual #5                  // Method \";QVOpcodeTest$InnerValue;\".hashCode:()I",
+              "24: pop",
+              "25: aload_1",
+              "26: iconst_0",
+              "27: aload_1",
+              "28: iconst_1",
+              "29: vaload",
+              "30: vastore",         // Direct store without intermediate buffering.
+              "31: vload         0",
+              "33: invokevirtual #4                  // Method foo:()QVOpcodeTest$Value;",
+              "36: vreturn",        // Return value without rebuffering.
+                         });
+     }
+
+     void runCheck(String [] params, String [] expectedOut) {
+        StringWriter s;
+        String out;
+
+        try (PrintWriter pw = new PrintWriter(s = new StringWriter())) {
+            com.sun.tools.javap.Main.run(params, pw);
+            out = s.toString();
+        }
+        for (String eo: expectedOut) {
+            if (!out.contains(eo))
+                throw new AssertionError("Unexpected output: " + eo + " \n in: " + out);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/langtools/tools/javac/valhalla/values/ValueCreationTest.java	Tue Sep 26 16:13:34 2017 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2016, 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 Check code generation for value creation ops
+ * @modules jdk.compiler/com.sun.tools.javac.util jdk.jdeps/com.sun.tools.javap
+ * @compile -XDenableValueTypes ValueCreationTest.java
+ * @run main/othervm -Xverify:none -XX:+EnableValhalla ValueCreationTest
+ * @modules jdk.compiler
+ */
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.file.Paths;
+
+public class ValueCreationTest {
+
+    __ByValue
+    static final class Point {
+
+        final int x;
+        final int y;
+
+        Point () {
+            x = 10;
+            y = 10;
+        }
+
+        __ValueFactory static Point makePoint(int x, int y) {
+           Point p = __MakeDefault Point();
+           p.x = x;
+           p.y = y;
+           return p;
+        }
+
+        public static void main(String [] args) {
+            Point p = makePoint(10, 20);
+        }
+    }
+
+    public static void main(String[] args) {
+        new ValueCreationTest().run();
+    }
+
+    void run() {
+        String [] params = new String [] { "-v",
+                                            Paths.get(System.getProperty("test.classes"),
+                                                "ValueCreationTest$Point.class").toString() };
+        runCheck(params, new String [] {
+
+           "0: vdefault      #4                  // class \";QValueCreationTest$Point;\"",
+           "3: vstore        2",
+           "5: vload         2",
+           "7: iload_0",
+           "8: vwithfield    #2                  // Field x:I",
+           "11: vstore        2",
+           "13: vload         2",
+           "15: iload_1",
+           "16: vwithfield    #3                  // Field y:I",
+           "19: vstore        2",
+           "21: vload         2",
+           "23: vreturn",
+         });
+
+     }
+
+     void runCheck(String [] params, String [] expectedOut) {
+        StringWriter s;
+        String out;
+
+        try (PrintWriter pw = new PrintWriter(s = new StringWriter())) {
+            com.sun.tools.javap.Main.run(params, pw);
+            out = s.toString();
+        }
+        int errors = 0;
+        for (String eo: expectedOut) {
+            if (!out.contains(eo)) {
+                System.err.println("Match not found for string: " + eo);
+                errors++;
+            }
+        }
+         if (errors > 0) {
+             throw new AssertionError("Unexpected javap output: " + out);
+         }
+    }
+}