1 /* 2 * Copyright (C) 2015 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 class Main { main(String[] args)18 public static void main(String[] args) { 19 foo(); 20 } 21 foo()22 public static void foo() { 23 int a = myField1; // esi 24 int b = myField2; // edi 25 $noinline$bar(); // makes allocation of a and b to be callee-save registers 26 int c = myField3; // ecx 27 int e = myField4; // ebx 28 int f = myField5; // edx 29 long d = a == 42 ? myLongField1 : 42L; // Will call AllocateBlockedReg -> edx/ebx 30 31 // At this point, the register allocator used to be in a bogus state, where the low 32 // part of the interval was in the active set, but not the high part. 33 34 long i = myLongField1; // Will call TrySplitNonPairOrUnalignedPairIntervalAt -> Failing DCHECK 35 36 // Use esi and edi first to not have d allocated to them. 37 myField2 = a; 38 myField3 = b; 39 40 // The following sequence of instructions are making the AllocateBlockedReg call 41 // for allocating the d variable misbehave: allocation of the low interval would split 42 // both low and high interval at the fixed use; therefore the allocation of the high interval 43 // would not see the register use, and think the interval can just be spilled and not be 44 // put in the active set, even though it is holding a register. 45 myField1 = (int)d; // stack use 46 myLongField3 = (long) myField2; // edx fixed use 47 myLongField2 = d; // register use 48 49 // Ensure the HInstruction mapping to i, c, e, and f have a live range. 50 myLongField1 = i; 51 myField4 = c; 52 myField5 = e; 53 myField6 = f; 54 } 55 $noinline$bar()56 public static long $noinline$bar() { 57 if (doThrow) throw new Error(); 58 return 42; 59 } 60 61 public static boolean doThrow = false; 62 63 public static int myField1 = 0; 64 public static int myField2 = 0; 65 public static int myField3 = 0; 66 public static int myField4 = 0; 67 public static int myField5 = 0; 68 public static int myField6 = 0; 69 public static long myLongField1 = 0L; 70 public static long myLongField2 = 0L; 71 public static long myLongField3 = 0L; 72 } 73