334 |
334 |
335 out.println(); |
335 out.println(); |
336 |
336 |
337 } |
337 } |
338 |
338 |
|
339 private static void testAlign(final ByteBuffer b, boolean direct) { |
|
340 // index out-of bounds |
|
341 tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(-1, (short) 1)); |
|
342 |
|
343 // unit size values |
|
344 tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, (short) 0)); |
|
345 for (int us = 1; us < 65; us++) { |
|
346 int _us = us; |
|
347 if ((us & (us - 1)) != 0) { |
|
348 // unit size not a power of two |
|
349 tryCatch(b, IllegalArgumentException.class, () -> b.alignmentOffset(0, _us)); |
|
350 } else { |
|
351 if (direct || us <= 8) { |
|
352 b.alignmentOffset(0, us); |
|
353 } else { |
|
354 // unit size > 8 with non-direct buffer |
|
355 tryCatch(b, UnsupportedOperationException.class, () -> b.alignmentOffset(0, _us)); |
|
356 } |
|
357 } |
|
358 } |
|
359 |
|
360 // Probe for long misalignment at index zero for a newly created buffer |
|
361 ByteBuffer empty = direct ? ByteBuffer.allocateDirect(0) : ByteBuffer.allocate(0); |
|
362 int longMisalignmentAtZero = empty.alignmentOffset(0, 8); |
|
363 |
|
364 if (direct) { |
|
365 // Freshly created direct byte buffers should be aligned at index 0 |
|
366 // for ref and primitive values (see Unsafe.allocateMemory) |
|
367 if (longMisalignmentAtZero != 0) |
|
368 fail("Direct byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); |
|
369 } else { |
|
370 // For heap byte buffers misalignment may occur on 32-bit systems |
|
371 // where Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 == 4 and not 0 |
|
372 // Note the GC will preserve alignment of the base address of the |
|
373 // array |
|
374 if (jdk.internal.misc.Unsafe.ARRAY_BYTE_BASE_OFFSET % 8 != longMisalignmentAtZero) |
|
375 fail("Heap byte buffer misalligned at index 0 for ref and primitive values " + longMisalignmentAtZero); |
|
376 } |
|
377 |
|
378 // Ensure test buffer is correctly aligned at index 0 |
|
379 if (b.alignmentOffset(0, 8) != longMisalignmentAtZero) |
|
380 fail("Test input buffer not correctly aligned at index 0", b); |
|
381 |
|
382 // Test misalignment values |
|
383 for (int us : new int[]{1, 2, 4, 8}) { |
|
384 for (int i = 0; i < us * 2; i++) { |
|
385 int am = b.alignmentOffset(i, us); |
|
386 int expectedAm = (longMisalignmentAtZero + i) % us; |
|
387 |
|
388 if (am != expectedAm) |
|
389 fail(String.format("b.alignmentOffset(%d, %d) == %d incorrect, expected %d", i, us, am, expectedAm)); |
|
390 } |
|
391 } |
|
392 |
|
393 // Created aligned slice to test against |
|
394 int ap = 8 - longMisalignmentAtZero; |
|
395 int al = b.limit() - b.alignmentOffset(b.limit(), 8); |
|
396 ByteBuffer ab = b.position(ap).limit(al). |
|
397 slice(); |
|
398 if (ab.limit() == 0) |
|
399 fail("Test input buffer not sufficiently sized to cover an aligned region for all values", b); |
|
400 if (ab.alignmentOffset(0, 8) != 0) |
|
401 fail("Aligned test input buffer not correctly aligned at index 0", ab); |
|
402 |
|
403 for (int us : new int[]{1, 2, 4, 8}) { |
|
404 for (int p = 1; p < 16; p++) { |
|
405 int l = ab.limit() - p; |
|
406 |
|
407 ByteBuffer as = ab.slice().position(p).limit(l). |
|
408 alignedSlice(us); |
|
409 |
|
410 ck(as, 0, as.position()); |
|
411 ck(as, as.capacity(), as.limit()); |
|
412 if (b.isDirect() != as.isDirect()) |
|
413 fail("Lost direction", as); |
|
414 if (b.isReadOnly() != as.isReadOnly()) |
|
415 fail("Lost read-only", as); |
|
416 |
|
417 if (as.alignmentOffset(0, us) != 0) |
|
418 fail("Buffer not correctly aligned at index 0", as); |
|
419 |
|
420 if (as.alignmentOffset(as.limit(), us) != 0) |
|
421 fail("Buffer not correctly aligned at limit", as); |
|
422 |
|
423 int p_mod = ab.alignmentOffset(p, us); |
|
424 int l_mod = ab.alignmentOffset(l, us); |
|
425 // Round up position |
|
426 p = (p_mod > 0) ? p + (us - p_mod) : p; |
|
427 // Round down limit |
|
428 l = l - l_mod; |
|
429 |
|
430 int ec = l - p; |
|
431 if (as.limit() != ec) |
|
432 fail("Buffer capacity incorrect, expected: " + ec, as); |
|
433 } |
|
434 } |
|
435 } |
339 #end[byte] |
436 #end[byte] |
340 |
437 |
341 private static void fail(String problem, |
438 private static void fail(String problem, |
342 $Type$Buffer xb, $Type$Buffer yb, |
439 $Type$Buffer xb, $Type$Buffer yb, |
343 $type$ x, $type$ y) { |
440 $type$ x, $type$ y) { |