On Wed, 13 Aug 2025 12:29:28 GMT, Emanuel Peter <epe...@openjdk.org> wrote:
>> 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/6f6585fd...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? > We have discussed the possibility of threads seeing different values, like in > the above example by @eme64. We think this is ok because there are no > guarantees of inter-thread visibility for memory segments. This has to be > provided externally (e.g., using volatile/CAS operations). There are other > cases where we are susceptible to similar problems (e.g, when doing unaligned > long access). In short, segments do not fulfill all the aspects of the normal > Java memory model (like for arrays). Hmm, I see. Is this documented in the `MemorySegment` API? What are all the bad things that can happen? - Tearing of unaligned access - can it also tear if the user has ensured alignment? - Repeated instructions (like the repeated copy I pointed out above). It is of course a little surprising that you lose the Java memory model guarantees of instruction ordering if you wrap an array in a `MemorySegment`. ------------- PR Comment: https://git.openjdk.org/jdk/pull/26672#issuecomment-3184127780