Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
874f866
8355798: Implement JEP-JDK-8350022: Ahead-of-time Command Line Ergono…
iklam Apr 29, 2025
6b0191c
Refactored code to enfore the order of argument parsing
iklam Apr 29, 2025
b9ebd92
added comment that was removed in previous commit
iklam Apr 29, 2025
9f70868
fixed typo
iklam May 4, 2025
0416487
Merge branch 'master' into 8355798-implement-leyden-ergo-jep-8350022
iklam May 4, 2025
2bdb005
Added %p substitution; clean up
iklam May 4, 2025
acba394
Remove %t restriction
iklam May 4, 2025
5e51e8f
AOT_TOOL_OPTIONS -> JAVA_AOT_OPTIONS
iklam May 5, 2025
0eb8b54
@vnkozlov comments
iklam May 5, 2025
5004a0b
@ashu-mehra comments; renamed test to JavaAOTOptionsEnvVar.java
iklam May 7, 2025
5697c24
Implemented JTREG=AOT_JDK=(onestep|twostep); default is onestep
iklam May 12, 2025
c7824b0
Use one-step training by default in AOT testing
iklam May 12, 2025
11fd910
Update java man page
iklam May 12, 2025
b044953
Merge branch 'master' into 8355798-implement-leyden-ergo-jep-8350022
iklam May 12, 2025
f33d599
Allow one-step training even when -XX:AOTMode=auto is specified
iklam May 12, 2025
3cc2cb3
Added param to makefile function SetupAOT for choosing onestep vs two…
iklam May 13, 2025
f468ae5
Resolved differences with CSR JDK-8356010
iklam May 14, 2025
cd7a5a6
java.md updates from @rose00
iklam May 14, 2025
7b8ad9b
Merge branch 'master' into 8355798-implement-leyden-ergo-jep-8350022
iklam May 14, 2025
d8d6e1f
fixed whitespace
iklam May 15, 2025
9ab4166
added info about JTREG/AOT_JDK testing
iklam May 15, 2025
7f4c0e8
@vnkozlov comments
iklam May 15, 2025
3347921
Merge branch 'master' into 8355798-implement-leyden-ergo-jep-8350022
iklam May 20, 2025
0956fca
@erikj79 comments
iklam May 20, 2025
502d1c0
Fixed merge
iklam May 20, 2025
f3ffe34
@erikj79 comments -- makefile indentation
iklam May 22, 2025
9a18864
Merge branch 'master' into 8355798-implement-leyden-ergo-jep-8350022
iklam May 22, 2025
de16fdb
Fixed merge
iklam May 22, 2025
a8ce491
Merge branch 'master' into 8355798-implement-leyden-ergo-jep-8350022
iklam May 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions doc/testing.html
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ <h1 class="title">Testing the JDK</h1>
<li><a href="#non-us-locale" id="toc-non-us-locale">Non-US
locale</a></li>
<li><a href="#pkcs11-tests" id="toc-pkcs11-tests">PKCS11 Tests</a></li>
<li><a href="#testing-ahead-of-time-optimizations"
id="toc-testing-ahead-of-time-optimizations">Testing Ahead-of-time
Optimizations</a></li>
<li><a href="#testing-with-alternative-security-providers"
id="toc-testing-with-alternative-security-providers">Testing with
alternative security providers</a></li>
Expand Down Expand Up @@ -596,6 +599,37 @@ <h3 id="pkcs11-tests">PKCS11 Tests</h3>
JTREG=&quot;JAVA_OPTIONS=-Djdk.test.lib.artifacts.nsslib-linux_aarch64=/path/to/NSS-libs&quot;</code></pre>
<p>For more notes about the PKCS11 tests, please refer to
test/jdk/sun/security/pkcs11/README.</p>
<h3 id="testing-ahead-of-time-optimizations">Testing Ahead-of-time
Optimizations</h3>
<p>One way to improve test coverage of ahead-of-time (AOT) optimizations
in the JDK is to run existing jtreg test cases in a special "AOT_JDK"
mode. Example:</p>
<pre><code>$ make test JTREG=&quot;AOT_JDK=onestep&quot; \
TEST=open/test/hotspot/jtreg/runtime/invokedynamic</code></pre>
<p>In this testing mode, we first perform an AOT training run (see
https://openjdk.org/jeps/483) of a special test program (<a
href="../test/setup_aot/TestSetupAOT.java">test/setup_aot/TestSetupAOT.java</a>)
that accesses about 5,0000 classes in the JDK core libraries.
Optimization artifacts for these classes (such as pre-linked lambda
expressions, execution profiles, and pre-generated native code) are
stored into an AOT cache file, which will be used by all the JVMs
launched by the selected jtreg test cases.</p>
<p>When the jtreg tests call into the core libraries classes that are in
the AOT cache, we will be able to test the AOT optimizations that were
used on those classes.</p>
<p>Please note that not all existing jtreg test cases can be executed
with the AOT_JDK mode. See <a
href="../test/hotspot/jtreg/ProblemList-AotJdk.txt">test/hotspot/jtreg/ProblemList-AotJdk.txt</a>
and <a
href="../test/jdk/ProblemList-AotJdk.txt">test/jdk/ProblemList-AotJdk.txt</a>.</p>
<p>Also, test cases that were written specifically to test AOT, such as
the tests under <a
href="../test/hotspot/jtreg/runtime/cds/">test/hotspot/jtreg/runtime/cds</a>,
cannot be executed with the AOT_JDK mode.</p>
<p>Valid values for <code>AOT_JDK</code> are <code>onestep</code> and
<code>twostep</code>. These control how the AOT cache is generated. See
https://openjdk.org/jeps/514 for details. All other values are
ignored.</p>
<h3 id="testing-with-alternative-security-providers">Testing with
alternative security providers</h3>
<p>Some security tests use a hardcoded provider for
Expand Down
37 changes: 37 additions & 0 deletions doc/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,43 @@ $ make test TEST="jtreg:sun/security/pkcs11/Secmod/AddTrustedCert.java" \
For more notes about the PKCS11 tests, please refer to
test/jdk/sun/security/pkcs11/README.

### Testing Ahead-of-time Optimizations
-------------------------------------------------------------------------------
One way to improve test coverage of ahead-of-time (AOT) optimizations in
the JDK is to run existing jtreg test cases in a special "AOT_JDK" mode.
Example:

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this extra newline intentional?

```
$ make test JTREG="AOT_JDK=onestep" \
TEST=open/test/hotspot/jtreg/runtime/invokedynamic
```

In this testing mode, we first perform an AOT training run
(see https://openjdk.org/jeps/483) of a special test program
([test/setup_aot/TestSetupAOT.java](../test/setup_aot/TestSetupAOT.java))
that accesses about 5,0000 classes in the JDK core libraries.
Optimization artifacts for these classes (such as pre-linked
lambda expressions, execution profiles, and pre-generated native code)
are stored into an AOT cache file, which will be used by all the JVMs
launched by the selected jtreg test cases.

When the jtreg tests call into the core libraries classes that are in
the AOT cache, we will be able to test the AOT optimizations that were
used on those classes.

Please note that not all existing jtreg test cases can be executed with
the AOT_JDK mode. See
[test/hotspot/jtreg/ProblemList-AotJdk.txt](../test/hotspot/jtreg/ProblemList-AotJdk.txt)
and [test/jdk/ProblemList-AotJdk.txt](../test/jdk/ProblemList-AotJdk.txt).

Also, test cases that were written specifically to test AOT, such as the tests
under [test/hotspot/jtreg/runtime/cds](../test/hotspot/jtreg/runtime/cds/),
cannot be executed with the AOT_JDK mode.

Valid values for `AOT_JDK` are `onestep` and `twostep`. These control how
the AOT cache is generated. See https://openjdk.org/jeps/514 for details.
All other values are ignored.

### Testing with alternative security providers

Some security tests use a hardcoded provider for `KeyFactory`, `Cipher`,
Expand Down
61 changes: 39 additions & 22 deletions make/RunTests.gmk
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,7 @@ endef
# Parameter 1 is the name of the rule.
#
# Remaining parameters are named arguments.
# TRAINING The AOT training mode: onestep or twostep
# VM_OPTIONS List of JVM arguments to use when creating AOT cache
#
# After calling this, the following variables are defined
Expand Down Expand Up @@ -753,23 +754,39 @@ define SetupAOTBody
$$($1_AOT_JDK_CACHE): $$(JDK_IMAGE_DIR)/release
$$(call MakeDir, $$($1_AOT_JDK_OUTPUT_DIR))

$$(call LogWarn, AOT: Create cache configuration) \
$$(call ExecuteWithLog, $$($1_AOT_JDK_OUTPUT_DIR), ( \
cd $$($1_AOT_JDK_OUTPUT_DIR); \
$(JAR) --extract --file $(TEST_IMAGE_DIR)/setup_aot/TestSetupAOT.jar; \
$$(FIXPATH) $(JDK_UNDER_TEST)/bin/java $$($1_VM_OPTIONS) \
-Xlog:class+load,aot,aot+class=debug:file=$$($1_AOT_JDK_CONF).log -Xlog:cds*=error -Xlog:aot*=error \
-XX:AOTMode=record -XX:AOTConfiguration=$$($1_AOT_JDK_CONF) \
TestSetupAOT $$($1_AOT_JDK_OUTPUT_DIR) > $$($1_AOT_JDK_LOG) \
))

$$(call LogWarn, AOT: Generate AOT cache $$($1_AOT_JDK_CACHE) with flags: $$($1_VM_OPTIONS))
$$(call ExecuteWithLog, $$($1_AOT_JDK_OUTPUT_DIR), ( \
$$(FIXPATH) $(JDK_UNDER_TEST)/bin/java \
$$($1_VM_OPTIONS) -Xlog:aot,aot+class=debug:file=$$($1_AOT_JDK_CACHE).log -Xlog:cds*=error -Xlog:aot*=error \
-XX:ExtraSharedClassListFile=$(JDK_UNDER_TEST)/lib/classlist \
-XX:AOTMode=create -XX:AOTConfiguration=$$($1_AOT_JDK_CONF) -XX:AOTCache=$$($1_AOT_JDK_CACHE) \
))
ifeq ($$($1_TRAINING), onestep)

$$(call LogWarn, AOT: Create AOT cache $$($1_AOT_JDK_CACHE) in one step with flags: $$($1_VM_OPTIONS)) \
$$(call ExecuteWithLog, $$($1_AOT_JDK_OUTPUT_DIR), ( \
cd $$($1_AOT_JDK_OUTPUT_DIR); \
$(JAR) --extract --file $(TEST_IMAGE_DIR)/setup_aot/TestSetupAOT.jar; \
$$(FIXPATH) $(JDK_UNDER_TEST)/bin/java $$($1_VM_OPTIONS) \
-Xlog:class+load,aot,aot+class=debug:file=$$($1_AOT_JDK_CACHE).log -Xlog:cds*=error -Xlog:aot*=error \
-XX:AOTMode=record -XX:AOTCacheOutput=$$($1_AOT_JDK_CACHE) \
TestSetupAOT $$($1_AOT_JDK_OUTPUT_DIR) > $$($1_AOT_JDK_LOG) \
))

else

$$(call LogWarn, AOT: Create cache configuration) \
$$(call ExecuteWithLog, $$($1_AOT_JDK_OUTPUT_DIR), ( \
cd $$($1_AOT_JDK_OUTPUT_DIR); \
$(JAR) --extract --file $(TEST_IMAGE_DIR)/setup_aot/TestSetupAOT.jar; \
$$(FIXPATH) $(JDK_UNDER_TEST)/bin/java $$($1_VM_OPTIONS) \
-Xlog:class+load,aot,aot+class=debug:file=$$($1_AOT_JDK_CONF).log -Xlog:cds*=error -Xlog:aot*=error \
-XX:AOTMode=record -XX:AOTConfiguration=$$($1_AOT_JDK_CONF) \
TestSetupAOT $$($1_AOT_JDK_OUTPUT_DIR) > $$($1_AOT_JDK_LOG) \
))

$$(call LogWarn, AOT: Generate AOT cache $$($1_AOT_JDK_CACHE) with flags: $$($1_VM_OPTIONS))
$$(call ExecuteWithLog, $$($1_AOT_JDK_OUTPUT_DIR), ( \
$$(FIXPATH) $(JDK_UNDER_TEST)/bin/java \
$$($1_VM_OPTIONS) -Xlog:aot,aot+class=debug:file=$$($1_AOT_JDK_CACHE).log -Xlog:cds*=error -Xlog:aot*=error \
-XX:ExtraSharedClassListFile=$(JDK_UNDER_TEST)/lib/classlist \
-XX:AOTMode=create -XX:AOTConfiguration=$$($1_AOT_JDK_CONF) -XX:AOTCache=$$($1_AOT_JDK_CACHE) \
))

endif

$1_AOT_TARGETS += $$($1_AOT_JDK_CACHE)

Expand Down Expand Up @@ -835,7 +852,7 @@ define SetupRunJtregTestBody
JTREG_RETRY_COUNT ?= 0
JTREG_REPEAT_COUNT ?= 0
JTREG_REPORT ?= files
JTREG_AOT_JDK ?= false
JTREG_AOT_JDK ?= none

ifneq ($$(JTREG_RETRY_COUNT), 0)
ifneq ($$(JTREG_REPEAT_COUNT), 0)
Expand Down Expand Up @@ -975,12 +992,12 @@ define SetupRunJtregTestBody
endif
endif

ifeq ($$(JTREG_AOT_JDK), true)
ifneq ($$(filter $$(JTREG_AOT_JDK), onestep twostep), )
$$(call LogWarn, Add AOT target for $1)
$$(eval $$(call SetupAOT, $1, VM_OPTIONS := $$(JTREG_ALL_OPTIONS) ))

$$(eval $$(call SetupAOT, $1, \
TRAINING := $$(JTREG_AOT_JDK), \
VM_OPTIONS := $$(JTREG_ALL_OPTIONS) ))
$$(call LogWarn, AOT_JDK_CACHE=$$($1_AOT_JDK_CACHE))

$1_JTREG_BASIC_OPTIONS += -vmoption:-XX:AOTCache="$$($1_AOT_JDK_CACHE)"
endif

Expand Down
124 changes: 105 additions & 19 deletions src/hotspot/share/cds/cdsConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ bool CDSConfig::_is_using_optimized_module_handling = true;
bool CDSConfig::_is_dumping_full_module_graph = true;
bool CDSConfig::_is_using_full_module_graph = true;
bool CDSConfig::_has_aot_linked_classes = false;
bool CDSConfig::_is_single_command_training = false;
bool CDSConfig::_has_temp_aot_config_file = false;
bool CDSConfig::_old_cds_flags_used = false;
bool CDSConfig::_new_aot_flags_used = false;
bool CDSConfig::_disable_heap_dumping = false;
Expand Down Expand Up @@ -398,12 +400,14 @@ void CDSConfig::check_aot_flags() {
_old_cds_flags_used = true;
}

// "New" AOT flags must not be mixed with "classic" flags such as -Xshare:dump
// "New" AOT flags must not be mixed with "classic" CDS flags such as -Xshare:dump
CHECK_NEW_FLAG(AOTCache);
CHECK_NEW_FLAG(AOTCacheOutput);
CHECK_NEW_FLAG(AOTConfiguration);
CHECK_NEW_FLAG(AOTMode);

CHECK_SINGLE_PATH(AOTCache);
CHECK_SINGLE_PATH(AOTCacheOutput);
CHECK_SINGLE_PATH(AOTConfiguration);

if (FLAG_IS_DEFAULT(AOTCache) && AOTAdapterCaching) {
Expand All @@ -413,29 +417,41 @@ void CDSConfig::check_aot_flags() {
log_debug(aot,codecache,init)("AOTCache is not specified - AOTStubCaching is ignored");
}

if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) {
// AOTCache/AOTConfiguration/AOTMode not used -> using the "classic CDS" workflow.
bool has_cache = !FLAG_IS_DEFAULT(AOTCache);
bool has_cache_output = !FLAG_IS_DEFAULT(AOTCacheOutput);
bool has_config = !FLAG_IS_DEFAULT(AOTConfiguration);
bool has_mode = !FLAG_IS_DEFAULT(AOTMode);

if (!has_cache && !has_cache_output && !has_config && !has_mode) {
// AOT flags are not used. Use classic CDS workflow
return;
} else {
_new_aot_flags_used = true;
}

if (has_cache && has_cache_output) {
vm_exit_during_initialization("Only one of AOTCache or AOTCacheOutput can be specified");
}

if (!has_cache && (!has_mode || strcmp(AOTMode, "auto") == 0)) {
if (has_cache_output) {
// If AOTCacheOutput has been set, effective mode is "record".
// Default value for AOTConfiguration, if necessary, will be assigned in check_aotmode_record().
log_info(aot)("Selected AOTMode=record because AOTCacheOutput is specified");
FLAG_SET_ERGO(AOTMode, "record");
}
}

// At least one AOT flag has been used
_new_aot_flags_used = true;

if (FLAG_IS_DEFAULT(AOTMode) || strcmp(AOTMode, "auto") == 0 || strcmp(AOTMode, "on") == 0) {
check_aotmode_auto_or_on();
} else if (strcmp(AOTMode, "off") == 0) {
check_aotmode_off();
} else if (strcmp(AOTMode, "record") == 0) {
check_aotmode_record();
} else {
// AOTMode is record or create
if (FLAG_IS_DEFAULT(AOTConfiguration)) {
vm_exit_during_initialization(err_msg("-XX:AOTMode=%s cannot be used without setting AOTConfiguration", AOTMode));
}

if (strcmp(AOTMode, "record") == 0) {
check_aotmode_record();
} else {
assert(strcmp(AOTMode, "create") == 0, "checked by AOTModeConstraintFunc");
check_aotmode_create();
}
assert(strcmp(AOTMode, "create") == 0, "checked by AOTModeConstraintFunc");
check_aotmode_create();
}

// This is an old flag used by CDS regression testing only. It doesn't apply
Expand All @@ -450,7 +466,8 @@ void CDSConfig::check_aotmode_off() {

void CDSConfig::check_aotmode_auto_or_on() {
if (!FLAG_IS_DEFAULT(AOTConfiguration)) {
vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create");
vm_exit_during_initialization(err_msg("AOTConfiguration can only be used with when AOTMode is record or create (selected AOTMode = %s)",
FLAG_IS_DEFAULT(AOTMode) ? "auto" : AOTMode));
}

UseSharedSpaces = true;
Expand All @@ -462,11 +479,63 @@ void CDSConfig::check_aotmode_auto_or_on() {
}
}

// %p substitution in AOTCache, AOTCacheOutput and AOTCacheConfiguration
static void substitute_aot_filename(JVMFlagsEnum flag_enum) {
JVMFlag* flag = JVMFlag::flag_from_enum(flag_enum);
const char* filename = flag->read<const char*>();
assert(filename != nullptr, "must not have default value");

// For simplicity, we don't allow %p/%t to be specified twice, because make_log_name()
// substitutes only the first occurrence. Otherwise, if we run with
// java -XX:AOTCacheOutput=%p%p.aot
// it will end up with both the pid of the training process and the assembly process.
const char* first_p = strstr(filename, "%p");
if (first_p != nullptr && strstr(first_p + 2, "%p") != nullptr) {
vm_exit_during_initialization(err_msg("%s cannot contain more than one %%p", flag->name()));
}
const char* first_t = strstr(filename, "%t");
if (first_t != nullptr && strstr(first_t + 2, "%t") != nullptr) {
vm_exit_during_initialization(err_msg("%s cannot contain more than one %%t", flag->name()));
}

// Note: with single-command training, %p will be the pid of the training process, not the
// assembly process.
const char* new_filename = make_log_name(filename, nullptr);
if (strcmp(filename, new_filename) != 0) {
JVMFlag::Error err = JVMFlagAccess::set_ccstr(flag, &new_filename, JVMFlagOrigin::ERGONOMIC);
assert(err == JVMFlag::SUCCESS, "must never fail");
}
FREE_C_HEAP_ARRAY(char, new_filename);
}

void CDSConfig::check_aotmode_record() {
bool has_config = !FLAG_IS_DEFAULT(AOTConfiguration);
bool has_output = !FLAG_IS_DEFAULT(AOTCacheOutput);

if (!has_output && !has_config) {
vm_exit_during_initialization("At least one of AOTCacheOutput and AOTConfiguration must be specified when using -XX:AOTMode=record");
}

if (has_output) {
_is_single_command_training = true;
substitute_aot_filename(FLAG_MEMBER_ENUM(AOTCacheOutput));
if (!has_config) {
// Too early; can't use resource allocation yet.
size_t len = strlen(AOTCacheOutput) + 10;
char* temp = AllocateHeap(len, mtArguments);
jio_snprintf(temp, len, "%s.config", AOTCacheOutput);
FLAG_SET_ERGO(AOTConfiguration, temp);
FreeHeap(temp);
_has_temp_aot_config_file = true;
}
}

if (!FLAG_IS_DEFAULT(AOTCache)) {
vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record");
}

substitute_aot_filename(FLAG_MEMBER_ENUM(AOTConfiguration));

UseSharedSpaces = false;
RequireSharedSpaces = false;
_is_dumping_static_archive = true;
Expand All @@ -478,10 +547,27 @@ void CDSConfig::check_aotmode_record() {
}

void CDSConfig::check_aotmode_create() {
if (FLAG_IS_DEFAULT(AOTCache)) {
vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create");
if (FLAG_IS_DEFAULT(AOTConfiguration)) {
vm_exit_during_initialization("AOTConfiguration must be specified when using -XX:AOTMode=create");
}

bool has_cache = !FLAG_IS_DEFAULT(AOTCache);
bool has_cache_output = !FLAG_IS_DEFAULT(AOTCacheOutput);

assert(!(has_cache && has_cache_output), "already checked");

if (!has_cache && !has_cache_output) {
vm_exit_during_initialization("AOTCache or AOTCacheOutput must be specified when using -XX:AOTMode=create");
}

if (!has_cache) {
precond(has_cache_output);
FLAG_SET_ERGO(AOTCache, AOTCacheOutput);
}
// No need to check for (!has_cache_output), as we don't look at AOTCacheOutput after here.

substitute_aot_filename(FLAG_MEMBER_ENUM(AOTCache));

_is_dumping_final_static_archive = true;
UseSharedSpaces = true;
RequireSharedSpaces = true;
Expand Down
5 changes: 5 additions & 0 deletions src/hotspot/share/cds/cdsConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ class CDSConfig : public AllStatic {
static bool _is_dumping_full_module_graph;
static bool _is_using_full_module_graph;
static bool _has_aot_linked_classes;
static bool _is_single_command_training;
static bool _has_temp_aot_config_file;

const static char* _default_archive_path;
const static char* _input_static_archive_path;
Expand Down Expand Up @@ -142,6 +144,9 @@ class CDSConfig : public AllStatic {
// Misc CDS features
static bool allow_only_single_java_thread() NOT_CDS_RETURN_(false);

static bool is_single_command_training() { return CDS_ONLY(_is_single_command_training) NOT_CDS(false); }
static bool has_temp_aot_config_file() { return CDS_ONLY(_has_temp_aot_config_file) NOT_CDS(false); }

// This is *Legacy* optimization for lambdas before JEP 483. May be removed in the future.
static bool is_dumping_lambdas_in_legacy_mode() NOT_CDS_RETURN_(false);

Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/cds/cds_globals.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@
"Cache for improving start up and warm up") \
constraint(AOTCacheConstraintFunc, AtParse) \
\
product(ccstr, AOTCacheOutput, nullptr, \
"Specifies the file name for writing the AOT cache") \
\
product(bool, AOTInvokeDynamicLinking, false, DIAGNOSTIC, \
"AOT-link JVM_CONSTANT_InvokeDynamic entries in cached " \
"ConstantPools") \
Expand Down
Loading