On Wed, 13 Aug 2025 10:08:33 GMT, Per Minborg <pminb...@openjdk.org> wrote:

>> This PR proposes to use overlapping memory areas in 
>> `SegmentBulkOperations::copy`, similar to what is proposed for 
>> `SegmentBulkOperations::fill` in https://github.com/openjdk/jdk/pull/25383.
>> 
>> This PR passes `tier1`, `tier2`, and `tier3`testing on multiple platforms.
>
> Per Minborg has updated the pull request with a new target base due to a 
> merge or a rebase. The incremental webrev excludes the unrelated changes 
> brought in by the merge/rebase. The pull request contains 12 additional 
> commits since the last revision:
> 
>  - Revert comment
>  - Revert change in AMSI
>  - Back paddle on the branchless overlap method
>  - Merge branch 'master' into copy-overlap
>  - Fix comment
>  - Simplify
>  - Update copyright year
>  - Add a branchless overlaps method
>  - Optimize copy for certain lengths
>  - Add methods to ScopedMemoryAccess
>  - ... and 2 more: https://git.openjdk.org/jdk/compare/b0f898b5...1a1606e2

If I see this right, it could be that we duplicate the copy on a byte. If we 
only copy 2 bytes, then the copy on the second byte is repeated:

src[0] -> dst[0]
src[1] -> dst[1]
src[1] -> dst[1]

But is that ok?

Assume we have threads 1 and 2, both access memory locations A and B:

// Initial state
A = x;
B = y;

// Concurrently:
1: B = A;
2: A = B + 1;

What states could be observed at the end? We could look at all permutations of 
the 4 operations from threads 1 and 2. Let's call the operations 1.1 (1 loads 
A), 1.2 (1 stores B), 2.1 (2 loads B), 2.2 (2 stores A).
These are the 4! / 4 = 6 possible permutations, together with the results for A 
and B:

1.1 1.2 2.1 2.2 -> A = x+1; B = x
1.1 2.1 1.2 2.2 -> A = y+1; B = x
1.1 2.1 2.2 1.2 -> A = y+1; B = x
2.1 1.1 1.2 2.2 -> A = y+1; B = x
2.1 1.1 2.2 1.2 -> A = y+1; B = x
2.1 2.2 1.1 1.2 -> A = y+1; B = y+1

Now assume we repeat the copy for thread 1. Thus, this could happen:

1: B = A;
2: A = B + 1;
1: B = A; // repeated copy

And if it happens in this sequence, we get result:
`A = x+1; B = x+1`
But this result was not observable before.

That makes me wonder if repeating the copy is really allowed in the Java memory 
model?

src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java 
line 156:

> 154:         // `putByte()` below is enough as 3 is the maximum number of 
> bytes covered
> 155:         final byte b = SCOPED_MEMORY_ACCESS.getByte(srcSession, 
> src.unsafeGetBase(), src.unsafeGetOffset() + srcOffset + len - Byte.BYTES);
> 156:         SCOPED_MEMORY_ACCESS.putByte(dstSession, dst.unsafeGetBase(), 
> dst.unsafeGetOffset() + dstOffset + len - Byte.BYTES, b);

Are these duplications of operations really ok? Do you have a good argument for 
that?

-------------

PR Review: https://git.openjdk.org/jdk/pull/26672#pullrequestreview-3115657763
PR Review Comment: https://git.openjdk.org/jdk/pull/26672#discussion_r2273228594

Reply via email to