1 /*
  2  * Copyright (c) 2012, 2024, 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 int getLockStackCapacity();
123 
124   public native boolean supportsRecursiveLightweightLocking();
125 
126   public native void forceSafepoint();
127 
128   private native long getConstantPool0(Class<?> aClass);
129   public         long getConstantPool(Class<?> aClass) {
130     Objects.requireNonNull(aClass);
131     return getConstantPool0(aClass);
132   }
133 
134   private native int getConstantPoolCacheIndexTag0();
135   public         int getConstantPoolCacheIndexTag() {
136     return getConstantPoolCacheIndexTag0();
137   }
138 
139   private native int getConstantPoolCacheLength0(Class<?> aClass);
140   public         int getConstantPoolCacheLength(Class<?> aClass) {
141     Objects.requireNonNull(aClass);
142     return getConstantPoolCacheLength0(aClass);
143   }
144 
145   private native int remapInstructionOperandFromCPCache0(Class<?> aClass, int index);
146   public         int remapInstructionOperandFromCPCache(Class<?> aClass, int index) {
147     Objects.requireNonNull(aClass);
148     return remapInstructionOperandFromCPCache0(aClass, index);
149   }
150 
151   private native int encodeConstantPoolIndyIndex0(int index);
152   public         int encodeConstantPoolIndyIndex(int index) {
153     return encodeConstantPoolIndyIndex0(index);
154   }
155 
156   // JVMTI
157   private native void addToBootstrapClassLoaderSearch0(String segment);
158   public         void addToBootstrapClassLoaderSearch(String segment){
159     Objects.requireNonNull(segment);
160     addToBootstrapClassLoaderSearch0(segment);
161   }
162 
163   private native void addToSystemClassLoaderSearch0(String segment);
164   public         void addToSystemClassLoaderSearch(String segment) {
165     Objects.requireNonNull(segment);
166     addToSystemClassLoaderSearch0(segment);
167   }
168 
169   // G1
170   public native boolean g1InConcurrentMark();
171   public native boolean g1HasRegionsToUncommit();
172   private native boolean g1IsHumongous0(Object o);
173   public         boolean g1IsHumongous(Object o) {
174     Objects.requireNonNull(o);
175     return g1IsHumongous0(o);
176   }
177 
178   private native boolean g1BelongsToHumongousRegion0(long adr);
179   public         boolean g1BelongsToHumongousRegion(long adr) {
180     if (adr == 0) {
181       throw new IllegalArgumentException("adr argument should not be null");
182     }
183     return g1BelongsToHumongousRegion0(adr);
184   }
185 
186 
187   private native boolean g1BelongsToFreeRegion0(long adr);
188   public         boolean g1BelongsToFreeRegion(long adr) {
189     if (adr == 0) {
190       throw new IllegalArgumentException("adr argument should not be null");
191     }
192     return g1BelongsToFreeRegion0(adr);
193   }
194 
195   public native long    g1NumMaxRegions();
196   public native long    g1NumFreeRegions();
197   public native int     g1RegionSize();
198   public native MemoryUsage g1AuxiliaryMemoryUsage();
199   private  native Object[]    parseCommandLine0(String commandline, char delim, DiagnosticCommand[] args);
200   public          Object[]    parseCommandLine(String commandline, char delim, DiagnosticCommand[] args) {
201     Objects.requireNonNull(args);
202     return parseCommandLine0(commandline, delim, args);
203   }
204 
205   public native int g1ActiveMemoryNodeCount();
206   public native int[] g1MemoryNodeIds();
207 
208   // Parallel GC
209   public native long psVirtualSpaceAlignment();
210   public native long psHeapGenerationAlignment();
211 
212   /**
213    * Enumerates old regions with liveness less than specified and produces some statistics
214    * @param liveness percent of region's liveness (live_objects / total_region_size * 100).
215    * @return long[3] array where long[0] - total count of old regions
216    *                             long[1] - total memory of old regions
217    *                             long[2] - lowest estimation of total memory of old regions to be freed (non-full
218    *                             regions are not included)
219    */
220   public native long[] g1GetMixedGCInfo(int liveness);
221 
222   // NMT
223   public native long NMTMalloc(long size);
224   public native void NMTFree(long mem);
225   public native long NMTReserveMemory(long size);
226   public native long NMTAttemptReserveMemoryAt(long addr, long size);
227   public native void NMTCommitMemory(long addr, long size);
228   public native void NMTUncommitMemory(long addr, long size);
229   public native void NMTReleaseMemory(long addr, long size);
230   public native long NMTMallocWithPseudoStack(long size, int index);
231   public native long NMTMallocWithPseudoStackAndType(long size, int index, int type);
232   public native int NMTGetHashSize();
233   public native long NMTNewArena(long initSize);
234   public native void NMTFreeArena(long arena);
235   public native void NMTArenaMalloc(long arena, long size);
236 
237   // Compiler
238   public native boolean isC2OrJVMCIIncluded();
239   public native boolean isJVMCISupportedByGC();
240 
241   public native int     matchesMethod(Executable method, String pattern);
242   public native int     matchesInline(Executable method, String pattern);
243   public native boolean shouldPrintAssembly(Executable method, int comp_level);
244   public native int     deoptimizeFrames(boolean makeNotEntrant);
245   public native boolean isFrameDeoptimized(int depth);
246   public native void    deoptimizeAll();
247 
248   public        boolean isMethodCompiled(Executable method) {
249     return isMethodCompiled(method, false /*not osr*/);
250   }
251   private native boolean isMethodCompiled0(Executable method, boolean isOsr);
252   public         boolean isMethodCompiled(Executable method, boolean isOsr){
253     Objects.requireNonNull(method);
254     return isMethodCompiled0(method, isOsr);
255   }
256   public        boolean isMethodCompilable(Executable method) {
257     return isMethodCompilable(method, -1 /*any*/);
258   }
259   public        boolean isMethodCompilable(Executable method, int compLevel) {
260     return isMethodCompilable(method, compLevel, false /*not osr*/);
261   }
262   private native boolean isMethodCompilable0(Executable method, int compLevel, boolean isOsr);
263   public         boolean isMethodCompilable(Executable method, int compLevel, boolean isOsr) {
264     Objects.requireNonNull(method);
265     return isMethodCompilable0(method, compLevel, isOsr);
266   }
267   private native boolean isMethodQueuedForCompilation0(Executable method);
268   public         boolean isMethodQueuedForCompilation(Executable method) {
269     Objects.requireNonNull(method);
270     return isMethodQueuedForCompilation0(method);
271   }
272   // Determine if the compiler corresponding to the compilation level 'compLevel'
273   // and to the compilation context 'compilation_context' provides an intrinsic
274   // for the method 'method'. An intrinsic is available for method 'method' if:
275   //  - the intrinsic is enabled (by using the appropriate command-line flag) and
276   //  - the platform on which the VM is running provides the instructions necessary
277   //    for the compiler to generate the intrinsic code.
278   //
279   // The compilation context is related to using the DisableIntrinsic flag on a
280   // per-method level, see hotspot/src/share/vm/compiler/abstractCompiler.hpp
281   // for more details.
282   public boolean isIntrinsicAvailable(Executable method,
283                                       Executable compilationContext,
284                                       int compLevel) {
285       Objects.requireNonNull(method);
286       return isIntrinsicAvailable0(method, compilationContext, compLevel);
287   }
288   // If usage of the DisableIntrinsic flag is not expected (or the usage can be ignored),
289   // use the below method that does not require the compilation context as argument.
290   public boolean isIntrinsicAvailable(Executable method, int compLevel) {
291       return isIntrinsicAvailable(method, null, compLevel);
292   }
293   private native boolean isIntrinsicAvailable0(Executable method,
294                                                Executable compilationContext,
295                                                int compLevel);
296   public        int     deoptimizeMethod(Executable method) {
297     return deoptimizeMethod(method, false /*not osr*/);
298   }
299   private native int     deoptimizeMethod0(Executable method, boolean isOsr);
300   public         int     deoptimizeMethod(Executable method, boolean isOsr) {
301     Objects.requireNonNull(method);
302     return deoptimizeMethod0(method, isOsr);
303   }
304   public        void    makeMethodNotCompilable(Executable method) {
305     makeMethodNotCompilable(method, -1 /*any*/);
306   }
307   public        void    makeMethodNotCompilable(Executable method, int compLevel) {
308     makeMethodNotCompilable(method, compLevel, false /*not osr*/);
309   }
310   private native void    makeMethodNotCompilable0(Executable method, int compLevel, boolean isOsr);
311   public         void    makeMethodNotCompilable(Executable method, int compLevel, boolean isOsr) {
312     Objects.requireNonNull(method);
313     makeMethodNotCompilable0(method, compLevel, isOsr);
314   }
315   public        int     getMethodCompilationLevel(Executable method) {
316     return getMethodCompilationLevel(method, false /*not ost*/);
317   }
318   private native int     getMethodCompilationLevel0(Executable method, boolean isOsr);
319   public         int     getMethodCompilationLevel(Executable method, boolean isOsr) {
320     Objects.requireNonNull(method);
321     return getMethodCompilationLevel0(method, isOsr);
322   }
323   private native boolean testSetDontInlineMethod0(Executable method, boolean value);
324   public         boolean testSetDontInlineMethod(Executable method, boolean value) {
325     Objects.requireNonNull(method);
326     return testSetDontInlineMethod0(method, value);
327   }
328   public        int     getCompileQueuesSize() {
329     return getCompileQueueSize(-1 /*any*/);
330   }
331   public native int     getCompileQueueSize(int compLevel);
332   private native boolean testSetForceInlineMethod0(Executable method, boolean value);
333   public         boolean testSetForceInlineMethod(Executable method, boolean value) {
334     Objects.requireNonNull(method);
335     return testSetForceInlineMethod0(method, value);
336   }
337   public        boolean enqueueMethodForCompilation(Executable method, int compLevel) {
338     return enqueueMethodForCompilation(method, compLevel, -1 /*InvocationEntryBci*/);
339   }
340   private native boolean enqueueMethodForCompilation0(Executable method, int compLevel, int entry_bci);
341   public  boolean enqueueMethodForCompilation(Executable method, int compLevel, int entry_bci) {
342     Objects.requireNonNull(method);
343     return enqueueMethodForCompilation0(method, compLevel, entry_bci);
344   }
345   private native boolean enqueueInitializerForCompilation0(Class<?> aClass, int compLevel);
346   public  boolean enqueueInitializerForCompilation(Class<?> aClass, int compLevel) {
347     Objects.requireNonNull(aClass);
348     return enqueueInitializerForCompilation0(aClass, compLevel);
349   }
350   private native void    clearMethodState0(Executable method);
351   public  native void    markMethodProfiled(Executable method);
352   public         void    clearMethodState(Executable method) {
353     Objects.requireNonNull(method);
354     clearMethodState0(method);
355   }
356   public native void    lockCompilation();
357   public native void    unlockCompilation();
358   private native int     getMethodEntryBci0(Executable method);
359   public         int     getMethodEntryBci(Executable method) {
360     Objects.requireNonNull(method);
361     return getMethodEntryBci0(method);
362   }
363   private native Object[] getNMethod0(Executable method, boolean isOsr);
364   public         Object[] getNMethod(Executable method, boolean isOsr) {
365     Objects.requireNonNull(method);
366     return getNMethod0(method, isOsr);
367   }
368   public native long    allocateCodeBlob(int size, int type);
369   public        long    allocateCodeBlob(long size, int type) {
370       int intSize = (int) size;
371       if ((long) intSize != size || size < 0) {
372           throw new IllegalArgumentException(
373                 "size argument has illegal value " + size);
374       }
375       return allocateCodeBlob( intSize, type);
376   }
377   public native void    freeCodeBlob(long addr);
378   public native void    forceNMethodSweep();
379   public native Object[] getCodeHeapEntries(int type);
380   public native int     getCompilationActivityMode();
381   private native long getMethodData0(Executable method);
382   public         long getMethodData(Executable method) {
383     Objects.requireNonNull(method);
384     return getMethodData0(method);
385   }
386   public native Object[] getCodeBlob(long addr);
387 
388   private native void clearInlineCaches0(boolean preserve_static_stubs);
389   public void clearInlineCaches() {
390     clearInlineCaches0(false);
391   }
392   public void clearInlineCaches(boolean preserve_static_stubs) {
393     clearInlineCaches0(preserve_static_stubs);
394   }
395 
396   // Intered strings
397   public native boolean isInStringTable(String str);
398 
399   // Memory
400   public native void readReservedMemory();
401   public native long allocateMetaspace(ClassLoader classLoader, long size);
402   public native long incMetaspaceCapacityUntilGC(long increment);
403   public native long metaspaceCapacityUntilGC();
404   public native long metaspaceSharedRegionAlignment();
405 
406   public native void cleanMetaspaces();
407 
408   // Metaspace Arena Tests
409   public native long createMetaspaceTestContext(long commit_limit, long reserve_limit);
410   public native void destroyMetaspaceTestContext(long context);
411   public native void purgeMetaspaceTestContext(long context);
412   public native void printMetaspaceTestContext(long context);
413   public native long getTotalCommittedWordsInMetaspaceTestContext(long context);
414   public native long getTotalUsedWordsInMetaspaceTestContext(long context);
415   public native long createArenaInTestContext(long context, boolean is_micro);
416   public native void destroyMetaspaceTestArena(long arena);
417   public native long allocateFromMetaspaceTestArena(long arena, long word_size);
418   public native void deallocateToMetaspaceTestArena(long arena, long p, long word_size);
419 
420   public native long maxMetaspaceAllocationSize();
421 
422   // Don't use these methods directly
423   // Use jdk.test.whitebox.gc.GC class instead.
424   public native boolean isGCSupported(int name);
425   public native boolean isGCSupportedByJVMCICompiler(int name);
426   public native boolean isGCSelected(int name);
427   public native boolean isGCSelectedErgonomically();
428 
429   // Force Young GC
430   public native void youngGC();
431 
432   // Force Full GC
433   public native void fullGC();
434 
435   // Returns true if the current GC supports concurrent collection control.
436   public native boolean supportsConcurrentGCBreakpoints();
437 
438   private void checkConcurrentGCBreakpointsSupported() {
439     if (!supportsConcurrentGCBreakpoints()) {
440       throw new UnsupportedOperationException("Concurrent GC breakpoints not supported");
441     }
442   }
443 
444   private native void concurrentGCAcquireControl0();
445   private native void concurrentGCReleaseControl0();
446   private native void concurrentGCRunToIdle0();
447   private native boolean concurrentGCRunTo0(String breakpoint);
448 
449   private static boolean concurrentGCIsControlled = false;
450   private void checkConcurrentGCIsControlled() {
451     if (!concurrentGCIsControlled) {
452       throw new IllegalStateException("Not controlling concurrent GC");
453     }
454   }
455 
456   // All collectors supporting concurrent GC breakpoints are expected
457   // to provide at least the following breakpoints.
458   public final String AFTER_MARKING_STARTED = "AFTER MARKING STARTED";
459   public final String BEFORE_MARKING_COMPLETED = "BEFORE MARKING COMPLETED";
460 
461   // Collectors supporting concurrent GC breakpoints that do reference
462   // processing concurrently should provide the following breakpoint.
463   public final String AFTER_CONCURRENT_REFERENCE_PROCESSING_STARTED =
464     "AFTER CONCURRENT REFERENCE PROCESSING STARTED";
465 
466   // G1 specific GC breakpoints.
467   public final String G1_AFTER_REBUILD_STARTED = "AFTER REBUILD STARTED";
468   public final String G1_BEFORE_REBUILD_COMPLETED = "BEFORE REBUILD COMPLETED";
469   public final String G1_AFTER_CLEANUP_STARTED = "AFTER CLEANUP STARTED";
470   public final String G1_BEFORE_CLEANUP_COMPLETED = "BEFORE CLEANUP COMPLETED";
471 
472   public void concurrentGCAcquireControl() {
473     checkConcurrentGCBreakpointsSupported();
474     if (concurrentGCIsControlled) {
475       throw new IllegalStateException("Already controlling concurrent GC");
476     }
477     concurrentGCAcquireControl0();
478     concurrentGCIsControlled = true;
479   }
480 
481   public void concurrentGCReleaseControl() {
482     checkConcurrentGCBreakpointsSupported();
483     concurrentGCReleaseControl0();
484     concurrentGCIsControlled = false;
485   }
486 
487   // Keep concurrent GC idle.  Release from breakpoint.
488   public void concurrentGCRunToIdle() {
489     checkConcurrentGCBreakpointsSupported();
490     checkConcurrentGCIsControlled();
491     concurrentGCRunToIdle0();
492   }
493 
494   // Allow concurrent GC to run to breakpoint.
495   // Throws IllegalStateException if reached end of cycle first.
496   public void concurrentGCRunTo(String breakpoint) {
497     concurrentGCRunTo(breakpoint, true);
498   }
499 
500   // Allow concurrent GC to run to breakpoint.
501   // Returns true if reached breakpoint.  If reached end of cycle first,
502   // then throws IllegalStateException if errorIfFail is true, returning
503   // false otherwise.
504   public boolean concurrentGCRunTo(String breakpoint, boolean errorIfFail) {
505     checkConcurrentGCBreakpointsSupported();
506     checkConcurrentGCIsControlled();
507     if (breakpoint == null) {
508       throw new NullPointerException("null breakpoint");
509     } else if (concurrentGCRunTo0(breakpoint)) {
510       return true;
511     } else if (errorIfFail) {
512       throw new IllegalStateException("Missed requested breakpoint \"" + breakpoint + "\"");
513     } else {
514       return false;
515     }
516   }
517 
518   // Method tries to start concurrent mark cycle.
519   // It returns false if CM Thread is always in concurrent cycle.
520   public native boolean g1StartConcMarkCycle();
521 
522   // Tests on ReservedSpace/VirtualSpace classes
523   public native int stressVirtualSpaceResize(long reservedSpaceSize, long magnitude, long iterations);
524   public native void readFromNoaccessArea();
525   public native long getThreadStackSize();
526   public native long getThreadRemainingStackSize();
527 
528   // CPU features
529   public native String getCPUFeatures();
530 
531   // VM flags
532   public native boolean isConstantVMFlag(String name);
533   public native boolean isLockedVMFlag(String name);
534   public native void    setBooleanVMFlag(String name, boolean value);
535   public native void    setIntVMFlag(String name, long value);
536   public native void    setUintVMFlag(String name, long value);
537   public native void    setIntxVMFlag(String name, long value);
538   public native void    setUintxVMFlag(String name, long value);
539   public native void    setUint64VMFlag(String name, long value);
540   public native void    setSizeTVMFlag(String name, long value);
541   public native void    setStringVMFlag(String name, String value);
542   public native void    setDoubleVMFlag(String name, double value);
543   public native Boolean getBooleanVMFlag(String name);
544   public native Long    getIntVMFlag(String name);
545   public native Long    getUintVMFlag(String name);
546   public native Long    getIntxVMFlag(String name);
547   public native Long    getUintxVMFlag(String name);
548   public native Long    getUint64VMFlag(String name);
549   public native Long    getSizeTVMFlag(String name);
550   public native String  getStringVMFlag(String name);
551   public native Double  getDoubleVMFlag(String name);
552   private final List<Function<String,Object>> flagsGetters = Arrays.asList(
553     this::getBooleanVMFlag, this::getIntVMFlag, this::getUintVMFlag,
554     this::getIntxVMFlag, this::getUintxVMFlag, this::getUint64VMFlag,
555     this::getSizeTVMFlag, this::getStringVMFlag, this::getDoubleVMFlag);
556 
557   public Object getVMFlag(String name) {
558     return flagsGetters.stream()
559                        .map(f -> f.apply(name))
560                        .filter(x -> x != null)
561                        .findAny()
562                        .orElse(null);
563   }
564 
565   // Jigsaw
566   public native void DefineModule(Object module, boolean is_open, String version,
567                                   String location, Object[] packages);
568   public native void AddModuleExports(Object from_module, String pkg, Object to_module);
569   public native void AddReadsModule(Object from_module, Object source_module);
570   public native void AddModuleExportsToAllUnnamed(Object module, String pkg);
571   public native void AddModuleExportsToAll(Object module, String pkg);
572 
573   public native int getOffsetForName0(String name);
574   public int getOffsetForName(String name) throws Exception {
575     int offset = getOffsetForName0(name);
576     if (offset == -1) {
577       throw new RuntimeException(name + " not found");
578     }
579     return offset;
580   }
581   public native Boolean getMethodBooleanOption(Executable method, String name);
582   public native Long    getMethodIntxOption(Executable method, String name);
583   public native Long    getMethodUintxOption(Executable method, String name);
584   public native Double  getMethodDoubleOption(Executable method, String name);
585   public native String  getMethodStringOption(Executable method, String name);
586   private final List<BiFunction<Executable,String,Object>> methodOptionGetters
587       = Arrays.asList(this::getMethodBooleanOption, this::getMethodIntxOption,
588           this::getMethodUintxOption, this::getMethodDoubleOption,
589           this::getMethodStringOption);
590 
591   public Object getMethodOption(Executable method, String name) {
592     return methodOptionGetters.stream()
593                               .map(f -> f.apply(method, name))
594                               .filter(x -> x != null)
595                               .findAny()
596                               .orElse(null);
597   }
598 
599   // Sharing & archiving
600   public native String  getDefaultArchivePath();
601   public native boolean cdsMemoryMappingFailed();
602   public native boolean isSharingEnabled();
603   public native boolean isShared(Object o);
604   public native boolean isSharedClass(Class<?> c);
605   public native boolean areSharedStringsIgnored();
606   public native boolean isCDSIncluded();
607   public native boolean isJFRIncluded();
608   public native boolean isDTraceIncluded();
609   public native boolean canWriteJavaHeapArchive();
610   public native Object  getResolvedReferences(Class<?> c);
611   public native void    linkClass(Class<?> c);
612   public native boolean areOpenArchiveHeapObjectsMapped();
613 
614   // Compiler Directive
615   public native int addCompilerDirective(String compDirect);
616   public native void removeCompilerDirective(int count);
617 
618   // Handshakes
619   public native int handshakeWalkStack(Thread t, boolean all_threads);
620   public native void asyncHandshakeWalkStack(Thread t);
621 
622   public native void lockAndBlock(boolean suspender);
623 
624   // Returns true on linux if library has the noexecstack flag set.
625   public native boolean checkLibSpecifiesNoexecstack(String libfilename);
626 
627   // Container testing
628   public native boolean isContainerized();
629   public native int validateCgroup(String procCgroups,
630                                    String procSelfCgroup,
631                                    String procSelfMountinfo);
632   public native void printOsInfo();
633   public native long hostPhysicalMemory();
634   public native long hostPhysicalSwap();
635 
636   // Decoder
637   public native void disableElfSectionCache();
638 
639   // Resolved Method Table
640   public native long resolvedMethodItemsCount();
641 
642   // Protection Domain Table
643   public native int protectionDomainRemovedCount();
644 
645   public native int getKlassMetadataSize(Class<?> c);
646 
647   // ThreadSMR GC safety check for threadObj
648   public native void checkThreadObjOfTerminatingThread(Thread target);
649 
650   // libc name
651   public native String getLibcName();
652 
653   // Walk stack frames of current thread
654   public native void verifyFrames(boolean log, boolean updateRegisterMap);
655 
656   public native boolean isJVMTIIncluded();
657 
658   public native void waitUnsafe(int time_ms);
659 
660   public native void lockCritical();
661 
662   public native void unlockCritical();
663 
664   public native void preTouchMemory(long addr, long size);
665 }