1 /*
2  * Copyright (c) 1996, 2011, 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.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.misc;
27 
28 import static java.lang.Thread.State.*;
29 import java.util.Properties;
30 import java.util.HashMap;
31 import java.util.Map;
32 import java.util.Set;
33 
34 public class VM {
35 
36     /* The following methods used to be native methods that instruct
37      * the VM to selectively suspend certain threads in low-memory
38      * situations. They are inherently dangerous and not implementable
39      * on native threads. We removed them in JDK 1.2. The skeletons
40      * remain so that existing applications that use these methods
41      * will still work.
42      */
43     private static boolean suspended = false;
44 
45     /** @deprecated */
46     @Deprecated
threadsSuspended()47     public static boolean threadsSuspended() {
48         return suspended;
49     }
50 
allowThreadSuspension(ThreadGroup g, boolean b)51     public static boolean allowThreadSuspension(ThreadGroup g, boolean b) {
52         return g.allowThreadSuspension(b);
53     }
54 
55     /** @deprecated */
56     @Deprecated
suspendThreads()57     public static boolean suspendThreads() {
58         suspended = true;
59         return true;
60     }
61 
62     // Causes any suspended threadgroups to be resumed.
63     /** @deprecated */
64     @Deprecated
unsuspendThreads()65     public static void unsuspendThreads() {
66         suspended = false;
67     }
68 
69     // Causes threadgroups no longer marked suspendable to be resumed.
70     /** @deprecated */
71     @Deprecated
unsuspendSomeThreads()72     public static void unsuspendSomeThreads() {
73     }
74 
75     /* Deprecated fields and methods -- Memory advice not supported in 1.2 */
76 
77     /** @deprecated */
78     @Deprecated
79     public static final int STATE_GREEN = 1;
80 
81     /** @deprecated */
82     @Deprecated
83     public static final int STATE_YELLOW = 2;
84 
85     /** @deprecated */
86     @Deprecated
87     public static final int STATE_RED = 3;
88 
89     /** @deprecated */
90     @Deprecated
getState()91     public static final int getState() {
92         return STATE_GREEN;
93     }
94 
95     /** @deprecated */
96     @Deprecated
asChange(int as_old, int as_new)97     public static void asChange(int as_old, int as_new) { }
98 
99     /** @deprecated */
100     @Deprecated
asChange_otherthread(int as_old, int as_new)101     public static void asChange_otherthread(int as_old, int as_new) { }
102 
103     /*
104      * Not supported in 1.2 because these will have to be exported as
105      * JVM functions, and we are not sure we want do that. Leaving
106      * here so it can be easily resurrected -- just remove the //
107      * comments.
108      */
109 
110     /**
111      * Resume Java profiling.  All profiling data is added to any
112      * earlier profiling, unless <code>resetJavaProfiler</code> is
113      * called in between.  If profiling was not started from the
114      * command line, <code>resumeJavaProfiler</code> will start it.
115      * <p>
116      *
117      * NOTE: Profiling must be enabled from the command line for a
118      * java.prof report to be automatically generated on exit; if not,
119      * writeJavaProfilerReport must be invoked to write a report.
120      *
121      * @see     resetJavaProfiler
122      * @see     writeJavaProfilerReport
123      */
124 
125     // public native static void resumeJavaProfiler();
126 
127     /**
128      * Suspend Java profiling.
129      */
130     // public native static void suspendJavaProfiler();
131 
132     /**
133      * Initialize Java profiling.  Any accumulated profiling
134      * information is discarded.
135      */
136     // public native static void resetJavaProfiler();
137 
138     /**
139      * Write the current profiling contents to the file "java.prof".
140      * If the file already exists, it will be overwritten.
141      */
142     // public native static void writeJavaProfilerReport();
143 
144 
145     private static volatile boolean booted = false;
146 
147     // Invoked by by System.initializeSystemClass just before returning.
148     // Subsystems that are invoked during initialization can check this
149     // property in order to avoid doing things that should wait until the
150     // application class loader has been set up.
151     //
booted()152     public static void booted() {
153         booted = true;
154     }
155 
isBooted()156     public static boolean isBooted() {
157         return booted;
158     }
159 
160     // A user-settable upper limit on the maximum amount of allocatable direct
161     // buffer memory.  This value may be changed during VM initialization if
162     // "java" is launched with "-XX:MaxDirectMemorySize=<size>".
163     //
164     // The initial value of this field is arbitrary; during JRE initialization
165     // it will be reset to the value specified on the command line, if any,
166     // otherwise to Runtime.getRuntime.maxDirectMemory().
167     //
168     private static long directMemory = 64 * 1024 * 1024;
169 
170     // Returns the maximum amount of allocatable direct buffer memory.
171     // The directMemory variable is initialized during system initialization
172     // in the saveAndRemoveProperties method.
173     //
maxDirectMemory()174     public static long maxDirectMemory() {
175         return directMemory;
176     }
177 
178     // User-controllable flag that determines if direct buffers should be page
179     // aligned. The "-XX:+PageAlignDirectMemory" option can be used to force
180     // buffers, allocated by ByteBuffer.allocateDirect, to be page aligned.
181     private static boolean pageAlignDirectMemory;
182 
183     // Returns {@code true} if the direct buffers should be page aligned. This
184     // variable is initialized by saveAndRemoveProperties.
isDirectMemoryPageAligned()185     public static boolean isDirectMemoryPageAligned() {
186         return pageAlignDirectMemory;
187     }
188 
189     // A user-settable boolean to determine whether ClassLoader.loadClass should
190     // accept array syntax.  This value may be changed during VM initialization
191     // via the system property "sun.lang.ClassLoader.allowArraySyntax".
192     //
193     // The default for 1.5 is "true", array syntax is allowed.  In 1.6, the
194     // default will be "false".  The presence of this system property to
195     // control array syntax allows applications the ability to preview this new
196     // behaviour.
197     //
198     private static boolean defaultAllowArraySyntax = false;
199     private static boolean allowArraySyntax = defaultAllowArraySyntax;
200 
201     // The allowArraySyntax boolean is initialized during system initialization
202     // in the saveAndRemoveProperties method.
203     //
204     // It is initialized based on the value of the system property
205     // "sun.lang.ClassLoader.allowArraySyntax".  If the system property is not
206     // provided, the default for 1.5 is "true".  In 1.6, the default will be
207     // "false".  If the system property is provided, then the value of
208     // allowArraySyntax will be equal to "true" if Boolean.parseBoolean()
209     // returns "true".   Otherwise, the field will be set to "false".
210     //
allowArraySyntax()211     public static boolean allowArraySyntax() {
212         return allowArraySyntax;
213     }
214 
215     private static boolean allowGetCallerClass = true;
216 
217     // Reflection.getCallerClass(int) is enabled by default.
218     // It can be disabled by setting the system property
219     // "jdk.reflect.allowGetCallerClass" to "false". It cannot be
220     // disabled if the logging stack walk (to find resource bundles)
221     // is enabled.
allowGetCallerClass()222     public static boolean allowGetCallerClass() {
223         return allowGetCallerClass;
224     }
225 
226     /**
227      * Returns the system property of the specified key saved at
228      * system initialization time.  This method should only be used
229      * for the system properties that are not changed during runtime.
230      * It accesses a private copy of the system properties so
231      * that user's locking of the system properties object will not
232      * cause the library to deadlock.
233      *
234      * Note that the saved system properties do not include
235      * the ones set by sun.misc.Version.init().
236      *
237      */
getSavedProperty(String key)238     public static String getSavedProperty(String key) {
239         // TODO(narayan): Why is this commented out ?
240         // if (savedProps.isEmpty())
241         //     throw new IllegalStateException("Should be non-empty if initialized");
242 
243         return savedProps.getProperty(key);
244     }
245 
246     // TODO: the Property Management needs to be refactored and
247     // the appropriate prop keys need to be accessible to the
248     // calling classes to avoid duplication of keys.
249     private static final Properties savedProps = new Properties();
250 
251     // Save a private copy of the system properties and remove
252     // the system properties that are not intended for public access.
253     //
254     // This method can only be invoked during system initialization.
saveAndRemoveProperties(Properties props)255     public static void saveAndRemoveProperties(Properties props) {
256         if (booted)
257             throw new IllegalStateException("System initialization has completed");
258 
259         savedProps.putAll(props);
260 
261         // Set the maximum amount of direct memory.  This value is controlled
262         // by the vm option -XX:MaxDirectMemorySize=<size>.
263         // The maximum amount of allocatable direct buffer memory (in bytes)
264         // from the system property sun.nio.MaxDirectMemorySize set by the VM.
265         // The system property will be removed.
266         String s = (String)props.remove("sun.nio.MaxDirectMemorySize");
267         if (s != null) {
268             if (s.equals("-1")) {
269                 // -XX:MaxDirectMemorySize not given, take default
270                 directMemory = Runtime.getRuntime().maxMemory();
271             } else {
272                 long l = Long.parseLong(s);
273                 if (l > -1)
274                     directMemory = l;
275             }
276         }
277 
278         // Check if direct buffers should be page aligned
279         s = (String)props.remove("sun.nio.PageAlignDirectMemory");
280         if ("true".equals(s))
281             pageAlignDirectMemory = true;
282 
283         // Set a boolean to determine whether ClassLoader.loadClass accepts
284         // array syntax.  This value is controlled by the system property
285         // "sun.lang.ClassLoader.allowArraySyntax".
286         s = props.getProperty("sun.lang.ClassLoader.allowArraySyntax");
287         allowArraySyntax = (s == null
288                                ? defaultAllowArraySyntax
289                                : Boolean.parseBoolean(s));
290 
291         // Reflection.getCallerClass(int) is enabled by default.
292         // It can be disabled by setting a system property (but only if
293         // the logging stack walk is not enabled)
294         s = props.getProperty("jdk.reflect.allowGetCallerClass");
295         allowGetCallerClass = (s != null
296                                    ? (s.isEmpty() || Boolean.parseBoolean(s))
297                                    : true) ||
298              Boolean.valueOf(props.getProperty("jdk.logging.allowStackWalkSearch"));
299 
300         // Remove other private system properties
301         // used by java.lang.Integer.IntegerCache
302         props.remove("java.lang.Integer.IntegerCache.high");
303 
304         // used by java.util.zip.ZipFile
305         props.remove("sun.zip.disableMemoryMapping");
306 
307         // used by sun.launcher.LauncherHelper
308         props.remove("sun.java.launcher.diag");
309     }
310 
311     // Initialize any miscellenous operating system settings that need to be
312     // set for the class libraries.
313     //
initializeOSEnvironment()314     public static void initializeOSEnvironment() {
315     }
316 
317     /* Current count of objects pending for finalization */
318     private static volatile int finalRefCount = 0;
319 
320     /* Peak count of objects pending for finalization */
321     private static volatile int peakFinalRefCount = 0;
322 
323     /*
324      * Gets the number of objects pending for finalization.
325      *
326      * @return the number of objects pending for finalization.
327      */
getFinalRefCount()328     public static int getFinalRefCount() {
329         return finalRefCount;
330     }
331 
332     /*
333      * Gets the peak number of objects pending for finalization.
334      *
335      * @return the peak number of objects pending for finalization.
336      */
getPeakFinalRefCount()337     public static int getPeakFinalRefCount() {
338         return peakFinalRefCount;
339     }
340 
341     /*
342      * Add <tt>n</tt> to the objects pending for finalization count.
343      *
344      * @param n an integer value to be added to the objects pending
345      * for finalization count
346      */
addFinalRefCount(int n)347     public static void addFinalRefCount(int n) {
348         // The caller must hold lock to synchronize the update.
349 
350         finalRefCount += n;
351         if (finalRefCount > peakFinalRefCount) {
352             peakFinalRefCount = finalRefCount;
353         }
354     }
355 
356     /**
357      * Returns Thread.State for the given threadStatus
358      */
toThreadState(int threadStatus)359     public static Thread.State toThreadState(int threadStatus) {
360         if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
361             return RUNNABLE;
362         } else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
363             return BLOCKED;
364         } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {
365             return WAITING;
366         } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {
367             return TIMED_WAITING;
368         } else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {
369             return TERMINATED;
370         } else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {
371             return NEW;
372         } else {
373             return RUNNABLE;
374         }
375     }
376 
377     /* The threadStatus field is set by the VM at state transition
378      * in the hotspot implementation. Its value is set according to
379      * the JVM TI specification GetThreadState function.
380      */
381     private final static int JVMTI_THREAD_STATE_ALIVE = 0x0001;
382     private final static int JVMTI_THREAD_STATE_TERMINATED = 0x0002;
383     private final static int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;
384     private final static int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
385     private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
386     private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
387 }
388