Skip to content

8387812: Refine ArraysSupport.vectorizedMismatch to compare all elements#31802

Open
kuaiwei wants to merge 2 commits into
openjdk:masterfrom
kuaiwei:refine_mismatch
Open

8387812: Refine ArraysSupport.vectorizedMismatch to compare all elements#31802
kuaiwei wants to merge 2 commits into
openjdk:masterfrom
kuaiwei:refine_mismatch

Conversation

@kuaiwei

@kuaiwei kuaiwei commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

I recently noticed a behavioral discrepancy in jdk.internal.util.ArraysSupport.vectorizedMismatch between the Java implementation and the platform intrinsic implementations.

Current behavior

The Java implementation may leave a tail of elements unchecked, returning the bitwise complement of the number of remaining elements (i.e., ~remaining).
The x86_64 intrinsic, by contrast, compares all elements and simply returns -1 when no mismatch is found.
Because of this inconsistency, every caller has to handle the "remaining elements" case defensively:

int i = vectorizedMismatch(...);
if (i >= 0) {
    return i; // mismatch found
} else {
    length -= ~i; // fall through to handle remaining elements
}

Proposed change

This PR refines the Java implementation so that it always compares all elements and returns -1 when no mismatch is found, matching the x86_64 intrinsic behavior. This also simplify all callsite because it eliminates the need for callers to handle remaining elements.

A regression test is included at test/hotspot/jtreg/compiler/intrinsics/VectorizedMismatchReturnDiffTest.java which demonstrates the original behavioral difference.

Test

  • tier1 test suites on linux x86_64
  • tier1 test suites on linux aarch64


Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

  • JDK-8387812: Refine ArraysSupport.vectorizedMismatch to compare all elements (Enhancement - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk.git pull/31802/head:pull/31802
$ git checkout pull/31802

Update a local copy of the PR:
$ git checkout pull/31802
$ git pull https://git.openjdk.org/jdk.git pull/31802/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 31802

View PR using the GUI difftool:
$ git pr show -t 31802

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/31802.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper

bridgekeeper Bot commented Jul 7, 2026

Copy link
Copy Markdown

👋 Welcome back kwei! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk

openjdk Bot commented Jul 7, 2026

Copy link
Copy Markdown

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

@openjdk openjdk Bot added nio nio-dev@openjdk.org hotspot-compiler hotspot-compiler-dev@openjdk.org core-libs core-libs-dev@openjdk.org labels Jul 7, 2026
@openjdk

openjdk Bot commented Jul 7, 2026

Copy link
Copy Markdown

@kuaiwei The following labels will be automatically applied to this pull request:

  • core-libs
  • hotspot-compiler
  • nio

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing lists. If you would like to change these labels, use the /label pull request command.

@kuaiwei kuaiwei changed the title 8387812: Refine ArraysSupport.vectorizedMismatch to compare all elements. 8387812: Refine ArraysSupport.vectorizedMismatch to compare all elements Jul 7, 2026
@openjdk

openjdk Bot commented Jul 7, 2026

Copy link
Copy Markdown

The total number of required reviews for this PR has been set to 2 based on the presence of this label: hotspot-compiler. This can be overridden with the /reviewers command.

@openjdk openjdk Bot added the rfr Pull request is ready for review label Jul 7, 2026
@mlbridge

mlbridge Bot commented Jul 7, 2026

Copy link
Copy Markdown

Webrevs

@iwanowww

iwanowww commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

ArraysSupport.vectorizedMismatch JavaDoc says the following:

     * @return if a mismatch is found a relative index, between 0 (inclusive)
     * and {@code length} (exclusive), of the first mismatching pair of elements
     * in the two arrays.  Otherwise, if a mismatch is not found the bitwise
     * compliment of the number of remaining pairs of elements to be checked in
     * the tail of the two arrays.

Unless you change the contract (so it is mandated to check all elements), I don't see how you can simplify checks at call sites.

But another question is do we really want to do so? It forces intrinsics on all platforms to fully process input arrays which may introduce unnecessary complexity. Alternatively, you can introduce a wrapper which handles tail processing in Java.

@kuaiwei

kuaiwei commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

ArraysSupport.vectorizedMismatch JavaDoc says the following:

     * @return if a mismatch is found a relative index, between 0 (inclusive)
     * and {@code length} (exclusive), of the first mismatching pair of elements
     * in the two arrays.  Otherwise, if a mismatch is not found the bitwise
     * compliment of the number of remaining pairs of elements to be checked in
     * the tail of the two arrays.

Unless you change the contract (so it is mandated to check all elements), I don't see how you can simplify checks at call sites.

But another question is do we really want to do so? It forces intrinsics on all platforms to fully process input arrays which may introduce unnecessary complexity. Alternatively, you can introduce a wrapper which handles tail processing in Java.

Thanks for the review. A couple of clarifications:

The proposed change does not break the existing contract. If all elements are checked and no mismatch is found, returning -1 is fully consistent with the current JavaDoc specification. Existing call sites continue to work correctly without any modification — the changes to current JDK call sites are merely simplifications that take advantage of the stronger guarantee.

In practice, x86_64 is the only platform that provides an intrinsic for this method today, and it already processes all elements. I noticed this behavioral discrepancy while working on a RISC-V intrinsic for it. From the RISC-V perspective, scanning all elements is actually the simpler approach to implement.

@iwanowww

iwanowww commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

the changes to current JDK call sites are merely simplifications that take advantage of the stronger guarantee.

How do you get stronger guarantees? Is it based solely on implementation-specific observations that the intrinsics always perform full scan over the arrays? If ArraysSupport.vectorizedMismatch() is allowed to perform partial comparison by the spec (and report non-zero count of remaining elements), then I don't see how you can drop the check at call sites.

@kuaiwei

kuaiwei commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

The call sites I modified are within the OpenJDK codebase itself, so they can be updated in the same PR to match the new spec.

To clarify the compatibility concern, here's the typical pattern for old spec:

int i = vectorizedMismatch(...);
if (i >= 0) {
    return i; // mismatch found
} else {
    i = length - ~i;
}
for (; i < length; i++) {
    if (a[i] != b[i])
        return i;
}
return -1; // no mismatch

Under the new behavior, vectorizedMismatch returns -1. This gives i = length - ~(-1) = length, so the for loop condition i < length is immediately false and the loop body is skipped. In other words, existing call sites that follow the old spec continue to work correctly — the tail loop becomes a no-op.

@kuaiwei

kuaiwei commented Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Hi @iwanowww, I think the spec can remain unchanged. The current spec does not limit a full scan or a partial scan — this is implementation-dependent. So the proposal is simply to align the Java implementation with the existing x86_64 intrinsic behavior, making them consistent without any spec changes. How do you think about it ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core-libs core-libs-dev@openjdk.org hotspot-compiler hotspot-compiler-dev@openjdk.org nio nio-dev@openjdk.org rfr Pull request is ready for review

Development

Successfully merging this pull request may close these issues.

2 participants