1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 public class Main { 18 static boolean doThrow = false; 19 20 // Note: We're not doing checker tests as we cannot do them specifically for a non-PIC 21 // configuration. The check here would be "prepare_for_register_allocation (before)" 22 // CHECK: LoadClass 23 // CHECK-NEXT: ClinitCheck 24 // CHECK-NEXT: LoadString load_kind:BootImageAddress 25 // CHECK-NEXT: NewInstance 26 // and "prepare_for_register_allocation (after)" 27 // CHECK: LoadString 28 // CHECK-NEXT: NewInstance 29 // but the order of instructions for non-PIC mode is different. $noinline$test()30 public static int $noinline$test() { 31 if (doThrow) { throw new Error(); } 32 33 int r = 0x12345678; 34 do { 35 // LICM pulls the LoadClass and ClinitCheck out of the loop, leaves NewInstance in the loop. 36 Helper h = new Helper(); 37 // For non-PIC mode, LICM pulls the boot image LoadString out of the loop. 38 // (For PIC mode, the LoadString can throw and will not be moved out of the loop.) 39 String s = ""; // Empty string is known to be in the boot image. 40 r = r ^ (r >> 5); 41 h.$noinline$printString(s); 42 // During DCE after inlining, the loop back-edge disappears and the pre-header is 43 // merged with the body, leaving consecutive LoadClass, ClinitCheck, LoadString 44 // and NewInstance in non-PIC mode. The prepare_for_register_allocation pass 45 // merges the LoadClass and ClinitCheck with the NewInstance and checks that 46 // there are no instructions with side effects in between. This check used to 47 // fail because LoadString was always listing SideEffects::CanTriggerGC() even 48 // when it doesn't really have any side effects, i.e. for direct references to 49 // boot image Strings or for Strings known to be in the dex cache. 50 } while ($inline$shouldContinue()); 51 return r; 52 } 53 $inline$shouldContinue()54 static boolean $inline$shouldContinue() { 55 return false; 56 } 57 main(String[] args)58 public static void main(String[] args) { 59 assertIntEquals(0x12345678 ^ (0x12345678 >> 5), $noinline$test()); 60 } 61 assertIntEquals(int expected, int result)62 public static void assertIntEquals(int expected, int result) { 63 if (expected != result) { 64 throw new Error("Expected: " + expected + ", found: " + result); 65 } 66 } 67 } 68 69 class Helper { 70 static boolean doThrow = false; 71 $noinline$printString(String s)72 public void $noinline$printString(String s) { 73 if (doThrow) { throw new Error(); } 74 75 System.out.println("String: \"" + s + "\""); 76 } 77 } 78