1# Copyright (C) 2015 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15.class public LBuilder; 16 17.super Ljava/lang/Object; 18 19# Basic test case with two try blocks and three catch handlers, one of which 20# is shared by the two tries. 21 22## CHECK-START: int Builder.testMultipleTryCatch(int, int, int) builder (after) 23 24## CHECK: name "B0" 25## CHECK: successors "<<BEnterTry1:B\d+>>" 26## CHECK-DAG: <<Minus1:i\d+>> IntConstant -1 27## CHECK-DAG: <<Minus2:i\d+>> IntConstant -2 28## CHECK-DAG: <<Minus3:i\d+>> IntConstant -3 29 30## CHECK: name "<<BTry1:B\d+>>" 31## CHECK: predecessors "<<BEnterTry1>>" 32## CHECK: successors "<<BExitTry1:B\d+>>" 33## CHECK: DivZeroCheck 34 35## CHECK: name "<<BAdd:B\d+>>" 36## CHECK: predecessors "<<BExitTry1>>" 37## CHECK: successors "<<BEnterTry2:B\d+>>" 38## CHECK: Add 39 40## CHECK: name "<<BTry2:B\d+>>" 41## CHECK: predecessors "<<BEnterTry2>>" 42## CHECK: successors "<<BExitTry2:B\d+>>" 43## CHECK: DivZeroCheck 44## CHECK: <<Div:i\d+>> Div 45 46## CHECK: name "<<BAfterTry2:B\d+>>" 47## CHECK: predecessors "<<BExitTry2>>" 48## CHECK: successors "<<BReturn:B\d+>>" 49## CHECK: Goto 50 51## CHECK: name "<<BReturn>>" 52## CHECK: predecessors "<<BAfterTry2>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>" "<<BCatch3:B\d+>>" 53## CHECK: Phi [<<Div>>,<<Minus1>>,<<Minus2>>,<<Minus3>>] 54## CHECK: Return 55 56## CHECK: name "<<BCatch1>>" 57## CHECK: predecessors "<<BEnterTry1>>" "<<BExitTry1>>" 58## CHECK: successors "<<BReturn>>" 59## CHECK: flags "catch_block" 60## CHECK: Goto 61 62## CHECK: name "<<BCatch2>>" 63## CHECK: predecessors "<<BEnterTry2>>" "<<BExitTry2>>" 64## CHECK: successors "<<BReturn>>" 65## CHECK: flags "catch_block" 66## CHECK: Goto 67 68## CHECK: name "<<BCatch3>>" 69## CHECK: predecessors "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>" 70## CHECK: successors "<<BReturn>>" 71## CHECK: flags "catch_block" 72## CHECK: Goto 73 74## CHECK: name "<<BEnterTry1>>" 75## CHECK: predecessors "B0" 76## CHECK: successors "<<BTry1>>" 77## CHECK: xhandlers "<<BCatch1>>" "<<BCatch3>>" 78## CHECK: TryBoundary kind:entry 79 80## CHECK: name "<<BEnterTry2>>" 81## CHECK: predecessors "<<BAdd>>" 82## CHECK: successors "<<BTry2>>" 83## CHECK: xhandlers "<<BCatch2>>" "<<BCatch3>>" 84## CHECK: TryBoundary kind:entry 85 86## CHECK: name "<<BExitTry1>>" 87## CHECK: predecessors "<<BTry1>>" 88## CHECK: successors "<<BAdd>>" 89## CHECK: xhandlers "<<BCatch1>>" "<<BCatch3>>" 90## CHECK: TryBoundary kind:exit 91 92## CHECK: name "<<BExitTry2>>" 93## CHECK: predecessors "<<BTry2>>" 94## CHECK: successors "<<BAfterTry2>>" 95## CHECK: xhandlers "<<BCatch2>>" "<<BCatch3>>" 96## CHECK: TryBoundary kind:exit 97 98.method public static testMultipleTryCatch(III)I 99 .registers 3 100 101 :try_start_1 102 div-int/2addr p0, p1 103 :try_end_1 104 .catch Ljava/lang/ArithmeticException; {:try_start_1 .. :try_end_1} :catch_arith 105 .catchall {:try_start_1 .. :try_end_1} :catch_other 106 107 add-int/2addr p0, p0 108 109 :try_start_2 110 div-int/2addr p0, p2 111 :try_end_2 112 .catch Ljava/lang/OutOfMemoryError; {:try_start_2 .. :try_end_2} :catch_mem 113 .catchall {:try_start_2 .. :try_end_2} :catch_other 114 115 nop 116 117 :return 118 return p0 119 120 :catch_arith 121 const/4 p0, -0x1 122 goto :return 123 124 :catch_mem 125 const/4 p0, -0x2 126 goto :return 127 128 :catch_other 129 const/4 p0, -0x3 130 goto :return 131.end method 132 133# Tests try-entry block when there are multiple entry points into the try block. 134 135## CHECK-START: int Builder.testMultipleEntries(int, int, int, int) builder (after) 136 137## CHECK: name "B0" 138## CHECK: successors "<<BIf:B\d+>>" 139## CHECK: <<Minus1:i\d+>> IntConstant -1 140 141## CHECK: name "<<BIf>>" 142## CHECK: predecessors "B0" 143## CHECK: successors "<<BSplit1:B\d+>>" "<<BThen:B\d+>>" 144## CHECK: If 145 146## CHECK: name "<<BThen>>" 147## CHECK: predecessors "<<BIf>>" 148## CHECK: successors "<<BEnterTry1:B\d+>>" 149## CHECK: Div 150 151## CHECK: name "<<BTry1:B\d+>>" 152## CHECK: predecessors "<<BEnterTry1>>" 153## CHECK: successors "<<BExitTry1:B\d+>>" 154## CHECK: Div 155 156## CHECK: name "<<BTry2:B\d+>>" 157## CHECK: predecessors "<<BEnterTry2:B\d+>>" 158## CHECK: successors "<<BExitTry2:B\d+>>" 159## CHECK: Div 160 161## CHECK: name "<<BReturn:B\d+>>" 162## CHECK: predecessors "<<BSplit3:B\d+>>" "<<BCatch:B\d+>>" 163## CHECK: Return 164 165## CHECK: name "<<BCatch>>" 166## CHECK: predecessors "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>" 167## CHECK: successors "<<BReturn>>" 168## CHECK: flags "catch_block" 169## CHECK: Goto 170 171## CHECK: name "<<BEnterTry1>>" 172## CHECK: predecessors "<<BThen>>" 173## CHECK: successors "<<BTry1>>" 174## CHECK: xhandlers "<<BCatch>>" 175## CHECK: TryBoundary kind:entry 176 177## CHECK: name "<<BEnterTry2>>" 178## CHECK: predecessors "<<BSplit1>>" "<<BSplit2:B\d+>>" 179## CHECK: successors "<<BTry2>>" 180## CHECK: xhandlers "<<BCatch>>" 181## CHECK: TryBoundary kind:entry 182 183## CHECK: name "<<BExitTry1>>" 184## CHECK: predecessors "<<BTry1>>" 185## CHECK: successors "<<BSplit2>>" 186## CHECK: xhandlers "<<BCatch>>" 187## CHECK: TryBoundary kind:exit 188 189## CHECK: name "<<BExitTry2>>" 190## CHECK: predecessors "<<BTry2>>" 191## CHECK: successors "<<BSplit3>>" 192## CHECK: xhandlers "<<BCatch>>" 193## CHECK: TryBoundary kind:exit 194 195## CHECK: name "<<BSplit1>>" 196## CHECK: predecessors "<<BIf>>" 197## CHECK: successors "<<BEnterTry2>>" 198## CHECK: Goto 199 200## CHECK: name "<<BSplit2>>" 201## CHECK: predecessors "<<BExitTry1>>" 202## CHECK: successors "<<BEnterTry2>>" 203## CHECK: Goto 204 205## CHECK: name "<<BSplit3>>" 206## CHECK: predecessors "<<BExitTry2>>" 207## CHECK: successors "<<BReturn>>" 208## CHECK: Goto 209 210.method public static testMultipleEntries(IIII)I 211 .registers 4 212 213 if-eqz p2, :else 214 215 div-int/2addr p0, p1 216 217 :try_start 218 div-int/2addr p0, p2 219 220 :else 221 div-int/2addr p0, p3 222 :try_end 223 .catchall {:try_start .. :try_end} :catch_all 224 225 :return 226 return p0 227 228 :catch_all 229 const/4 p0, -0x1 230 goto :return 231 232.end method 233 234# Test that multiple try-exit blocks are generated if (normal) control flow can 235# jump out of the try block at multiple points. 236 237## CHECK-START: int Builder.testMultipleExits(int, int) builder (after) 238 239## CHECK: name "B0" 240## CHECK: successors "<<BEnterTry:B\d+>>" 241## CHECK-DAG: <<Minus1:i\d+>> IntConstant -1 242## CHECK-DAG: <<Minus2:i\d+>> IntConstant -2 243 244## CHECK: name "<<BTry:B\d+>>" 245## CHECK: predecessors "<<BEnterTry>>" 246## CHECK: successors "<<BExitTry1:B\d+>>" "<<BExitTry2:B\d+>>" 247## CHECK: <<Div:i\d+>> Div 248## CHECK: If 249 250## CHECK: name "<<BReturn:B\d+>>" 251## CHECK: predecessors "<<BSplit:B\d+>>" "<<BThen:B\d+>>" "<<BCatch:B\d+>>" 252## CHECK: Phi [<<Div>>,<<Minus1>>,<<Minus2>>] 253## CHECK: Return 254 255## CHECK: name "<<BThen>>" 256## CHECK: predecessors "<<BExitTry1>>" 257## CHECK: successors "<<BReturn>>" 258## CHECK: Goto 259 260## CHECK: name "<<BCatch>>" 261## CHECK: predecessors "<<BEnterTry>>" "<<BExitTry1>>" "<<BExitTry2>>" 262## CHECK: successors "<<BReturn>>" 263## CHECK: flags "catch_block" 264## CHECK: Goto 265 266## CHECK: name "<<BEnterTry>>" 267## CHECK: predecessors "B0" 268## CHECK: successors "<<BTry>>" 269## CHECK: xhandlers "<<BCatch>>" 270## CHECK: TryBoundary kind:entry 271 272## CHECK: name "<<BExitTry1>>" 273## CHECK: predecessors "<<BTry>>" 274## CHECK: successors "<<BThen>>" 275## CHECK: xhandlers "<<BCatch>>" 276## CHECK: TryBoundary kind:exit 277 278## CHECK: name "<<BExitTry2>>" 279## CHECK: predecessors "<<BTry>>" 280## CHECK: successors "<<BSplit>>" 281## CHECK: xhandlers "<<BCatch>>" 282## CHECK: TryBoundary kind:exit 283 284## CHECK: name "<<BSplit>>" 285## CHECK: predecessors "<<BExitTry2>>" 286## CHECK: successors "<<BReturn>>" 287## CHECK: Goto 288 289.method public static testMultipleExits(II)I 290 .registers 2 291 292 :try_start 293 div-int/2addr p0, p1 294 if-eqz p0, :then 295 :try_end 296 .catchall {:try_start .. :try_end} :catch_all 297 298 :return 299 return p0 300 301 :then 302 const/4 p0, -0x1 303 goto :return 304 305 :catch_all 306 const/4 p0, -0x2 307 goto :return 308.end method 309 310# Test that only one TryBoundary is inserted when an edge connects two different 311# try ranges. 312 313## CHECK-START: int Builder.testSharedBoundary(int, int, int) builder (after) 314 315## CHECK: name "B0" 316## CHECK: successors "<<BEnter1:B\d+>>" 317## CHECK-DAG: <<Minus1:i\d+>> IntConstant -1 318## CHECK-DAG: <<Minus2:i\d+>> IntConstant -2 319 320## CHECK: name "<<BTry1:B\d+>>" 321## CHECK: predecessors "<<BEnter1>>" 322## CHECK: successors "<<BExit1:B\d+>>" 323## CHECK: Div 324 325## CHECK: name "<<BTry2:B\d+>>" 326## CHECK: predecessors "<<BEnter2:B\d+>>" 327## CHECK: successors "<<BExit2:B\d+>>" 328## CHECK: <<Div:i\d+>> Div 329## CHECK: Goto 330 331## CHECK: name "<<BReturn:B\d+>>" 332## CHECK: predecessors "<<BSplit:B\d+>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>" 333## CHECK: Phi [<<Div>>,<<Minus1>>,<<Minus2>>] 334## CHECK: Return 335 336## CHECK: name "<<BCatch1>>" 337## CHECK: predecessors "<<BEnter1>>" "<<BExit1>>" 338## CHECK: successors "<<BReturn>>" 339## CHECK: flags "catch_block" 340## CHECK: Goto 341 342## CHECK: name "<<BCatch2>>" 343## CHECK: predecessors "<<BEnter2>>" "<<BExit2>>" 344## CHECK: successors "<<BReturn>>" 345## CHECK: flags "catch_block" 346## CHECK: Goto 347 348## CHECK: name "<<BEnter1>>" 349## CHECK: predecessors "B0" 350## CHECK: successors "<<BTry1>>" 351## CHECK: xhandlers "<<BCatch1>>" 352## CHECK: TryBoundary kind:entry 353 354## CHECK: name "<<BEnter2>>" 355## CHECK: predecessors "<<BExit1>>" 356## CHECK: successors "<<BTry2>>" 357## CHECK: xhandlers "<<BCatch2>>" 358## CHECK: TryBoundary kind:entry 359 360## CHECK: name "<<BExit1>>" 361## CHECK: predecessors "<<BTry1>>" 362## CHECK: successors "<<BEnter2>>" 363## CHECK: xhandlers "<<BCatch1>>" 364## CHECK: TryBoundary kind:exit 365 366## CHECK: name "<<BExit2>>" 367## CHECK: predecessors "<<BTry2>>" 368## CHECK: successors "<<BSplit>>" 369## CHECK: xhandlers "<<BCatch2>>" 370## CHECK: TryBoundary kind:exit 371 372## CHECK: name "<<BSplit>>" 373## CHECK: predecessors "<<BExit2>>" 374## CHECK: successors "<<BReturn>>" 375## CHECK: Goto 376 377.method public static testSharedBoundary(III)I 378 .registers 3 379 380 :try_start_1 381 div-int/2addr p0, p1 382 :try_end_1 383 .catchall {:try_start_1 .. :try_end_1} :catch_all_1 384 385 :try_start_2 386 div-int/2addr p0, p2 387 :try_end_2 388 .catchall {:try_start_2 .. :try_end_2} :catch_all_2 389 390 :return 391 return p0 392 393 :catch_all_1 394 const/4 p0, -0x1 395 goto :return 396 397 :catch_all_2 398 const/4 p0, -0x2 399 goto :return 400.end method 401 402# Same as previous test, only the blocks are processed in the opposite order. 403 404## CHECK-START: int Builder.testSharedBoundary_Reverse(int, int, int) builder (after) 405 406## CHECK: name "B0" 407## CHECK: successors "<<BGoto:B\d+>>" 408## CHECK-DAG: <<Minus1:i\d+>> IntConstant -1 409## CHECK-DAG: <<Minus2:i\d+>> IntConstant -2 410 411## CHECK: name "<<BGoto>>" 412## CHECK: successors "<<BEnter2:B\d+>>" 413## CHECK: Goto 414 415## CHECK: name "<<BTry1:B\d+>>" 416## CHECK: predecessors "<<BEnter1:B\d+>>" 417## CHECK: successors "<<BExit1:B\d+>>" 418## CHECK: <<Div:i\d+>> Div 419## CHECK: Goto 420 421## CHECK: name "<<BTry2:B\d+>>" 422## CHECK: predecessors "<<BEnter2>>" 423## CHECK: successors "<<BExit2:B\d+>>" 424## CHECK: Div 425## CHECK: Goto 426 427## CHECK: name "<<BReturn:B\d+>>" 428## CHECK: predecessors "<<BSplit:B\d+>>" "<<BCatch1:B\d+>>" "<<BCatch2:B\d+>>" 429## CHECK: Phi [<<Div>>,<<Minus1>>,<<Minus2>>] 430## CHECK: Return 431 432## CHECK: name "<<BCatch1>>" 433## CHECK: predecessors "<<BEnter1>>" "<<BExit1>>" 434## CHECK: successors "<<BReturn>>" 435## CHECK: flags "catch_block" 436## CHECK: Goto 437 438## CHECK: name "<<BCatch2>>" 439## CHECK: predecessors "<<BEnter2>>" "<<BExit2>>" 440## CHECK: successors "<<BReturn>>" 441## CHECK: flags "catch_block" 442## CHECK: Goto 443 444## CHECK: name "<<BEnter1>>" 445## CHECK: predecessors "<<BExit2>>" 446## CHECK: successors "<<BTry1>>" 447## CHECK: xhandlers "<<BCatch1>>" 448## CHECK: TryBoundary kind:entry 449 450## CHECK: name "<<BEnter2>>" 451## CHECK: predecessors "<<BGoto>>" 452## CHECK: successors "<<BTry2>>" 453## CHECK: xhandlers "<<BCatch2>>" 454## CHECK: TryBoundary kind:entry 455 456## CHECK: name "<<BExit1>>" 457## CHECK: predecessors "<<BTry1>>" 458## CHECK: successors "<<BSplit>>" 459## CHECK: xhandlers "<<BCatch1>>" 460## CHECK: TryBoundary kind:exit 461 462## CHECK: name "<<BExit2>>" 463## CHECK: predecessors "<<BTry2>>" 464## CHECK: successors "<<BEnter1>>" 465## CHECK: xhandlers "<<BCatch2>>" 466## CHECK: TryBoundary kind:exit 467 468## CHECK: name "<<BSplit>>" 469## CHECK: predecessors "<<BExit1>>" 470## CHECK: successors "<<BReturn>>" 471## CHECK: Goto 472 473.method public static testSharedBoundary_Reverse(III)I 474 .registers 3 475 476 goto :try_start_2 477 478 :try_start_1 479 div-int/2addr p0, p1 480 goto :return 481 :try_end_1 482 .catchall {:try_start_1 .. :try_end_1} :catch_all_1 483 484 :try_start_2 485 div-int/2addr p0, p2 486 goto :try_start_1 487 :try_end_2 488 .catchall {:try_start_2 .. :try_end_2} :catch_all_2 489 490 :return 491 return p0 492 493 :catch_all_1 494 const/4 p0, -0x1 495 goto :return 496 497 :catch_all_2 498 const/4 p0, -0x2 499 goto :return 500.end method 501 502# Test that nested tries are split into non-overlapping blocks and TryBoundary 503# blocks are correctly created between them. 504 505## CHECK-START: int Builder.testNestedTry(int, int, int, int) builder (after) 506 507## CHECK: name "B0" 508## CHECK-DAG: <<Minus1:i\d+>> IntConstant -1 509## CHECK-DAG: <<Minus2:i\d+>> IntConstant -2 510 511## CHECK: name "<<BTry1:B\d+>>" 512## CHECK: predecessors "<<BEnter1:B\d+>>" 513## CHECK: successors "<<BExit1:B\d+>>" 514## CHECK: Div 515 516## CHECK: name "<<BTry2:B\d+>>" 517## CHECK: predecessors "<<BEnter2:B\d+>>" 518## CHECK: successors "<<BExit2:B\d+>>" 519## CHECK: Div 520## CHECK: Goto 521 522## CHECK: name "<<BTry3:B\d+>>" 523## CHECK: predecessors "<<BEnter3:B\d+>>" 524## CHECK: successors "<<BExit3:B\d+>>" 525## CHECK: <<Div:i\d+>> Div 526## CHECK: Goto 527 528## CHECK: name "<<BReturn:B\d+>>" 529## CHECK: predecessors "<<BSplit:B\d+>>" "<<BCatchArith:B\d+>>" "<<BCatchAll:B\d+>>" 530## CHECK: Phi [<<Div>>,<<Minus1>>,<<Minus2>>] 531## CHECK: Return 532 533## CHECK: name "<<BCatchArith>>" 534## CHECK: predecessors "<<BEnter2>>" "<<BExit2>>" 535## CHECK: successors "<<BReturn>>" 536## CHECK: flags "catch_block" 537## CHECK: Goto 538 539## CHECK: name "<<BCatchAll>>" 540## CHECK: predecessors "<<BEnter1>>" "<<BEnter2>>" "<<BEnter3>>" "<<BExit1>>" "<<BExit2>>" "<<BExit3>>" 541## CHECK: successors "<<BReturn>>" 542## CHECK: flags "catch_block" 543## CHECK: Goto 544 545## CHECK: name "<<BEnter1>>" 546## CHECK: predecessors "B0" 547## CHECK: successors "<<BTry1>>" 548## CHECK: xhandlers "<<BCatchAll>>" 549## CHECK: TryBoundary kind:entry 550 551## CHECK: name "<<BEnter2>>" 552## CHECK: predecessors "<<BExit1>>" 553## CHECK: successors "<<BTry2>>" 554## CHECK: xhandlers "<<BCatchArith>>" "<<BCatchAll>>" 555## CHECK: TryBoundary kind:entry 556 557## CHECK: name "<<BEnter3>>" 558## CHECK: predecessors "<<BExit2>>" 559## CHECK: successors "<<BTry3>>" 560## CHECK: xhandlers "<<BCatchAll>>" 561## CHECK: TryBoundary kind:entry 562 563## CHECK: name "<<BExit1>>" 564## CHECK: predecessors "<<BTry1>>" 565## CHECK: successors "<<BEnter2>>" 566## CHECK: xhandlers "<<BCatchAll>>" 567## CHECK: TryBoundary kind:exit 568 569## CHECK: name "<<BExit2>>" 570## CHECK: predecessors "<<BTry2>>" 571## CHECK: successors "<<BEnter3>>" 572## CHECK: xhandlers "<<BCatchArith>>" "<<BCatchAll>>" 573## CHECK: TryBoundary kind:exit 574 575## CHECK: name "<<BExit3>>" 576## CHECK: predecessors "<<BTry3>>" 577## CHECK: successors "<<BSplit>>" 578## CHECK: xhandlers "<<BCatchAll>>" 579## CHECK: TryBoundary kind:exit 580 581## CHECK: name "<<BSplit>>" 582## CHECK: predecessors "<<BExit3>>" 583## CHECK: successors "<<BReturn>>" 584## CHECK: Goto 585 586.method public static testNestedTry(IIII)I 587 .registers 4 588 589 :try_start_1 590 div-int/2addr p0, p1 591 592 :try_start_2 593 div-int/2addr p0, p2 594 :try_end_2 595 .catch Ljava/lang/ArithmeticException; {:try_start_2 .. :try_end_2} :catch_arith 596 597 div-int/2addr p0, p3 598 :try_end_1 599 .catchall {:try_start_1 .. :try_end_1} :catch_all 600 601 :return 602 return p0 603 604 :catch_arith 605 const/4 p0, -0x1 606 goto :return 607 608 :catch_all 609 const/4 p0, -0x2 610 goto :return 611.end method 612 613# Test control flow that enters a try block, leaves it and returns again. 614 615## CHECK-START: int Builder.testIncontinuousTry(int, int, int, int) builder (after) 616 617## CHECK: name "B0" 618## CHECK: <<Minus1:i\d+>> IntConstant -1 619 620## CHECK: name "<<BTry1:B\d+>>" 621## CHECK: predecessors "<<BEnterTry1:B\d+>>" 622## CHECK: successors "<<BExitTry1:B\d+>>" 623## CHECK: Div 624## CHECK: Goto 625 626## CHECK: name "<<BTry2:B\d+>>" 627## CHECK: predecessors "<<BEnterTry2:B\d+>>" 628## CHECK: successors "<<BExitTry2:B\d+>>" 629## CHECK: <<Div:i\d+>> Div 630## CHECK: Goto 631 632## CHECK: name "<<BReturn:B\d+>>" 633## CHECK: predecessors "<<BSplit:B\d+>>" "<<BCatch:B\d+>>" 634## CHECK: Phi [<<Div>>,<<Minus1>>] 635## CHECK: Return 636 637## CHECK: name "<<BOutside:B\d+>>" 638## CHECK: predecessors "<<BExitTry1>>" 639## CHECK: successors "<<BEnterTry2>>" 640## CHECK: Div 641 642## CHECK: name "<<BCatch>>" 643## CHECK: predecessors "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>" 644## CHECK: successors "<<BReturn>>" 645## CHECK: flags "catch_block" 646## CHECK: Goto 647 648## CHECK: name "<<BEnterTry1>>" 649## CHECK: predecessors "B0" 650## CHECK: successors "<<BTry1>>" 651## CHECK: xhandlers "<<BCatch>>" 652## CHECK: TryBoundary kind:entry 653 654## CHECK: name "<<BEnterTry2>>" 655## CHECK: predecessors "<<BOutside>>" 656## CHECK: successors "<<BTry2>>" 657## CHECK: xhandlers "<<BCatch>>" 658## CHECK: TryBoundary kind:entry 659 660## CHECK: name "<<BExitTry1>>" 661## CHECK: predecessors "<<BTry1>>" 662## CHECK: successors "<<BOutside>>" 663## CHECK: xhandlers "<<BCatch>>" 664## CHECK: TryBoundary kind:exit 665 666## CHECK: name "<<BExitTry2>>" 667## CHECK: predecessors "<<BTry2>>" 668## CHECK: successors "<<BSplit>>" 669## CHECK: xhandlers "<<BCatch>>" 670## CHECK: TryBoundary kind:exit 671 672## CHECK: name "<<BSplit>>" 673## CHECK: predecessors "<<BExitTry2>>" 674## CHECK: successors "<<BReturn>>" 675## CHECK: Goto 676 677.method public static testIncontinuousTry(IIII)I 678 .registers 4 679 680 :try_start 681 div-int/2addr p0, p1 682 goto :outside 683 684 :inside 685 div-int/2addr p0, p3 686 :try_end 687 .catchall {:try_start .. :try_end} :catch_all 688 689 :return 690 return p0 691 692 :outside 693 div-int/2addr p0, p2 694 goto :inside 695 696 :catch_all 697 const/4 p0, -0x1 698 goto :return 699.end method 700 701## CHECK-START: int Builder.testSwitchTryEnter(int, int, int, int) builder (after) 702 703## CHECK: name "B0" 704## CHECK: successors "<<BPSwitch0:B\d+>>" 705 706## CHECK: name "<<BPSwitch0>>" 707## CHECK: predecessors "B0" 708## CHECK: successors "<<BSplit1:B\d+>>" "<<BPSwitch1:B\d+>>" 709## CHECK: If 710 711## CHECK: name "<<BPSwitch1>>" 712## CHECK: predecessors "<<BPSwitch0>>" 713## CHECK: successors "<<BSplit2:B\d+>>" "<<BEnterTry1:B\d+>>" 714## CHECK: If 715 716## CHECK: name "<<BTry1:B\d+>>" 717## CHECK: predecessors "<<BEnterTry1>>" 718## CHECK: successors "<<BExitTry1:B\d+>>" 719## CHECK: Div 720 721## CHECK: name "<<BTry2:B\d+>>" 722## CHECK: predecessors "<<BEnterTry2:B\d+>>" 723## CHECK: successors "<<BExitTry2:B\d+>>" 724## CHECK: Div 725 726## CHECK: name "<<BOutside:B\d+>>" 727## CHECK: predecessors "<<BSplit2>>" "<<BSplit4:B\d+>>" 728## CHECK: successors "<<BReturn:B\d+>>" 729## CHECK: Div 730 731## CHECK: name "<<BReturn>>" 732## CHECK: predecessors "<<BOutside>>" "<<BCatch:B\d+>>" 733## CHECK: successors "<<BExit:B\d+>>" 734## CHECK: Return 735 736## CHECK: name "<<BExit>>" 737## CHECK: Exit 738 739## CHECK: name "<<BCatch>>" 740## CHECK: predecessors "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>" 741## CHECK: successors "<<BReturn>>" 742## CHECK: flags "catch_block" 743## CHECK: Goto 744 745## CHECK: name "<<BEnterTry1>>" 746## CHECK: predecessors "<<BPSwitch1>>" 747## CHECK: successors "<<BTry1>>" 748## CHECK: xhandlers "<<BCatch>>" 749## CHECK: TryBoundary kind:entry 750 751## CHECK: name "<<BEnterTry2>>" 752## CHECK: predecessors "<<BSplit1>>" "<<BSplit3:B\d+>>" 753## CHECK: successors "<<BTry2>>" 754## CHECK: xhandlers "<<BCatch>>" 755## CHECK: TryBoundary kind:entry 756 757## CHECK: name "<<BExitTry1>>" 758## CHECK: predecessors "<<BTry1>>" 759## CHECK: successors "<<BSplit3>>" 760## CHECK: xhandlers "<<BCatch>>" 761## CHECK: TryBoundary kind:exit 762 763## CHECK: name "<<BExitTry2>>" 764## CHECK: predecessors "<<BTry2>>" 765## CHECK: successors "<<BSplit4>>" 766## CHECK: xhandlers "<<BCatch>>" 767## CHECK: TryBoundary kind:exit 768 769## CHECK: name "<<BSplit1>>" 770## CHECK: predecessors "<<BPSwitch0>>" 771## CHECK: successors "<<BEnterTry2>>" 772## CHECK: Goto 773 774## CHECK: name "<<BSplit2>>" 775## CHECK: predecessors "<<BPSwitch1>>" 776## CHECK: successors "<<BOutside>>" 777## CHECK: Goto 778 779## CHECK: name "<<BSplit3>>" 780## CHECK: predecessors "<<BExitTry1>>" 781## CHECK: successors "<<BEnterTry2>>" 782## CHECK: Goto 783 784## CHECK: name "<<BSplit4>>" 785## CHECK: predecessors "<<BExitTry2>>" 786## CHECK: successors "<<BOutside>>" 787## CHECK: Goto 788 789.method public static testSwitchTryEnter(IIII)I 790 .registers 4 791 792 packed-switch p0, :pswitch_data 793 794 :try_start 795 div-int/2addr p0, p1 796 797 :pswitch1 798 div-int/2addr p0, p2 799 goto :pswitch2 800 801 :pswitch_data 802 .packed-switch 0x0 803 :pswitch1 804 :pswitch2 805 .end packed-switch 806 :try_end 807 .catchall {:try_start .. :try_end} :catch_all 808 809 :pswitch2 810 div-int/2addr p0, p3 811 812 :catch_all 813 return p0 814.end method 815 816## CHECK-START: int Builder.testSwitchTryExit(int, int, int, int) builder (after) 817 818## CHECK: name "B0" 819## CHECK: successors "<<BEnterTry1:B\d+>>" 820 821## CHECK: name "<<BPSwitch0:B\d+>>" 822## CHECK: predecessors "<<BEnterTry1>>" 823## CHECK: successors "<<BSplit1:B\d+>>" "<<BExitTry1:B\d+>>" 824## CHECK: If 825 826## CHECK: name "<<BPSwitch1:B\d+>>" 827## CHECK: predecessors "<<BExitTry1>>" 828## CHECK: successors "<<BSplit2:B\d+>>" "<<BEnterTry2:B\d+>>" 829## CHECK: If 830 831## CHECK: name "<<BTry1:B\d+>>" 832## CHECK: predecessors "<<BEnterTry2>>" 833## CHECK: successors "<<BTry2:B\d+>>" 834## CHECK: Div 835 836## CHECK: name "<<BTry2>>" 837## CHECK: predecessors "<<BSplit1>>" "<<BTry1>>" 838## CHECK: successors "<<BExitTry2:B\d+>>" 839## CHECK: Div 840 841## CHECK: name "<<BOutside:B\d+>>" 842## CHECK: predecessors "<<BSplit2>>" "<<BSplit3:B\d+>>" 843## CHECK: successors "<<BReturn:B\d+>>" 844## CHECK: Div 845 846## CHECK: name "<<BReturn>>" 847## CHECK: predecessors "<<BOutside>>" "<<BCatch:B\d+>>" 848## CHECK: successors "<<BExit:B\d+>>" 849## CHECK: Return 850 851## CHECK: name "<<BExit>>" 852## CHECK: Exit 853 854## CHECK: name "<<BCatch>>" 855## CHECK: predecessors "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>" 856## CHECK: successors "<<BReturn>>" 857## CHECK: flags "catch_block" 858## CHECK: Goto 859 860## CHECK: name "<<BEnterTry1>>" 861## CHECK: predecessors "B0" 862## CHECK: successors "<<BPSwitch0>>" 863## CHECK: xhandlers "<<BCatch>>" 864## CHECK: TryBoundary kind:entry 865 866## CHECK: name "<<BEnterTry2>>" 867## CHECK: predecessors "<<BPSwitch1>>" 868## CHECK: successors "<<BTry1>>" 869## CHECK: xhandlers "<<BCatch>>" 870## CHECK: TryBoundary kind:entry 871 872## CHECK: name "<<BExitTry1>>" 873## CHECK: predecessors "<<BPSwitch0>>" 874## CHECK: successors "<<BPSwitch1>>" 875## CHECK: xhandlers "<<BCatch>>" 876## CHECK: TryBoundary kind:exit 877 878## CHECK: name "<<BExitTry2>>" 879## CHECK: predecessors "<<BTry2>>" 880## CHECK: successors "<<BSplit3>>" 881## CHECK: xhandlers "<<BCatch>>" 882## CHECK: TryBoundary kind:exit 883 884## CHECK: name "<<BSplit1>>" 885## CHECK: predecessors "<<BPSwitch0>>" 886## CHECK: successors "<<BTry2>>" 887## CHECK: Goto 888 889## CHECK: name "<<BSplit2>>" 890## CHECK: predecessors "<<BPSwitch1>>" 891## CHECK: successors "<<BOutside>>" 892## CHECK: Goto 893 894## CHECK: name "<<BSplit3>>" 895## CHECK: predecessors "<<BExitTry2>>" 896## CHECK: successors "<<BOutside>>" 897## CHECK: Goto 898 899.method public static testSwitchTryExit(IIII)I 900 .registers 4 901 902 :try_start 903 div-int/2addr p0, p1 904 packed-switch p0, :pswitch_data 905 906 div-int/2addr p0, p1 907 908 :pswitch1 909 div-int/2addr p0, p2 910 :try_end 911 .catchall {:try_start .. :try_end} :catch_all 912 913 :pswitch2 914 div-int/2addr p0, p3 915 916 :catch_all 917 return p0 918 919 :pswitch_data 920 .packed-switch 0x0 921 :pswitch1 922 :pswitch2 923 .end packed-switch 924.end method 925 926# Test that a TryBoundary is inserted between a Throw instruction and the exit 927# block when covered by a try range. 928 929## CHECK-START: int Builder.testThrow(java.lang.Exception) builder (after) 930 931## CHECK: name "B0" 932## CHECK: successors "<<BEnterTry:B\d+>>" 933## CHECK: <<Minus1:i\d+>> IntConstant -1 934 935## CHECK: name "<<BTry:B\d+>>" 936## CHECK: predecessors "<<BEnterTry>>" 937## CHECK: successors "<<BExitTry:B\d+>>" 938## CHECK: Throw 939 940## CHECK: name "<<BCatch:B\d+>>" 941## CHECK: predecessors "<<BEnterTry>>" "<<BExitTry>>" 942## CHECK: successors "<<BExit:B\d+>>" 943## CHECK: flags "catch_block" 944## CHECK: Return [<<Minus1>>] 945 946## CHECK: name "<<BExit>>" 947## CHECK: predecessors "<<BExitTry>>" "<<BCatch>>" 948## CHECK: Exit 949 950## CHECK: name "<<BEnterTry>>" 951## CHECK: predecessors "B0" 952## CHECK: successors "<<BTry>>" 953## CHECK: xhandlers "<<BCatch>>" 954## CHECK: TryBoundary kind:entry 955 956## CHECK: name "<<BExitTry>>" 957## CHECK: predecessors "<<BTry>>" 958## CHECK: successors "<<BExit>>" 959## CHECK: xhandlers "<<BCatch>>" 960## CHECK: TryBoundary kind:exit 961 962.method public static testThrow(Ljava/lang/Exception;)I 963 .registers 2 964 965 :try_start 966 throw p0 967 :try_end 968 .catchall {:try_start .. :try_end} :catch_all 969 970 :catch_all 971 const/4 v0, -0x1 972 return v0 973.end method 974 975# Test graph with a throw/catch loop. 976 977## CHECK-START: int Builder.testCatchLoop(int, int, int) builder (after) 978 979## CHECK: name "B0" 980## CHECK: successors "<<BSplit:B\d+>>" 981 982## CHECK: name "<<BTry:B\d+>>" 983## CHECK: predecessors "<<BEnterTry:B\d+>>" 984## CHECK: successors "<<BExitTry:B\d+>>" 985## CHECK: Div 986 987## CHECK: name "<<BReturn:B\d+>>" 988## CHECK: predecessors "<<BExitTry>>" 989## CHECK: successors "<<BExit:B\d+>>" 990## CHECK: Return 991 992## CHECK: name "<<BExit>>" 993## CHECK: predecessors "<<BReturn>>" 994## CHECK: Exit 995 996## CHECK: name "<<BCatch:B\d+>>" 997## CHECK: predecessors "<<BEnterTry>>" "<<BExitTry>>" 998## CHECK: successors "<<BEnterTry>>" 999## CHECK: flags "catch_block" 1000## CHECK: Goto 1001 1002## CHECK: name "<<BEnterTry>>" 1003## CHECK: predecessors "<<BSplit>>" "<<BCatch>>" 1004## CHECK: successors "<<BTry>>" 1005## CHECK: xhandlers "<<BCatch>>" 1006## CHECK: TryBoundary kind:entry 1007 1008## CHECK: name "<<BExitTry>>" 1009## CHECK: predecessors "<<BTry>>" 1010## CHECK: successors "<<BReturn>>" 1011## CHECK: xhandlers "<<BCatch>>" 1012## CHECK: TryBoundary kind:exit 1013 1014## CHECK: name "<<BSplit>>" 1015## CHECK: predecessors "B0" 1016## CHECK: successors "<<BEnterTry>>" 1017## CHECK: Goto 1018 1019.method public static testCatchLoop(III)I 1020 .registers 4 1021 1022 :try_start 1023 :catch_all 1024 div-int/2addr p0, p2 1025 :try_end 1026 .catchall {:try_start .. :try_end} :catch_all 1027 1028 :return 1029 return p0 1030.end method 1031 1032# Test that handler edges are not split. In this scenario, the catch block is 1033# only the handler of the try block. 1034 1035## CHECK-START: int Builder.testHandlerEdge1(int, int, int) builder (after) 1036 1037## CHECK: name "B0" 1038## CHECK: successors "<<BEnterTry1:B\d+>>" 1039 1040## CHECK: name "<<BTry1:B\d+>>" 1041## CHECK: predecessors "<<BEnterTry1>>" 1042## CHECK: successors "<<BExitTry1:B\d+>>" 1043## CHECK: Div 1044 1045## CHECK: name "<<BTry2:B\d+>>" 1046## CHECK: predecessors "<<BEnterTry2:B\d+>>" 1047## CHECK: successors "<<BExitTry2:B\d+>>" 1048## CHECK: Div 1049 1050## CHECK: name "<<BReturn:B\d+>>" 1051## CHECK: predecessors "<<BExitTry2>>" 1052## CHECK: successors "<<BExit:B\d+>>" 1053## CHECK: Return 1054 1055## CHECK: name "<<BExit>>" 1056## CHECK: predecessors "<<BReturn>>" 1057## CHECK: Exit 1058 1059## CHECK: name "<<BCatch:B\d+>>" 1060## CHECK: predecessors "<<BEnterTry1>>" "<<BEnterTry2>>" "<<BExitTry1>>" "<<BExitTry2>>" 1061## CHECK: successors "<<BEnterTry2>>" 1062## CHECK: flags "catch_block" 1063## CHECK: Goto 1064 1065## CHECK: name "<<BEnterTry1>>" 1066## CHECK: predecessors "B0" 1067## CHECK: successors "<<BTry1>>" 1068## CHECK: xhandlers "<<BCatch>>" 1069## CHECK: TryBoundary kind:entry 1070 1071## CHECK: name "<<BEnterTry2>>" 1072## CHECK: predecessors "<<BSplit:B\d+>>" "<<BCatch>>" 1073## CHECK: successors "<<BTry2>>" 1074## CHECK: xhandlers "<<BCatch>>" 1075## CHECK: TryBoundary kind:entry 1076 1077## CHECK: name "<<BExitTry1>>" 1078## CHECK: predecessors "<<BTry1>>" 1079## CHECK: successors "<<BSplit>>" 1080## CHECK: xhandlers "<<BCatch>>" 1081## CHECK: TryBoundary kind:exit 1082 1083## CHECK: name "<<BExitTry2>>" 1084## CHECK: predecessors "<<BTry2>>" 1085## CHECK: successors "<<BReturn>>" 1086## CHECK: xhandlers "<<BCatch>>" 1087## CHECK: TryBoundary kind:exit 1088 1089## CHECK: name "<<BSplit>>" 1090## CHECK: predecessors "<<BExitTry1>>" 1091## CHECK: successors "<<BEnterTry2>>" 1092## CHECK: Goto 1093 1094.method public static testHandlerEdge1(III)I 1095 .registers 4 1096 1097 :try_start 1098 div-int/2addr p0, p1 1099 1100 :catch_all 1101 div-int/2addr p0, p2 1102 :try_end 1103 .catchall {:try_start .. :try_end} :catch_all 1104 1105 return p0 1106.end method 1107 1108# Test that handler edges are not split. In this scenario, the catch block is 1109# the handler and also the successor of the try block. 1110 1111## CHECK-START: int Builder.testHandlerEdge2(int, int, int) builder (after) 1112 1113## CHECK: name "B0" 1114## CHECK: successors "<<BSplit1:B\d+>>" 1115 1116## CHECK: name "<<BTry1:B\d+>>" 1117## CHECK: predecessors "<<BEnterTry1:B\d+>>" 1118## CHECK: successors "<<BExitTry1:B\d+>>" 1119## CHECK: Div 1120 1121## CHECK: name "<<BTry2:B\d+>>" 1122## CHECK: predecessors "<<BEnterTry2:B\d+>>" 1123## CHECK: successors "<<BExitTry2:B\d+>>" 1124## CHECK: Div 1125 1126## CHECK: name "<<BReturn:B\d+>>" 1127## CHECK: predecessors "<<BExitTry2>>" 1128## CHECK: successors "<<BExit:B\d+>>" 1129## CHECK: Return 1130 1131## CHECK: name "<<BExit>>" 1132## CHECK: Exit 1133 1134## CHECK: name "<<BCatch2:B\d+>>" 1135## CHECK: predecessors "<<BEnterTry1>>" "<<BExitTry1>>" 1136## CHECK: successors "<<BEnterTry2>>" 1137## CHECK: flags "catch_block" 1138 1139## CHECK: name "<<BCatch1:B\d+>>" 1140## CHECK: predecessors "<<BEnterTry2>>" "<<BExitTry2>>" 1141## CHECK: successors "<<BEnterTry1>>" 1142## CHECK: flags "catch_block" 1143 1144## CHECK: name "<<BEnterTry1>>" 1145## CHECK: predecessors "<<BSplit1>>" "<<BCatch1>>" 1146## CHECK: successors "<<BTry1>>" 1147## CHECK: xhandlers "<<BCatch2>>" 1148## CHECK: TryBoundary kind:entry 1149 1150## CHECK: name "<<BEnterTry2>>" 1151## CHECK: predecessors "<<BSplit2:B\d+>>" "<<BCatch2>>" 1152## CHECK: successors "<<BTry2>>" 1153## CHECK: xhandlers "<<BCatch1>>" 1154## CHECK: TryBoundary kind:entry 1155 1156## CHECK: name "<<BExitTry1>>" 1157## CHECK: predecessors "<<BTry1>>" 1158## CHECK: successors "<<BSplit2>>" 1159## CHECK: xhandlers "<<BCatch2>>" 1160## CHECK: TryBoundary kind:exit 1161 1162## CHECK: name "<<BExitTry2>>" 1163## CHECK: predecessors "<<BTry2>>" 1164## CHECK: successors "<<BReturn>>" 1165## CHECK: xhandlers "<<BCatch1>>" 1166## CHECK: TryBoundary kind:exit 1167 1168## CHECK: name "<<BSplit1>>" 1169## CHECK: predecessors "B0" 1170## CHECK: successors "<<BEnterTry1>>" 1171## CHECK: Goto 1172 1173## CHECK: name "<<BSplit2>>" 1174## CHECK: predecessors "<<BExitTry1>>" 1175## CHECK: successors "<<BEnterTry2>>" 1176## CHECK: Goto 1177 1178.method public static testHandlerEdge2(III)I 1179 .registers 4 1180 1181 :try_start_1 1182 :catch_all_1 1183 div-int/2addr p0, p1 1184 :try_end_1 1185 .catchall {:try_start_1 .. :try_end_1} :catch_all_2 1186 1187 :try_start_2 1188 :catch_all_2 1189 div-int/2addr p0, p2 1190 :try_end_2 1191 .catchall {:try_start_2 .. :try_end_2} :catch_all_1 1192 1193 return p0 1194.end method 1195 1196# Test graph with try/catch inside a loop. 1197 1198## CHECK-START: int Builder.testTryInLoop(int, int) builder (after) 1199 1200## CHECK: name "B0" 1201## CHECK: successors "<<BSplit1:B\d+>>" 1202 1203## CHECK: name "<<BTry:B\d+>>" 1204## CHECK: predecessors "<<BEnterTry:B\d+>>" 1205## CHECK: successors "<<BExitTry:B\d+>>" 1206## CHECK: Div 1207 1208## CHECK: name "<<BCatch:B\d+>>" 1209## CHECK: predecessors "<<BEnterTry>>" "<<BExitTry>>" 1210## CHECK: successors "<<BEnterTry>>" 1211## CHECK: flags "catch_block" 1212 1213## CHECK: name "<<BEnterTry>>" 1214## CHECK: predecessors "<<BSplit1>>" 1215## CHECK: successors "<<BTry>>" 1216## CHECK: xhandlers "<<BCatch>>" 1217## CHECK: TryBoundary kind:entry 1218 1219## CHECK: name "<<BExitTry>>" 1220## CHECK: predecessors "<<BTry>>" 1221## CHECK: successors "<<BSplit2:B\d+>>" 1222## CHECK: xhandlers "<<BCatch>>" 1223## CHECK: TryBoundary kind:exit 1224 1225## CHECK: name "<<BSplit1>>" 1226## CHECK: predecessors "B0" 1227## CHECK: successors "<<BEnterTry>>" 1228## CHECK: Goto 1229 1230## CHECK: name "<<BSplit2>>" 1231## CHECK: predecessors "<<BExitTry>>" 1232## CHECK: successors "<<BEnterTry>>" 1233## CHECK: Goto 1234 1235.method public static testTryInLoop(II)I 1236 .registers 3 1237 1238 :try_start 1239 div-int/2addr p0, p1 1240 goto :try_start 1241 :try_end 1242 .catchall {:try_start .. :try_end} :catch_all 1243 1244 :catch_all 1245 goto :try_start 1246.end method 1247 1248# Test that a MOVE_RESULT instruction is placed into the same block as the 1249# INVOKE it follows, even if there is a try boundary between them. 1250 1251## CHECK-START: int Builder.testMoveResult_Invoke(int, int, int) builder (after) 1252## CHECK-DAG: <<M1:i\d+>> IntConstant -1 1253## CHECK-DAG: <<Res:i\d+>> InvokeStaticOrDirect 1254## CHECK-DAG: <<Phi:i\d+>> Phi [<<Res>>,<<M1>>] 1255## CHECK-DAG: Return [<<Phi>>] 1256 1257.method public static testMoveResult_Invoke(III)I 1258 .registers 3 1259 1260 :try_start 1261 invoke-static {p0, p1, p2}, LBuilder;->testCatchLoop(III)I 1262 :try_end 1263 .catchall {:try_start .. :try_end} :catch_all 1264 1265 move-result p0 1266 1267 :return 1268 return p0 1269 1270 :catch_all 1271 const/4 p0, -0x1 1272 goto :return 1273.end method 1274 1275# Test that a MOVE_RESULT instruction is placed into the same block as the 1276# FILLED_NEW_ARRAY it follows, even if there is a try boundary between them. 1277 1278## CHECK-START: int[] Builder.testMoveResult_FilledNewArray(int, int, int) builder (after) 1279## CHECK-DAG: <<Arg1:i\d+>> ParameterValue 1280## CHECK-DAG: <<Arg2:i\d+>> ParameterValue 1281## CHECK-DAG: <<Arg3:i\d+>> ParameterValue 1282## CHECK-DAG: <<Null:l\d+>> NullConstant 1283## CHECK-DAG: <<Res:l\d+>> NewArray 1284## CHECK-DAG: ArraySet [<<Res>>,{{i\d+}},<<Arg1>>] 1285## CHECK-DAG: ArraySet [<<Res>>,{{i\d+}},<<Arg2>>] 1286## CHECK-DAG: ArraySet [<<Res>>,{{i\d+}},<<Arg3>>] 1287## CHECK-DAG: <<Phi:l\d+>> Phi [<<Res>>,<<Null>>] 1288## CHECK-DAG: Return [<<Phi>>] 1289 1290.method public static testMoveResult_FilledNewArray(III)[I 1291 .registers 3 1292 1293 :try_start 1294 filled-new-array {p0, p1, p2}, [I 1295 :try_end 1296 .catchall {:try_start .. :try_end} :catch_all 1297 1298 move-result-object p0 1299 1300 :return 1301 return-object p0 1302 1303 :catch_all 1304 const/4 p0, 0x0 1305 goto :return 1306.end method 1307 1308# Test case for ReturnVoid inside a try block. Builder needs to move it outside 1309# the try block so as to not split the ReturnVoid-Exit edge. 1310# This invariant is enforced by GraphChecker. 1311 1312.method public static testReturnVoidInTry(II)V 1313 .registers 2 1314 1315 :catch_all 1316 :try_start 1317 return-void 1318 :try_end 1319 .catchall {:try_start .. :try_end} :catch_all 1320.end method 1321 1322# Test case for Return inside a try block. Builder needs to move it outside the 1323# try block so as to not split the Return-Exit edge. 1324# This invariant is enforced by GraphChecker. 1325 1326.method public static testReturnInTry(II)I 1327 .registers 2 1328 1329 :try_start 1330 div-int/2addr p0, p1 1331 return p0 1332 :try_end 1333 .catchall {:try_start .. :try_end} :catch_all 1334 1335 :catch_all 1336 const/4 v0, 0x0 1337 return v0 1338.end method 1339 1340# Test a (dead) try block which flows out of the method. The block will be 1341# removed by DCE but needs to pass post-builder GraphChecker. 1342 1343## CHECK-START: int Builder.testDeadEndTry(int) builder (after) 1344## CHECK-NOT: TryBoundary is_exit:true 1345 1346.method public static testDeadEndTry(I)I 1347 .registers 1 1348 1349 return p0 1350 1351 :catch_all 1352 nop 1353 1354 :try_start 1355 nop 1356 :try_end 1357 .catchall {:try_start .. :try_end} :catch_all 1358.end method 1359 1360# Test that a throw-catch loop on monitor-exit is eliminated. 1361# Note that we do not test this until after DCE which merges trivially split blocks. 1362 1363## CHECK-START: int Builder.testSynchronized(java.lang.Object) dead_code_elimination$initial (after) 1364## CHECK: flags "catch_block" 1365## CHECK-NOT: end_block 1366## CHECK: MonitorOperation kind:exit 1367 1368.method public static testSynchronized(Ljava/lang/Object;)I 1369 .registers 2 1370 1371 monitor-enter p0 1372 1373 :try_start_9 1374 invoke-virtual {p0}, Ljava/lang/Object;->hashCode()I 1375 move-result v0 1376 1377 monitor-exit p0 1378 return v0 1379 1380 :catchall_11 1381 move-exception v0 1382 monitor-exit p0 1383 :try_end_15 1384 .catchall {:try_start_9 .. :try_end_15} :catchall_11 1385 1386 throw v0 1387.end method 1388