1 /* 2 * Copyright (c) 2015, 2018, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @compile -XDenableValueTypes Value.java 27 * @run testng/othervm -Xverify:none -Diters=10 -Xint VarHandleTestAccessBoolean 28 */ 29 /* Disabled temporarily for lworld 30 * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 VarHandleTestAccessBoolean 31 * @run testng/othervm -Diters=20000 VarHandleTestAccessBoolean 32 * @run testng/othervm -Diters=20000 -XX:-TieredCompilation VarHandleTestAccessBoolean 33 */ 34 35 import org.testng.annotations.BeforeClass; 36 import org.testng.annotations.DataProvider; 37 import org.testng.annotations.Test; 38 39 import java.lang.invoke.MethodHandles; 40 import java.lang.invoke.VarHandle; 41 import java.util.ArrayList; 42 import java.util.Arrays; 43 import java.util.List; 44 45 import static org.testng.Assert.*; 46 47 public class VarHandleTestAccessBoolean extends VarHandleBaseTest { 48 static final boolean static_final_v = true; 49 50 static boolean static_v; 51 52 final boolean final_v = true; 53 54 boolean v; 55 56 VarHandle vhFinalField; 57 58 VarHandle vhField; 59 60 VarHandle vhStaticField; 61 62 VarHandle vhStaticFinalField; 63 64 VarHandle vhArray; 65 66 VarHandle vhValueTypeField; 67 68 @BeforeClass 69 public void setup() throws Exception { 70 vhFinalField = MethodHandles.lookup().findVarHandle( 71 VarHandleTestAccessBoolean.class, "final_v", boolean.class); 72 73 vhField = MethodHandles.lookup().findVarHandle( 74 VarHandleTestAccessBoolean.class, "v", boolean.class); 75 76 vhStaticFinalField = MethodHandles.lookup().findStaticVarHandle( 77 VarHandleTestAccessBoolean.class, "static_final_v", boolean.class); 78 79 vhStaticField = MethodHandles.lookup().findStaticVarHandle( 80 VarHandleTestAccessBoolean.class, "static_v", boolean.class); 81 82 vhArray = MethodHandles.arrayElementVarHandle(boolean[].class); 83 84 vhValueTypeField = MethodHandles.lookup().findVarHandle( 85 Value.class, "boolean_v", boolean.class); 86 } 87 88 89 @DataProvider 90 public Object[][] varHandlesProvider() throws Exception { 91 List<VarHandle> vhs = new ArrayList<>(); 92 vhs.add(vhField); 93 vhs.add(vhStaticField); 94 vhs.add(vhArray); 95 96 return vhs.stream().map(tc -> new Object[]{tc}).toArray(Object[][]::new); 97 } 98 99 @Test(dataProvider = "varHandlesProvider") 100 public void testIsAccessModeSupported(VarHandle vh) { 101 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET)); 102 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET)); 103 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_VOLATILE)); 104 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_VOLATILE)); 105 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_ACQUIRE)); 106 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_RELEASE)); 107 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_OPAQUE)); 108 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.SET_OPAQUE)); 109 110 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_SET)); 111 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE)); 112 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_ACQUIRE)); 113 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.COMPARE_AND_EXCHANGE_RELEASE)); 114 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_PLAIN)); 115 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET)); 116 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_ACQUIRE)); 117 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.WEAK_COMPARE_AND_SET_RELEASE)); 118 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET)); 119 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_ACQUIRE)); 120 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_SET_RELEASE)); 121 122 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD)); 123 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_ACQUIRE)); 124 assertFalse(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_ADD_RELEASE)); 125 126 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR)); 127 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_ACQUIRE)); 128 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_OR_RELEASE)); 129 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND)); 130 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_ACQUIRE)); 131 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_AND_RELEASE)); 132 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR)); 133 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_ACQUIRE)); 134 assertTrue(vh.isAccessModeSupported(VarHandle.AccessMode.GET_AND_BITWISE_XOR_RELEASE)); 135 } 136 137 138 @DataProvider 139 public Object[][] typesProvider() throws Exception { 140 List<Object[]> types = new ArrayList<>(); 141 types.add(new Object[] {vhField, Arrays.asList(VarHandleTestAccessBoolean.class)}); 142 types.add(new Object[] {vhStaticField, Arrays.asList()}); 143 types.add(new Object[] {vhArray, Arrays.asList(boolean[].class, int.class)}); 144 145 return types.stream().toArray(Object[][]::new); 146 } 147 148 @Test(dataProvider = "typesProvider") 149 public void testTypes(VarHandle vh, List<Class<?>> pts) { 150 assertEquals(vh.varType(), boolean.class); 151 152 assertEquals(vh.coordinateTypes(), pts); 153 154 testTypes(vh); 155 } 156 157 158 @Test 159 public void testLookupInstanceToStatic() { 160 checkIAE("Lookup of static final field to instance final field", () -> { 161 MethodHandles.lookup().findStaticVarHandle( 162 VarHandleTestAccessBoolean.class, "final_v", boolean.class); 163 }); 164 165 checkIAE("Lookup of static field to instance field", () -> { 166 MethodHandles.lookup().findStaticVarHandle( 167 VarHandleTestAccessBoolean.class, "v", boolean.class); 168 }); 169 } 170 171 @Test 172 public void testLookupStaticToInstance() { 173 checkIAE("Lookup of instance final field to static final field", () -> { 174 MethodHandles.lookup().findVarHandle( 175 VarHandleTestAccessBoolean.class, "static_final_v", boolean.class); 176 }); 177 178 checkIAE("Lookup of instance field to static field", () -> { 179 vhStaticField = MethodHandles.lookup().findVarHandle( 180 VarHandleTestAccessBoolean.class, "static_v", boolean.class); 181 }); 182 } 183 184 185 @DataProvider 186 public Object[][] accessTestCaseProvider() throws Exception { 187 List<AccessTestCase<?>> cases = new ArrayList<>(); 188 189 cases.add(new VarHandleAccessTestCase("Instance final field", 190 vhFinalField, vh -> testInstanceFinalField(this, vh))); 191 cases.add(new VarHandleAccessTestCase("Instance final field unsupported", 192 vhFinalField, vh -> testInstanceFinalFieldUnsupported(this, vh), 193 false)); 194 195 cases.add(new VarHandleAccessTestCase("Static final field", 196 vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalField)); 197 cases.add(new VarHandleAccessTestCase("Static final field unsupported", 198 vhStaticFinalField, VarHandleTestAccessBoolean::testStaticFinalFieldUnsupported, 199 false)); 200 201 cases.add(new VarHandleAccessTestCase("Instance field", 202 vhField, vh -> testInstanceField(this, vh))); 203 cases.add(new VarHandleAccessTestCase("Instance field unsupported", 204 vhField, vh -> testInstanceFieldUnsupported(this, vh), 205 false)); 206 207 cases.add(new VarHandleAccessTestCase("Static field", 208 vhStaticField, VarHandleTestAccessBoolean::testStaticField)); 209 cases.add(new VarHandleAccessTestCase("Static field unsupported", 210 vhStaticField, VarHandleTestAccessBoolean::testStaticFieldUnsupported, 211 false)); 212 213 cases.add(new VarHandleAccessTestCase("Array", 214 vhArray, VarHandleTestAccessBoolean::testArray)); 215 cases.add(new VarHandleAccessTestCase("Array unsupported", 216 vhArray, VarHandleTestAccessBoolean::testArrayUnsupported, 217 false)); 218 cases.add(new VarHandleAccessTestCase("Array index out of bounds", 219 vhArray, VarHandleTestAccessBoolean::testArrayIndexOutOfBounds, 220 false)); 221 cases.add(new VarHandleAccessTestCase("Value type field", 222 vhValueTypeField, vh -> testValueTypeField(Value.VT, vh))); 223 cases.add(new VarHandleAccessTestCase("Value type field unsupported", 224 vhValueTypeField, vh -> testValueTypeFieldUnsupported(Value.VT, vh), 225 false)); 226 227 // Work around issue with jtreg summary reporting which truncates 228 // the String result of Object.toString to 30 characters, hence 229 // the first dummy argument 230 return cases.stream().map(tc -> new Object[]{tc.toString(), tc}).toArray(Object[][]::new); 231 } 232 233 @Test(dataProvider = "accessTestCaseProvider") 234 public <T> void testAccess(String desc, AccessTestCase<T> atc) throws Throwable { 235 T t = atc.get(); 236 int iters = atc.requiresLoop() ? ITERS : 1; 237 for (int c = 0; c < iters; c++) { 238 atc.testAccess(t); 239 } 240 } 241 242 243 244 245 static void testInstanceFinalField(VarHandleTestAccessBoolean recv, VarHandle vh) { 246 // Plain 247 { 248 boolean x = (boolean) vh.get(recv); 249 assertEquals(x, true, "get boolean value"); 250 } 251 252 253 // Volatile 254 { 255 boolean x = (boolean) vh.getVolatile(recv); 256 assertEquals(x, true, "getVolatile boolean value"); 257 } 258 259 // Lazy 260 { 261 boolean x = (boolean) vh.getAcquire(recv); 262 assertEquals(x, true, "getRelease boolean value"); 263 } 264 265 // Opaque 266 { 267 boolean x = (boolean) vh.getOpaque(recv); 268 assertEquals(x, true, "getOpaque boolean value"); 269 } 270 } 271 272 static void testInstanceFinalFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) { 273 checkUOE(() -> { 274 vh.set(recv, false); 275 }); 276 277 checkUOE(() -> { 278 vh.setVolatile(recv, false); 279 }); 280 281 checkUOE(() -> { 282 vh.setRelease(recv, false); 283 }); 284 285 checkUOE(() -> { 286 vh.setOpaque(recv, false); 287 }); 288 289 290 checkUOE(() -> { 291 boolean o = (boolean) vh.getAndAdd(recv, true); 292 }); 293 294 checkUOE(() -> { 295 boolean o = (boolean) vh.getAndAddAcquire(recv, true); 296 }); 297 298 checkUOE(() -> { 299 boolean o = (boolean) vh.getAndAddRelease(recv, true); 300 }); 301 302 } 303 304 static void testValueTypeField(Value recv, VarHandle vh) { 305 // Plain 306 { 307 boolean x = (boolean) vh.get(recv); 308 assertEquals(x, true, "get boolean value"); 309 } 310 } 311 312 static void testValueTypeFieldUnsupported(Value recv, VarHandle vh) { 313 checkUOE(() -> { 314 vh.set(recv, false); 315 }); 316 } 317 318 static void testStaticFinalField(VarHandle vh) { 319 // Plain 320 { 321 boolean x = (boolean) vh.get(); 322 assertEquals(x, true, "get boolean value"); 323 } 324 325 326 // Volatile 327 { 328 boolean x = (boolean) vh.getVolatile(); 329 assertEquals(x, true, "getVolatile boolean value"); 330 } 331 332 // Lazy 333 { 334 boolean x = (boolean) vh.getAcquire(); 335 assertEquals(x, true, "getRelease boolean value"); 336 } 337 338 // Opaque 339 { 340 boolean x = (boolean) vh.getOpaque(); 341 assertEquals(x, true, "getOpaque boolean value"); 342 } 343 } 344 345 static void testStaticFinalFieldUnsupported(VarHandle vh) { 346 checkUOE(() -> { 347 vh.set(false); 348 }); 349 350 checkUOE(() -> { 351 vh.setVolatile(false); 352 }); 353 354 checkUOE(() -> { 355 vh.setRelease(false); 356 }); 357 358 checkUOE(() -> { 359 vh.setOpaque(false); 360 }); 361 362 363 checkUOE(() -> { 364 boolean o = (boolean) vh.getAndAdd(true); 365 }); 366 367 checkUOE(() -> { 368 boolean o = (boolean) vh.getAndAddAcquire(true); 369 }); 370 371 checkUOE(() -> { 372 boolean o = (boolean) vh.getAndAddRelease(true); 373 }); 374 375 } 376 377 378 static void testInstanceField(VarHandleTestAccessBoolean recv, VarHandle vh) { 379 // Plain 380 { 381 vh.set(recv, true); 382 boolean x = (boolean) vh.get(recv); 383 assertEquals(x, true, "set boolean value"); 384 } 385 386 387 // Volatile 388 { 389 vh.setVolatile(recv, false); 390 boolean x = (boolean) vh.getVolatile(recv); 391 assertEquals(x, false, "setVolatile boolean value"); 392 } 393 394 // Lazy 395 { 396 vh.setRelease(recv, true); 397 boolean x = (boolean) vh.getAcquire(recv); 398 assertEquals(x, true, "setRelease boolean value"); 399 } 400 401 // Opaque 402 { 403 vh.setOpaque(recv, false); 404 boolean x = (boolean) vh.getOpaque(recv); 405 assertEquals(x, false, "setOpaque boolean value"); 406 } 407 408 vh.set(recv, true); 409 410 // Compare 411 { 412 boolean r = vh.compareAndSet(recv, true, false); 413 assertEquals(r, true, "success compareAndSet boolean"); 414 boolean x = (boolean) vh.get(recv); 415 assertEquals(x, false, "success compareAndSet boolean value"); 416 } 417 418 { 419 boolean r = vh.compareAndSet(recv, true, false); 420 assertEquals(r, false, "failing compareAndSet boolean"); 421 boolean x = (boolean) vh.get(recv); 422 assertEquals(x, false, "failing compareAndSet boolean value"); 423 } 424 425 { 426 boolean r = (boolean) vh.compareAndExchange(recv, false, true); 427 assertEquals(r, false, "success compareAndExchange boolean"); 428 boolean x = (boolean) vh.get(recv); 429 assertEquals(x, true, "success compareAndExchange boolean value"); 430 } 431 432 { 433 boolean r = (boolean) vh.compareAndExchange(recv, false, false); 434 assertEquals(r, true, "failing compareAndExchange boolean"); 435 boolean x = (boolean) vh.get(recv); 436 assertEquals(x, true, "failing compareAndExchange boolean value"); 437 } 438 439 { 440 boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false); 441 assertEquals(r, true, "success compareAndExchangeAcquire boolean"); 442 boolean x = (boolean) vh.get(recv); 443 assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); 444 } 445 446 { 447 boolean r = (boolean) vh.compareAndExchangeAcquire(recv, true, false); 448 assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); 449 boolean x = (boolean) vh.get(recv); 450 assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); 451 } 452 453 { 454 boolean r = (boolean) vh.compareAndExchangeRelease(recv, false, true); 455 assertEquals(r, false, "success compareAndExchangeRelease boolean"); 456 boolean x = (boolean) vh.get(recv); 457 assertEquals(x, true, "success compareAndExchangeRelease boolean value"); 458 } 459 460 { 461 boolean r = (boolean) vh.compareAndExchangeRelease(recv, false, false); 462 assertEquals(r, true, "failing compareAndExchangeRelease boolean"); 463 boolean x = (boolean) vh.get(recv); 464 assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); 465 } 466 467 { 468 boolean success = false; 469 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 470 success = vh.weakCompareAndSetPlain(recv, true, false); 471 } 472 assertEquals(success, true, "weakCompareAndSetPlain boolean"); 473 boolean x = (boolean) vh.get(recv); 474 assertEquals(x, false, "weakCompareAndSetPlain boolean value"); 475 } 476 477 { 478 boolean success = false; 479 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 480 success = vh.weakCompareAndSetAcquire(recv, false, true); 481 } 482 assertEquals(success, true, "weakCompareAndSetAcquire boolean"); 483 boolean x = (boolean) vh.get(recv); 484 assertEquals(x, true, "weakCompareAndSetAcquire boolean"); 485 } 486 487 { 488 boolean success = false; 489 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 490 success = vh.weakCompareAndSetRelease(recv, true, false); 491 } 492 assertEquals(success, true, "weakCompareAndSetRelease boolean"); 493 boolean x = (boolean) vh.get(recv); 494 assertEquals(x, false, "weakCompareAndSetRelease boolean"); 495 } 496 497 { 498 boolean success = false; 499 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 500 success = vh.weakCompareAndSet(recv, false, true); 501 } 502 assertEquals(success, true, "weakCompareAndSet boolean"); 503 boolean x = (boolean) vh.get(recv); 504 assertEquals(x, true, "weakCompareAndSet boolean value"); 505 } 506 507 // Compare set and get 508 { 509 vh.set(recv, true); 510 511 boolean o = (boolean) vh.getAndSet(recv, false); 512 assertEquals(o, true, "getAndSet boolean"); 513 boolean x = (boolean) vh.get(recv); 514 assertEquals(x, false, "getAndSet boolean value"); 515 } 516 517 { 518 vh.set(recv, true); 519 520 boolean o = (boolean) vh.getAndSetAcquire(recv, false); 521 assertEquals(o, true, "getAndSetAcquire boolean"); 522 boolean x = (boolean) vh.get(recv); 523 assertEquals(x, false, "getAndSetAcquire boolean value"); 524 } 525 526 { 527 vh.set(recv, true); 528 529 boolean o = (boolean) vh.getAndSetRelease(recv, false); 530 assertEquals(o, true, "getAndSetRelease boolean"); 531 boolean x = (boolean) vh.get(recv); 532 assertEquals(x, false, "getAndSetRelease boolean value"); 533 } 534 535 536 // get and bitwise or 537 { 538 vh.set(recv, true); 539 540 boolean o = (boolean) vh.getAndBitwiseOr(recv, false); 541 assertEquals(o, true, "getAndBitwiseOr boolean"); 542 boolean x = (boolean) vh.get(recv); 543 assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); 544 } 545 546 { 547 vh.set(recv, true); 548 549 boolean o = (boolean) vh.getAndBitwiseOrAcquire(recv, false); 550 assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); 551 boolean x = (boolean) vh.get(recv); 552 assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); 553 } 554 555 { 556 vh.set(recv, true); 557 558 boolean o = (boolean) vh.getAndBitwiseOrRelease(recv, false); 559 assertEquals(o, true, "getAndBitwiseOrRelease boolean"); 560 boolean x = (boolean) vh.get(recv); 561 assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); 562 } 563 564 // get and bitwise and 565 { 566 vh.set(recv, true); 567 568 boolean o = (boolean) vh.getAndBitwiseAnd(recv, false); 569 assertEquals(o, true, "getAndBitwiseAnd boolean"); 570 boolean x = (boolean) vh.get(recv); 571 assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); 572 } 573 574 { 575 vh.set(recv, true); 576 577 boolean o = (boolean) vh.getAndBitwiseAndAcquire(recv, false); 578 assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); 579 boolean x = (boolean) vh.get(recv); 580 assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); 581 } 582 583 { 584 vh.set(recv, true); 585 586 boolean o = (boolean) vh.getAndBitwiseAndRelease(recv, false); 587 assertEquals(o, true, "getAndBitwiseAndRelease boolean"); 588 boolean x = (boolean) vh.get(recv); 589 assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); 590 } 591 592 // get and bitwise xor 593 { 594 vh.set(recv, true); 595 596 boolean o = (boolean) vh.getAndBitwiseXor(recv, false); 597 assertEquals(o, true, "getAndBitwiseXor boolean"); 598 boolean x = (boolean) vh.get(recv); 599 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); 600 } 601 602 { 603 vh.set(recv, true); 604 605 boolean o = (boolean) vh.getAndBitwiseXorAcquire(recv, false); 606 assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); 607 boolean x = (boolean) vh.get(recv); 608 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); 609 } 610 611 { 612 vh.set(recv, true); 613 614 boolean o = (boolean) vh.getAndBitwiseXorRelease(recv, false); 615 assertEquals(o, true, "getAndBitwiseXorRelease boolean"); 616 boolean x = (boolean) vh.get(recv); 617 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); 618 } 619 } 620 621 static void testInstanceFieldUnsupported(VarHandleTestAccessBoolean recv, VarHandle vh) { 622 623 checkUOE(() -> { 624 boolean o = (boolean) vh.getAndAdd(recv, true); 625 }); 626 627 checkUOE(() -> { 628 boolean o = (boolean) vh.getAndAddAcquire(recv, true); 629 }); 630 631 checkUOE(() -> { 632 boolean o = (boolean) vh.getAndAddRelease(recv, true); 633 }); 634 635 } 636 637 638 static void testStaticField(VarHandle vh) { 639 // Plain 640 { 641 vh.set(true); 642 boolean x = (boolean) vh.get(); 643 assertEquals(x, true, "set boolean value"); 644 } 645 646 647 // Volatile 648 { 649 vh.setVolatile(false); 650 boolean x = (boolean) vh.getVolatile(); 651 assertEquals(x, false, "setVolatile boolean value"); 652 } 653 654 // Lazy 655 { 656 vh.setRelease(true); 657 boolean x = (boolean) vh.getAcquire(); 658 assertEquals(x, true, "setRelease boolean value"); 659 } 660 661 // Opaque 662 { 663 vh.setOpaque(false); 664 boolean x = (boolean) vh.getOpaque(); 665 assertEquals(x, false, "setOpaque boolean value"); 666 } 667 668 vh.set(true); 669 670 // Compare 671 { 672 boolean r = vh.compareAndSet(true, false); 673 assertEquals(r, true, "success compareAndSet boolean"); 674 boolean x = (boolean) vh.get(); 675 assertEquals(x, false, "success compareAndSet boolean value"); 676 } 677 678 { 679 boolean r = vh.compareAndSet(true, false); 680 assertEquals(r, false, "failing compareAndSet boolean"); 681 boolean x = (boolean) vh.get(); 682 assertEquals(x, false, "failing compareAndSet boolean value"); 683 } 684 685 { 686 boolean r = (boolean) vh.compareAndExchange(false, true); 687 assertEquals(r, false, "success compareAndExchange boolean"); 688 boolean x = (boolean) vh.get(); 689 assertEquals(x, true, "success compareAndExchange boolean value"); 690 } 691 692 { 693 boolean r = (boolean) vh.compareAndExchange(false, false); 694 assertEquals(r, true, "failing compareAndExchange boolean"); 695 boolean x = (boolean) vh.get(); 696 assertEquals(x, true, "failing compareAndExchange boolean value"); 697 } 698 699 { 700 boolean r = (boolean) vh.compareAndExchangeAcquire(true, false); 701 assertEquals(r, true, "success compareAndExchangeAcquire boolean"); 702 boolean x = (boolean) vh.get(); 703 assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); 704 } 705 706 { 707 boolean r = (boolean) vh.compareAndExchangeAcquire(true, false); 708 assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); 709 boolean x = (boolean) vh.get(); 710 assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); 711 } 712 713 { 714 boolean r = (boolean) vh.compareAndExchangeRelease(false, true); 715 assertEquals(r, false, "success compareAndExchangeRelease boolean"); 716 boolean x = (boolean) vh.get(); 717 assertEquals(x, true, "success compareAndExchangeRelease boolean value"); 718 } 719 720 { 721 boolean r = (boolean) vh.compareAndExchangeRelease(false, false); 722 assertEquals(r, true, "failing compareAndExchangeRelease boolean"); 723 boolean x = (boolean) vh.get(); 724 assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); 725 } 726 727 { 728 boolean success = false; 729 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 730 success = vh.weakCompareAndSetPlain(true, false); 731 } 732 assertEquals(success, true, "weakCompareAndSetPlain boolean"); 733 boolean x = (boolean) vh.get(); 734 assertEquals(x, false, "weakCompareAndSetPlain boolean value"); 735 } 736 737 { 738 boolean success = false; 739 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 740 success = vh.weakCompareAndSetAcquire(false, true); 741 } 742 assertEquals(success, true, "weakCompareAndSetAcquire boolean"); 743 boolean x = (boolean) vh.get(); 744 assertEquals(x, true, "weakCompareAndSetAcquire boolean"); 745 } 746 747 { 748 boolean success = false; 749 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 750 success = vh.weakCompareAndSetRelease(true, false); 751 } 752 assertEquals(success, true, "weakCompareAndSetRelease boolean"); 753 boolean x = (boolean) vh.get(); 754 assertEquals(x, false, "weakCompareAndSetRelease boolean"); 755 } 756 757 { 758 boolean success = false; 759 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 760 success = vh.weakCompareAndSet(false, true); 761 } 762 assertEquals(success, true, "weakCompareAndSet boolean"); 763 boolean x = (boolean) vh.get(); 764 assertEquals(x, true, "weakCompareAndSet boolean"); 765 } 766 767 // Compare set and get 768 { 769 vh.set(true); 770 771 boolean o = (boolean) vh.getAndSet(false); 772 assertEquals(o, true, "getAndSet boolean"); 773 boolean x = (boolean) vh.get(); 774 assertEquals(x, false, "getAndSet boolean value"); 775 } 776 777 { 778 vh.set(true); 779 780 boolean o = (boolean) vh.getAndSetAcquire(false); 781 assertEquals(o, true, "getAndSetAcquire boolean"); 782 boolean x = (boolean) vh.get(); 783 assertEquals(x, false, "getAndSetAcquire boolean value"); 784 } 785 786 { 787 vh.set(true); 788 789 boolean o = (boolean) vh.getAndSetRelease(false); 790 assertEquals(o, true, "getAndSetRelease boolean"); 791 boolean x = (boolean) vh.get(); 792 assertEquals(x, false, "getAndSetRelease boolean value"); 793 } 794 795 796 // get and bitwise or 797 { 798 vh.set(true); 799 800 boolean o = (boolean) vh.getAndBitwiseOr(false); 801 assertEquals(o, true, "getAndBitwiseOr boolean"); 802 boolean x = (boolean) vh.get(); 803 assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); 804 } 805 806 { 807 vh.set(true); 808 809 boolean o = (boolean) vh.getAndBitwiseOrAcquire(false); 810 assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); 811 boolean x = (boolean) vh.get(); 812 assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); 813 } 814 815 { 816 vh.set(true); 817 818 boolean o = (boolean) vh.getAndBitwiseOrRelease(false); 819 assertEquals(o, true, "getAndBitwiseOrRelease boolean"); 820 boolean x = (boolean) vh.get(); 821 assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); 822 } 823 824 // get and bitwise and 825 { 826 vh.set(true); 827 828 boolean o = (boolean) vh.getAndBitwiseAnd(false); 829 assertEquals(o, true, "getAndBitwiseAnd boolean"); 830 boolean x = (boolean) vh.get(); 831 assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); 832 } 833 834 { 835 vh.set(true); 836 837 boolean o = (boolean) vh.getAndBitwiseAndAcquire(false); 838 assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); 839 boolean x = (boolean) vh.get(); 840 assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); 841 } 842 843 { 844 vh.set(true); 845 846 boolean o = (boolean) vh.getAndBitwiseAndRelease(false); 847 assertEquals(o, true, "getAndBitwiseAndRelease boolean"); 848 boolean x = (boolean) vh.get(); 849 assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); 850 } 851 852 // get and bitwise xor 853 { 854 vh.set(true); 855 856 boolean o = (boolean) vh.getAndBitwiseXor(false); 857 assertEquals(o, true, "getAndBitwiseXor boolean"); 858 boolean x = (boolean) vh.get(); 859 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); 860 } 861 862 { 863 vh.set(true); 864 865 boolean o = (boolean) vh.getAndBitwiseXorAcquire(false); 866 assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); 867 boolean x = (boolean) vh.get(); 868 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); 869 } 870 871 { 872 vh.set(true); 873 874 boolean o = (boolean) vh.getAndBitwiseXorRelease(false); 875 assertEquals(o, true, "getAndBitwiseXorRelease boolean"); 876 boolean x = (boolean) vh.get(); 877 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); 878 } 879 } 880 881 static void testStaticFieldUnsupported(VarHandle vh) { 882 883 checkUOE(() -> { 884 boolean o = (boolean) vh.getAndAdd(true); 885 }); 886 887 checkUOE(() -> { 888 boolean o = (boolean) vh.getAndAddAcquire(true); 889 }); 890 891 checkUOE(() -> { 892 boolean o = (boolean) vh.getAndAddRelease(true); 893 }); 894 895 } 896 897 898 static void testArray(VarHandle vh) { 899 boolean[] array = new boolean[10]; 900 901 for (int i = 0; i < array.length; i++) { 902 // Plain 903 { 904 vh.set(array, i, true); 905 boolean x = (boolean) vh.get(array, i); 906 assertEquals(x, true, "get boolean value"); 907 } 908 909 910 // Volatile 911 { 912 vh.setVolatile(array, i, false); 913 boolean x = (boolean) vh.getVolatile(array, i); 914 assertEquals(x, false, "setVolatile boolean value"); 915 } 916 917 // Lazy 918 { 919 vh.setRelease(array, i, true); 920 boolean x = (boolean) vh.getAcquire(array, i); 921 assertEquals(x, true, "setRelease boolean value"); 922 } 923 924 // Opaque 925 { 926 vh.setOpaque(array, i, false); 927 boolean x = (boolean) vh.getOpaque(array, i); 928 assertEquals(x, false, "setOpaque boolean value"); 929 } 930 931 vh.set(array, i, true); 932 933 // Compare 934 { 935 boolean r = vh.compareAndSet(array, i, true, false); 936 assertEquals(r, true, "success compareAndSet boolean"); 937 boolean x = (boolean) vh.get(array, i); 938 assertEquals(x, false, "success compareAndSet boolean value"); 939 } 940 941 { 942 boolean r = vh.compareAndSet(array, i, true, false); 943 assertEquals(r, false, "failing compareAndSet boolean"); 944 boolean x = (boolean) vh.get(array, i); 945 assertEquals(x, false, "failing compareAndSet boolean value"); 946 } 947 948 { 949 boolean r = (boolean) vh.compareAndExchange(array, i, false, true); 950 assertEquals(r, false, "success compareAndExchange boolean"); 951 boolean x = (boolean) vh.get(array, i); 952 assertEquals(x, true, "success compareAndExchange boolean value"); 953 } 954 955 { 956 boolean r = (boolean) vh.compareAndExchange(array, i, false, false); 957 assertEquals(r, true, "failing compareAndExchange boolean"); 958 boolean x = (boolean) vh.get(array, i); 959 assertEquals(x, true, "failing compareAndExchange boolean value"); 960 } 961 962 { 963 boolean r = (boolean) vh.compareAndExchangeAcquire(array, i, true, false); 964 assertEquals(r, true, "success compareAndExchangeAcquire boolean"); 965 boolean x = (boolean) vh.get(array, i); 966 assertEquals(x, false, "success compareAndExchangeAcquire boolean value"); 967 } 968 969 { 970 boolean r = (boolean) vh.compareAndExchangeAcquire(array, i, true, false); 971 assertEquals(r, false, "failing compareAndExchangeAcquire boolean"); 972 boolean x = (boolean) vh.get(array, i); 973 assertEquals(x, false, "failing compareAndExchangeAcquire boolean value"); 974 } 975 976 { 977 boolean r = (boolean) vh.compareAndExchangeRelease(array, i, false, true); 978 assertEquals(r, false, "success compareAndExchangeRelease boolean"); 979 boolean x = (boolean) vh.get(array, i); 980 assertEquals(x, true, "success compareAndExchangeRelease boolean value"); 981 } 982 983 { 984 boolean r = (boolean) vh.compareAndExchangeRelease(array, i, false, false); 985 assertEquals(r, true, "failing compareAndExchangeRelease boolean"); 986 boolean x = (boolean) vh.get(array, i); 987 assertEquals(x, true, "failing compareAndExchangeRelease boolean value"); 988 } 989 990 { 991 boolean success = false; 992 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 993 success = vh.weakCompareAndSetPlain(array, i, true, false); 994 } 995 assertEquals(success, true, "weakCompareAndSetPlain boolean"); 996 boolean x = (boolean) vh.get(array, i); 997 assertEquals(x, false, "weakCompareAndSetPlain boolean value"); 998 } 999 1000 { 1001 boolean success = false; 1002 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1003 success = vh.weakCompareAndSetAcquire(array, i, false, true); 1004 } 1005 assertEquals(success, true, "weakCompareAndSetAcquire boolean"); 1006 boolean x = (boolean) vh.get(array, i); 1007 assertEquals(x, true, "weakCompareAndSetAcquire boolean"); 1008 } 1009 1010 { 1011 boolean success = false; 1012 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1013 success = vh.weakCompareAndSetRelease(array, i, true, false); 1014 } 1015 assertEquals(success, true, "weakCompareAndSetRelease boolean"); 1016 boolean x = (boolean) vh.get(array, i); 1017 assertEquals(x, false, "weakCompareAndSetRelease boolean"); 1018 } 1019 1020 { 1021 boolean success = false; 1022 for (int c = 0; c < WEAK_ATTEMPTS && !success; c++) { 1023 success = vh.weakCompareAndSet(array, i, false, true); 1024 } 1025 assertEquals(success, true, "weakCompareAndSet boolean"); 1026 boolean x = (boolean) vh.get(array, i); 1027 assertEquals(x, true, "weakCompareAndSet boolean"); 1028 } 1029 1030 // Compare set and get 1031 { 1032 vh.set(array, i, true); 1033 1034 boolean o = (boolean) vh.getAndSet(array, i, false); 1035 assertEquals(o, true, "getAndSet boolean"); 1036 boolean x = (boolean) vh.get(array, i); 1037 assertEquals(x, false, "getAndSet boolean value"); 1038 } 1039 1040 { 1041 vh.set(array, i, true); 1042 1043 boolean o = (boolean) vh.getAndSetAcquire(array, i, false); 1044 assertEquals(o, true, "getAndSetAcquire boolean"); 1045 boolean x = (boolean) vh.get(array, i); 1046 assertEquals(x, false, "getAndSetAcquire boolean value"); 1047 } 1048 1049 { 1050 vh.set(array, i, true); 1051 1052 boolean o = (boolean) vh.getAndSetRelease(array, i, false); 1053 assertEquals(o, true, "getAndSetRelease boolean"); 1054 boolean x = (boolean) vh.get(array, i); 1055 assertEquals(x, false, "getAndSetRelease boolean value"); 1056 } 1057 1058 1059 // get and bitwise or 1060 { 1061 vh.set(array, i, true); 1062 1063 boolean o = (boolean) vh.getAndBitwiseOr(array, i, false); 1064 assertEquals(o, true, "getAndBitwiseOr boolean"); 1065 boolean x = (boolean) vh.get(array, i); 1066 assertEquals(x, (boolean)(true | false), "getAndBitwiseOr boolean value"); 1067 } 1068 1069 { 1070 vh.set(array, i, true); 1071 1072 boolean o = (boolean) vh.getAndBitwiseOrAcquire(array, i, false); 1073 assertEquals(o, true, "getAndBitwiseOrAcquire boolean"); 1074 boolean x = (boolean) vh.get(array, i); 1075 assertEquals(x, (boolean)(true | false), "getAndBitwiseOrAcquire boolean value"); 1076 } 1077 1078 { 1079 vh.set(array, i, true); 1080 1081 boolean o = (boolean) vh.getAndBitwiseOrRelease(array, i, false); 1082 assertEquals(o, true, "getAndBitwiseOrRelease boolean"); 1083 boolean x = (boolean) vh.get(array, i); 1084 assertEquals(x, (boolean)(true | false), "getAndBitwiseOrRelease boolean value"); 1085 } 1086 1087 // get and bitwise and 1088 { 1089 vh.set(array, i, true); 1090 1091 boolean o = (boolean) vh.getAndBitwiseAnd(array, i, false); 1092 assertEquals(o, true, "getAndBitwiseAnd boolean"); 1093 boolean x = (boolean) vh.get(array, i); 1094 assertEquals(x, (boolean)(true & false), "getAndBitwiseAnd boolean value"); 1095 } 1096 1097 { 1098 vh.set(array, i, true); 1099 1100 boolean o = (boolean) vh.getAndBitwiseAndAcquire(array, i, false); 1101 assertEquals(o, true, "getAndBitwiseAndAcquire boolean"); 1102 boolean x = (boolean) vh.get(array, i); 1103 assertEquals(x, (boolean)(true & false), "getAndBitwiseAndAcquire boolean value"); 1104 } 1105 1106 { 1107 vh.set(array, i, true); 1108 1109 boolean o = (boolean) vh.getAndBitwiseAndRelease(array, i, false); 1110 assertEquals(o, true, "getAndBitwiseAndRelease boolean"); 1111 boolean x = (boolean) vh.get(array, i); 1112 assertEquals(x, (boolean)(true & false), "getAndBitwiseAndRelease boolean value"); 1113 } 1114 1115 // get and bitwise xor 1116 { 1117 vh.set(array, i, true); 1118 1119 boolean o = (boolean) vh.getAndBitwiseXor(array, i, false); 1120 assertEquals(o, true, "getAndBitwiseXor boolean"); 1121 boolean x = (boolean) vh.get(array, i); 1122 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXor boolean value"); 1123 } 1124 1125 { 1126 vh.set(array, i, true); 1127 1128 boolean o = (boolean) vh.getAndBitwiseXorAcquire(array, i, false); 1129 assertEquals(o, true, "getAndBitwiseXorAcquire boolean"); 1130 boolean x = (boolean) vh.get(array, i); 1131 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorAcquire boolean value"); 1132 } 1133 1134 { 1135 vh.set(array, i, true); 1136 1137 boolean o = (boolean) vh.getAndBitwiseXorRelease(array, i, false); 1138 assertEquals(o, true, "getAndBitwiseXorRelease boolean"); 1139 boolean x = (boolean) vh.get(array, i); 1140 assertEquals(x, (boolean)(true ^ false), "getAndBitwiseXorRelease boolean value"); 1141 } 1142 } 1143 } 1144 1145 static void testArrayUnsupported(VarHandle vh) { 1146 boolean[] array = new boolean[10]; 1147 1148 int i = 0; 1149 1150 checkUOE(() -> { 1151 boolean o = (boolean) vh.getAndAdd(array, i, true); 1152 }); 1153 1154 checkUOE(() -> { 1155 boolean o = (boolean) vh.getAndAddAcquire(array, i, true); 1156 }); 1157 1158 checkUOE(() -> { 1159 boolean o = (boolean) vh.getAndAddRelease(array, i, true); 1160 }); 1161 1162 } 1163 1164 static void testArrayIndexOutOfBounds(VarHandle vh) throws Throwable { 1165 boolean[] array = new boolean[10]; 1166 1167 for (int i : new int[]{-1, Integer.MIN_VALUE, 10, 11, Integer.MAX_VALUE}) { 1168 final int ci = i; 1169 1170 checkIOOBE(() -> { 1171 boolean x = (boolean) vh.get(array, ci); 1172 }); 1173 1174 checkIOOBE(() -> { 1175 vh.set(array, ci, true); 1176 }); 1177 1178 checkIOOBE(() -> { 1179 boolean x = (boolean) vh.getVolatile(array, ci); 1180 }); 1181 1182 checkIOOBE(() -> { 1183 vh.setVolatile(array, ci, true); 1184 }); 1185 1186 checkIOOBE(() -> { 1187 boolean x = (boolean) vh.getAcquire(array, ci); 1188 }); 1189 1190 checkIOOBE(() -> { 1191 vh.setRelease(array, ci, true); 1192 }); 1193 1194 checkIOOBE(() -> { 1195 boolean x = (boolean) vh.getOpaque(array, ci); 1196 }); 1197 1198 checkIOOBE(() -> { 1199 vh.setOpaque(array, ci, true); 1200 }); 1201 1202 checkIOOBE(() -> { 1203 boolean r = vh.compareAndSet(array, ci, true, false); 1204 }); 1205 1206 checkIOOBE(() -> { 1207 boolean r = (boolean) vh.compareAndExchange(array, ci, false, true); 1208 }); 1209 1210 checkIOOBE(() -> { 1211 boolean r = (boolean) vh.compareAndExchangeAcquire(array, ci, false, true); 1212 }); 1213 1214 checkIOOBE(() -> { 1215 boolean r = (boolean) vh.compareAndExchangeRelease(array, ci, false, true); 1216 }); 1217 1218 checkIOOBE(() -> { 1219 boolean r = vh.weakCompareAndSetPlain(array, ci, true, false); 1220 }); 1221 1222 checkIOOBE(() -> { 1223 boolean r = vh.weakCompareAndSet(array, ci, true, false); 1224 }); 1225 1226 checkIOOBE(() -> { 1227 boolean r = vh.weakCompareAndSetAcquire(array, ci, true, false); 1228 }); 1229 1230 checkIOOBE(() -> { 1231 boolean r = vh.weakCompareAndSetRelease(array, ci, true, false); 1232 }); 1233 1234 checkIOOBE(() -> { 1235 boolean o = (boolean) vh.getAndSet(array, ci, true); 1236 }); 1237 1238 checkIOOBE(() -> { 1239 boolean o = (boolean) vh.getAndSetAcquire(array, ci, true); 1240 }); 1241 1242 checkIOOBE(() -> { 1243 boolean o = (boolean) vh.getAndSetRelease(array, ci, true); 1244 }); 1245 1246 1247 checkIOOBE(() -> { 1248 boolean o = (boolean) vh.getAndBitwiseOr(array, ci, true); 1249 }); 1250 1251 checkIOOBE(() -> { 1252 boolean o = (boolean) vh.getAndBitwiseOrAcquire(array, ci, true); 1253 }); 1254 1255 checkIOOBE(() -> { 1256 boolean o = (boolean) vh.getAndBitwiseOrRelease(array, ci, true); 1257 }); 1258 1259 checkIOOBE(() -> { 1260 boolean o = (boolean) vh.getAndBitwiseAnd(array, ci, true); 1261 }); 1262 1263 checkIOOBE(() -> { 1264 boolean o = (boolean) vh.getAndBitwiseAndAcquire(array, ci, true); 1265 }); 1266 1267 checkIOOBE(() -> { 1268 boolean o = (boolean) vh.getAndBitwiseAndRelease(array, ci, true); 1269 }); 1270 1271 checkIOOBE(() -> { 1272 boolean o = (boolean) vh.getAndBitwiseXor(array, ci, true); 1273 }); 1274 1275 checkIOOBE(() -> { 1276 boolean o = (boolean) vh.getAndBitwiseXorAcquire(array, ci, true); 1277 }); 1278 1279 checkIOOBE(() -> { 1280 boolean o = (boolean) vh.getAndBitwiseXorRelease(array, ci, true); 1281 }); 1282 } 1283 } 1284 } 1285