Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/jdk/internal/misc/VM.java
41159 views
1
/*
2
* Copyright (c) 1996, 2020, 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 jdk.internal.misc;
27
28
import static java.lang.Thread.State.*;
29
30
import java.text.NumberFormat;
31
import java.util.ArrayList;
32
import java.util.Collections;
33
import java.util.List;
34
import java.util.Map;
35
36
import jdk.internal.access.SharedSecrets;
37
38
import sun.nio.ch.FileChannelImpl;
39
40
public class VM {
41
42
// the init level when the VM is fully initialized
43
private static final int JAVA_LANG_SYSTEM_INITED = 1;
44
private static final int MODULE_SYSTEM_INITED = 2;
45
private static final int SYSTEM_LOADER_INITIALIZING = 3;
46
private static final int SYSTEM_BOOTED = 4;
47
private static final int SYSTEM_SHUTDOWN = 5;
48
49
// 0, 1, 2, ...
50
private static volatile int initLevel;
51
private static final Object lock = new Object();
52
53
/**
54
* Sets the init level.
55
*
56
* @see java.lang.System#initPhase1
57
* @see java.lang.System#initPhase2
58
* @see java.lang.System#initPhase3
59
*/
60
public static void initLevel(int value) {
61
synchronized (lock) {
62
if (value <= initLevel || value > SYSTEM_SHUTDOWN)
63
throw new InternalError("Bad level: " + value);
64
initLevel = value;
65
lock.notifyAll();
66
}
67
}
68
69
/**
70
* Returns the current init level.
71
*/
72
public static int initLevel() {
73
return initLevel;
74
}
75
76
/**
77
* Waits for the init level to get the given value.
78
*
79
* @see java.lang.ref.Finalizer
80
*/
81
public static void awaitInitLevel(int value) throws InterruptedException {
82
synchronized (lock) {
83
while (initLevel < value) {
84
lock.wait();
85
}
86
}
87
}
88
89
/**
90
* Returns {@code true} if the module system has been initialized.
91
* @see java.lang.System#initPhase2
92
*/
93
public static boolean isModuleSystemInited() {
94
return VM.initLevel() >= MODULE_SYSTEM_INITED;
95
}
96
97
/**
98
* Returns {@code true} if the VM is fully initialized.
99
*/
100
public static boolean isBooted() {
101
return initLevel >= SYSTEM_BOOTED;
102
}
103
104
/**
105
* Set shutdown state. Shutdown completes when all registered shutdown
106
* hooks have been run.
107
*
108
* @see java.lang.Shutdown
109
*/
110
public static void shutdown() {
111
initLevel(SYSTEM_SHUTDOWN);
112
}
113
114
/**
115
* Returns {@code true} if the VM has been shutdown
116
*/
117
public static boolean isShutdown() {
118
return initLevel == SYSTEM_SHUTDOWN;
119
}
120
121
// A user-settable upper limit on the maximum amount of allocatable direct
122
// buffer memory. This value may be changed during VM initialization if
123
// "java" is launched with "-XX:MaxDirectMemorySize=<size>".
124
//
125
// The initial value of this field is arbitrary; during JRE initialization
126
// it will be reset to the value specified on the command line, if any,
127
// otherwise to Runtime.getRuntime().maxMemory().
128
//
129
private static long directMemory = 64 * 1024 * 1024;
130
131
// Returns the maximum amount of allocatable direct buffer memory.
132
// The directMemory variable is initialized during system initialization
133
// in the saveAndRemoveProperties method.
134
//
135
public static long maxDirectMemory() {
136
return directMemory;
137
}
138
139
// User-controllable flag that determines if direct buffers should be page
140
// aligned. The "-XX:+PageAlignDirectMemory" option can be used to force
141
// buffers, allocated by ByteBuffer.allocateDirect, to be page aligned.
142
private static boolean pageAlignDirectMemory;
143
144
// Returns {@code true} if the direct buffers should be page aligned. This
145
// variable is initialized by saveAndRemoveProperties.
146
public static boolean isDirectMemoryPageAligned() {
147
return pageAlignDirectMemory;
148
}
149
150
private static int classFileMajorVersion;
151
private static int classFileMinorVersion;
152
private static final int PREVIEW_MINOR_VERSION = 65535;
153
154
/**
155
* Tests if the given version is a supported {@code class}
156
* file version.
157
*
158
* A {@code class} file depends on the preview features of Java SE {@code N}
159
* if the major version is {@code N} and the minor version is 65535.
160
* This method returns {@code true} if the given version is a supported
161
* {@code class} file version regardless of whether the preview features
162
* are enabled or not.
163
*
164
* @jvms 4.1 Table 4.1-A. class file format major versions
165
*/
166
public static boolean isSupportedClassFileVersion(int major, int minor) {
167
if (major < 45 || major > classFileMajorVersion) return false;
168
// for major version is between 45 and 55 inclusive, the minor version may be any value
169
if (major < 56) return true;
170
// otherwise, the minor version must be 0 or 65535
171
return minor == 0 || minor == PREVIEW_MINOR_VERSION;
172
}
173
174
/**
175
* Tests if the given version is a supported {@code class}
176
* file version for module descriptor.
177
*
178
* major.minor version >= 53.0
179
*/
180
public static boolean isSupportedModuleDescriptorVersion(int major, int minor) {
181
if (major < 53 || major > classFileMajorVersion) return false;
182
// for major version is between 45 and 55 inclusive, the minor version may be any value
183
if (major < 56) return true;
184
// otherwise, the minor version must be 0 or 65535
185
// preview features do not apply to module-info.class but JVMS allows it
186
return minor == 0 || minor == PREVIEW_MINOR_VERSION;
187
}
188
189
/**
190
* Returns true if the given class loader is the bootstrap class loader
191
* or the platform class loader.
192
*/
193
public static boolean isSystemDomainLoader(ClassLoader loader) {
194
return loader == null || loader == ClassLoader.getPlatformClassLoader();
195
}
196
197
/**
198
* Returns the system property of the specified key saved at
199
* system initialization time. This method should only be used
200
* for the system properties that are not changed during runtime.
201
*
202
* Note that the saved system properties do not include
203
* the ones set by java.lang.VersionProps.init().
204
*/
205
public static String getSavedProperty(String key) {
206
if (savedProps == null)
207
throw new IllegalStateException("Not yet initialized");
208
209
return savedProps.get(key);
210
}
211
212
/**
213
* Gets an unmodifiable view of the system properties saved at system
214
* initialization time. This method should only be used
215
* for the system properties that are not changed during runtime.
216
*
217
* Note that the saved system properties do not include
218
* the ones set by java.lang.VersionProps.init().
219
*/
220
public static Map<String, String> getSavedProperties() {
221
if (savedProps == null)
222
throw new IllegalStateException("Not yet initialized");
223
224
return Collections.unmodifiableMap(savedProps);
225
}
226
227
private static Map<String, String> savedProps;
228
229
// Save a private copy of the system properties and remove
230
// the system properties that are not intended for public access.
231
//
232
// This method can only be invoked during system initialization.
233
public static void saveProperties(Map<String, String> props) {
234
if (initLevel() != 0)
235
throw new IllegalStateException("Wrong init level");
236
237
// only main thread is running at this time, so savedProps and
238
// its content will be correctly published to threads started later
239
if (savedProps == null) {
240
savedProps = props;
241
}
242
243
// Set the maximum amount of direct memory. This value is controlled
244
// by the vm option -XX:MaxDirectMemorySize=<size>.
245
// The maximum amount of allocatable direct buffer memory (in bytes)
246
// from the system property sun.nio.MaxDirectMemorySize set by the VM.
247
// If not set or set to -1, the max memory will be used
248
// The system property will be removed.
249
String s = props.get("sun.nio.MaxDirectMemorySize");
250
if (s == null || s.isEmpty() || s.equals("-1")) {
251
// -XX:MaxDirectMemorySize not given, take default
252
directMemory = Runtime.getRuntime().maxMemory();
253
} else {
254
long l = Long.parseLong(s);
255
if (l > -1)
256
directMemory = l;
257
}
258
259
// Check if direct buffers should be page aligned
260
s = props.get("sun.nio.PageAlignDirectMemory");
261
if ("true".equals(s))
262
pageAlignDirectMemory = true;
263
264
s = props.get("java.class.version");
265
int index = s.indexOf('.');
266
try {
267
classFileMajorVersion = Integer.valueOf(s.substring(0, index));
268
classFileMinorVersion = Integer.valueOf(s.substring(index+1, s.length()));
269
} catch (NumberFormatException e) {
270
throw new InternalError(e);
271
}
272
}
273
274
// Initialize any miscellaneous operating system settings that need to be
275
// set for the class libraries.
276
//
277
public static void initializeOSEnvironment() {
278
if (initLevel() == 0) {
279
OSEnvironment.initialize();
280
}
281
}
282
283
/* Current count of objects pending for finalization */
284
private static volatile int finalRefCount;
285
286
/* Peak count of objects pending for finalization */
287
private static volatile int peakFinalRefCount;
288
289
/*
290
* Gets the number of objects pending for finalization.
291
*
292
* @return the number of objects pending for finalization.
293
*/
294
public static int getFinalRefCount() {
295
return finalRefCount;
296
}
297
298
/*
299
* Gets the peak number of objects pending for finalization.
300
*
301
* @return the peak number of objects pending for finalization.
302
*/
303
public static int getPeakFinalRefCount() {
304
return peakFinalRefCount;
305
}
306
307
/*
308
* Add {@code n} to the objects pending for finalization count.
309
*
310
* @param n an integer value to be added to the objects pending
311
* for finalization count
312
*/
313
public static void addFinalRefCount(int n) {
314
// The caller must hold lock to synchronize the update.
315
316
finalRefCount += n;
317
if (finalRefCount > peakFinalRefCount) {
318
peakFinalRefCount = finalRefCount;
319
}
320
}
321
322
/**
323
* Returns Thread.State for the given threadStatus
324
*/
325
public static Thread.State toThreadState(int threadStatus) {
326
if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) {
327
return RUNNABLE;
328
} else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) {
329
return BLOCKED;
330
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) {
331
return WAITING;
332
} else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) {
333
return TIMED_WAITING;
334
} else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) {
335
return TERMINATED;
336
} else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) {
337
return NEW;
338
} else {
339
return RUNNABLE;
340
}
341
}
342
343
/* The threadStatus field is set by the VM at state transition
344
* in the hotspot implementation. Its value is set according to
345
* the JVM TI specification GetThreadState function.
346
*/
347
private static final int JVMTI_THREAD_STATE_ALIVE = 0x0001;
348
private static final int JVMTI_THREAD_STATE_TERMINATED = 0x0002;
349
private static final int JVMTI_THREAD_STATE_RUNNABLE = 0x0004;
350
private static final int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400;
351
private static final int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
352
private static final int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
353
354
/*
355
* Returns the first user-defined class loader up the execution stack,
356
* or the platform class loader if only code from the platform or
357
* bootstrap class loader is on the stack.
358
*/
359
public static ClassLoader latestUserDefinedLoader() {
360
ClassLoader loader = latestUserDefinedLoader0();
361
return loader != null ? loader : ClassLoader.getPlatformClassLoader();
362
}
363
364
/*
365
* Returns the first user-defined class loader up the execution stack,
366
* or null if only code from the platform or bootstrap class loader is
367
* on the stack. VM does not keep a reference of platform loader and so
368
* it returns null.
369
*
370
* This method should be replaced with StackWalker::walk and then we can
371
* remove the logic in the VM.
372
*/
373
private static native ClassLoader latestUserDefinedLoader0();
374
375
/**
376
* Returns {@code true} if we are in a set UID program.
377
*/
378
public static boolean isSetUID() {
379
long uid = getuid();
380
long euid = geteuid();
381
long gid = getgid();
382
long egid = getegid();
383
return uid != euid || gid != egid;
384
}
385
386
/**
387
* Returns the real user ID of the calling process,
388
* or -1 if the value is not available.
389
*/
390
public static native long getuid();
391
392
/**
393
* Returns the effective user ID of the calling process,
394
* or -1 if the value is not available.
395
*/
396
public static native long geteuid();
397
398
/**
399
* Returns the real group ID of the calling process,
400
* or -1 if the value is not available.
401
*/
402
public static native long getgid();
403
404
/**
405
* Returns the effective group ID of the calling process,
406
* or -1 if the value is not available.
407
*/
408
public static native long getegid();
409
410
/**
411
* Get a nanosecond time stamp adjustment in the form of a single long.
412
*
413
* This value can be used to create an instant using
414
* {@link java.time.Instant#ofEpochSecond(long, long)
415
* java.time.Instant.ofEpochSecond(offsetInSeconds,
416
* getNanoTimeAdjustment(offsetInSeconds))}.
417
* <p>
418
* The value returned has the best resolution available to the JVM on
419
* the current system.
420
* This is usually down to microseconds - or tenth of microseconds -
421
* depending on the OS/Hardware and the JVM implementation.
422
*
423
* @param offsetInSeconds The offset in seconds from which the nanosecond
424
* time stamp should be computed.
425
*
426
* @apiNote The offset should be recent enough - so that
427
* {@code offsetInSeconds} is within {@code +/- 2^32} seconds of the
428
* current UTC time. If the offset is too far off, {@code -1} will be
429
* returned. As such, {@code -1} must not be considered as a valid
430
* nano time adjustment, but as an exception value indicating
431
* that an offset closer to the current time should be used.
432
*
433
* @return A nanosecond time stamp adjustment in the form of a single long.
434
* If the offset is too far off the current time, this method returns -1.
435
* In that case, the caller should call this method again, passing a
436
* more accurate offset.
437
*/
438
public static native long getNanoTimeAdjustment(long offsetInSeconds);
439
440
/**
441
* Returns the VM arguments for this runtime environment.
442
*
443
* @implNote
444
* The HotSpot JVM processes the input arguments from multiple sources
445
* in the following order:
446
* 1. JAVA_TOOL_OPTIONS environment variable
447
* 2. Options from JNI Invocation API
448
* 3. _JAVA_OPTIONS environment variable
449
*
450
* If VM options file is specified via -XX:VMOptionsFile, the vm options
451
* file is read and expanded in place of -XX:VMOptionFile option.
452
*/
453
public static native String[] getRuntimeArguments();
454
455
static {
456
initialize();
457
}
458
private static native void initialize();
459
460
/**
461
* Provides access to information on buffer usage.
462
*/
463
public interface BufferPool {
464
String getName();
465
long getCount();
466
long getTotalCapacity();
467
long getMemoryUsed();
468
}
469
470
private static class BufferPoolsHolder {
471
static final List<BufferPool> BUFFER_POOLS;
472
473
static {
474
ArrayList<BufferPool> bufferPools = new ArrayList<>(3);
475
bufferPools.add(SharedSecrets.getJavaNioAccess().getDirectBufferPool());
476
bufferPools.add(FileChannelImpl.getMappedBufferPool());
477
bufferPools.add(FileChannelImpl.getSyncMappedBufferPool());
478
479
BUFFER_POOLS = Collections.unmodifiableList(bufferPools);
480
}
481
}
482
483
/**
484
* @return the list of buffer pools.
485
*/
486
public static List<BufferPool> getBufferPools() {
487
return BufferPoolsHolder.BUFFER_POOLS;
488
}
489
}
490
491