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