diff a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
--- a/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
+++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/jvm/Gen.java
@@ -422,10 +422,12 @@
      *  @param defs         The list of class member declarations.
      *  @param c            The enclosing class.
      */
     List<JCTree> normalizeDefs(List<JCTree> defs, ClassSymbol c) {
         ListBuffer<JCStatement> initCode = new ListBuffer<>();
+        // only used for value classes
+        ListBuffer<JCStatement> initBlocks = new ListBuffer<>();
         ListBuffer<Attribute.TypeCompound> initTAs = new ListBuffer<>();
         ListBuffer<JCStatement> clinitCode = new ListBuffer<>();
         ListBuffer<Attribute.TypeCompound> clinitTAs = new ListBuffer<>();
         ListBuffer<JCTree> methodDefs = new ListBuffer<>();
         // Sort definitions into three listbuffers:
@@ -437,12 +439,17 @@
             switch (def.getTag()) {
             case BLOCK:
                 JCBlock block = (JCBlock)def;
                 if ((block.flags & STATIC) != 0)
                     clinitCode.append(block);
-                else if ((block.flags & SYNTHETIC) == 0)
-                    initCode.append(block);
+                else if ((block.flags & SYNTHETIC) == 0) {
+                    if (c.isValueClass()) {
+                        initBlocks.append(block);
+                    } else {
+                        initCode.append(block);
+                    }
+                }
                 break;
             case METHODDEF:
                 methodDefs.append(def);
                 break;
             case VARDEF:
@@ -477,16 +484,15 @@
             default:
                 Assert.error();
             }
         }
         // Insert any instance initializers into all constructors.
-        if (initCode.length() != 0) {
-            List<JCStatement> inits = initCode.toList();
+        if (initCode.length() != 0 || initBlocks.length() != 0) {
             initTAs.addAll(c.getInitTypeAttributes());
             List<Attribute.TypeCompound> initTAlist = initTAs.toList();
             for (JCTree t : methodDefs) {
-                normalizeMethod((JCMethodDecl)t, inits, initTAlist);
+                normalizeMethod((JCMethodDecl)t, initCode.toList(), initBlocks.toList(), initTAlist);
             }
         }
         // If there are class initializers, create a <clinit> method
         // that contains them as its body.
         if (clinitCode.length() != 0) {
@@ -539,55 +545,68 @@
             return;
         log.error(pos, Errors.LimitString);
         nerrs++;
     }
 
-    /** Insert instance initializer code into initial constructor.
+    /** Insert instance initializer code into constructors prior to the super() call.
      *  @param md        The tree potentially representing a
      *                   constructor's definition.
      *  @param initCode  The list of instance initializer statements.
      *  @param initTAs  Type annotations from the initializer expression.
      */
-    void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<TypeCompound> initTAs) {
-        if (md.name == names.init && TreeInfo.isInitialConstructor(md)) {
-            // We are seeing a constructor that does not call another
-            // constructor of the same class.
-            List<JCStatement> stats = md.body.stats;
-            ListBuffer<JCStatement> newstats = new ListBuffer<>();
-
-            if (stats.nonEmpty()) {
-                // Copy initializers of synthetic variables generated in
-                // the translation of inner classes.
-                while (TreeInfo.isSyntheticInit(stats.head)) {
-                    newstats.append(stats.head);
-                    stats = stats.tail;
-                }
-                // Copy superclass constructor call
-                newstats.append(stats.head);
-                stats = stats.tail;
-                // Copy remaining synthetic initializers.
-                while (stats.nonEmpty() &&
-                       TreeInfo.isSyntheticInit(stats.head)) {
-                    newstats.append(stats.head);
-                    stats = stats.tail;
-                }
-                // Now insert the initializer code.
-                newstats.appendList(initCode);
-                // And copy all remaining statements.
-                while (stats.nonEmpty()) {
-                    newstats.append(stats.head);
-                    stats = stats.tail;
-                }
+    void normalizeMethod(JCMethodDecl md, List<JCStatement> initCode, List<JCStatement> initBlocks,  List<TypeCompound> initTAs) {
+        if (TreeInfo.isConstructor(md) && TreeInfo.hasConstructorCall(md, names._super)) {
+            // We are seeing a constructor that has a super() call.
+            // Find the super() invocation and append the given initializer code.
+            if (md.sym.owner.isValueClass()) {
+                rewriteInitializersIfNeeded(md, initCode);
+                TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.append(supercall).appendList(initBlocks)));
+            } else {
+                TreeInfo.mapSuperCalls(md.body, supercall -> make.Block(0, initCode.prepend(supercall)));
             }
-            md.body.stats = newstats.toList();
+
             if (md.body.endpos == Position.NOPOS)
                 md.body.endpos = TreeInfo.endPos(md.body.stats.last());
 
             md.sym.appendUniqueTypeAttributes(initTAs);
         }
     }
 
+    void rewriteInitializersIfNeeded(JCMethodDecl md, List<JCStatement> initCode) {
+        if (lower.initializerOuterThis.containsKey(md.sym.owner)) {
+            InitializerVisitor initializerVisitor = new InitializerVisitor(md, lower.initializerOuterThis.get(md.sym.owner));
+            for (JCStatement init : initCode) {
+                initializerVisitor.scan(init);
+            }
+        }
+    }
+
+    class InitializerVisitor extends TreeScanner {
+        JCMethodDecl md;
+        Set<JCExpression> exprSet;
+
+        InitializerVisitor(JCMethodDecl md, Set<JCExpression> exprSet) {
+            this.md = md;
+            this.exprSet = exprSet;
+        }
+
+        @Override
+        public void visitTree(JCTree tree) {}
+
+        @Override
+        public void visitIdent(JCIdent tree) {
+            if (exprSet.contains(tree)) {
+                for (JCVariableDecl param: md.params) {
+                    if (param.name == tree.name &&
+                            ((param.sym.flags_field & (MANDATED | NOOUTERTHIS)) == (MANDATED | NOOUTERTHIS))) {
+                        tree.sym = param.sym;
+                    }
+                }
+            }
+        }
+    }
+
 /* ************************************************************************
  * Traversal methods
  *************************************************************************/
 
     /** Visitor argument: The current environment.
@@ -1092,10 +1111,14 @@
             }
         } else {
             code.newLocal(v);
         }
         checkDimension(tree.pos(), v.type);
+        Type localType = v.erasure(types);
+        if (localType.requiresPreload(env.enclClass.sym)) {
+            poolWriter.enterPreloadClass((ClassSymbol) localType.tsym);
+        }
     }
 
     public void visitSkip(JCSkip tree) {
     }
 
@@ -2359,11 +2382,11 @@
 
         if (tree.name == names._class) {
             code.emitLdc((LoadableConstant)checkDimension(tree.pos(), tree.selected.type));
             result = items.makeStackItem(pt);
             return;
-       }
+        }
 
         Symbol ssym = TreeInfo.symbol(tree.selected);
 
         // Are we selecting via super?
         boolean selectSuper =
