1 /*
  2  * Copyright (c) 2012, 2025, 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 package jdk.test.whitebox;
 25 
 26 import java.lang.management.MemoryUsage;
 27 import java.lang.reflect.Executable;
 28 import java.util.Arrays;
 29 import java.util.List;
 30 import java.util.function.BiFunction;
 31 import java.util.function.Function;
 32 import java.util.Objects;
 33 
 34 import jdk.test.whitebox.parser.DiagnosticCommand;
 35 
 36 public class WhiteBox {
 37 
 38   private WhiteBox() {}
 39   private static final WhiteBox instance = new WhiteBox();
 40   private static native void registerNatives();
 41 
 42   /**
 43    * Returns the singleton WhiteBox instance.
 44    *
 45    * The returned WhiteBox object should be carefully guarded
 46    * by the caller, since it can be used to read and write data
 47    * at arbitrary memory addresses. It must never be passed to
 48    * untrusted code.
 49    */
 50   public synchronized static WhiteBox getWhiteBox() {
 51     return instance;
 52   }
 53 
 54   static {
 55     registerNatives();
 56   }
 57 
 58   // Get the maximum heap size supporting COOPs
 59   public native long getCompressedOopsMaxHeapSize();
 60   // Arguments
 61   public native void printHeapSizes();
 62 
 63   // Memory
 64   private native long getObjectAddress0(Object o);
 65   public           long getObjectAddress(Object o) {
 66     Objects.requireNonNull(o);
 67     return getObjectAddress0(o);
 68   }
 69 
 70   public native int  getHeapOopSize();
 71   public native int  getVMPageSize();
 72   public native long getVMAllocationGranularity();
 73   public native long getVMLargePageSize();
 74   public native long getHeapSpaceAlignment();
 75   public native long getHeapAlignment();
 76 
 77   private native boolean isObjectInOldGen0(Object o);
 78   public         boolean isObjectInOldGen(Object o) {
 79     Objects.requireNonNull(o);
 80     return isObjectInOldGen0(o);
 81   }
 82 
 83   private native long getObjectSize0(Object o);
 84   public         long getObjectSize(Object o) {
 85     Objects.requireNonNull(o);
 86     return getObjectSize0(o);
 87   }
 88 
 89   // Runtime
 90 
 91   // Returns the potentially abridged form of `str` as it would be
 92   // printed by the VM.
 93   public native String printString(String str, int maxLength);
 94 
 95   public native void lockAndStuckInSafepoint();
 96 
 97   public int countAliveClasses(String name) {
 98     // Make sure class name is in the correct format
 99     return countAliveClasses0(name.replace('.', '/'));
100   }
101   private native int countAliveClasses0(String name);
102 
103   public boolean isClassAlive(String name) {
104     return countAliveClasses(name) != 0;
105   }
106 
107   public  native int getSymbolRefcount(String name);
108 
109   public native boolean deflateIdleMonitors();
110 
111   private native boolean isMonitorInflated0(Object obj);
112   public         boolean isMonitorInflated(Object obj) {
113     Objects.requireNonNull(obj);
114     return isMonitorInflated0(obj);
115   }
116 
117   public native long getInUseMonitorCount();
118 
119   public native int getLockStackCapacity();
120 
121   public native boolean supportsRecursiveLightweightLocking();
122 
123   public native void forceSafepoint();
124 
125   public native void forceClassLoaderStatsSafepoint();
126 
127   private native long getConstantPool0(Class<?> aClass);
128   public         long getConstantPool(Class<?> aClass) {
129     Objects.requireNonNull(aClass);
130     return getConstantPool0(aClass);
131   }
132 
133   private native Object[] getResolvedReferences0(Class<?> aClass);
134   public         Object[] getResolvedReferences(Class<?> aClass) {
135     Objects.requireNonNull(aClass);
136     return getResolvedReferences0(aClass);
137   }
138 
139   private native int remapInstructionOperandFromCPCache0(Class<?> aClass, int index);
140   public         int remapInstructionOperandFromCPCache(Class<?> aClass, int index) {
141     Objects.requireNonNull(aClass);
142     return remapInstructionOperandFromCPCache0(aClass, index);
143   }
144 
145   private native int encodeConstantPoolIndyIndex0(int index);
146   public         int encodeConstantPoolIndyIndex(int index) {
147     return encodeConstantPoolIndyIndex0(index);
148   }
149 
150   private native Object[] getObjectsViaKlassOopMaps0(Object thing);
151   public Object[] getObjectsViaKlassOopMaps(Object thing) {
152     Objects.requireNonNull(thing);
153     return getObjectsViaKlassOopMaps0(thing);
154   }
155 
156   private native Object[] getObjectsViaOopIterator0(Object thing);
157   public Object[] getObjectsViaOopIterator(Object thing) {
158     Objects.requireNonNull(thing);
159     return getObjectsViaOopIterator0(thing);
160   }
161 
162   public native Object[] getObjectsViaFrameOopIterator(int depth);
163 
164   private native int getFieldEntriesLength0(Class<?> aClass);
165   public         int getFieldEntriesLength(Class<?> aClass) {
166     Objects.requireNonNull(aClass);
167     return getFieldEntriesLength0(aClass);
168   }
169 
170   private native int getFieldCPIndex0(Class<?> aClass, int index);
171   public         int getFieldCPIndex(Class<?> aClass, int index) {
172     Objects.requireNonNull(aClass);
173     return getFieldCPIndex0(aClass, index);
174   }
175 
176   private native int getMethodEntriesLength0(Class<?> aClass);
177   public         int getMethodEntriesLength(Class<?> aClass) {
178     Objects.requireNonNull(aClass);
179     return getMethodEntriesLength0(aClass);
180   }
181 
182   private native int getMethodCPIndex0(Class<?> aClass, int index);
183   public         int getMethodCPIndex(Class<?> aClass, int index) {
184     Objects.requireNonNull(aClass);
185     return getMethodCPIndex0(aClass, index);
186   }
187 
188   private native int getIndyInfoLength0(Class<?> aClass);
189   public         int getIndyInfoLength(Class<?> aClass) {
190     Objects.requireNonNull(aClass);
191     return getIndyInfoLength0(aClass);
192   }
193 
194   private native int getIndyCPIndex0(Class<?> aClass, int index);
195   public         int getIndyCPIndex(Class<?> aClass, int index) {
196     Objects.requireNonNull(aClass);
197     return getIndyCPIndex0(aClass, index);
198   }
199 
200   private native String printClasses0(String classNamePattern, int flags);
201   public         String printClasses(String classNamePattern, int flags) {
202     Objects.requireNonNull(classNamePattern);
203     return printClasses0(classNamePattern, flags);
204   }
205 
206   private native String printMethods0(String classNamePattern, String methodPattern, int flags);
207   public         String printMethods(String classNamePattern, String methodPattern, int flags) {
208     Objects.requireNonNull(classNamePattern);
209     Objects.requireNonNull(methodPattern);
210     return printMethods0(classNamePattern, methodPattern, flags);
211   }
212 
213   // JVMTI
214   private native void addToBootstrapClassLoaderSearch0(String segment);
215   public         void addToBootstrapClassLoaderSearch(String segment){
216     Objects.requireNonNull(segment);
217     addToBootstrapClassLoaderSearch0(segment);
218   }
219 
220   private native void addToSystemClassLoaderSearch0(String segment);
221   public         void addToSystemClassLoaderSearch(String segment) {
222     Objects.requireNonNull(segment);
223     addToSystemClassLoaderSearch0(segment);
224   }
225 
226   // G1
227 
228   public native boolean g1InConcurrentMark();
229   public native int g1CompletedConcurrentMarkCycles();
230 
231   // Perform a complete concurrent GC cycle, using concurrent GC breakpoints.
232   // Completes any in-progress cycle before performing the requested cycle.
233   // Returns true if the cycle completed successfully.  If the cycle was not
234   // successful (e.g. it was aborted), then throws RuntimeException if
235   // errorIfFail is true, returning false otherwise.
236   public boolean g1RunConcurrentGC(boolean errorIfFail) {
237     try {
238       // Take control, waiting until any in-progress cycle completes.
239       concurrentGCAcquireControl();
240       int count = g1CompletedConcurrentMarkCycles();
241       concurrentGCRunTo(AFTER_MARKING_STARTED, false);
242       concurrentGCRunToIdle();
243       if (count < g1CompletedConcurrentMarkCycles()) {
244         return true;
245       } else if (errorIfFail) {
246         throw new RuntimeException("Concurrent GC aborted");
247       } else {
248         return false;
249       }
250     } finally {
251       concurrentGCReleaseControl();
252     }
253   }
254 
255   public void g1RunConcurrentGC() {
256     g1RunConcurrentGC(true);
257   }
258 
259   // Start a concurrent GC cycle, using concurrent GC breakpoints.
260   // The concurrent GC will continue in parallel with the caller.
261   // Completes any in-progress cycle before starting the requested cycle.
262   public void g1StartConcurrentGC() {
263     try {
264       // Take control, waiting until any in-progress cycle completes.
265       concurrentGCAcquireControl();
266       concurrentGCRunTo(AFTER_MARKING_STARTED, false);
267     } finally {
268       // Release control, permitting the cycle to complete.
269       concurrentGCReleaseControl();
270     }
271   }
272 
273   public native boolean g1HasRegionsToUncommit();
274   private native boolean g1IsHumongous0(Object o);
275   public         boolean g1IsHumongous(Object o) {
276     Objects.requireNonNull(o);
277     return g1IsHumongous0(o);
278   }
279 
280   private native boolean g1BelongsToHumongousRegion0(long adr);
281   public         boolean g1BelongsToHumongousRegion(long adr) {
282     if (adr == 0) {
283       throw new IllegalArgumentException("adr argument should not be null");
284     }
285     return g1BelongsToHumongousRegion0(adr);
286   }
287 
288 
289   private native boolean g1BelongsToFreeRegion0(long adr);
290   public         boolean g1BelongsToFreeRegion(long adr) {
291     if (adr == 0) {
292       throw new IllegalArgumentException("adr argument should not be null");
293     }
294     return g1BelongsToFreeRegion0(adr);
295   }
296 
297   public native long    g1NumMaxRegions();
298   public native long    g1NumFreeRegions();
299   public native int     g1RegionSize();
300   public native MemoryUsage g1AuxiliaryMemoryUsage();
301   private  native Object[]    parseCommandLine0(String commandline, char delim, DiagnosticCommand[] args);
302   public          Object[]    parseCommandLine(String commandline, char delim, DiagnosticCommand[] args) {
303     Objects.requireNonNull(args);
304     return parseCommandLine0(commandline, delim, args);
305   }
306 
307   public native int g1ActiveMemoryNodeCount();
308   public native int[] g1MemoryNodeIds();
309 
310   // Parallel GC
311   public native long psVirtualSpaceAlignment();
312   public native long psHeapGenerationAlignment();
313 
314   /**
315    * Enumerates old regions with liveness less than specified and produces some statistics
316    * @param liveness percent of region's liveness (live_objects / total_region_size * 100).
317    * @return long[3] array where long[0] - total count of old regions
318    *                             long[1] - total memory of old regions
319    *                             long[2] - lowest estimation of total memory of old regions to be freed (non-full
320    *                             regions are not included)
321    */
322   public native long[] g1GetMixedGCInfo(int liveness);
323 
324   // NMT
325   public native long NMTMalloc(long size);
326   public native void NMTFree(long mem);
327   public native long NMTReserveMemory(long size);
328   public native long NMTAttemptReserveMemoryAt(long addr, long size);
329   public native void NMTCommitMemory(long addr, long size);
330   public native void NMTUncommitMemory(long addr, long size);
331   public native void NMTReleaseMemory(long addr, long size);
332   public native long NMTMallocWithPseudoStack(long size, int index);
333   public native long NMTMallocWithPseudoStackAndType(long size, int index, int type);
334   public native int NMTGetHashSize();
335   public native long NMTNewArena(long initSize);
336   public native void NMTFreeArena(long arena);
337   public native void NMTArenaMalloc(long arena, long size);
338 
339   // Compiler
340 
341   // Determines if the libgraal shared library file is present.
342   public native boolean hasLibgraal();
343   public native boolean isC2OrJVMCIIncluded();
344   public native boolean isJVMCISupportedByGC();
345 
346   public native int     matchesMethod(Executable method, String pattern);
347   public native int     matchesInline(Executable method, String pattern);
348   public native boolean shouldPrintAssembly(Executable method, int comp_level);
349   public native int     deoptimizeFrames(boolean makeNotEntrant);
350   public native boolean isFrameDeoptimized(int depth);
351   public native void    deoptimizeAll();
352 
353   public        boolean isMethodCompiled(Executable method) {
354     return isMethodCompiled(method, false /*not osr*/);
355   }
356   private native boolean isMethodCompiled0(Executable method, boolean isOsr);
357   public         boolean isMethodCompiled(Executable method, boolean isOsr){
358     Objects.requireNonNull(method);
359     return isMethodCompiled0(method, isOsr);
360   }
361   public        boolean isMethodCompilable(Executable method) {
362     return isMethodCompilable(method, -1 /*any*/);
363   }
364   public        boolean isMethodCompilable(Executable method, int compLevel) {
365     return isMethodCompilable(method, compLevel, false /*not osr*/);
366   }
367   private native boolean isMethodCompilable0(Executable method, int compLevel, boolean isOsr);
368   public         boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr) {
369     Objects.requireNonNull(method);
370     return isMethodCompilable0(method, compLevel, isOsr);
371   }
372   private native boolean isMethodQueuedForCompilation0(Executable method);
373   public         boolean isMethodQueuedForCompilation(Executable method) {
374     Objects.requireNonNull(method);
375     return isMethodQueuedForCompilation0(method);
376   }
377   // Determine if the compiler corresponding to the compilation level 'compLevel'
378   // and to the compilation context 'compilation_context' provides an intrinsic
379   // for the method 'method'. An intrinsic is available for method 'method' if:
380   //  - the intrinsic is enabled (by using the appropriate command-line flag) and
381   //  - the platform on which the VM is running provides the instructions necessary
382   //    for the compiler to generate the intrinsic code.
383   //
384   // The compilation context is related to using the DisableIntrinsic flag on a
385   // per-method level, see hotspot/src/share/vm/compiler/abstractCompiler.hpp
386   // for more details.
387   public boolean isIntrinsicAvailable(Executable method,
388                                       Executable compilationContext,
389                                       int compLevel) {
390       Objects.requireNonNull(method);
391       return isIntrinsicAvailable0(method, compilationContext, compLevel);
392   }
393   // If usage of the DisableIntrinsic flag is not expected (or the usage can be ignored),
394   // use the below method that does not require the compilation context as argument.
395   public boolean isIntrinsicAvailable(Executable method, int compLevel) {
396       return isIntrinsicAvailable(method, null, compLevel);
397   }
398   private native boolean isIntrinsicAvailable0(Executable method,
399                                                Executable compilationContext,
400                                                int compLevel);
401   public        int     deoptimizeMethod(Executable method) {
402     return deoptimizeMethod(method, false /*not osr*/);
403   }
404   private native int     deoptimizeMethod0(Executable method, boolean isOsr);
405   public         int     deoptimizeMethod(Executable method, boolean isOsr) {
406     Objects.requireNonNull(method);
407     return deoptimizeMethod0(method, isOsr);
408   }
409   public        void    makeMethodNotCompilable(Executable method) {
410     makeMethodNotCompilable(method, -1 /*any*/);
411   }
412   public        void    makeMethodNotCompilable(Executable method, int compLevel) {
413     makeMethodNotCompilable(method, compLevel, false /*not osr*/);
414   }
415   private native void    makeMethodNotCompilable0(Executable method, int compLevel, boolean isOsr);
416   public         void    makeMethodNotCompilable(Executable method, int compLevel, boolean isOsr) {
417     Objects.requireNonNull(method);
418     makeMethodNotCompilable0(method, compLevel, isOsr);
419   }
420   public        int     getMethodCompilationLevel(Executable method) {
421     return getMethodCompilationLevel(method, false /*not osr*/);
422   }
423   private native int     getMethodCompilationLevel0(Executable method, boolean isOsr);
424   public         int     getMethodCompilationLevel(Executable method, boolean isOsr) {
425     Objects.requireNonNull(method);
426     return getMethodCompilationLevel0(method, isOsr);
427   }
428   public         int     getMethodDecompileCount(Executable method) {
429     Objects.requireNonNull(method);
430     return getMethodDecompileCount0(method);
431   }
432   private native int     getMethodDecompileCount0(Executable method);
433   // Get the total trap count of a method. If the trap count for a specific reason
434   // did overflow, this includes the overflow trap count of the method.
435   public         int     getMethodTrapCount(Executable method) {
436     Objects.requireNonNull(method);
437     return getMethodTrapCount0(method, null);
438   }
439   // Get the trap count of a method for a specific reason. If the trap count for
440   // that reason did overflow, this includes the overflow trap count of the method.
441   public         int     getMethodTrapCount(Executable method, String reason) {
442     Objects.requireNonNull(method);
443     return getMethodTrapCount0(method, reason);
444   }
445   private native int     getMethodTrapCount0(Executable method, String reason);
446   // Get the total deopt count.
447   public         int     getDeoptCount() {
448     return getDeoptCount0(null, null);
449   }
450   // Get the deopt count for a specific reason and a specific action. If either
451   // one of 'reason' or 'action' is null, the method returns the sum of all
452   // deoptimizations with the specific 'action' or 'reason' respectively.
453   // If both arguments are null, the method returns the total deopt count.
454   public         int     getDeoptCount(String reason, String action) {
455     return getDeoptCount0(reason, action);
456   }
457   private native int     getDeoptCount0(String reason, String action);
458   private native boolean testSetDontInlineMethod0(Executable method, boolean value);
459   public         boolean testSetDontInlineMethod(Executable method, boolean value) {
460     Objects.requireNonNull(method);
461     return testSetDontInlineMethod0(method, value);
462   }
463   public        int     getCompileQueuesSize() {
464     return getCompileQueueSize(-1 /*any*/);
465   }
466   public native int     getCompileQueueSize(int compLevel);
467   private native boolean testSetForceInlineMethod0(Executable method, boolean value);
468   public         boolean testSetForceInlineMethod(Executable method, boolean value) {
469     Objects.requireNonNull(method);
470     return testSetForceInlineMethod0(method, value);
471   }
472   public        boolean enqueueMethodForCompilation(Executable method, int compLevel) {
473     return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/);
474   }
475   private native boolean enqueueMethodForCompilation0(Executable method, int compLevel, int entry_bci);
476   public  boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci) {
477     Objects.requireNonNull(method);
478     return enqueueMethodForCompilation0(method, compLevel, entry_bci);
479   }
480   private native boolean enqueueInitializerForCompilation0(Class<?> aClass, int compLevel);
481   public  boolean enqueueInitializerForCompilation(Class<?> aClass, int compLevel) {
482     Objects.requireNonNull(aClass);
483     return enqueueInitializerForCompilation0(aClass, compLevel);
484   }
485   private native void    clearMethodState0(Executable method);
486   public  native void    markMethodProfiled(Executable method);
487   public         void    clearMethodState(Executable method) {
488     Objects.requireNonNull(method);
489     clearMethodState0(method);
490   }
491   public native void    lockCompilation();
492   public native void    unlockCompilation();
493   private native int     getMethodEntryBci0(Executable method);
494   public         int     getMethodEntryBci(Executable method) {
495     Objects.requireNonNull(method);
496     return getMethodEntryBci0(method);
497   }
498   private native Object[] getNMethod0(Executable method, boolean isOsr);
499   public         Object[] getNMethod(Executable method, boolean isOsr) {
500     Objects.requireNonNull(method);
501     return getNMethod0(method, isOsr);
502   }
503   public native long    allocateCodeBlob(int size, int type);
504   public        long    allocateCodeBlob(long size, int type) {
505       int intSize = (int) size;
506       if ((long) intSize != size || size < 0) {
507           throw new IllegalArgumentException(
508                 "size argument has illegal value " + size);
509       }
510       return allocateCodeBlob( intSize, type);
511   }
512   public native void    freeCodeBlob(long addr);
513   public native Object[] getCodeHeapEntries(int type);
514   public native int     getCompilationActivityMode();
515   private native long getMethodData0(Executable method);
516   public         long getMethodData(Executable method) {
517     Objects.requireNonNull(method);
518     return getMethodData0(method);
519   }
520   public native Object[] getCodeBlob(long addr);
521 
522   private native void clearInlineCaches0(boolean preserve_static_stubs);
523   public void clearInlineCaches() {
524     clearInlineCaches0(false);
525   }
526   public void clearInlineCaches(boolean preserve_static_stubs) {
527     clearInlineCaches0(preserve_static_stubs);
528   }
529 
530   // Intered strings
531   public native boolean isInStringTable(String str);
532 
533   // Memory
534   public native void readReservedMemory();
535   public native long allocateMetaspace(ClassLoader classLoader, long size);
536   public native long incMetaspaceCapacityUntilGC(long increment);
537   public native long metaspaceCapacityUntilGC();
538   public native long metaspaceSharedRegionAlignment();
539 
540   public native void cleanMetaspaces();
541 
542   // Metaspace Arena Tests
543   public native long createMetaspaceTestContext(long commit_limit, long reserve_limit);
544   public native void destroyMetaspaceTestContext(long context);
545   public native void purgeMetaspaceTestContext(long context);
546   public native void printMetaspaceTestContext(long context);
547   public native long getTotalCommittedBytesInMetaspaceTestContext(long context);
548   public native long getTotalUsedBytesInMetaspaceTestContext(long context);
549   public native long createArenaInTestContext(long context, boolean is_micro);
550   public native void destroyMetaspaceTestArena(long arena);
551   public native long allocateFromMetaspaceTestArena(long arena, long size);
552   public native void deallocateToMetaspaceTestArena(long arena, long p, long size);
553 
554   public native long maxMetaspaceAllocationSize();
555 
556   // Word size measured in bytes
557   public native long wordSize();
558   public native long rootChunkWordSize();
559 
560   // Don't use these methods directly
561   // Use jdk.test.whitebox.gc.GC class instead.
562   public native boolean isGCSupported(int name);
563   public native boolean isGCSupportedByJVMCICompiler(int name);
564   public native boolean isGCSelected(int name);
565   public native boolean isGCSelectedErgonomically();
566 
567   // Force Young GC
568   public native void youngGC();
569 
570   // Force Full GC
571   public native void fullGC();
572 
573   // Returns true if the current GC supports concurrent collection control.
574   public native boolean supportsConcurrentGCBreakpoints();
575 
576   private void checkConcurrentGCBreakpointsSupported() {
577     if (!supportsConcurrentGCBreakpoints()) {
578       throw new UnsupportedOperationException("Concurrent GC breakpoints not supported");
579     }
580   }
581 
582   private native void concurrentGCAcquireControl0();
583   private native void concurrentGCReleaseControl0();
584   private native void concurrentGCRunToIdle0();
585   private native boolean concurrentGCRunTo0(String breakpoint);
586 
587   private static boolean concurrentGCIsControlled = false;
588   private void checkConcurrentGCIsControlled() {
589     if (!concurrentGCIsControlled) {
590       throw new IllegalStateException("Not controlling concurrent GC");
591     }
592   }
593 
594   // All collectors supporting concurrent GC breakpoints are expected
595   // to provide at least the following breakpoints.
596   public final String AFTER_MARKING_STARTED = "AFTER MARKING STARTED";
597   public final String BEFORE_MARKING_COMPLETED = "BEFORE MARKING COMPLETED";
598 
599   // Collectors supporting concurrent GC breakpoints that do reference
600   // processing concurrently should provide the following breakpoint.
601   public final String AFTER_CONCURRENT_REFERENCE_PROCESSING_STARTED =
602     "AFTER CONCURRENT REFERENCE PROCESSING STARTED";
603 
604   // G1 specific GC breakpoints.
605   public final String G1_AFTER_REBUILD_STARTED = "AFTER REBUILD STARTED";
606   public final String G1_BEFORE_REBUILD_COMPLETED = "BEFORE REBUILD COMPLETED";
607   public final String G1_AFTER_CLEANUP_STARTED = "AFTER CLEANUP STARTED";
608   public final String G1_BEFORE_CLEANUP_COMPLETED = "BEFORE CLEANUP COMPLETED";
609 
610   public void concurrentGCAcquireControl() {
611     checkConcurrentGCBreakpointsSupported();
612     if (concurrentGCIsControlled) {
613       throw new IllegalStateException("Already controlling concurrent GC");
614     }
615     concurrentGCAcquireControl0();
616     concurrentGCIsControlled = true;
617   }
618 
619   public void concurrentGCReleaseControl() {
620     checkConcurrentGCBreakpointsSupported();
621     concurrentGCReleaseControl0();
622     concurrentGCIsControlled = false;
623   }
624 
625   // Keep concurrent GC idle.  Release from breakpoint.
626   public void concurrentGCRunToIdle() {
627     checkConcurrentGCBreakpointsSupported();
628     checkConcurrentGCIsControlled();
629     concurrentGCRunToIdle0();
630   }
631 
632   // Allow concurrent GC to run to breakpoint.
633   // Throws IllegalStateException if reached end of cycle first.
634   public void concurrentGCRunTo(String breakpoint) {
635     concurrentGCRunTo(breakpoint, true);
636   }
637 
638   // Allow concurrent GC to run to breakpoint.
639   // Returns true if reached breakpoint.  If reached end of cycle first,
640   // then throws IllegalStateException if errorIfFail is true, returning
641   // false otherwise.
642   public boolean concurrentGCRunTo(String breakpoint, boolean errorIfFail) {
643     checkConcurrentGCBreakpointsSupported();
644     checkConcurrentGCIsControlled();
645     if (breakpoint == null) {
646       throw new NullPointerException("null breakpoint");
647     } else if (concurrentGCRunTo0(breakpoint)) {
648       return true;
649     } else if (errorIfFail) {
650       throw new IllegalStateException("Missed requested breakpoint \"" + breakpoint + "\"");
651     } else {
652       return false;
653     }
654   }
655 
656   // Tests on ReservedSpace/VirtualSpace classes
657   public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations);
658   public native void readFromNoaccessArea();
659 
660   public native void decodeNKlassAndAccessKlass(int nKlass);
661   public native long getThreadStackSize();
662   public native long getThreadRemainingStackSize();
663 
664   // CPU features
665   public native String getCPUFeatures();
666 
667   // VM flags
668   public native boolean isConstantVMFlag(String name);
669   public native boolean isDefaultVMFlag(String name);
670   public native boolean isLockedVMFlag(String name);
671   public native void    setBooleanVMFlag(String name, boolean value);
672   public native void    setIntVMFlag(String name, long value);
673   public native void    setUintVMFlag(String name, long value);
674   public native void    setIntxVMFlag(String name, long value);
675   public native void    setUintxVMFlag(String name, long value);
676   public native void    setUint64VMFlag(String name, long value);
677   public native void    setSizeTVMFlag(String name, long value);
678   public native void    setStringVMFlag(String name, String value);
679   public native void    setDoubleVMFlag(String name, double value);
680   public native Boolean getBooleanVMFlag(String name);
681   public native Long    getIntVMFlag(String name);
682   public native Long    getUintVMFlag(String name);
683   public native Long    getIntxVMFlag(String name);
684   public native Long    getUintxVMFlag(String name);
685   public native Long    getUint64VMFlag(String name);
686   public native Long    getSizeTVMFlag(String name);
687   public native String  getStringVMFlag(String name);
688   public native Double  getDoubleVMFlag(String name);
689   private final List<Function<String,Object>> flagsGetters = Arrays.asList(
690     this::getBooleanVMFlag, this::getIntVMFlag, this::getUintVMFlag,
691     this::getIntxVMFlag, this::getUintxVMFlag, this::getUint64VMFlag,
692     this::getSizeTVMFlag, this::getStringVMFlag, this::getDoubleVMFlag);
693 
694   public Object getVMFlag(String name) {
695     return flagsGetters.stream()
696                        .map(f -> f.apply(name))
697                        .filter(x -> x != null)
698                        .findAny()
699                        .orElse(null);
700   }
701 
702   // Jigsaw
703   public native void DefineModule(Object module, boolean is_open, String version,
704                                   String location, Object[] packages);
705   public native void AddModuleExports(Object from_module, String pkg, Object to_module);
706   public native void AddReadsModule(Object from_module, Object source_module);
707   public native void AddModuleExportsToAllUnnamed(Object module, String pkg);
708   public native void AddModuleExportsToAll(Object module, String pkg);
709 
710   public native int getCDSOffsetForName0(String name);
711   public int getCDSOffsetForName(String name) throws Exception {
712     int offset = getCDSOffsetForName0(name);
713     if (offset == -1) {
714       throw new RuntimeException(name + " not found");
715     }
716     return offset;
717   }
718   public native int getCDSConstantForName0(String name);
719   public int getCDSConstantForName(String name) throws Exception {
720     int constant = getCDSConstantForName0(name);
721     if (constant == -1) {
722       throw new RuntimeException(name + " not found");
723     }
724     return constant;
725   }
726   public native Boolean getMethodBooleanOption(Executable method, String name);
727   public native Long    getMethodIntxOption(Executable method, String name);
728   public native Long    getMethodUintxOption(Executable method, String name);
729   public native Double  getMethodDoubleOption(Executable method, String name);
730   public native String  getMethodStringOption(Executable method, String name);
731   private final List<BiFunction<Executable,String,Object>> methodOptionGetters
732       = Arrays.asList(this::getMethodBooleanOption, this::getMethodIntxOption,
733           this::getMethodUintxOption, this::getMethodDoubleOption,
734           this::getMethodStringOption);
735 
736   public Object getMethodOption(Executable method, String name) {
737     return methodOptionGetters.stream()
738                               .map(f -> f.apply(method, name))
739                               .filter(x -> x != null)
740                               .findAny()
741                               .orElse(null);
742   }
743 
744   // Sharing & archiving
745   public native int     getCDSGenericHeaderMinVersion();
746   public native int     getCurrentCDSVersion();
747   public native String  getDefaultArchivePath();
748   public native boolean cdsMemoryMappingFailed();
749   public native boolean isSharingEnabled();
750   public native boolean isSharedClass(Class<?> c);
751   public native boolean areSharedStringsMapped();
752   public native boolean isSharedInternedString(String s);
753   public native boolean isCDSIncluded();
754   public native boolean isJFRIncluded();
755   public native boolean isDTraceIncluded();
756   public native boolean canWriteJavaHeapArchive();
757   public native void    linkClass(Class<?> c);
758   public native boolean areOpenArchiveHeapObjectsMapped();
759 
760   // Compiler Directive
761   public native int addCompilerDirective(String compDirect);
762   public native void removeCompilerDirective(int count);
763 
764   // Handshakes
765   public native int handshakeWalkStack(Thread t, boolean all_threads);
766   public native boolean handshakeReadMonitors(Thread t);
767   public native void asyncHandshakeWalkStack(Thread t);
768 
769   public native void lockAndBlock(boolean suspender);
770 
771   // Returns true on linux if library has the noexecstack flag set.
772   public native boolean checkLibSpecifiesNoexecstack(String libfilename);
773 
774   // Container testing
775   public native boolean isContainerized();
776   public native int validateCgroup(boolean cgroupsV2Enabled,
777                                    String controllersFile,
778                                    String procSelfCgroup,
779                                    String procSelfMountinfo);
780   public native void printOsInfo();
781   public native long hostPhysicalMemory();
782   public native long hostPhysicalSwap();
783   public native int hostCPUs();
784 
785   // Decoder
786   public native void disableElfSectionCache();
787 
788   // Resolved Method Table
789   public native long resolvedMethodItemsCount();
790 
791   public native int getKlassMetadataSize(Class<?> c);
792 
793   // ThreadSMR GC safety check for threadObj
794   public native void checkThreadObjOfTerminatingThread(Thread target);
795 
796   // libc name
797   public native String getLibcName();
798 
799   // Walk stack frames of current thread
800   public native void verifyFrames(boolean log, boolean updateRegisterMap);
801 
802   public native boolean isJVMTIIncluded();
803 
804   public native void waitUnsafe(int time_ms);
805 
806   public native void pinObject(Object o);
807 
808   public native void unpinObject(Object o);
809 
810   public native boolean setVirtualThreadsNotifyJvmtiMode(boolean enabled);
811 
812   public native void preTouchMemory(long addr, long size);
813   public native long rss();
814 
815   public native boolean isStatic();
816 }