1/*
2 * Copyright (c) 2016, 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
24import sun.jvm.hotspot.memory.SymbolTable;
25import sun.jvm.hotspot.oops.Symbol;
26import sun.jvm.hotspot.runtime.VM;
27import sun.jvm.hotspot.tools.Tool;
28
29/**
30 * This class is launched in a sub-process by the main test,
31 * SASymbolTableTest.java.
32 *
33 * It uses SA to connect to another JVM process, whose PID is specified in args[].
34 * The purpose of the test is to validate that we can walk the SymbolTable
35 * and CompactHashTable of the other process. Everything should work regardless
36 * of whether the other process runs in CDS mode or not.
37 *
38 * Note: CompactHashTable is used only when CDS is enabled.
39 */
40public class SASymbolTableTestAgent extends Tool {
41    public SASymbolTableTestAgent() {
42        super();
43    }
44    public static void main(String args[]) {
45        SASymbolTableTestAgent tool = new SASymbolTableTestAgent();
46        tool.execute(args);
47    }
48
49    static String[] commonNames = {
50        "java/lang/Object",
51        "java/lang/String",
52        "java/lang/Class",
53        "java/lang/Cloneable",
54        "java/lang/ClassLoader",
55        "java/io/Serializable",
56        "java/lang/System",
57        "java/lang/Throwable",
58        "java/lang/Error",
59        "java/lang/ThreadDeath",
60        "java/lang/Exception",
61        "java/lang/RuntimeException",
62        "java/lang/SecurityManager",
63        "java/security/ProtectionDomain",
64        "java/security/AccessControlContext",
65        "java/security/SecureClassLoader",
66        "java/lang/ClassNotFoundException",
67        "java/lang/NoClassDefFoundError",
68        "java/lang/LinkageError",
69        "java/lang/ClassCastException",
70        "java/lang/ArrayStoreException",
71        "java/lang/VirtualMachineError",
72        "java/lang/OutOfMemoryError",
73        "java/lang/StackOverflowError",
74        "java/lang/IllegalMonitorStateException",
75        "java/lang/ref/Reference",
76        "java/lang/ref/SoftReference",
77        "java/lang/ref/WeakReference",
78        "java/lang/ref/FinalReference",
79        "java/lang/ref/PhantomReference",
80        "java/lang/ref/Finalizer",
81        "java/lang/Thread",
82        "java/lang/ThreadGroup",
83        "java/util/Properties",
84        "java/lang/reflect/AccessibleObject",
85        "java/lang/reflect/Field",
86        "java/lang/reflect/Method",
87        "java/lang/reflect/Constructor",
88        "java/lang/invoke/MethodHandle",
89        "java/lang/invoke/MemberName",
90        "java/lang/invoke/MethodHandleNatives",
91        "java/lang/invoke/MethodType",
92        "java/lang/BootstrapMethodError",
93        "java/lang/invoke/CallSite",
94        "java/lang/invoke/ConstantCallSite",
95        "java/lang/invoke/MutableCallSite",
96        "java/lang/invoke/VolatileCallSite",
97        "java/lang/StringBuffer",
98        "java/lang/StringBuilder",
99        "java/io/ByteArrayInputStream",
100        "java/io/File",
101        "java/net/URLClassLoader",
102        "java/net/URL",
103        "java/util/jar/Manifest",
104        "java/security/CodeSource",
105    };
106
107    static String[] badNames = {
108        "java/lang/badbadbad",
109        "java/io/badbadbadbad",
110        "this*symbol*must*not*exist"
111    };
112
113    public void run() {
114        System.out.println("SASymbolTableTestAgent: starting");
115        try {
116            VM vm = VM.getVM();
117            SymbolTable table = vm.getSymbolTable();
118
119            // (a) These are names that are likely to exist in the symbol table
120            //     of a JVM after start-up. They were taken from vmSymbols.hpp
121            //     during the middle of JDK9 development.
122            //
123            //     The purpose is not to check that each name must exist (a future
124            //     version of JDK may not preload some of the classes).
125            //
126            //     The purpose of this loops is to ensure that we check a lot of symbols,
127            //     so we will (most likely) hit on both VALUE_ONLY_BUCKET_TYPE and normal bucket type
128            //     in CompactHashTable.probe().
129            for (String n : commonNames) {
130                Symbol s = table.probe(n);
131                System.out.format("%-40s = %s\n", n, s);
132            }
133
134            System.out.println("======================================================================");
135
136            // (b) Also test a few strings that are known to not exist in the table. This will
137            //     both the compact table (if it exists) and the regular table to be walked.
138            for (String n : badNames) {
139                Symbol s = table.probe(n);
140                System.out.format("%-40s = %s\n", n, s);
141            }
142        } catch (NullPointerException e) {
143            System.out.println("connected too early -- please try again");
144        }
145    }
146}
147