Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable MemorySegment in MMapDirectory for Java 22+ and Vectorization (incubation) for exact Java 22 #12706

Merged
merged 16 commits into from Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion gradle/generation/extract-jdk-apis.gradle
Expand Up @@ -20,7 +20,7 @@ def resources = scriptResources(buildscript)
configure(rootProject) {
ext {
// also change this in extractor tool: ExtractForeignAPI
vectorIncubatorJavaVersions = [ JavaVersion.VERSION_20, JavaVersion.VERSION_21 ] as Set
vectorIncubatorJavaVersions = [ JavaVersion.VERSION_20, JavaVersion.VERSION_21, JavaVersion.VERSION_22 ] as Set
}
}

Expand Down
11 changes: 11 additions & 0 deletions lucene/CHANGES.txt
Expand Up @@ -200,6 +200,17 @@ New Features
* GITHUB#12336: Index additional data per facet label in the taxonomy. (Shai Erera, Egor Potemkin, Mike McCandless,
Stefan Vodita)

* GITHUB#12706: Add support for the final release of Java foreign memory API in Java 22 (and later).
Lucene's MMapDirectory will now mmap Lucene indexes in chunks of 16 GiB (instead of 1 GiB) starting
from Java 19. Indexes closed while queries are running can no longer crash the JVM.
Support for vectorized implementations of VectorUtil based on jdk.incubator.vector APIs was added
for eactly Java 22. Therefore, applications started with command line parameter
"java --add-modules jdk.incubator.vector" will automatically use the new vectorized implementations
if running on a supported platform (Java 20/21/22 on x86 CPUs with AVX2 or later or ARM NEON CPUs).
This is an opt-in feature and requires explicit Java command line flag! When enabled, Lucene logs
a notice using java.util.logging. Please test thoroughly and report bugs/slowness to Lucene's mailing
list. (Uwe Schindler, Chris Hegarty)

Improvements
---------------------

Expand Down
Expand Up @@ -103,7 +103,7 @@ public static VectorizationProvider getInstance() {
// visible for tests
static VectorizationProvider lookup(boolean testMode) {
final int runtimeVersion = Runtime.version().feature();
if (runtimeVersion >= 20 && runtimeVersion <= 21) {
if (runtimeVersion >= 20 && runtimeVersion <= 22) {
// is locale sane (only buggy in Java 20)
if (isAffectedByJDK8301190()) {
LOG.warning(
Expand Down Expand Up @@ -169,9 +169,9 @@ static VectorizationProvider lookup(boolean testMode) {
} catch (ClassNotFoundException cnfe) {
throw new LinkageError("PanamaVectorizationProvider is missing in Lucene JAR file", cnfe);
}
} else if (runtimeVersion >= 22) {
} else if (runtimeVersion >= 23) {
LOG.warning(
"You are running with Java 22 or later. To make full use of the Vector API, please update Apache Lucene.");
"You are running with Java 23 or later. To make full use of the Vector API, please update Apache Lucene.");
} else if (lookupVectorModule().isPresent()) {
LOG.warning(
"Java vector incubator module was enabled by command line flags, but your Java version is too old: "
Expand Down
Expand Up @@ -346,7 +346,7 @@ private static MMapIndexInputProvider lookupProvider() {
}
final var lookup = MethodHandles.lookup();
final int runtimeVersion = Runtime.version().feature();
if (runtimeVersion >= 19 && runtimeVersion <= 21) {
if (runtimeVersion >= 19) {
try {
final var cls = lookup.findClass("org.apache.lucene.store.MemorySegmentIndexInputProvider");
// we use method handles, so we do not need to deal with setAccessible as we have private
Expand All @@ -366,9 +366,6 @@ private static MMapIndexInputProvider lookupProvider() {
throw new LinkageError(
"MemorySegmentIndexInputProvider is missing in Lucene JAR file", cnfe);
}
} else if (runtimeVersion >= 22) {
LOG.warning(
"You are running with Java 22 or later. To make full use of MMapDirectory, please update Apache Lucene.");
}
return new MappedByteBufferIndexInputProvider();
}
Expand Down
Expand Up @@ -108,10 +108,16 @@ AlreadyClosedException alreadyClosed(RuntimeException e) {
if (this.curSegment == null) {
return new AlreadyClosedException("Already closed: " + this);
}
// ISE can be thrown by MemorySegment and contains "closed" in message:
// in Java 22 or later we can check the isAlive status of all segments
// (see https://bugs.openjdk.org/browse/JDK-8310644):
if (Arrays.stream(segments).allMatch(s -> s.scope().isAlive()) == false) {
return new AlreadyClosedException("Already closed: " + this);
}
// fallback for Java 21: ISE can be thrown by MemorySegment and contains "closed" in message:
if (e instanceof IllegalStateException
&& e.getMessage() != null
&& e.getMessage().contains("closed")) {
// the check is on message only, so preserve original cause for debugging:
return new AlreadyClosedException("Already closed: " + this, e);
}
// otherwise rethrow unmodified NPE/ISE (as it possibly a bug with passing a null parameter to
Expand Down
Expand Up @@ -33,7 +33,7 @@ final class MemorySegmentIndexInputProvider implements MMapDirectory.MMapIndexIn
public MemorySegmentIndexInputProvider() {
var log = Logger.getLogger(getClass().getName());
log.info(
"Using MemorySegmentIndexInput with Java 21; to disable start with -D"
"Using MemorySegmentIndexInput with Java 21 or later; to disable start with -D"
+ MMapDirectory.ENABLE_MEMORY_SEGMENTS_SYSPROP
+ "=false");
}
Expand Down
Expand Up @@ -48,9 +48,9 @@ private static boolean isMemorySegmentImpl() {

public void testCorrectImplementation() {
final int runtimeVersion = Runtime.version().feature();
if (runtimeVersion >= 19 && runtimeVersion <= 21) {
if (runtimeVersion >= 19) {
assertTrue(
"on Java 19, 20, and 21 we should use MemorySegmentIndexInputProvider to create mmap IndexInputs",
"on Java 19 or later we should use MemorySegmentIndexInputProvider to create mmap IndexInputs",
isMemorySegmentImpl());
} else {
assertSame(MappedByteBufferIndexInputProvider.class, MMapDirectory.PROVIDER.getClass());
Expand Down