1 /*
2  * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package java.nio;
26 
27 import jdk.internal.util.ArraysSupport;
28 
29 /**
30  * Mismatch methods for buffers
31  */
32 final class BufferMismatch {
33 
mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length)34     static int mismatch(ByteBuffer a, int aOff, ByteBuffer b, int bOff, int length) {
35         int i = 0;
36         // Android-removed: Disable vectorized match until http://b/305287555 is fixed.
37         /*
38         if (length > 7) {
39             if (a.get(aOff) != b.get(bOff))
40                 return 0;
41             i = ArraysSupport.vectorizedMismatch(
42                     a.base(), a.address + aOff,
43                     b.base(), b.address + bOff,
44                     length,
45                     ArraysSupport.LOG2_ARRAY_BYTE_INDEX_SCALE);
46             if (i >= 0) return i;
47             i = length - ~i;
48         }
49         */
50         for (; i < length; i++) {
51             if (a.get(aOff + i) != b.get(bOff + i))
52                 return i;
53         }
54         return -1;
55     }
56 
mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length)57     static int mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length) {
58         int i = 0;
59         // Ensure only heap or off-heap buffer instances use the
60         // vectorized mismatch. If either buffer is a StringCharBuffer
61         // (order is null) then the slow path is taken
62         // Android-removed: Disable vectorized match until http://b/305287555 is fixed.
63         /*
64         if (length > 3 && a.charRegionOrder() == b.charRegionOrder()
65             && a.charRegionOrder() != null && b.charRegionOrder() != null) {
66             if (a.get(aOff) != b.get(bOff))
67                 return 0;
68             i = ArraysSupport.vectorizedMismatch(
69                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
70                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE),
71                     length,
72                     ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE);
73             if (i >= 0) return i;
74             i = length - ~i;
75         }
76         */
77         for (; i < length; i++) {
78             if (a.get(aOff + i) != b.get(bOff + i))
79                 return i;
80         }
81         return -1;
82     }
83 
mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length)84     static int mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length) {
85         int i = 0;
86         // Android-removed: Disable vectorized match until http://b/305287555 is fixed.
87         /*
88         if (length > 3 && a.order() == b.order()) {
89             if (a.get(aOff) != b.get(bOff))
90                 return 0;
91             i = ArraysSupport.vectorizedMismatch(
92                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
93                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE),
94                     length,
95                     ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE);
96             if (i >= 0) return i;
97             i = length - ~i;
98         }
99         */
100         for (; i < length; i++) {
101             if (a.get(aOff + i) != b.get(bOff + i))
102                 return i;
103         }
104         return -1;
105     }
106 
mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length)107     static int mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length) {
108         int i = 0;
109         // Android-removed: Disable vectorized match until http://b/305287555 is fixed.
110         /*
111         if (length > 1 && a.order() == b.order()) {
112             if (a.get(aOff) != b.get(bOff))
113                 return 0;
114             i = ArraysSupport.vectorizedMismatch(
115                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
116                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE),
117                     length,
118                     ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE);
119             if (i >= 0) return i;
120             i = length - ~i;
121         }
122         */
123         for (; i < length; i++) {
124             if (a.get(aOff + i) != b.get(bOff + i))
125                 return i;
126         }
127         return -1;
128     }
129 
mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length)130     static int mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length) {
131         int i = 0;
132         // Android-removed: Disable vectorized match until http://b/305287555 is fixed.
133         /*
134         if (length > 1 && a.order() == b.order()) {
135             if (Float.floatToRawIntBits(a.get(aOff)) == Float.floatToRawIntBits(b.get(bOff))) {
136                 i = ArraysSupport.vectorizedMismatch(
137                         a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
138                         b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE),
139                         length,
140                         ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE);
141             }
142             // Mismatched
143             if (i >= 0) {
144                 // Check if mismatch is not associated with two NaN values; and
145                 // is not associated with +0 and -0
146                 float av = a.get(aOff + i);
147                 float bv = b.get(bOff + i);
148                 if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
149                     return i;
150 
151                 // Fall back to slow mechanism
152                 // ISSUE: Consider looping over vectorizedMismatch adjusting ranges
153                 // However, requires that returned value be relative to input ranges
154                 i++;
155             }
156             // Matched
157             else {
158                 i = length - ~i;
159             }
160         }
161         */
162         for (; i < length; i++) {
163             float av = a.get(aOff + i);
164             float bv = b.get(bOff + i);
165             if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv)))
166                 return i;
167         }
168         return -1;
169     }
170 
mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length)171     static int mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length) {
172         int i = 0;
173         // Android-removed: Disable vectorized match until http://b/305287555 is fixed.
174         /*
175         if (length > 0 && a.order() == b.order()) {
176             if (a.get(aOff) != b.get(bOff))
177                 return 0;
178             i = ArraysSupport.vectorizedMismatch(
179                     a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
180                     b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE),
181                     length,
182                     ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE);
183             return i >= 0 ? i : -1;
184         }
185         */
186         for (; i < length; i++) {
187             if (a.get(aOff + i) != b.get(bOff + i))
188                 return i;
189         }
190         return -1;
191     }
192 
mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length)193     static int mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length) {
194         int i = 0;
195         // Android-removed: Disable vectorized match until http://b/305287555 is fixed.
196         /*
197         if (length > 0 && a.order() == b.order()) {
198             if (Double.doubleToRawLongBits(a.get(aOff)) == Double.doubleToRawLongBits(b.get(bOff))) {
199                 i = ArraysSupport.vectorizedMismatch(
200                         a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
201                         b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE),
202                         length,
203                         ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE);
204             }
205             // Mismatched
206             if (i >= 0) {
207                 // Check if mismatch is not associated with two NaN values; and
208                 // is not associated with +0 and -0
209                 double av = a.get(aOff + i);
210                 double bv = b.get(bOff + i);
211                 if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
212                     return i;
213 
214                 // Fall back to slow mechanism
215                 // ISSUE: Consider looping over vectorizedMismatch adjusting ranges
216                 // However, requires that returned value be relative to input ranges
217                 i++;
218             }
219             // Matched
220             else {
221                 return -1;
222             }
223         }
224         */
225         for (; i < length; i++) {
226             double av = a.get(aOff + i);
227             double bv = b.get(bOff + i);
228             if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv)))
229                 return i;
230         }
231         return -1;
232     }
233 }
234