1 <!DOCTYPE html>
  2 <html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
  3 <head>
  4   <meta charset="utf-8" />
  5   <meta name="generator" content="pandoc" />
  6   <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
  7   <title>Migration of JDK Classes to Value Classes</title>
  8   <style>
  9     code{white-space: pre-wrap;}
 10     span.smallcaps{font-variant: small-caps;}
 11     div.columns{display: flex; gap: min(4vw, 1.5em);}
 12     div.column{flex: auto; overflow-x: auto;}
 13     div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
 14     ul.task-list{list-style: none;}
 15     ul.task-list li input[type="checkbox"] {
 16       width: 0.8em;
 17       margin: 0 0.8em 0.2em -1.6em;
 18       vertical-align: middle;
 19     }
 20     .display.math{display: block; text-align: center; margin: 0.5rem auto;}
 21   </style>
 22   <link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
 23   <style type="text/css">pre, code, tt { color: #1d6ae5; }</style>
 24   <!--[if lt IE 9]>
 25     <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
 26   <![endif]-->
 27 </head>
 28 <body>
 29 <header id="title-block-header">
 30 <h1 class="title">Migration of JDK Classes to Value Classes</h1>
 31 </header>
 32 <nav id="TOC" role="doc-toc">
 33 <ul>
 34 <li><a href="#introduction" id="toc-introduction">Introduction</a></li>
 35 <li><a href="#the-build-process" id="toc-the-build-process">The Build
 36 Process</a>
 37 <ul>
 38 <li><a href="#the-custom-handling-for-the-value-objects-jep"
 39 id="toc-the-custom-handling-for-the-value-objects-jep">The Custom
 40 Handling for the Value Objects JEP</a></li>
 41 <li><a href="#the-general-preview-source-to-binary-pipeline"
 42 id="toc-the-general-preview-source-to-binary-pipeline">The General
 43 Preview Source to Binary Pipeline</a></li>
 44 <li><a href="#non-goals" id="toc-non-goals">Non-Goals</a></li>
 45 </ul></li>
 46 <li><a href="#testing" id="toc-testing">Testing</a></li>
 47 <li><a href="#wrapper-class-caches"
 48 id="toc-wrapper-class-caches">Wrapper Class Caches</a></li>
 49 <li><a href="#editing-this-document"
 50 id="toc-editing-this-document">Editing This Document</a></li>
 51 </ul>
 52 </nav>
 53 <h2 id="introduction">Introduction</h2>
 54 <p>The Value Objects feature introduces value objects and migrates
 55 suitable classes to value classes. This means that when preview features
 56 are enabled, different class files are used for the migrated classes in
 57 the Java class library.</p>
 58 <p>To accomplish this, a built JDK uses <em>preview-specific</em> files
 59 in <code>META-INF/preview</code>, which overrides the regular files of
 60 the same name. For example,
 61 <code>META-INF/preview/java/lang/Integer.class</code> overrides
 62 <code>java/lang/Integer.class</code>.</p>
 63 <p>The JDK generates preview-specific source files (they may use preview
 64 language features), compiles class files from them, and distributes
 65 these class files in <code>META-INF/preview</code>.</p>
 66 <h2 id="the-build-process">The Build Process</h2>
 67 <h3 id="the-custom-handling-for-the-value-objects-jep">The Custom
 68 Handling for the Value Objects JEP</h3>
 69 <p>The Value Objects JEP requires a few select classes in the
 70 <code>java.base</code> module to become value classes when preview
 71 features are enabled.</p>
 72 <p>The build of <code>java.base</code> module first creates the source
 73 code of those value classes, done in <a
 74 href="../make/modules/java.base/gensrc/GensrcValueClasses.gmk"><code>GensrcValueClasses.gmk</code></a>.</p>
 75 <ol type="1">
 76 <li><p>A hardcoded list of regular source files are selected for
 77 preview-specific generation.</p></li>
 78 <li><p>Extract the content of each regular source file, search for any
 79 occurrences of <code>/*value*/ class</code> or
 80 <code>/*value*/ record</code>, and replace with <code>value class</code>
 81 or <code>value record</code>.</p></li>
 82 <li><p>The replaced contents are written to the preview-specific
 83 generated files, located in
 84 <code>support/gensrc-valueclasses/java.base/</code>. The regular source
 85 files remain unchanged in their original locations.</p></li>
 86 <li><p>The general preview source to binary build pipeline recognizes
 87 the <code>support/gensrc-valueclasses/java.base/</code> directory as
 88 where the <code>java.base</code> module places its preview-specific
 89 source files.</p></li>
 90 </ol>
 91 <h3 id="the-general-preview-source-to-binary-pipeline">The General
 92 Preview Source to Binary Pipeline</h3>
 93 <p>Once the preview-specific source files are ready, they are picked up
 94 by the build system into a fully automated pipeline handling all modules
 95 and all outcome images.</p>
 96 <ol type="1">
 97 <li><p>The <code>GENERATED_PREVIEW_SUBDIRS</code> variable in <a
 98 href="../make/common/Modules.gmk"><code>make/common/Modules.gmk</code></a>
 99 indicates where the source files are found.</p></li>
100 <li><p>For each module that has preview-specific source files, a goal is
101 created to compile these source files into class files.</p></li>
102 <li><p>The class files from each of these tasks reside in
103 <code>support/preview/&lt;module&gt;</code> for each module.</p></li>
104 <li><p>These preview-specific class files and other resources are copied
105 to the <code>META-INF/preview</code> directory of the regular output
106 directory.</p></li>
107 <li><p>At run-time, jimage will pick up the preview-specific overrides
108 from <code>META-INF/preview</code> only when preview features are
109 enabled.</p></li>
110 <li><p>The interim javac used by the build system cannot pick up the
111 preview-specific overrides; they must be supplied explicitly with the
112 following javac flag for every single module where overrides are
113 significant:</p>
114 <pre><code>--patch-module &lt;module&gt;=$(SUPPORT_OUTPUTDIR)/preview/&lt;module&gt;</code></pre>
115 <p>See <a
116 href="../make/test/BuildMicrobenchmark.gmk"><code>BuildMicroBenchmarks.gmk</code></a>
117 for an example.</p></li>
118 </ol>
119 <h3 id="non-goals">Non-Goals</h3>
120 <p>The Value Objects JEP only plans to introduce value classes that
121 are:</p>
122 <ol type="1">
123 <li><p>In the <code>java.base</code> module.</p>
124 <p>There's no plan to migrate other classes in other modules.</p></li>
125 <li><p>Migrated from existing classes.</p>
126 <p>These classes are available as identity classes when preview features
127 are disabled. There's no plan to introduce completely new value
128 classes.</p></li>
129 </ol>
130 <p>Support for other value classes would require significant changes to
131 the build system.</p>
132 <h2 id="testing">Testing</h2>
133 <p>In addition to tests that require preview features to be enabled,
134 tests that do not depend on preview features wish to run with preview
135 features enabled to ensure compatibility:</p>
136 <ol type="1">
137 <li><p>Some tests wish to run against the Java SE class library with
138 value classes.</p>
139 <p>The jtreg tests may be run with
140 <code>JTREG=VM_OPTIONS=--enable-preview</code>.</p></li>
141 <li><p>Some tests wish to run against their own classes migrated to
142 value classes.</p>
143 <p>The jtreg <a
144 href="testing.html#VALUE_CLASS_PLUGIN">VALUE_CLASS_PLUGIN</a> allows
145 tests to migrate their own classes to value classes when running with
146 the plugin.</p></li>
147 </ol>
148 <h2 id="wrapper-class-caches">Wrapper Class Caches</h2>
149 <p>Currently, wrapper class caches are retained even when preview
150 features are enabled to address performance losses. They have no
151 semantic impact to value objects.</p>
152 <p>In interpreter or C1 execution in Hotspot, allocations of a value
153 object to the heap as a full object with header happen when a value
154 object is:</p>
155 <ol type="1">
156 <li>Loaded from a flat storage (field or array)</li>
157 <li>Created by a constructor</li>
158 <li>If C2 uses scalarized calling convention, at C2 to C1/interpreter
159 calls and returns</li>
160 </ol>
161 <p>Ideally, C2 can eliminate such allocations, but this does not work if
162 the resulting object is stored into references. Unfortunately, many uses
163 of boxing conversions store the resulting wrapper objects as
164 references.</p>
165 <p>For the uses that store wrapper objects to references, if the boxing
166 conversion is:</p>
167 <ol type="1">
168 <li>Returning a value object from a flat cache array</li>
169 <li>Calling the value class constructor</li>
170 </ol>
171 <p>Then we would have heap allocation on every single use.</p>
172 <p>To avoid the allocations, we fall back to returning a value object
173 from a reference cache array, from which the loaded reference is
174 directly storable into a destination that wants a reference without any
175 allocation.</p>
176 <p>Since Hotspot may create flat arrays if an array of value objects is
177 requested by regular Java array creation mechanisms, we use
178 <code>ValueClass.newReferenceArray</code> to ensure we always create a
179 reference cache array.</p>
180 <p>The cache array for value objects may be removed without notice if
181 the performance losses from allocations are no longer significant.</p>
182 <h2 id="editing-this-document">Editing This Document</h2>
183 <p>If you want to contribute changes to this document, edit
184 <code>doc/value-class-preview.md</code> and then run
185 <code>make update-build-docs</code> to generate the same changes in
186 <code>doc/value-class-preview.html</code>.</p>
187 </body>
188 </html>