FinalLocalsTest.java revision 11884:b45c81ca8671
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 */
38import com.sun.jdi.*;
39import com.sun.jdi.event.*;
40import com.sun.jdi.request.*;
41
42import java.util.*;
43
44    /********** target program **********/
45
46class 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
68public 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}
217