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 if (length > 7) { 37 if (a.get(aOff) != b.get(bOff)) 38 return 0; 39 i = ArraysSupport.vectorizedMismatch( 40 a.base(), a.address + aOff, 41 b.base(), b.address + bOff, 42 length, 43 ArraysSupport.LOG2_ARRAY_BYTE_INDEX_SCALE); 44 if (i >= 0) return i; 45 i = length - ~i; 46 } 47 for (; i < length; i++) { 48 if (a.get(aOff + i) != b.get(bOff + i)) 49 return i; 50 } 51 return -1; 52 } 53 mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length)54 static int mismatch(CharBuffer a, int aOff, CharBuffer b, int bOff, int length) { 55 int i = 0; 56 // Ensure only heap or off-heap buffer instances use the 57 // vectorized mismatch. If either buffer is a StringCharBuffer 58 // (order is null) then the slow path is taken 59 if (length > 3 && a.charRegionOrder() == b.charRegionOrder() 60 && a.charRegionOrder() != null && b.charRegionOrder() != null) { 61 if (a.get(aOff) != b.get(bOff)) 62 return 0; 63 i = ArraysSupport.vectorizedMismatch( 64 a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE), 65 b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE), 66 length, 67 ArraysSupport.LOG2_ARRAY_CHAR_INDEX_SCALE); 68 if (i >= 0) return i; 69 i = length - ~i; 70 } 71 for (; i < length; i++) { 72 if (a.get(aOff + i) != b.get(bOff + i)) 73 return i; 74 } 75 return -1; 76 } 77 mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length)78 static int mismatch(ShortBuffer a, int aOff, ShortBuffer b, int bOff, int length) { 79 int i = 0; 80 if (length > 3 && a.order() == b.order()) { 81 if (a.get(aOff) != b.get(bOff)) 82 return 0; 83 i = ArraysSupport.vectorizedMismatch( 84 a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE), 85 b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE), 86 length, 87 ArraysSupport.LOG2_ARRAY_SHORT_INDEX_SCALE); 88 if (i >= 0) return i; 89 i = length - ~i; 90 } 91 for (; i < length; i++) { 92 if (a.get(aOff + i) != b.get(bOff + i)) 93 return i; 94 } 95 return -1; 96 } 97 mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length)98 static int mismatch(IntBuffer a, int aOff, IntBuffer b, int bOff, int length) { 99 int i = 0; 100 if (length > 1 && a.order() == b.order()) { 101 if (a.get(aOff) != b.get(bOff)) 102 return 0; 103 i = ArraysSupport.vectorizedMismatch( 104 a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE), 105 b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE), 106 length, 107 ArraysSupport.LOG2_ARRAY_INT_INDEX_SCALE); 108 if (i >= 0) return i; 109 i = length - ~i; 110 } 111 for (; i < length; i++) { 112 if (a.get(aOff + i) != b.get(bOff + i)) 113 return i; 114 } 115 return -1; 116 } 117 mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length)118 static int mismatch(FloatBuffer a, int aOff, FloatBuffer b, int bOff, int length) { 119 int i = 0; 120 if (length > 1 && a.order() == b.order()) { 121 if (Float.floatToRawIntBits(a.get(aOff)) == Float.floatToRawIntBits(b.get(bOff))) { 122 i = ArraysSupport.vectorizedMismatch( 123 a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE), 124 b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE), 125 length, 126 ArraysSupport.LOG2_ARRAY_FLOAT_INDEX_SCALE); 127 } 128 // Mismatched 129 if (i >= 0) { 130 // Check if mismatch is not associated with two NaN values; and 131 // is not associated with +0 and -0 132 float av = a.get(aOff + i); 133 float bv = b.get(bOff + i); 134 if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv))) 135 return i; 136 137 // Fall back to slow mechanism 138 // ISSUE: Consider looping over vectorizedMismatch adjusting ranges 139 // However, requires that returned value be relative to input ranges 140 i++; 141 } 142 // Matched 143 else { 144 i = length - ~i; 145 } 146 } 147 for (; i < length; i++) { 148 float av = a.get(aOff + i); 149 float bv = b.get(bOff + i); 150 if (av != bv && (!Float.isNaN(av) || !Float.isNaN(bv))) 151 return i; 152 } 153 return -1; 154 } 155 mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length)156 static int mismatch(LongBuffer a, int aOff, LongBuffer b, int bOff, int length) { 157 int i = 0; 158 if (length > 0 && a.order() == b.order()) { 159 if (a.get(aOff) != b.get(bOff)) 160 return 0; 161 i = ArraysSupport.vectorizedMismatch( 162 a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE), 163 b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE), 164 length, 165 ArraysSupport.LOG2_ARRAY_LONG_INDEX_SCALE); 166 return i >= 0 ? i : -1; 167 } 168 for (; i < length; i++) { 169 if (a.get(aOff + i) != b.get(bOff + i)) 170 return i; 171 } 172 return -1; 173 } 174 mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length)175 static int mismatch(DoubleBuffer a, int aOff, DoubleBuffer b, int bOff, int length) { 176 int i = 0; 177 if (length > 0 && a.order() == b.order()) { 178 if (Double.doubleToRawLongBits(a.get(aOff)) == Double.doubleToRawLongBits(b.get(bOff))) { 179 i = ArraysSupport.vectorizedMismatch( 180 a.base(), a.address + (aOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE), 181 b.base(), b.address + (bOff << ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE), 182 length, 183 ArraysSupport.LOG2_ARRAY_DOUBLE_INDEX_SCALE); 184 } 185 // Mismatched 186 if (i >= 0) { 187 // Check if mismatch is not associated with two NaN values; and 188 // is not associated with +0 and -0 189 double av = a.get(aOff + i); 190 double bv = b.get(bOff + i); 191 if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv))) 192 return i; 193 194 // Fall back to slow mechanism 195 // ISSUE: Consider looping over vectorizedMismatch adjusting ranges 196 // However, requires that returned value be relative to input ranges 197 i++; 198 } 199 // Matched 200 else { 201 return -1; 202 } 203 } 204 for (; i < length; i++) { 205 double av = a.get(aOff + i); 206 double bv = b.get(bOff + i); 207 if (av != bv && (!Double.isNaN(av) || !Double.isNaN(bv))) 208 return i; 209 } 210 return -1; 211 } 212 } 213