diff --git a/make/common/Modules.gmk b/make/common/Modules.gmk index fd6b9b4ec10..c8c78ed8041 100644 --- a/make/common/Modules.gmk +++ b/make/common/Modules.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2025, 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 @@ -92,7 +92,7 @@ SRC_SUBDIRS += share/classes SPEC_SUBDIRS += share/specs -MAN_SUBDIRS += share/man +MAN_SUBDIRS += share/man windows/man # Find all module-info.java files for the current build target platform and # configuration. diff --git a/make/conf/version-numbers.conf b/make/conf/version-numbers.conf index 055f9ca8866..0f03ef3886a 100644 --- a/make/conf/version-numbers.conf +++ b/make/conf/version-numbers.conf @@ -39,4 +39,4 @@ DEFAULT_VERSION_CLASSFILE_MINOR=0 DEFAULT_VERSION_DOCS_API_SINCE=11 DEFAULT_ACCEPTABLE_BOOT_VERSIONS="23 24" DEFAULT_JDK_SOURCE_TARGET_VERSION=24 -DEFAULT_PROMOTED_VERSION_PRE=ea +DEFAULT_PROMOTED_VERSION_PRE= diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index 6ab77bf0007..f9ff16dc0e9 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -420,6 +420,11 @@ void CDSConfig::check_flag_aliases() { bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) { check_flag_aliases(); + if (!FLAG_IS_DEFAULT(AOTMode)) { + // Using any form of the new AOTMode switch enables enhanced optimizations. + FLAG_SET_ERGO_IF_DEFAULT(AOTClassLinking, true); + } + if (AOTClassLinking) { // If AOTClassLinking is specified, enable all AOT optimizations by default. FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true); diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 594d8817322..cd6616a8d52 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -2511,6 +2511,13 @@ bool FileMapInfo::validate_aot_class_linking() { log_error(cds)("CDS archive has aot-linked classes. It cannot be used with -Djava.security.manager=%s.", prop); return false; } + +#if INCLUDE_JVMTI + if (Arguments::has_jdwp_agent()) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used with JDWP agent"); + return false; + } +#endif } return true; diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 84b7ea0d6b9..ff84b7e3ff9 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -327,6 +327,13 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { if (!k->is_linked()) { if (has_class_failed_verification(k)) { return warn_excluded(k, "Failed verification"); + } else if (CDSConfig::is_dumping_aot_linked_classes()) { + // Most loaded classes should have been speculatively linked by MetaspaceShared::link_class_for_cds(). + // However, we do not speculatively link old classes, as they are not recorded by + // SystemDictionaryShared::record_linking_constraint(). As a result, such an unlinked + // class may fail to verify in AOTLinkedClassBulkLoader::init_required_classes_for_loader(), + // causing the JVM to fail at bootstrap. + return warn_excluded(k, "Unlinked class not supported by AOTClassLinking"); } } else { if (!k->can_be_verified_at_dumptime()) { diff --git a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp index 3f9c09f1c8c..4c4087adc37 100644 --- a/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp +++ b/src/hotspot/share/gc/z/c2/zBarrierSetC2.cpp @@ -559,7 +559,9 @@ static const Node* get_base_and_offset(const MachNode* mach, intptr_t& offset) { // The memory address is computed by 'base' and fed to 'mach' via an // indirect memory operand (indicated by offset == 0). The ultimate base and // offset can be fetched directly from the inputs and Ideal type of 'base'. - offset = base->bottom_type()->isa_oopptr()->offset(); + const TypeOopPtr* oopptr = base->bottom_type()->isa_oopptr(); + if (oopptr == nullptr) return nullptr; + offset = oopptr->offset(); // Even if 'base' is not an Ideal AddP node anymore, Matcher::ReduceInst() // guarantees that the base address is still available at the same slot. base = base->in(AddPNode::Base); diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 11481954e10..5148d5f4fef 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -103,6 +103,7 @@ bool Arguments::_ClipInlining = ClipInlining; size_t Arguments::_default_SharedBaseAddress = SharedBaseAddress; bool Arguments::_enable_preview = false; +bool Arguments::_has_jdwp_agent = false; LegacyGCLogging Arguments::_legacyGCLogging = { nullptr, 0 }; @@ -2021,7 +2022,7 @@ jint Arguments::parse_vm_init_args(const JavaVMInitArgs *vm_options_args, return JNI_OK; } -#if !INCLUDE_JVMTI +#if !INCLUDE_JVMTI || INCLUDE_CDS // Checks if name in command-line argument -agent{lib,path}:name[=options] // represents a valid JDWP agent. is_path==true denotes that we // are dealing with -agentpath (case where name is a path), otherwise with @@ -2319,6 +2320,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, JVMFlagOrigin "Debugging agents are not supported in this VM\n"); return JNI_ERR; } +#elif INCLUDE_CDS + if (valid_jdwp_agent(name, is_absolute_path)) { + _has_jdwp_agent = true; + } #endif // !INCLUDE_JVMTI JvmtiAgentList::add(name, options, is_absolute_path); os::free(name); diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index f18e44bbb55..0c18797f1cf 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2025, 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 @@ -254,6 +254,9 @@ class Arguments : AllStatic { // preview features static bool _enable_preview; + // jdwp + static bool _has_jdwp_agent; + // Used to save default settings static bool _AlwaysCompileLoopMethods; static bool _UseOnStackReplacement; @@ -506,6 +509,9 @@ class Arguments : AllStatic { static void set_enable_preview() { _enable_preview = true; } static bool enable_preview() { return _enable_preview; } + // jdwp + static bool has_jdwp_agent() { return _has_jdwp_agent; } + // Utility: copies src into buf, replacing "%%" with "%" and "%p" with pid. static bool copy_expand_pid(const char* src, size_t srclen, char* buf, size_t buflen); diff --git a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java index b40f6274412..e0c3aa19f54 100644 --- a/src/java.base/share/classes/java/lang/AbstractStringBuilder.java +++ b/src/java.base/share/classes/java/lang/AbstractStringBuilder.java @@ -640,11 +640,14 @@ private AbstractStringBuilder appendNull() { int count = this.count; byte[] val = this.value; if (isLatin1()) { - StringLatin1.putCharsAt(val, count, 'n', 'u', 'l', 'l'); + val[count++] = 'n'; + val[count++] = 'u'; + val[count++] = 'l'; + val[count++] = 'l'; } else { - StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l'); + count = StringUTF16.putCharsAt(val, count, 'n', 'u', 'l', 'l'); } - this.count = count + 4; + this.count = count; return this; } @@ -769,18 +772,25 @@ public AbstractStringBuilder append(boolean b) { byte[] val = this.value; if (isLatin1()) { if (b) { - StringLatin1.putCharsAt(val, count, 't', 'r', 'u', 'e'); + val[count++] = 't'; + val[count++] = 'r'; + val[count++] = 'u'; + val[count++] = 'e'; } else { - StringLatin1.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e'); + val[count++] = 'f'; + val[count++] = 'a'; + val[count++] = 'l'; + val[count++] = 's'; + val[count++] = 'e'; } } else { if (b) { - StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e'); + count = StringUTF16.putCharsAt(val, count, 't', 'r', 'u', 'e'); } else { - StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e'); + count = StringUTF16.putCharsAt(val, count, 'f', 'a', 'l', 's', 'e'); } } - this.count = count + (b ? 4 : 5); + this.count = count; return this; } diff --git a/src/java.base/share/classes/java/lang/StringConcatHelper.java b/src/java.base/share/classes/java/lang/StringConcatHelper.java index b635d0dee0f..d0c558ed93a 100644 --- a/src/java.base/share/classes/java/lang/StringConcatHelper.java +++ b/src/java.base/share/classes/java/lang/StringConcatHelper.java @@ -236,10 +236,17 @@ static long prepend(long indexCoder, byte[] buf, boolean value, String prefix) { if (indexCoder < UTF16) { if (value) { index -= 4; - StringLatin1.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + buf[index] = 't'; + buf[index + 1] = 'r'; + buf[index + 2] = 'u'; + buf[index + 3] = 'e'; } else { index -= 5; - StringLatin1.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + buf[index] = 'f'; + buf[index + 1] = 'a'; + buf[index + 2] = 'l'; + buf[index + 3] = 's'; + buf[index + 4] = 'e'; } index -= prefix.length(); prefix.getBytes(buf, index, String.LATIN1); @@ -247,10 +254,17 @@ static long prepend(long indexCoder, byte[] buf, boolean value, String prefix) { } else { if (value) { index -= 4; - StringUTF16.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + StringUTF16.putChar(buf, index, 't'); + StringUTF16.putChar(buf, index + 1, 'r'); + StringUTF16.putChar(buf, index + 2, 'u'); + StringUTF16.putChar(buf, index + 3, 'e'); } else { index -= 5; - StringUTF16.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + StringUTF16.putChar(buf, index, 'f'); + StringUTF16.putChar(buf, index + 1, 'a'); + StringUTF16.putChar(buf, index + 2, 'l'); + StringUTF16.putChar(buf, index + 3, 's'); + StringUTF16.putChar(buf, index + 4, 'e'); } index -= prefix.length(); prefix.getBytes(buf, index, String.UTF16); @@ -624,20 +638,34 @@ static int prepend(int index, byte coder, byte[] buf, boolean value, String pref if (coder == String.LATIN1) { if (value) { index -= 4; - StringLatin1.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + buf[index] = 't'; + buf[index + 1] = 'r'; + buf[index + 2] = 'u'; + buf[index + 3] = 'e'; } else { index -= 5; - StringLatin1.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + buf[index] = 'f'; + buf[index + 1] = 'a'; + buf[index + 2] = 'l'; + buf[index + 3] = 's'; + buf[index + 4] = 'e'; } index -= prefix.length(); prefix.getBytes(buf, index, String.LATIN1); } else { if (value) { index -= 4; - StringUTF16.putCharsAt(buf, index, 't', 'r', 'u', 'e'); + StringUTF16.putChar(buf, index, 't'); + StringUTF16.putChar(buf, index + 1, 'r'); + StringUTF16.putChar(buf, index + 2, 'u'); + StringUTF16.putChar(buf, index + 3, 'e'); } else { index -= 5; - StringUTF16.putCharsAt(buf, index, 'f', 'a', 'l', 's', 'e'); + StringUTF16.putChar(buf, index, 'f'); + StringUTF16.putChar(buf, index + 1, 'a'); + StringUTF16.putChar(buf, index + 2, 'l'); + StringUTF16.putChar(buf, index + 3, 's'); + StringUTF16.putChar(buf, index + 4, 'e'); } index -= prefix.length(); prefix.getBytes(buf, index, String.UTF16); diff --git a/src/java.base/share/classes/java/lang/StringLatin1.java b/src/java.base/share/classes/java/lang/StringLatin1.java index 7680bcbfa45..abec36af1d9 100644 --- a/src/java.base/share/classes/java/lang/StringLatin1.java +++ b/src/java.base/share/classes/java/lang/StringLatin1.java @@ -32,7 +32,6 @@ import java.util.function.IntConsumer; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import jdk.internal.misc.Unsafe; import jdk.internal.util.ArraysSupport; import jdk.internal.util.DecimalDigits; import jdk.internal.vm.annotation.IntrinsicCandidate; @@ -43,8 +42,6 @@ import static java.lang.String.checkOffset; final class StringLatin1 { - private static final Unsafe UNSAFE = Unsafe.getUnsafe(); - public static char charAt(byte[] value, int index) { checkIndex(index, value.length); return (char)(value[index] & 0xff); @@ -827,27 +824,6 @@ static Stream lines(byte[] value) { return StreamSupport.stream(LinesSpliterator.spliterator(value), false); } - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4) { - assert index >= 0 && index + 3 < length(val) : "Trusted caller missed bounds check"; - // Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores. - long offset = (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + index; - UNSAFE.putByte(val, offset , (byte)(c1)); - UNSAFE.putByte(val, offset + 1, (byte)(c2)); - UNSAFE.putByte(val, offset + 2, (byte)(c3)); - UNSAFE.putByte(val, offset + 3, (byte)(c4)); - } - - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4, int c5) { - assert index >= 0 && index + 4 < length(val) : "Trusted caller missed bounds check"; - // Don't use the putChar method, Its instrinsic will cause C2 unable to combining values into larger stores. - long offset = (long) Unsafe.ARRAY_BYTE_BASE_OFFSET + index; - UNSAFE.putByte(val, offset , (byte)(c1)); - UNSAFE.putByte(val, offset + 1, (byte)(c2)); - UNSAFE.putByte(val, offset + 2, (byte)(c3)); - UNSAFE.putByte(val, offset + 3, (byte)(c4)); - UNSAFE.putByte(val, offset + 4, (byte)(c5)); - } - public static void putChar(byte[] val, int index, int c) { //assert (canEncode(c)); val[index] = (byte)(c); diff --git a/src/java.base/share/classes/java/lang/StringUTF16.java b/src/java.base/share/classes/java/lang/StringUTF16.java index f04b991827f..000483f29bc 100644 --- a/src/java.base/share/classes/java/lang/StringUTF16.java +++ b/src/java.base/share/classes/java/lang/StringUTF16.java @@ -43,6 +43,7 @@ import static java.lang.String.LATIN1; final class StringUTF16 { + // Return a new byte array for a UTF16-coded string for len chars // Throw an exception if out of range public static byte[] newBytesFor(int len) { @@ -1547,20 +1548,27 @@ public static boolean contentEquals(byte[] value, CharSequence cs, int len) { return true; } - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4) { - assert index >= 0 && index + 3 < length(val) : "Trusted caller missed bounds check"; - putChar(val, index , c1); - putChar(val, index + 1, c2); - putChar(val, index + 2, c3); - putChar(val, index + 3, c4); - } - - static void putCharsAt(byte[] val, int index, int c1, int c2, int c3, int c4, int c5) { - putChar(val, index , c1); - putChar(val, index + 1, c2); - putChar(val, index + 2, c3); - putChar(val, index + 3, c4); - putChar(val, index + 4, c5); + public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4) { + int end = i + 4; + checkBoundsBeginEnd(i, end, value); + putChar(value, i++, c1); + putChar(value, i++, c2); + putChar(value, i++, c3); + putChar(value, i++, c4); + assert(i == end); + return end; + } + + public static int putCharsAt(byte[] value, int i, char c1, char c2, char c3, char c4, char c5) { + int end = i + 5; + checkBoundsBeginEnd(i, end, value); + putChar(value, i++, c1); + putChar(value, i++, c2); + putChar(value, i++, c3); + putChar(value, i++, c4); + putChar(value, i++, c5); + assert(i == end); + return end; } public static char charAt(byte[] value, int index) { diff --git a/src/java.base/share/classes/java/util/Formatter.java b/src/java.base/share/classes/java/util/Formatter.java index 6ab07e14594..d0b4f6744d0 100644 --- a/src/java.base/share/classes/java/util/Formatter.java +++ b/src/java.base/share/classes/java/util/Formatter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2025, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2023, Alibaba Group Holding Limited. All Rights Reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -432,7 +432,7 @@ * prefix {@code 'T'} forces this output to upper case. * * {@code 'z'} - * RFC 822 + * RFC 822 * style numeric time zone offset from GMT, e.g. {@code -0800}. This * value will be adjusted as necessary for Daylight Saving Time. For * {@code long}, {@link Long}, and {@link Date} the time zone used is @@ -1720,7 +1720,7 @@ * * {@code 'z'} * '\u007a' - * RFC 822 + * RFC 822 * style numeric time zone offset from GMT, e.g. {@code -0800}. This * value will be adjusted as necessary for Daylight Saving Time. For * {@code long}, {@link Long}, and {@link Date} the time zone used is diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index 9d1d6e266a3..9ebc93ce3fd 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -4011,12 +4011,12 @@ The values for these options (if specified), should be identical when creating a CDS archive. Otherwise, if there is a mismatch of any of these options, the CDS archive may be partially or completely disabled, leading to lower performance. -- If the -XX:+AOTClassLinking options *was* used during CDS archive creation, the CDS archive +- If the `AOTClassLinking` option (see below) *was* enabled during CDS archive creation, the CDS archive cannot be used, and the following error message is printed: `CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used` -- If the -XX:+AOTClassLinking options *was not* used during CDS archive creation, the CDS archive +- If the `AOTClassLinking` option *was not* enabled during CDS archive creation, the CDS archive can be used, but the "archived module graph" feature will be disabled. This can lead to increased start-up time. @@ -4037,6 +4037,115 @@ JVM will execute without loading any CDS archives. In addition, if you try to create a CDS archive with any of these 3 options specified, the JVM will report an error. +## Ahead-of-Time Cache + +The JDK supports ahead-of-time (AOT) optimizations that can be performed before an +application is executed. One example is Class Data Sharing (CDS), as described above, +that parses classes ahead of time. AOT optimizations can improve the start-up and +warm-up performance of Java applications. + +The Ahead-of-Time Cache (AOT cache) is a container introduced in JDK 24 for +storing artifacts produced by AOT optimizations. The AOT cache currently contains +Java classes and heap objects. In future JDK releases, the AOT cache may contain additional +artifacts, such as execution profiles and compiled methods. + +An AOT cache is specific to a combination of the following: + +- A particular application (as expressed by `-classpath`, `-jar`, or `--module-path`.) +- A particular JDK release. +- A particular OS and CPU architecture. + +If any of the above changes, you must recreate the AOT cache. + +The deployment of the AOT cache is divided into three phases: + +- **Training:** We execute the application with a representative work-load + to gather statistical data that tell us what artifacts should be included + into the AOT cache. The data are saved in an *AOT Configuration* file. + +- **Assembly:** We use the AOT Configuration file to produce an AOT cache. + +- **Production:** We execute the application with the AOT cache for better + start-up and warm-up performance. + +The AOT cache can be used with the following command-line options: + +`-XX:AOTCache:=`*cachefile* +: Specifies the location of the AOT cache. The standard extension for *cachefile* is `.aot`. + If `-XX:AOTCache` is specified but `-XX:AOTMode` is not specified, + then `AOTMode` will be given the value of `auto`. + +`-XX:AOTConfiguration:=`*configfile* +: Specifies the AOT Configuration file for the JVM to write to or read from. + This option can be used only with `-XX:AOTMode=record` and `-XX:AOTMode=create`. + The standard extension for *configfile* is `.aotconfig`. + +`-XX:+AOTMode:=`*mode* +: *mode* must be one of the following: `off`, `record`, `create`, `auto`, or `on`. + +- `off`: no AOT cache is used. + +- `record`: Execute the application in the Training phase. + `-XX:AOTConfiguration=`*configfile* must be specified. The JVM gathers + statistical data and stores them into *configfile*. + +- `create`: Perform the Assembly phase. `-XX:AOTConfiguration=`*configfile* + and `-XX:AOTCache=`*cachefile* must be specified. The JVM reads the statistical + data from *configfile* and writes the optimization artifacts into *cachefile*. + Note that the application itself is not executed in this phase. + +- `auto` or `on`: These modes should be used in the Production phase. + If `-XX:AOTCache=`*cachefile* is specified, the JVM tries to + load *cachefile* as the AOT cache. Otherwise, the JVM tries to load + a *default CDS archive* from the JDK installation directory as the AOT cache. + + The loading of an AOT cache can fail for a number of reasons: + + - You are trying to use the AOT cache with an incompatible application, JDK release, + or OS/CPU. + + - The specified *cachefile* does not exist or is not accessible. + + - Incompatible JVM options are used (for example, certain JVMTI options). + + Since the AOT cache is an optimization feature, there's no guarantee that it will be + compatible with all possible JVM options. See [JEP 483](https://openjdk.org/jeps/483), + section **Consistency of training and subsequent runs** for a representative + list of scenarios that may be incompatible with the AOT cache for JDK 24. + + These scenarios usually involve arbitrary modification of classes for diagnostic + purposes and are typically not relevant for production environments. + + When the AOT cache fails to load: + + - If `AOTMode` is `auto`, the JVM will continue execution without using the + AOT cache. This is the recommended mode for production environments, especially + when you may not have complete control of the command-line (e.g., your + application's launch script may allow users to inject options to the command-line). + This allows your application to function correctly, although sometimes it may not + benefit from the AOT cache. + + - If `AOTMode` is `on`, the JVM will print an error message and exit immediately. This + mode should be used only as a "fail-fast" debugging aid to check if your command-line + options are compatible with the AOT cache. An alternative is to run your application with + `-XX:AOTMode=auto -Xlog:cds` to see if the AOT cache can be used or not. + +`-XX:+AOTClassLinking` +: If this option is enabled, the JVM will perform more advanced optimizations (such + as ahead-of-time resolution of invokedynamic instructions) + when creating the AOT cache. As a result, the application will see further improvements + in start-up and warm-up performance. However, an AOT cache created with this option + cannot be used when certain command-line parameters are specified in + the Production phase. Please see [JEP 483](https://openjdk.org/jeps/483) for a + detailed discussion of `-XX:+AOTClassLinking` and its restrictions. + + When `-XX:AOTMode` *is used* in the command-line, `AOTClassLinking` is automatically + enabled. To disable it, you must explicitly pass the `-XX:-AOTClassLinking` option. + + When `-XX:AOTMode` *is not used* in the command-line, `AOTClassLinking` is disabled by + default to provide full compatibility with traditional CDS options such as `-Xshare:dump. + + ## Performance Tuning Examples You can use the Java advanced runtime options to optimize the performance of diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultResponseControlFactory.java b/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultResponseControlFactory.java index 89b01484cd4..534aa95a916 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultResponseControlFactory.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/DefaultResponseControlFactory.java @@ -36,7 +36,7 @@ *