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
26package sun.misc;
27
28import static java.lang.Thread.State.*;
29import java.util.Properties;
30import java.util.HashMap;
31import java.util.Map;
32import java.util.Set;
33
34public 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
47    public static boolean threadsSuspended() {
48        return suspended;
49    }
50
51    public static boolean allowThreadSuspension(ThreadGroup g, boolean b) {
52        return g.allowThreadSuspension(b);
53    }
54
55    /** @deprecated */
56    @Deprecated
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
65    public static void unsuspendThreads() {
66        suspended = false;
67    }
68
69    // Causes threadgroups no longer marked suspendable to be resumed.
70    /** @deprecated */
71    @Deprecated
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
91    public static final int getState() {
92        return STATE_GREEN;
93    }
94
95    /** @deprecated */
96    @Deprecated
97    public static void asChange(int as_old, int as_new) { }
98
99    /** @deprecated */
100    @Deprecated
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    //
152    public static void booted() {
153        booted = true;
154    }
155
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    //
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.
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    //
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.
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     */
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.
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    //
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     */
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     */
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     */
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     */
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