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