148 ? Integer.numberOfLeadingZeros(x) >> (LOG2_BYTE_BIT_SIZE + log2ArrayIndexScale) 149 : Integer.numberOfTrailingZeros(x) >> (LOG2_BYTE_BIT_SIZE + log2ArrayIndexScale); 150 return (wi << log2ValuesPerWidth) + o; 151 } 152 tail -= wordTail; 153 } 154 return ~tail; 155 } 156 else { 157 return ~tail; 158 } 159 } 160 161 // Booleans 162 // Each boolean element takes up one byte 163 164 public static int mismatch(boolean[] a, 165 boolean[] b, 166 int length) { 167 int i = 0; 168 if (length > 7) { 169 i = vectorizedMismatch( 170 a, Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, 171 b, Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, 172 length, LOG2_ARRAY_BOOLEAN_INDEX_SCALE); 173 if (i >= 0) 174 return i; 175 i = length - ~i; 176 } 177 for (; i < length; i++) { 178 if (a[i] != b[i]) 179 return i; 180 } 181 return -1; 182 } 183 184 public static int mismatch(boolean[] a, int aFromIndex, 185 boolean[] b, int bFromIndex, 186 int length) { 187 int i = 0; 188 if (length > 7) { 189 int aOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + aFromIndex; 190 int bOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + bFromIndex; 191 i = vectorizedMismatch( 192 a, aOffset, 193 b, bOffset, 194 length, LOG2_ARRAY_BOOLEAN_INDEX_SCALE); 195 if (i >= 0) 196 return i; 197 i = length - ~i; 198 } 199 for (; i < length; i++) { 200 if (a[aFromIndex + i] != b[bFromIndex + i]) 201 return i; 202 } 203 return -1; 204 } 205 206 207 // Bytes 210 * Find the index of a mismatch between two arrays. 211 * 212 * <p>This method does not perform bounds checks. It is the responsibility 213 * of the caller to perform such bounds checks before calling this method. 214 * 215 * @param a the first array to be tested for a mismatch 216 * @param b the second array to be tested for a mismatch 217 * @param length the number of bytes from each array to check 218 * @return the index of a mismatch between the two arrays, otherwise -1 if 219 * no mismatch. The index will be within the range of (inclusive) 0 to 220 * (exclusive) the smaller of the two array lengths. 221 */ 222 public static int mismatch(byte[] a, 223 byte[] b, 224 int length) { 225 // ISSUE: defer to index receiving methods if performance is good 226 // assert length <= a.length 227 // assert length <= b.length 228 229 int i = 0; 230 if (length > 7) { 231 i = vectorizedMismatch( 232 a, Unsafe.ARRAY_BYTE_BASE_OFFSET, 233 b, Unsafe.ARRAY_BYTE_BASE_OFFSET, 234 length, LOG2_ARRAY_BYTE_INDEX_SCALE); 235 if (i >= 0) 236 return i; 237 // Align to tail 238 i = length - ~i; 239 // assert i >= 0 && i <= 7; 240 } 241 // Tail < 8 bytes 242 for (; i < length; i++) { 243 if (a[i] != b[i]) 244 return i; 245 } 246 return -1; 247 } 248 249 /** 257 * @param aFromIndex the index of the first element (inclusive) in the first 258 * array to be compared 259 * @param b the second array to be tested for a mismatch 260 * @param bFromIndex the index of the first element (inclusive) in the 261 * second array to be compared 262 * @param length the number of bytes from each array to check 263 * @return the relative index of a mismatch between the two arrays, 264 * otherwise -1 if no mismatch. The index will be within the range of 265 * (inclusive) 0 to (exclusive) the smaller of the two array bounds. 266 */ 267 public static int mismatch(byte[] a, int aFromIndex, 268 byte[] b, int bFromIndex, 269 int length) { 270 // assert 0 <= aFromIndex < a.length 271 // assert 0 <= aFromIndex + length <= a.length 272 // assert 0 <= bFromIndex < b.length 273 // assert 0 <= bFromIndex + length <= b.length 274 // assert length >= 0 275 276 int i = 0; 277 if (length > 7) { 278 int aOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + aFromIndex; 279 int bOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + bFromIndex; 280 i = vectorizedMismatch( 281 a, aOffset, 282 b, bOffset, 283 length, LOG2_ARRAY_BYTE_INDEX_SCALE); 284 if (i >= 0) 285 return i; 286 i = length - ~i; 287 } 288 for (; i < length; i++) { 289 if (a[aFromIndex + i] != b[bFromIndex + i]) 290 return i; 291 } 292 return -1; 293 } 294 295 296 // Chars 297 298 public static int mismatch(char[] a, 299 char[] b, 300 int length) { 301 int i = 0; 302 if (length > 3) { 303 i = vectorizedMismatch( 304 a, Unsafe.ARRAY_CHAR_BASE_OFFSET, 305 b, Unsafe.ARRAY_CHAR_BASE_OFFSET, 306 length, LOG2_ARRAY_CHAR_INDEX_SCALE); 307 if (i >= 0) 308 return i; 309 i = length - ~i; 310 } 311 for (; i < length; i++) { 312 if (a[i] != b[i]) 313 return i; 314 } 315 return -1; 316 } 317 318 public static int mismatch(char[] a, int aFromIndex, 319 char[] b, int bFromIndex, 320 int length) { 321 int i = 0; 322 if (length > 3) { 323 int aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); 324 int bOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); 325 i = vectorizedMismatch( 326 a, aOffset, 327 b, bOffset, 328 length, LOG2_ARRAY_CHAR_INDEX_SCALE); 329 if (i >= 0) 330 return i; 331 i = length - ~i; 332 } 333 for (; i < length; i++) { 334 if (a[aFromIndex + i] != b[bFromIndex + i]) 335 return i; 336 } 337 return -1; 338 } 339 340 341 // Shorts 342 343 public static int mismatch(short[] a, 344 short[] b, 345 int length) { 346 int i = 0; 347 if (length > 3) { 348 i = vectorizedMismatch( 349 a, Unsafe.ARRAY_SHORT_BASE_OFFSET, 350 b, Unsafe.ARRAY_SHORT_BASE_OFFSET, 351 length, LOG2_ARRAY_SHORT_INDEX_SCALE); 352 if (i >= 0) 353 return i; 354 i = length - ~i; 355 } 356 for (; i < length; i++) { 357 if (a[i] != b[i]) 358 return i; 359 } 360 return -1; 361 } 362 363 public static int mismatch(short[] a, int aFromIndex, 364 short[] b, int bFromIndex, 365 int length) { 366 int i = 0; 367 if (length > 3) { 368 int aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); 369 int bOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); 370 i = vectorizedMismatch( 371 a, aOffset, 372 b, bOffset, 373 length, LOG2_ARRAY_SHORT_INDEX_SCALE); 374 if (i >= 0) 375 return i; 376 i = length - ~i; 377 } 378 for (; i < length; i++) { 379 if (a[aFromIndex + i] != b[bFromIndex + i]) 380 return i; 381 } 382 return -1; 383 } 384 385 386 // Ints 387 388 public static int mismatch(int[] a, 389 int[] b, 390 int length) { 391 int i = 0; 392 if (length > 1) { 393 i = vectorizedMismatch( 394 a, Unsafe.ARRAY_INT_BASE_OFFSET, 395 b, Unsafe.ARRAY_INT_BASE_OFFSET, 396 length, LOG2_ARRAY_INT_INDEX_SCALE); 397 if (i >= 0) 398 return i; 399 i = length - ~i; 400 } 401 for (; i < length; i++) { 402 if (a[i] != b[i]) 403 return i; 404 } 405 return -1; 406 } 407 408 public static int mismatch(int[] a, int aFromIndex, 409 int[] b, int bFromIndex, 410 int length) { 411 int i = 0; 412 if (length > 1) { 413 int aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); 414 int bOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); 415 i = vectorizedMismatch( 416 a, aOffset, 417 b, bOffset, 418 length, LOG2_ARRAY_INT_INDEX_SCALE); 419 if (i >= 0) 420 return i; 421 i = length - ~i; 422 } 423 for (; i < length; i++) { 424 if (a[aFromIndex + i] != b[bFromIndex + i]) 425 return i; 426 } 427 return -1; 428 } 429 430 431 // Floats 432 433 public static int mismatch(float[] a, 434 float[] b, 435 int length) { 436 return mismatch(a, 0, b, 0, length); 437 } 438 439 public static int mismatch(float[] a, int aFromIndex, 440 float[] b, int bFromIndex, 441 int length) { 442 int i = 0; 443 if (length > 1) { 444 int aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); 445 int bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); 446 i = vectorizedMismatch( 447 a, aOffset, 448 b, bOffset, 449 length, LOG2_ARRAY_FLOAT_INDEX_SCALE); 450 // Mismatched 451 if (i >= 0) { 452 // Check if mismatch is not associated with two NaN values 453 if (!Float.isNaN(a[aFromIndex + i]) || !Float.isNaN(b[bFromIndex + i])) 454 return i; 455 456 // Mismatch on two different NaN values that are normalized to match 457 // Fall back to slow mechanism 458 // ISSUE: Consider looping over vectorizedMismatch adjusting ranges 459 // However, requires that returned value be relative to input ranges 460 i++; 461 } 462 // Matched | 148 ? Integer.numberOfLeadingZeros(x) >> (LOG2_BYTE_BIT_SIZE + log2ArrayIndexScale) 149 : Integer.numberOfTrailingZeros(x) >> (LOG2_BYTE_BIT_SIZE + log2ArrayIndexScale); 150 return (wi << log2ValuesPerWidth) + o; 151 } 152 tail -= wordTail; 153 } 154 return ~tail; 155 } 156 else { 157 return ~tail; 158 } 159 } 160 161 // Booleans 162 // Each boolean element takes up one byte 163 164 public static int mismatch(boolean[] a, 165 boolean[] b, 166 int length) { 167 int i = 0; 168 if (a[i] != b[i]) 169 return i; 170 if (length > 7) { 171 i = vectorizedMismatch( 172 a, Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, 173 b, Unsafe.ARRAY_BOOLEAN_BASE_OFFSET, 174 length, LOG2_ARRAY_BOOLEAN_INDEX_SCALE); 175 if (i >= 0) 176 return i; 177 i = length - ~i; 178 } 179 for (; i < length; i++) { 180 if (a[i] != b[i]) 181 return i; 182 } 183 return -1; 184 } 185 186 public static int mismatch(boolean[] a, int aFromIndex, 187 boolean[] b, int bFromIndex, 188 int length) { 189 int i = 0; 190 if (a[i] != b[i]) 191 return i; 192 if (length > 7) { 193 int aOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + aFromIndex; 194 int bOffset = Unsafe.ARRAY_BOOLEAN_BASE_OFFSET + bFromIndex; 195 i = vectorizedMismatch( 196 a, aOffset, 197 b, bOffset, 198 length, LOG2_ARRAY_BOOLEAN_INDEX_SCALE); 199 if (i >= 0) 200 return i; 201 i = length - ~i; 202 } 203 for (; i < length; i++) { 204 if (a[aFromIndex + i] != b[bFromIndex + i]) 205 return i; 206 } 207 return -1; 208 } 209 210 211 // Bytes 214 * Find the index of a mismatch between two arrays. 215 * 216 * <p>This method does not perform bounds checks. It is the responsibility 217 * of the caller to perform such bounds checks before calling this method. 218 * 219 * @param a the first array to be tested for a mismatch 220 * @param b the second array to be tested for a mismatch 221 * @param length the number of bytes from each array to check 222 * @return the index of a mismatch between the two arrays, otherwise -1 if 223 * no mismatch. The index will be within the range of (inclusive) 0 to 224 * (exclusive) the smaller of the two array lengths. 225 */ 226 public static int mismatch(byte[] a, 227 byte[] b, 228 int length) { 229 // ISSUE: defer to index receiving methods if performance is good 230 // assert length <= a.length 231 // assert length <= b.length 232 233 int i = 0; 234 if (a[i] != b[i]) 235 return i; 236 if (length > 7) { 237 i = vectorizedMismatch( 238 a, Unsafe.ARRAY_BYTE_BASE_OFFSET, 239 b, Unsafe.ARRAY_BYTE_BASE_OFFSET, 240 length, LOG2_ARRAY_BYTE_INDEX_SCALE); 241 if (i >= 0) 242 return i; 243 // Align to tail 244 i = length - ~i; 245 // assert i >= 0 && i <= 7; 246 } 247 // Tail < 8 bytes 248 for (; i < length; i++) { 249 if (a[i] != b[i]) 250 return i; 251 } 252 return -1; 253 } 254 255 /** 263 * @param aFromIndex the index of the first element (inclusive) in the first 264 * array to be compared 265 * @param b the second array to be tested for a mismatch 266 * @param bFromIndex the index of the first element (inclusive) in the 267 * second array to be compared 268 * @param length the number of bytes from each array to check 269 * @return the relative index of a mismatch between the two arrays, 270 * otherwise -1 if no mismatch. The index will be within the range of 271 * (inclusive) 0 to (exclusive) the smaller of the two array bounds. 272 */ 273 public static int mismatch(byte[] a, int aFromIndex, 274 byte[] b, int bFromIndex, 275 int length) { 276 // assert 0 <= aFromIndex < a.length 277 // assert 0 <= aFromIndex + length <= a.length 278 // assert 0 <= bFromIndex < b.length 279 // assert 0 <= bFromIndex + length <= b.length 280 // assert length >= 0 281 282 int i = 0; 283 if (a[i] != b[i]) 284 return i; 285 if (length > 7) { 286 int aOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + aFromIndex; 287 int bOffset = Unsafe.ARRAY_BYTE_BASE_OFFSET + bFromIndex; 288 i = vectorizedMismatch( 289 a, aOffset, 290 b, bOffset, 291 length, LOG2_ARRAY_BYTE_INDEX_SCALE); 292 if (i >= 0) 293 return i; 294 i = length - ~i; 295 } 296 for (; i < length; i++) { 297 if (a[aFromIndex + i] != b[bFromIndex + i]) 298 return i; 299 } 300 return -1; 301 } 302 303 304 // Chars 305 306 public static int mismatch(char[] a, 307 char[] b, 308 int length) { 309 int i = 0; 310 if (a[i] != b[i]) 311 return i; 312 if (length > 3) { 313 i = vectorizedMismatch( 314 a, Unsafe.ARRAY_CHAR_BASE_OFFSET, 315 b, Unsafe.ARRAY_CHAR_BASE_OFFSET, 316 length, LOG2_ARRAY_CHAR_INDEX_SCALE); 317 if (i >= 0) 318 return i; 319 i = length - ~i; 320 } 321 for (; i < length; i++) { 322 if (a[i] != b[i]) 323 return i; 324 } 325 return -1; 326 } 327 328 public static int mismatch(char[] a, int aFromIndex, 329 char[] b, int bFromIndex, 330 int length) { 331 int i = 0; 332 if (a[i] != b[i]) 333 return i; 334 if (length > 3) { 335 int aOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); 336 int bOffset = Unsafe.ARRAY_CHAR_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_CHAR_INDEX_SCALE); 337 i = vectorizedMismatch( 338 a, aOffset, 339 b, bOffset, 340 length, LOG2_ARRAY_CHAR_INDEX_SCALE); 341 if (i >= 0) 342 return i; 343 i = length - ~i; 344 } 345 for (; i < length; i++) { 346 if (a[aFromIndex + i] != b[bFromIndex + i]) 347 return i; 348 } 349 return -1; 350 } 351 352 353 // Shorts 354 355 public static int mismatch(short[] a, 356 short[] b, 357 int length) { 358 int i = 0; 359 if (a[i] != b[i]) 360 return i; 361 if (length > 3) { 362 i = vectorizedMismatch( 363 a, Unsafe.ARRAY_SHORT_BASE_OFFSET, 364 b, Unsafe.ARRAY_SHORT_BASE_OFFSET, 365 length, LOG2_ARRAY_SHORT_INDEX_SCALE); 366 if (i >= 0) 367 return i; 368 i = length - ~i; 369 } 370 for (; i < length; i++) { 371 if (a[i] != b[i]) 372 return i; 373 } 374 return -1; 375 } 376 377 public static int mismatch(short[] a, int aFromIndex, 378 short[] b, int bFromIndex, 379 int length) { 380 int i = 0; 381 if (a[i] != b[i]) 382 return i; 383 if (length > 3) { 384 int aOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); 385 int bOffset = Unsafe.ARRAY_SHORT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_SHORT_INDEX_SCALE); 386 i = vectorizedMismatch( 387 a, aOffset, 388 b, bOffset, 389 length, LOG2_ARRAY_SHORT_INDEX_SCALE); 390 if (i >= 0) 391 return i; 392 i = length - ~i; 393 } 394 for (; i < length; i++) { 395 if (a[aFromIndex + i] != b[bFromIndex + i]) 396 return i; 397 } 398 return -1; 399 } 400 401 402 // Ints 403 404 public static int mismatch(int[] a, 405 int[] b, 406 int length) { 407 int i = 0; 408 if (a[i] != b[i]) 409 return i; 410 if (length > 1) { 411 i = vectorizedMismatch( 412 a, Unsafe.ARRAY_INT_BASE_OFFSET, 413 b, Unsafe.ARRAY_INT_BASE_OFFSET, 414 length, LOG2_ARRAY_INT_INDEX_SCALE); 415 if (i >= 0) 416 return i; 417 i = length - ~i; 418 } 419 for (; i < length; i++) { 420 if (a[i] != b[i]) 421 return i; 422 } 423 return -1; 424 } 425 426 public static int mismatch(int[] a, int aFromIndex, 427 int[] b, int bFromIndex, 428 int length) { 429 int i = 0; 430 if (a[i] != b[i]) 431 return i; 432 if (length > 1) { 433 int aOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); 434 int bOffset = Unsafe.ARRAY_INT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_INT_INDEX_SCALE); 435 i = vectorizedMismatch( 436 a, aOffset, 437 b, bOffset, 438 length, LOG2_ARRAY_INT_INDEX_SCALE); 439 if (i >= 0) 440 return i; 441 i = length - ~i; 442 } 443 for (; i < length; i++) { 444 if (a[aFromIndex + i] != b[bFromIndex + i]) 445 return i; 446 } 447 return -1; 448 } 449 450 451 // Floats 452 453 public static int mismatch(float[] a, 454 float[] b, 455 int length) { 456 return mismatch(a, 0, b, 0, length); 457 } 458 459 public static int mismatch(float[] a, int aFromIndex, 460 float[] b, int bFromIndex, 461 int length) { 462 int i = 0; 463 if (a[i] != b[i]) 464 return i; 465 if (length > 1) { 466 int aOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (aFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); 467 int bOffset = Unsafe.ARRAY_FLOAT_BASE_OFFSET + (bFromIndex << LOG2_ARRAY_FLOAT_INDEX_SCALE); 468 i = vectorizedMismatch( 469 a, aOffset, 470 b, bOffset, 471 length, LOG2_ARRAY_FLOAT_INDEX_SCALE); 472 // Mismatched 473 if (i >= 0) { 474 // Check if mismatch is not associated with two NaN values 475 if (!Float.isNaN(a[aFromIndex + i]) || !Float.isNaN(b[bFromIndex + i])) 476 return i; 477 478 // Mismatch on two different NaN values that are normalized to match 479 // Fall back to slow mechanism 480 // ISSUE: Consider looping over vectorizedMismatch adjusting ranges 481 // However, requires that returned value be relative to input ranges 482 i++; 483 } 484 // Matched |