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