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