@@ -42,6 +42,25 @@ public class TestCharTermAttributeImplBufferWriter : LuceneTestCase
4242 // LUCENENET specific: 10 is MIN_BUFFER_SIZE, but it gets oversized
4343 private static readonly int DefaultBufferSize = ArrayUtil . Oversize ( 10 , RamUsageEstimator . NUM_BYTES_CHAR ) ;
4444
45+ // LUCENENET specific: works around a .NET Framework x64 RyuJIT bug where
46+ // ReadOnlyMemory<char>.Span returns an empty span when the property is read
47+ // inline on a local inside a large method (it only reproduces with the
48+ // System.Memory polyfill; modern .NET is unaffected). Forcing the .Span read
49+ // into its own non-inlined method makes the JIT compile it correctly. These
50+ // helpers preserve the original assertion intent (comparing the Memory view
51+ // against the Span view) on all target frameworks.
52+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
53+ private static bool SpanEqualsMemory ( ReadOnlySpan < char > span , ReadOnlyMemory < char > memory )
54+ => span . SequenceEqual ( memory . Span ) ;
55+
56+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
57+ private static bool MemoryEqualsMemory ( ReadOnlyMemory < char > a , ReadOnlyMemory < char > b )
58+ => a . Span . SequenceEqual ( b . Span ) ;
59+
60+ [ MethodImpl ( MethodImplOptions . NoInlining ) ]
61+ private static char MemoryElementAt ( ReadOnlyMemory < char > memory , int index )
62+ => memory . Span [ index ] ;
63+
4564 // LUCENENET specific: note that Clear behaves more like a Reset, which resets the position without clearing the
4665 // buffer. so this test looks a lot more like the ResetWrittenCount in ArrayBufferWriter tests, than Clear.
4766 [ Test ]
@@ -53,22 +72,22 @@ public void Clear()
5372 Assert . True ( output . FreeCapacity < previousAvailable ) ;
5473 Assert . True ( output . Length > 0 ) ;
5574 Assert . False ( ReadOnlySpan < char > . Empty . SequenceEqual ( output . AsSpan ( ) ) ) ;
56- Assert . False ( ReadOnlyMemory < char > . Empty . Span . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
57- Assert . True ( output . AsSpan ( ) . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
75+ Assert . False ( MemoryEqualsMemory ( ReadOnlyMemory < char > . Empty , output . AsMemory ( ) ) ) ;
76+ Assert . True ( SpanEqualsMemory ( output . AsSpan ( ) , output . AsMemory ( ) ) ) ;
5877
5978 ReadOnlyMemory < char > transientMemory = output . AsMemory ( ) ;
6079 ReadOnlySpan < char > transientSpan = output . AsSpan ( ) ;
61- char t0 = transientMemory . Span [ 0 ] ;
80+ char t0 = MemoryElementAt ( transientMemory , 0 ) ;
6281 char t1 = transientSpan [ 1 ] ;
6382 Assert . AreNotEqual ( DefaultChar , t0 ) ;
6483 Assert . AreNotEqual ( DefaultChar , t1 ) ;
6584 output . Clear ( ) ;
66- Assert . AreEqual ( t0 , transientMemory . Span [ 0 ] ) ;
85+ Assert . AreEqual ( t0 , MemoryElementAt ( transientMemory , 0 ) ) ;
6786 Assert . AreEqual ( t1 , transientSpan [ 1 ] ) ;
6887
6988 Assert . AreEqual ( 0 , output . Length ) ;
7089 Assert . True ( ReadOnlySpan < char > . Empty . SequenceEqual ( output . AsSpan ( ) ) ) ;
71- Assert . True ( ReadOnlyMemory < char > . Empty . Span . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
90+ Assert . True ( MemoryEqualsMemory ( ReadOnlyMemory < char > . Empty , output . AsMemory ( ) ) ) ;
7291 Assert . AreEqual ( previousAvailable , output . FreeCapacity ) ;
7392 }
7493
@@ -82,22 +101,22 @@ public void SetLengthToZero()
82101 Assert . True ( output . FreeCapacity < previousAvailable ) ;
83102 Assert . True ( output . Length > 0 ) ;
84103 Assert . False ( ReadOnlySpan < char > . Empty . SequenceEqual ( output . AsSpan ( ) ) ) ;
85- Assert . False ( ReadOnlyMemory < char > . Empty . Span . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
86- Assert . True ( output . AsSpan ( ) . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
104+ Assert . False ( MemoryEqualsMemory ( ReadOnlyMemory < char > . Empty , output . AsMemory ( ) ) ) ;
105+ Assert . True ( SpanEqualsMemory ( output . AsSpan ( ) , output . AsMemory ( ) ) ) ;
87106
88107 ReadOnlyMemory < char > transientMemory = output . AsMemory ( ) ;
89108 ReadOnlySpan < char > transientSpan = output . AsSpan ( ) ;
90- char t0 = transientMemory . Span [ 0 ] ;
109+ char t0 = MemoryElementAt ( transientMemory , 0 ) ;
91110 char t1 = transientSpan [ 1 ] ;
92111 Assert . AreNotEqual ( DefaultChar , t0 ) ;
93112 Assert . AreNotEqual ( DefaultChar , t1 ) ;
94113 output . Length = 0 ;
95- Assert . AreEqual ( t0 , transientMemory . Span [ 0 ] ) ;
114+ Assert . AreEqual ( t0 , MemoryElementAt ( transientMemory , 0 ) ) ;
96115 Assert . AreEqual ( t1 , transientSpan [ 1 ] ) ;
97116
98117 Assert . AreEqual ( 0 , output . Length ) ;
99118 Assert . True ( ReadOnlySpan < char > . Empty . SequenceEqual ( output . AsSpan ( ) ) ) ;
100- Assert . True ( ReadOnlyMemory < char > . Empty . Span . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
119+ Assert . True ( MemoryEqualsMemory ( ReadOnlyMemory < char > . Empty , output . AsMemory ( ) ) ) ;
101120 Assert . AreEqual ( previousAvailable , output . FreeCapacity ) ;
102121 }
103122
@@ -128,11 +147,11 @@ public void Advance()
128147 WriteData ( output , 2 ) ;
129148 ReadOnlyMemory < char > previousMemory = output . AsMemory ( ) ;
130149 ReadOnlySpan < char > previousSpan = output . AsSpan ( ) ;
131- Assert . True ( previousSpan . SequenceEqual ( previousMemory . Span ) ) ;
150+ Assert . True ( SpanEqualsMemory ( previousSpan , previousMemory ) ) ;
132151 output . Advance ( 10 ) ;
133- Assert . False ( previousMemory . Span . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
152+ Assert . False ( MemoryEqualsMemory ( previousMemory , output . AsMemory ( ) ) ) ;
134153 Assert . False ( previousSpan . SequenceEqual ( output . AsSpan ( ) ) ) ;
135- Assert . True ( output . AsSpan ( ) . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
154+ Assert . True ( SpanEqualsMemory ( output . AsSpan ( ) , output . AsMemory ( ) ) ) ;
136155 }
137156
138157 {
@@ -141,12 +160,12 @@ public void Advance()
141160 WriteData ( output , 10 ) ;
142161 ReadOnlyMemory < char > previousMemory = output . AsMemory ( ) ;
143162 ReadOnlySpan < char > previousSpan = output . AsSpan ( ) ;
144- Assert . True ( previousSpan . SequenceEqual ( previousMemory . Span ) ) ;
163+ Assert . True ( SpanEqualsMemory ( previousSpan , previousMemory ) ) ;
145164 Assert . Throws < InvalidOperationException > ( ( ) => output . Advance ( 247 ) ) ;
146165 output . Advance ( 10 ) ;
147- Assert . False ( previousMemory . Span . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
166+ Assert . False ( MemoryEqualsMemory ( previousMemory , output . AsMemory ( ) ) ) ;
148167 Assert . False ( previousSpan . SequenceEqual ( output . AsSpan ( ) ) ) ;
149- Assert . True ( output . AsSpan ( ) . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
168+ Assert . True ( SpanEqualsMemory ( output . AsSpan ( ) , output . AsMemory ( ) ) ) ;
150169 }
151170 }
152171
@@ -158,12 +177,12 @@ public void AdvanceZero()
158177 Assert . AreEqual ( 2 , output . Length ) ;
159178 ReadOnlyMemory < char > previousMemory = output . AsMemory ( ) ;
160179 ReadOnlySpan < char > previousSpan = output . AsSpan ( ) ;
161- Assert . True ( previousSpan . SequenceEqual ( previousMemory . Span ) ) ;
180+ Assert . True ( SpanEqualsMemory ( previousSpan , previousMemory ) ) ;
162181 output . Advance ( 0 ) ;
163182 Assert . AreEqual ( 2 , output . Length ) ;
164- Assert . True ( previousMemory . Span . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
183+ Assert . True ( MemoryEqualsMemory ( previousMemory , output . AsMemory ( ) ) ) ;
165184 Assert . True ( previousSpan . SequenceEqual ( output . AsSpan ( ) ) ) ;
166- Assert . True ( output . AsSpan ( ) . SequenceEqual ( output . AsMemory ( ) . Span ) ) ;
185+ Assert . True ( SpanEqualsMemory ( output . AsSpan ( ) , output . AsMemory ( ) ) ) ;
167186 }
168187
169188 [ Test ]
@@ -291,7 +310,7 @@ public void GetMemoryAndSpan()
291310 WriteData ( output , 2 ) ;
292311 ReadOnlyMemory < char > writtenSoFarMemory = output . AsMemory ( ) ;
293312 ReadOnlySpan < char > writtenSoFar = output . AsSpan ( ) ;
294- Assert . True ( writtenSoFarMemory . Span . SequenceEqual ( writtenSoFar ) ) ;
313+ Assert . True ( SpanEqualsMemory ( writtenSoFar , writtenSoFarMemory ) ) ;
295314 int previousAvailable = output . FreeCapacity ;
296315 Span < char > span = output . GetSpan ( 500 ) ;
297316 Assert . True ( span . Length >= 500 ) ;
0 commit comments