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