Pitfall (unspecified?) behavior of MemorySegment.mismatch. JDK 21

Jorn Vernee jorn.vernee at oracle.com
Wed Jan 10 13:38:30 UTC 2024


Hey Roman,

I agree with you that this looks like a bug. I can reproduce it here as 
well (thanks for the nice reproducer!). The check fails to take the 
offsets passed to mismatch into account. Previously we only had the 
instance mismatch method, for which this check would have been correct. 
However, when offsets are involved, it is not.

Thanks for reporting this! I have filed: 
https://bugs.openjdk.org/browse/JDK-8323524

As a workaround, you could create slices first and then compare those 
using the instance mismatch method:

long mismatch = memory.asSlice(searchTermOffset, 
len).mismatch(memory.asSlice(checkOffset, len));

Jorn

On 10/01/2024 13:33, Roman Stoffel wrote:
> Hi
>
> First, I'm not sure if I am at the right place, let me know if I'm wrong.
>
> I was trying to compare different sections of Memory and used 
> MemorySegment.mismatch.
> My program got unexpected results and failed.
>
> The issue boiled down to that I compared the same MemorySegment with 
> itself, but on different range. Example program, which demonstrates 
> the issue:
>
> public class UnexpectedMismatchBehavior {
>      public static void main(String[]args) {
>          byte[]exampleData =new byte[]{1,2,3,4,
>                  -1, -1, -1, -1,
>                  1,2,8,8,
>                  -1, -1, -1, -1};
>          // In the real world, this is a large memory mapped file MemorySegment 
> memory =MemorySegment.ofArray(exampleData);
>          // In the real app these are of course dynamic int searchTermOffset =0;
>          int len =4;
>
>          int checkOffset =8;
>
>          long missMatch =MemorySegment.mismatch(memory,searchTermOffset,searchTermOffset+len,memory,checkOffset,checkOffset+len);
>          int debug =Arrays.mismatch(exampleData,searchTermOffset,searchTermOffset+len,exampleData,checkOffset,checkOffset+len);
>          if(missMatch == -1){
>              System.out.println("Unexpected match!!!");
>              System.out.println("Array.mismatch gives: " +debug);
>              throw new Exception("What, should not match?");
>          }else{
>              System.out.println("Missmatch, as expected");
>          }
>      }
> }
>
> Overall, I would expect the same behavior as Arrays.missmatch.
>
> The cuprid seems this check in the implementation:
> AbstractMemorySegmentImpl.mismatch(...) ...
> if (dstImpl ==srcImpl) {
>      srcImpl.checkValidState();
>      return -1;
> }
>
> The current behavior is in my opinion problementatic.
> I consider it a bug. Because I get the same return value as if there would be no match, the program
> continues on with the wrong value.
>
> What would instead expect:
> - Best would be if it behaves like Arrays.missmatch
> - Second best option: It throws an exception.
> - Last option: Mention the limitation in the JavaDoc: But still many bugs will be written because
>    the 'fine' print isn't read.
>
> Best regards
> Roman Stoffel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/panama-dev/attachments/20240110/b6adf980/attachment-0001.htm>


More information about the panama-dev mailing list