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 // Note: We're not doing checker tests as we cannot do them specifically for a non-PIC 19 // configuration. The check here would be "prepare_for_register_allocation (before)" 20 // CHECK: LoadClass 21 // CHECK-NEXT: ClinitCheck 22 // CHECK-NEXT: LoadString load_kind:BootImageAddress 23 // CHECK-NEXT: NewInstance 24 // and "prepare_for_register_allocation (after)" 25 // CHECK: LoadString 26 // CHECK-NEXT: NewInstance 27 // but the order of instructions for non-PIC mode is different. $noinline$test()28 public static int $noinline$test() { 29 int r = 0x12345678; 30 do { 31 // LICM pulls the LoadClass and ClinitCheck out of the loop, leaves NewInstance in the loop. 32 Helper h = new Helper(); 33 // For non-PIC mode, LICM pulls the boot image LoadString out of the loop. 34 // (For PIC mode, the LoadString can throw and will not be moved out of the loop.) 35 String s = ""; // Empty string is known to be in the boot image. 36 r = r ^ (r >> 5); 37 h.$noinline$printString(s); 38 // During DCE after inlining, the loop back-edge disappears and the pre-header is 39 // merged with the body, leaving consecutive LoadClass, ClinitCheck, LoadString 40 // and NewInstance in non-PIC mode. The prepare_for_register_allocation pass 41 // merges the LoadClass and ClinitCheck with the NewInstance and checks that 42 // there are no instructions with side effects in between. This check used to 43 // fail because LoadString was always listing SideEffects::CanTriggerGC() even 44 // when it doesn't really have any side effects, i.e. for direct references to 45 // boot image Strings or for Strings known to be in the dex cache. 46 } while ($inline$shouldContinue()); 47 return r; 48 } 49 $inline$shouldContinue()50 static boolean $inline$shouldContinue() { 51 return false; 52 } 53 main(String[] args)54 public static void main(String[] args) { 55 assertIntEquals(0x12345678 ^ (0x12345678 >> 5), $noinline$test()); 56 } 57 assertIntEquals(int expected, int result)58 public static void assertIntEquals(int expected, int result) { 59 if (expected != result) { 60 throw new Error("Expected: " + expected + ", found: " + result); 61 } 62 } 63 } 64 65 class Helper { $noinline$printString(String s)66 public void $noinline$printString(String s) { 67 System.out.println("String: \"" + s + "\""); 68 } 69 } 70