1 /* 2 * Copyright (c) 1999, 2015, 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 * @bug 4238644 4238643 4238641 4944198 27 * @summary Test javac regressions in the generation of line number info 28 * @author Gordon Hirsch 29 * 30 * @run build TestScaffold VMConnection TargetListener TargetAdapter 31 * @run compile -XDstringConcat=inline -g LineNumberInfo.java ControlFlow.java 32 * 33 * @run driver LineNumberInfo 34 */ 35 import com.sun.jdi.*; 36 import com.sun.jdi.event.*; 37 import com.sun.jdi.request.*; 38 39 import java.util.List; 40 import java.util.Iterator; 41 42 public class LineNumberInfo extends TestScaffold { 43 /* 44 * These two arrays are used to validate the line number 45 * information returned by JDI. There are limitations to 46 * this approach: 47 * - there are no strict rules about 48 * what constitutes the "right" line number mapping, so 49 * this kind of test may have false negatives with other 50 * compilers. 51 * - this test is also sensitive to the compiler's code generation; 52 * if that changes, this test will likely need updating. 53 * - this test assumes that JDI code index == class file 54 * byte code index which may not be true in all VMs. 55 * - To find the values for these tables, compile ControlFlow.java and then 56 * do: 57 * javap -classpath _jj1.solaris-sparc/JTwork/classes/com/sun/jdi \ 58 * -l ControlFlow 59 */ 60 final int[] lineNumbers = { 61 15, 62 16, 63 19, 64 20, 65 22, 66 25, 67 26, 68 28, 69 32, 70 33, 71 34, 72 36, 73 37, 74 36, 75 40, 76 41, 77 42, 78 45, 79 46, 80 45, 81 49, 82 51, 83 53, 84 55, 85 57, 86 59, 87 60, 88 62, 89 65, 90 67, 91 69, 92 71, 93 73, 94 75, 95 78 96 }; 97 98 final int[] codeIndices = { 99 0 , 100 7 , 101 15 , 102 22 , 103 33 , 104 43 , 105 50 , 106 60 , 107 68 , 108 76 , 109 77 , 110 85 , 111 93 , 112 96 , 113 107, 114 111, 115 119, 116 129, 117 139, 118 178, 119 184, 120 240, 121 250, 122 260, 123 270, 124 280, 125 288, 126 291, 127 301, 128 336, 129 346, 130 356, 131 366, 132 376, 133 384 134 }; 135 136 LineNumberInfo(String args[]) { 137 super(args); 138 } 139 140 public static void main(String args[]) throws Exception { 141 new LineNumberInfo(args).startTests(); 142 } 143 144 protected void runTests() throws Exception { 145 startUp("ControlFlow"); 146 147 // Get the ControlFlow class loaded. 148 ClassPrepareEvent event = resumeToPrepareOf("ControlFlow"); 149 150 ClassType clazz = (ClassType)event.referenceType(); 151 Method method = clazz.concreteMethodByName("go", "()V"); 152 List locations = method.allLineLocations(); 153 154 if (lineNumbers.length != codeIndices.length) { 155 failure("FAILED: Bad test. Line number and code index arrays " + 156 "must be equal in size"); 157 } 158 159 if (locations.size() != codeIndices.length) { 160 // Help the tester see why it failed. 161 Iterator iter = locations.iterator(); 162 while (iter.hasNext()) { 163 Location location = (Location)iter.next(); 164 System.err.println("location=" + location); 165 } 166 167 failure("FAILED: Bad line number table size: jdi=" + 168 locations.size() + 169 ", test=" + codeIndices.length); 170 } 171 172 int i = 0; 173 Iterator iter = locations.iterator(); 174 while (iter.hasNext()) { 175 Location location = (Location)iter.next(); 176 if (location.codeIndex() != codeIndices[i]) { 177 failure("FAILED: Code index mismatch: jdi=" + 178 location.codeIndex() + 179 ", test=" + codeIndices[i]); 180 } 181 if (location.lineNumber() != lineNumbers[i]) { 182 failure("FAILED: Line number mismatch: jdi=" + 183 location.lineNumber() + 184 ", test=" + lineNumbers[i]); 185 } 186 i++; 187 } 188 189 190 // Allow application to complete 191 listenUntilVMDisconnect(); 192 193 /* 194 * deal with results of test 195 * if anything has called failure("foo") testFailed will be true 196 */ 197 if (!testFailed) { 198 println("LineNumberInfo: passed"); 199 } else { 200 throw new Exception("LineNumberInfo: failed"); 201 } 202 203 } 204 }