1 /* 2 * Copyright (c) 2000, 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 4326648 4768329 27 * @summary Test to verify that table entries are generated for all final 28 * locals when a class is built for debug, even if they could be 29 * inlined otherwise. 30 * @author Tim Bell 31 * 32 * @run build TestScaffold VMConnection TargetListener TargetAdapter 33 * @run compile -g FinalLocalsTest.java 34 * @run driver FinalLocalsTest 35 */ 36 import com.sun.jdi.*; 37 import com.sun.jdi.event.*; 38 import com.sun.jdi.request.*; 39 40 import java.util.*; 41 42 /********** target program **********/ 43 44 class FinalLocalsTarg { 45 public void test1 (final int t, int k){ 46 String s1 = "first"; 47 final int z = 0; 48 if (true) { 49 final float r = 10.00f; 50 boolean b = true; 51 System.out.println(r); 52 } 53 } 54 public void hi(){ 55 return; 56 } 57 public static void main(String[] args) { 58 System.out.print("in FinalLocalsTarg:"); 59 new FinalLocalsTarg().hi(); 60 return; 61 } 62 } 63 64 /********** test program **********/ 65 66 public class FinalLocalsTest extends TestScaffold { 67 ReferenceType targetClass; 68 ThreadReference mainThread; 69 70 FinalLocalsTest (String args[]) { 71 super(args); 72 } 73 74 public static void main(String[] args) throws Exception { 75 new FinalLocalsTest(args).startTests(); 76 } 77 78 /********** test core **********/ 79 static final int VARIABLES = 1; 80 static final int BYNAME = 2; 81 static final int ARGUMENTS = 3; 82 /* 83 * Take a String containing comma separated values 84 * and return those values in a TreeSet. 85 */ 86 private TreeSet buildSet(String in) { 87 TreeSet result = new TreeSet(); 88 StringTokenizer tt = new StringTokenizer(in, ","); 89 while (tt.hasMoreTokens()) { 90 String ss = tt.nextToken(); 91 if (! result.add(ss)) { 92 failure ("Duplicate entry \"" + ss + "\" in string: " + 93 in + " is not allowed"); 94 } 95 } 96 return result; 97 } 98 99 private void test(Method method, int which, String name, String expected) { 100 String got = testCase(method, which); 101 System.out.println(" test() comparing expected = " + expected + 102 " to got = " + got); 103 TreeSet expectedSet = buildSet(expected); 104 TreeSet gotSet = buildSet(got); 105 106 while (! expectedSet.isEmpty()) { 107 String ee = (String)expectedSet.first(); 108 expectedSet.remove(ee); 109 if (gotSet.contains(ee)) { 110 gotSet.remove(ee); 111 } else { 112 failure (name + " Expected entry \"" + ee + "\" not found"); 113 } 114 } 115 116 //assert expectedSet.isEmpty() : name + " expected set should have been emptied"; 117 118 if (! gotSet.isEmpty()) { 119 StringBuffer sb = new StringBuffer(); 120 Iterator it = gotSet.iterator(); 121 while (it.hasNext()) { 122 sb.append(it.next()); 123 if (it.hasNext()) { 124 sb.append(","); 125 } 126 } 127 failure (name + " Unexpected entries found: " + sb.toString()); 128 } 129 } 130 131 String testCase(Method method, int which) { 132 try { 133 List vars; 134 switch (which) { 135 case VARIABLES: 136 vars = method.variables(); 137 break; 138 case BYNAME: 139 vars = method.variablesByName("s1"); 140 break; 141 case ARGUMENTS: 142 vars = method.arguments(); 143 break; 144 default: 145 throw new InternalException("should not happen"); 146 } 147 StringBuffer sb = new StringBuffer(); 148 for (Iterator it = vars.iterator(); it.hasNext(); ) { 149 LocalVariable lv = (LocalVariable)it.next(); 150 if (sb.length() > 0) { 151 sb.append(","); 152 } 153 sb.append(lv.name()); 154 } 155 return sb.toString(); 156 } catch (Exception exc) { 157 String st = exc.getClass().getName(); 158 int inx = st.lastIndexOf('.'); 159 return st.substring(inx+1); 160 } 161 } 162 163 protected void runTests() throws Exception { 164 /* 165 * Get to the top of main() 166 * to determine targetClass and mainThread 167 */ 168 BreakpointEvent bpe = startToMain("FinalLocalsTarg"); 169 targetClass = bpe.location().declaringType(); 170 mainThread = bpe.thread(); 171 EventRequestManager erm = vm().eventRequestManager(); 172 173 /* 174 * Get to a point where the classes are loaded. 175 */ 176 BreakpointEvent bp = resumeTo("FinalLocalsTarg", "hi", "()V"); 177 178 ReferenceType rt = findReferenceType("FinalLocalsTarg"); 179 if (rt == null) { 180 throw new Exception("FinalLocalsTarg: not loaded"); 181 } 182 183 /* 184 * Inspect the LocalVariableTable attributes for method "test1" 185 * NOTE: .class files compiled with some versions of javac will 186 * give results listed in different order. That's OK. 187 */ 188 Method method = findMethod(rt, "test1", "(II)V"); 189 if (method == null) { 190 throw new Exception("Method not found"); 191 } 192 test(method, VARIABLES, "VARIABLES", 193 "t,k,s1,z,r,b"); 194 test(method, BYNAME, "BYNAME", 195 "s1"); 196 test(method, ARGUMENTS, "ARGUMENTS", 197 "t,k"); 198 199 /* 200 * All Done. Resume the target listening for events 201 */ 202 listenUntilVMDisconnect(); 203 204 /* 205 * deal with results of test 206 * if anything has called failure("foo") testFailed will be true 207 */ 208 if (!testFailed) { 209 println("FinalLocalsTest: passed"); 210 } else { 211 throw new Exception("FinalLocalsTest: failed"); 212 } 213 } 214 }