Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
76f9490
8388030: Provide configure option to disable build of libjsound
MBaesken Jul 30, 2026
d78a34e
8389323: Remove unused jdk.internal.httpclient.monitorFlowDelegate pr…
djelinski Jul 30, 2026
7e6a820
8386884: GC.heap_dump -parallel accepts values outside uint range and…
Jul 30, 2026
0d4fb55
8385131: HTTP/2 connection not closed after receiving GOAWAY frame wh…
jaikiran Jul 30, 2026
cc278db
8389219: Implement JEP 401: Value Objects (Preview)
MrSimms Jul 31, 2026
3362738
8389392: Leftover policy files in java.net tests after Security Manag…
jaikiran Jul 31, 2026
17ae726
8389498: Enable HttpClient debug logging in java/net/httpclient/http2…
jaikiran Jul 31, 2026
6b590fd
8389395: Use factory method to construct SequentialSchedulers
djelinski Jul 31, 2026
835c7b1
8354489: Some callers of VMError::report_and_die think it can return
Jul 31, 2026
b030a50
8382692: Use 'isb' instruction in SpinPause on windows-aarch64
Jul 31, 2026
eacfa42
8389533: ProblemList gc/g1/TestCodeCacheUnloadDuringConcurrentMark.ja…
Jul 31, 2026
af4e946
8389514: HttpClientImpl$SelectorManager.deregistrations collection is…
jaikiran Aug 1, 2026
add59ed
8388400: Incorrect null check in jdk.internal.jrtfs.ExplodedImage$Pat…
jaikiran Aug 1, 2026
4a6718b
8389312: RISC-V: vector_update_crc32 wrongly assumes undisturbed tail…
zifeihan Aug 1, 2026
79b0a1c
8389552: [s390]: Build fails due to missing CodeCache declaration in …
hgqxjj Aug 1, 2026
5b2d699
8389384: JDK-6960970 broke cross compilation on slow-debug level
lgxbslgx Aug 2, 2026
c6da3a4
8388317: [lworld] LibraryCallKit::inline_unsafe_flat_access asserts o…
TobiHartmann Aug 3, 2026
a282521
8388851: [lworld] Remove obsolete array store address recomputation
TobiHartmann Aug 3, 2026
85860be
8388468: [lworld] TestIntrinsics intermittently fails due to unexpect…
TobiHartmann Aug 3, 2026
3bfc2b8
8389235: [lworld] Wrong reason for too_many_traps_or_recompiles check…
TobiHartmann Aug 3, 2026
3b3f964
8382879: AOT training run exits with 0 even if assembly subprocess fails
iklam Aug 3, 2026
282b67e
8389214: [lworld] StoreFlatNode with TOP value input not correctly ha…
TobiHartmann Aug 3, 2026
0ddc887
8389450: [lworld] Value class adapter generation leaks CodeCache Buff…
TobiHartmann Aug 3, 2026
ba05044
8388007: [lworld] [Umbrella] Adressing remaining compiler review comm…
chhagedorn Aug 3, 2026
37ab50a
8389088: [lworld] C2: assert(false) failed: empty program detected du…
chhagedorn Aug 3, 2026
93635de
8346316: compiler/rangechecks/TestLongRangeCheck.java fails intermitt…
chhagedorn Aug 3, 2026
185c99f
8388192: [lworld] Some code is not guarded by Arguments::is_valhalla_…
TobiHartmann Aug 3, 2026
7f418b7
8388441: [lworld] Expansion of substitutability test fails after macr…
TobiHartmann Aug 3, 2026
0200a83
8389453: [unix] Avoid unused variables warnings in libj2pkcs11 and ad…
MBaesken Aug 3, 2026
775ecc3
8389537: (fs) Failure in querying attributes of a OneDrive folder ove…
raneashay Aug 3, 2026
d5da754
8389341: [lworld] C2 Class.isAssignableFrom intrinsic returns false f…
TobiHartmann Aug 3, 2026
6625973
8389234: [lworld] Bad cast for delayed access through abstract value …
TobiHartmann Aug 3, 2026
ae364a0
8389391: [lworld] Return buffer allocation for late-inlined MH calls …
TobiHartmann Aug 3, 2026
17e1f97
8388193: [lworld] C2's ClearArray keeps zero fill value alive in regi…
TobiHartmann Aug 3, 2026
81c9ea0
8388709: [lworld] replay parts of JDK-8350865
marc-chevalier Aug 3, 2026
ef218b0
8388018: [IR Framework] Be more lenient about system properties
marc-chevalier Aug 3, 2026
45d3b16
8387856: G1: Fix passing G1ParScanThreadState and worker_id in methods
Aug 3, 2026
032eae5
8387860: G1: G1ConcurrentMark padding should use variables instead of…
Aug 3, 2026
e0cfc8c
8389139: [lworld] C1 should not reuse CodeEmitInfo for G1 pre-barrier…
TobiHartmann Aug 3, 2026
062ab7f
8388005: G1: Decrease parallelism in actual deferred code root update…
albertnetymk Aug 3, 2026
6936bcf
8388361: [lworld] C2 hits node limit during scalarization in safepoints
TobiHartmann Aug 3, 2026
0df7d08
8388256: [lworld] Clone of reference array is broken in C2
TobiHartmann Aug 3, 2026
9be1c44
8388544: [lworld] Bad dominance assert in C2 when late-inlining throu…
TobiHartmann Aug 3, 2026
bc6a625
8389089: [lworld] C1 should not initialize value class when accessing…
TobiHartmann Aug 3, 2026
cc72529
8388442: C2: LoadNKlassNode::Identity() may return a new node
hgqxjj Aug 3, 2026
83fa552
8389354: [lworld] PhaseIdealLoop::move_flat_array_check_out_of_loop c…
TobiHartmann Aug 3, 2026
3385e51
8382605: C2: second call of inline_incrementally doesn't happen with …
hgqxjj Aug 3, 2026
218fb7f
8389259: Class::desiredAssertionStatus asserts with primitive or arra…
coleenp Aug 3, 2026
1b79e91
8380391: Update java.smartcardio finalizer to use Cleaner
Aug 3, 2026
963ae29
8388386: Remove deprecated sun.net.www.http.HttpClient#resetProperties
by1361092 Aug 4, 2026
63808b0
8388755: Use floating point argument for fillVertex in MTLRenderer
jayathirthrao Aug 4, 2026
1672751
8389588: [s390x] Zero build is broken after JDK-8388561
vpa1977 Aug 4, 2026
a97facb
8341518: TestJcmdWithSideCar.java fails with 'sun.tools.jcmd.JCmd' mi…
Domest0s Aug 4, 2026
b67d698
8389509: SetPrinterDevice check GlobalAlloc return value
MBaesken Aug 4, 2026
5cf67d0
8386833: java/lang/management/MemoryMXBean/TestGetTotalGcCpuTime.java…
kevinjwalls Aug 4, 2026
017e253
8388460: RISC-V: Auto-enable Zcb extension features
zifeihan Aug 4, 2026
0bdfb3a
8388791: Refactor JavaClasses Throwable and StackTrace classes
coleenp Aug 4, 2026
6ca70ae
8389130: [lworld] Compiled frame walking is slow due to scalarized ca…
marc-chevalier Aug 4, 2026
0b095ac
8388302: [lworld] allocate_inline_types_impl could dereference a null…
marc-chevalier Aug 4, 2026
9822518
8388295: [lworld] C2: inline_unsafe_flat_access could dereference a n…
marc-chevalier Aug 4, 2026
87af1ea
8388917: G1: "guarantee(variance() > -1.0) failed: variance should be…
albertnetymk Aug 4, 2026
cec41f1
8385163: JMX: Use recommended MessageDigest comparison method
kevinjwalls Aug 4, 2026
820aa25
8386687: Regression >6% on Crypto-MLDSA.sign on x64
Aug 4, 2026
cdf491e
8388848: [lworld] ConnectionGraph::process_call_arguments does not co…
TobiHartmann Aug 4, 2026
a6be6cf
8388469: Error: assert(_init_deps.contains(ktd)) failed when running …
Aug 4, 2026
683c639
8389518: Should record dependency on -XX:+-ProfileExceptionHandlers flag
Aug 4, 2026
8878934
8253442: Bigapps SIGSEGV in DeadlockCycle::print_on_with
coleenp Aug 4, 2026
b19cc6c
8388480: System.arraycopy fails to partially copy nullable flat arrays
fparain Aug 4, 2026
8f0032f
8382405: AArch64: Dubious non-saves of ptrue after runtime calls
Aug 4, 2026
4afa191
8385593: Clarify the wording of UnsupportedClassVersionError
Aug 4, 2026
279a5a5
8388594: Clean up return statements with CHECK in them
Aug 4, 2026
5117341
8388527: Add "indistinguishable" cross-reference to Double's discussi…
jddarcy Aug 5, 2026
fd8ab6c
8385616: [VectorAPI] Remove VectorOperators.OR fallback handling for …
Aug 5, 2026
d5336eb
8385157: C2: RegionNode::optimize_trichotomy wrongly folds CmpI and C…
eme64 Aug 5, 2026
a935581
8388338: javac shares proxy initializer trees across constructors
lahodaj Aug 5, 2026
0f73c4c
8389455: Avoid local initialized unused variables in libjimage
MBaesken Aug 5, 2026
21b0c22
8293983: ValueTearing fails with "torn point NOT observed"
johan-sjolen Aug 5, 2026
441d51f
8389128: G1: Avoid redundant card marks during remembered set rebuilding
albertnetymk Aug 5, 2026
f1b723b
8388427: Fix javadoc typos related to {@code} and {@linkplain}
rybak Aug 5, 2026
7ab4033
8385322: Provide configure flag to disable cds archive generation for…
MBaesken Aug 5, 2026
fc51e5e
8389512: [lworld] Stale acmp profile data causes repeated deoptimization
marc-chevalier Aug 5, 2026
ec53c3d
8389705: RawBytecodeHelper doesn't check bounds passed to unsafe code
liach Aug 5, 2026
09e226c
8387957: G1: Investigate merging G1EdenRegions and G1SurvivorRegions
Aug 5, 2026
957b5b2
8388631: Copy StackMapTable for the current frame
Aug 5, 2026
8f6db41
8388799: ClhsdbLongConstant should not assert a specific value for VM…
shivshah-oracle Aug 5, 2026
5121008
8388882: Disable automatic integer spills to floating point registers…
Aug 5, 2026
f43bcd4
8389611: vframeStreamCommon::skip_prefixed_method_and_wrappers: unsig…
devnexen Aug 5, 2026
5085458
8287010: Port TraceDeoptimization to UL
coleenp Aug 5, 2026
a5a6ee4
8370493: [ubsan] aotMapLogger.cpp:864:44: runtime error: applying non…
Aug 5, 2026
c678a27
8353854: Change map_memory() signature to match other functions
Aug 5, 2026
6449400
8389189: Ignore different AOTClassLinking option between AOT training…
iklam Aug 5, 2026
52cd87f
8389589: [TEST_BUG] java/awt/FullScreen/SetFSWindow/FSFrame.java hide…
Aug 6, 2026
b3ba447
8388279: Compiled code fails with verifier error (II)
lahodaj Aug 6, 2026
f0a1d02
8386769: [lworld] C2 parts of JDK-8350865 - Part. 2
marc-chevalier Aug 6, 2026
f602bd4
8389357: Avoid local initialized unused variables in jdk.accessibility
MBaesken Aug 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
38 changes: 38 additions & 0 deletions doc/testing.html
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,44 @@ <h4 id="test_thread_factory">TEST_THREAD_FACTORY</h4>
<code>test/jtreg_test_thread_factory/</code> directory. This class gets
compiled during the test image build. The implementation of the Virtual
class creates a new virtual thread for executing each test class.</p>
<h4 id="value_class_plugin">VALUE_CLASS_PLUGIN</h4>
<p>Enables the <code>ValueClassPlugin</code> javac plugin when compiling
and running JTReg tests. This is a <strong>temporary mode</strong>
intended for use while value classes (JEP 401) are a preview feature.
The long-term plan is to replace classes annotated with
<code>@jdk.test.lib.valueclass.AsValueClass</code> with plain
<code>value class</code> declarations once value classes are
finalized.</p>
<p>In the meantime, this mode allows test sources to compile and run as
either value classes or regular identity classes without source-level
changes.</p>
<p>When set to any non-empty value, the following options are appended to
every JTReg invocation:</p>
<ul>
<li><code>-cpa:&lt;valueClassPlugin.jar&gt;</code> — appends the plugin
JAR to the compile-time classpath (only when the JAR is present in the
test image under
<code>jtreg_value_class_plugin/valueClassPlugin.jar</code>).</li>
<li><code>-vmoption:--enable-preview</code> — enables JVM preview
features at runtime.</li>
<li><code>-javacoption:-XDaccessInternalAPI</code> — grants the compiler
access to internal APIs required by the plugin.</li>
<li><code>-javacoption:--source &lt;version&gt; --enable-preview</code>
— enables preview language features at compile time.</li>
<li><code>-javacoption:-Xplugin:ValueClassPlugin</code> — activates the
plugin.</li>
</ul>
<p>The plugin scans each compilation unit after parsing and converts any
class annotated with
<code>@jdk.test.lib.valueclass.AsValueClass</code> into a value class by
setting the internal <code>VALUE_CLASS</code> modifier flag and clearing
the <code>IDENTITY_TYPE</code> flag. This transformation only takes
effect when <code>--enable-preview</code> is active; without it the
annotation is a no-op and the class compiles as an ordinary identity
class, so the same test source can exercise both code paths.</p>
<p>Example:</p>
<pre><code>$ make test TEST=jdk_lang JTREG="VALUE_CLASS_PLUGIN=true"
</code></pre>
<h4 id="jvmti_stress_agent">JVMTI_STRESS_AGENT</h4>
<p>Executes JTReg tests with JVM TI stress agent. The stress agent is
the part of test library and located in
Expand Down
36 changes: 36 additions & 0 deletions doc/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,42 @@ the `test/jtreg_test_thread_factory/` directory. This class gets compiled
during the test image build. The implementation of the Virtual class creates a
new virtual thread for executing each test class.

#### VALUE_CLASS_PLUGIN

Enables the `ValueClassPlugin` javac plugin when compiling and running JTReg
tests. This is a **temporary mode** intended for use while value classes
(JEP 401) are a preview feature. The long-term plan is to replace classes
annotated with `@jdk.test.lib.valueclass.AsValueClass` with plain
`value class` declarations once value classes are finalized.

In the meantime, this mode allows test sources to compile and run as either
value classes or regular identity classes without source-level changes.

When set to any non-empty value, the following options are appended to every
JTReg invocation:

* `-cpa:<valueClassPlugin.jar>` — appends the plugin JAR to the compile-time
classpath (only when the JAR is present in the test image under
`jtreg_value_class_plugin/valueClassPlugin.jar`).
* `-vmoption:--enable-preview` — enables JVM preview features at runtime.
* `-javacoption:-XDaccessInternalAPI` — grants the compiler access to internal
APIs required by the plugin.
* `-javacoption:--source <version> --enable-preview` — enables preview language
features at compile time.
* `-javacoption:-Xplugin:ValueClassPlugin` — activates the plugin.

The plugin scans each compilation unit after parsing and converts any class
annotated with `@jdk.test.lib.valueclass.AsValueClass` into a value class by
setting the internal `VALUE_CLASS` modifier flag and clearing the
`IDENTITY_TYPE` flag. This transformation only takes effect when
`--enable-preview` is active; without it the annotation is a no-op and the
class compiles as an ordinary identity class, so the same test source can
exercise both code paths.

Example:

$ make test TEST=jdk_lang JTREG="VALUE_CLASS_PLUGIN=true"

#### JVMTI_STRESS_AGENT

Executes JTReg tests with JVM TI stress agent. The stress agent is the part of
Expand Down
188 changes: 188 additions & 0 deletions doc/value-class-preview.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">
<head>
<meta charset="utf-8" />
<meta name="generator" content="pandoc" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
<title>Migration of JDK Classes to Value Classes</title>
<style>
code{white-space: pre-wrap;}
span.smallcaps{font-variant: small-caps;}
div.columns{display: flex; gap: min(4vw, 1.5em);}
div.column{flex: auto; overflow-x: auto;}
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
ul.task-list{list-style: none;}
ul.task-list li input[type="checkbox"] {
width: 0.8em;
margin: 0 0.8em 0.2em -1.6em;
vertical-align: middle;
}
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
</style>
<link rel="stylesheet" href="../make/data/docs-resources/resources/jdk-default.css" />
<style type="text/css">pre, code, tt { color: #1d6ae5; }</style>
<!--[if lt IE 9]>
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
<![endif]-->
</head>
<body>
<header id="title-block-header">
<h1 class="title">Migration of JDK Classes to Value Classes</h1>
</header>
<nav id="TOC" role="doc-toc">
<ul>
<li><a href="#introduction" id="toc-introduction">Introduction</a></li>
<li><a href="#the-build-process" id="toc-the-build-process">The Build
Process</a>
<ul>
<li><a href="#the-custom-handling-for-the-value-objects-jep"
id="toc-the-custom-handling-for-the-value-objects-jep">The Custom
Handling for the Value Objects JEP</a></li>
<li><a href="#the-general-preview-source-to-binary-pipeline"
id="toc-the-general-preview-source-to-binary-pipeline">The General
Preview Source to Binary Pipeline</a></li>
<li><a href="#non-goals" id="toc-non-goals">Non-Goals</a></li>
</ul></li>
<li><a href="#testing" id="toc-testing">Testing</a></li>
<li><a href="#wrapper-class-caches"
id="toc-wrapper-class-caches">Wrapper Class Caches</a></li>
<li><a href="#editing-this-document"
id="toc-editing-this-document">Editing This Document</a></li>
</ul>
</nav>
<h2 id="introduction">Introduction</h2>
<p>The Value Objects feature introduces value objects and migrates
suitable classes to value classes. This means that when preview features
are enabled, different class files are used for the migrated classes in
the Java class library.</p>
<p>To accomplish this, a built JDK uses <em>preview-specific</em> files
in <code>META-INF/preview</code>, which overrides the regular files of
the same name. For example,
<code>META-INF/preview/java/lang/Integer.class</code> overrides
<code>java/lang/Integer.class</code>.</p>
<p>The JDK generates preview-specific source files (they may use preview
language features), compiles class files from them, and distributes
these class files in <code>META-INF/preview</code>.</p>
<h2 id="the-build-process">The Build Process</h2>
<h3 id="the-custom-handling-for-the-value-objects-jep">The Custom
Handling for the Value Objects JEP</h3>
<p>The Value Objects JEP requires a few select classes in the
<code>java.base</code> module to become value classes when preview
features are enabled.</p>
<p>The build of <code>java.base</code> module first creates the source
code of those value classes, done in <a
href="../make/modules/java.base/gensrc/GensrcValueClasses.gmk"><code>GensrcValueClasses.gmk</code></a>.</p>
<ol type="1">
<li><p>A hardcoded list of regular source files are selected for
preview-specific generation.</p></li>
<li><p>Extract the content of each regular source file, search for any
occurrences of <code>/*value*/ class</code> or
<code>/*value*/ record</code>, and replace with <code>value class</code>
or <code>value record</code>.</p></li>
<li><p>The replaced contents are written to the preview-specific
generated files, located in
<code>support/gensrc-valueclasses/java.base/</code>. The regular source
files remain unchanged in their original locations.</p></li>
<li><p>The general preview source to binary build pipeline recognizes
the <code>support/gensrc-valueclasses/java.base/</code> directory as
where the <code>java.base</code> module places its preview-specific
source files.</p></li>
</ol>
<h3 id="the-general-preview-source-to-binary-pipeline">The General
Preview Source to Binary Pipeline</h3>
<p>Once the preview-specific source files are ready, they are picked up
by the build system into a fully automated pipeline handling all modules
and all outcome images.</p>
<ol type="1">
<li><p>The <code>GENERATED_PREVIEW_SUBDIRS</code> variable in <a
href="../make/common/Modules.gmk"><code>make/common/Modules.gmk</code></a>
indicates where the source files are found.</p></li>
<li><p>For each module that has preview-specific source files, a goal is
created to compile these source files into class files.</p></li>
<li><p>The class files from each of these tasks reside in
<code>support/preview/&lt;module&gt;</code> for each module.</p></li>
<li><p>These preview-specific class files and other resources are copied
to the <code>META-INF/preview</code> directory of the regular output
directory.</p></li>
<li><p>At run-time, jimage will pick up the preview-specific overrides
from <code>META-INF/preview</code> only when preview features are
enabled.</p></li>
<li><p>The interim javac used by the build system cannot pick up the
preview-specific overrides; they must be supplied explicitly with the
following javac flag for every single module where overrides are
significant:</p>
<pre><code>--patch-module &lt;module&gt;=$(SUPPORT_OUTPUTDIR)/preview/&lt;module&gt;</code></pre>
<p>See <a
href="../make/test/BuildMicrobenchmark.gmk"><code>BuildMicroBenchmarks.gmk</code></a>
for an example.</p></li>
</ol>
<h3 id="non-goals">Non-Goals</h3>
<p>The Value Objects JEP only plans to introduce value classes that
are:</p>
<ol type="1">
<li><p>In the <code>java.base</code> module.</p>
<p>There's no plan to migrate other classes in other modules.</p></li>
<li><p>Migrated from existing classes.</p>
<p>These classes are available as identity classes when preview features
are disabled. There's no plan to introduce completely new value
classes.</p></li>
</ol>
<p>Support for other value classes would require significant changes to
the build system.</p>
<h2 id="testing">Testing</h2>
<p>In addition to tests that require preview features to be enabled,
tests that do not depend on preview features wish to run with preview
features enabled to ensure compatibility:</p>
<ol type="1">
<li><p>Some tests wish to run against the Java SE class library with
value classes.</p>
<p>The jtreg tests may be run with
<code>JTREG=VM_OPTIONS=--enable-preview</code>.</p></li>
<li><p>Some tests wish to run against their own classes migrated to
value classes.</p>
<p>The jtreg <a
href="testing.html#VALUE_CLASS_PLUGIN">VALUE_CLASS_PLUGIN</a> allows
tests to migrate their own classes to value classes when running with
the plugin.</p></li>
</ol>
<h2 id="wrapper-class-caches">Wrapper Class Caches</h2>
<p>Currently, wrapper class caches are retained even when preview
features are enabled to address performance losses. They have no
semantic impact to value objects.</p>
<p>In interpreter or C1 execution in Hotspot, allocations of a value
object to the heap as a full object with header happen when a value
object is:</p>
<ol type="1">
<li>Loaded from a flat storage (field or array)</li>
<li>Created by a constructor</li>
<li>If C2 uses scalarized calling convention, at C2 to C1/interpreter
calls and returns</li>
</ol>
<p>Ideally, C2 can eliminate such allocations, but this does not work if
the resulting object is stored into references. Unfortunately, many uses
of boxing conversions store the resulting wrapper objects as
references.</p>
<p>For the uses that store wrapper objects to references, if the boxing
conversion is:</p>
<ol type="1">
<li>Returning a value object from a flat cache array</li>
<li>Calling the value class constructor</li>
</ol>
<p>Then we would have heap allocation on every single use.</p>
<p>To avoid the allocations, we fall back to returning a value object
from a reference cache array, from which the loaded reference is
directly storable into a destination that wants a reference without any
allocation.</p>
<p>Since Hotspot may create flat arrays if an array of value objects is
requested by regular Java array creation mechanisms, we use
<code>ValueClass.newReferenceArray</code> to ensure we always create a
reference cache array.</p>
<p>The cache array for value objects may be removed without notice if
the performance losses from allocations are no longer significant.</p>
<h2 id="editing-this-document">Editing This Document</h2>
<p>If you want to contribute changes to this document, edit
<code>doc/value-class-preview.md</code> and then run
<code>make update-build-docs</code> to generate the same changes in
<code>doc/value-class-preview.html</code>.</p>
</body>
</html>
Loading
Loading