1 /*
   2  * Copyright (c) 2012, 2020, 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 
  25 #include "precompiled.hpp"
  26 
  27 #include <new>
  28 
  29 #include "classfile/classLoaderDataGraph.hpp"
  30 #include "classfile/modules.hpp"
  31 #include "classfile/protectionDomainCache.hpp"
  32 #include "classfile/stringTable.hpp"
  33 #include "classfile/symbolTable.hpp"
  34 #include "code/codeCache.hpp"
  35 #include "compiler/compilationPolicy.hpp"
  36 #include "compiler/methodMatcher.hpp"
  37 #include "compiler/directivesParser.hpp"
  38 #include "gc/shared/concurrentGCBreakpoints.hpp"
  39 #include "gc/shared/gcConfig.hpp"
  40 #include "gc/shared/genArguments.hpp"
  41 #include "gc/shared/genCollectedHeap.hpp"
  42 #include "jvmtifiles/jvmtiEnv.hpp"
  43 #include "memory/filemap.hpp"
  44 #include "memory/heapShared.inline.hpp"
  45 #include "memory/metaspaceShared.hpp"
  46 #include "memory/metadataFactory.hpp"
  47 #include "memory/iterator.hpp"
  48 #include "memory/resourceArea.hpp"
  49 #include "memory/universe.hpp"
  50 #include "memory/oopFactory.hpp"
  51 #include "oops/array.hpp"
  52 #include "oops/compressedOops.hpp"
  53 #include "oops/constantPool.inline.hpp"
  54 #include "oops/method.inline.hpp"
  55 #include "oops/objArrayKlass.hpp"
  56 #include "oops/objArrayOop.inline.hpp"
  57 #include "oops/oop.inline.hpp"
  58 #include "oops/typeArrayOop.inline.hpp"
  59 #include "prims/resolvedMethodTable.hpp"
  60 #include "prims/wbtestmethods/parserTests.hpp"
  61 #include "prims/whitebox.inline.hpp"
  62 #include "runtime/arguments.hpp"
  63 #include "runtime/atomic.hpp"
  64 #include "runtime/deoptimization.hpp"
  65 #include "runtime/fieldDescriptor.inline.hpp"
  66 #include "runtime/flags/jvmFlag.hpp"
  67 #include "runtime/frame.inline.hpp"
  68 #include "runtime/handles.inline.hpp"
  69 #include "runtime/handshake.hpp"
  70 #include "runtime/interfaceSupport.inline.hpp"
  71 #include "runtime/javaCalls.hpp"
  72 #include "runtime/jniHandles.inline.hpp"
  73 #include "runtime/os.hpp"
  74 #include "runtime/sweeper.hpp"
  75 #include "runtime/thread.hpp"
  76 #include "runtime/threadSMR.hpp"
  77 #include "runtime/vm_version.hpp"
  78 #include "services/memoryService.hpp"
  79 #include "utilities/align.hpp"
  80 #include "utilities/debug.hpp"
  81 #include "utilities/elfFile.hpp"
  82 #include "utilities/exceptions.hpp"
  83 #include "utilities/macros.hpp"
  84 #if INCLUDE_CDS
  85 #include "prims/cdsoffsets.hpp"
  86 #endif // INCLUDE_CDS
  87 #if INCLUDE_G1GC
  88 #include "gc/g1/g1Arguments.hpp"
  89 #include "gc/g1/g1CollectedHeap.inline.hpp"
  90 #include "gc/g1/g1ConcurrentMark.hpp"
  91 #include "gc/g1/g1ConcurrentMarkThread.hpp"
  92 #include "gc/g1/heapRegionRemSet.hpp"
  93 #include "gc/g1/heterogeneousHeapRegionManager.hpp"
  94 #endif // INCLUDE_G1GC
  95 #if INCLUDE_PARALLELGC
  96 #include "gc/parallel/parallelScavengeHeap.inline.hpp"
  97 #endif // INCLUDE_PARALLELGC
  98 #if INCLUDE_NMT
  99 #include "services/mallocSiteTable.hpp"
 100 #include "services/memTracker.hpp"
 101 #include "utilities/nativeCallStack.hpp"
 102 #endif // INCLUDE_NMT
 103 #if INCLUDE_AOT
 104 #include "aot/aotLoader.hpp"
 105 #endif // INCLUDE_AOT
 106 
 107 #ifdef LINUX
 108 #include "osContainer_linux.hpp"
 109 #include "cgroupSubsystem_linux.hpp"
 110 #endif
 111 
 112 #define SIZE_T_MAX_VALUE ((size_t) -1)
 113 
 114 #define CHECK_JNI_EXCEPTION_(env, value)                               \
 115   do {                                                                 \
 116     JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \
 117     THREAD->clear_pending_jni_exception_check();                       \
 118     if (HAS_PENDING_EXCEPTION) {                                       \
 119       return(value);                                                   \
 120     }                                                                  \
 121   } while (0)
 122 
 123 #define CHECK_JNI_EXCEPTION(env)                                       \
 124   do {                                                                 \
 125     JavaThread* THREAD = JavaThread::thread_from_jni_environment(env); \
 126     THREAD->clear_pending_jni_exception_check();                       \
 127     if (HAS_PENDING_EXCEPTION) {                                       \
 128       return;                                                          \
 129     }                                                                  \
 130   } while (0)
 131 
 132 bool WhiteBox::_used = false;
 133 volatile bool WhiteBox::compilation_locked = false;
 134 
 135 class VM_WhiteBoxOperation : public VM_Operation {
 136  public:
 137   VM_WhiteBoxOperation()                         { }
 138   VMOp_Type type()                  const        { return VMOp_WhiteBoxOperation; }
 139   bool allow_nested_vm_operations() const        { return true; }
 140 };
 141 
 142 
 143 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
 144   return (jlong)(void*)JNIHandles::resolve(obj);
 145 WB_END
 146 
 147 WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
 148   return heapOopSize;
 149 WB_END
 150 
 151 WB_ENTRY(jint, WB_GetVMPageSize(JNIEnv* env, jobject o))
 152   return os::vm_page_size();
 153 WB_END
 154 
 155 WB_ENTRY(jlong, WB_GetVMAllocationGranularity(JNIEnv* env, jobject o))
 156   return os::vm_allocation_granularity();
 157 WB_END
 158 
 159 WB_ENTRY(jlong, WB_GetVMLargePageSize(JNIEnv* env, jobject o))
 160   return os::large_page_size();
 161 WB_END
 162 
 163 class WBIsKlassAliveClosure : public LockedClassesDo {
 164     Symbol* _name;
 165     int _count;
 166 public:
 167     WBIsKlassAliveClosure(Symbol* name) : _name(name), _count(0) {}
 168 
 169     void do_klass(Klass* k) {
 170       Symbol* ksym = k->name();
 171       if (ksym->fast_compare(_name) == 0) {
 172         _count++;
 173       }
 174     }
 175 
 176     int count() const {
 177         return _count;
 178     }
 179 };
 180 
 181 WB_ENTRY(jint, WB_CountAliveClasses(JNIEnv* env, jobject target, jstring name))
 182   oop h_name = JNIHandles::resolve(name);
 183   if (h_name == NULL) return false;
 184   Symbol* sym = java_lang_String::as_symbol(h_name);
 185   TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return
 186 
 187   WBIsKlassAliveClosure closure(sym);
 188   ClassLoaderDataGraph::classes_do(&closure);
 189 
 190   // Return the count of alive classes with this name.
 191   return closure.count();
 192 WB_END
 193 
 194 WB_ENTRY(jint, WB_GetSymbolRefcount(JNIEnv* env, jobject unused, jstring name))
 195   oop h_name = JNIHandles::resolve(name);
 196   if (h_name == NULL) return false;
 197   Symbol* sym = java_lang_String::as_symbol(h_name);
 198   TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return
 199   return (jint)sym->refcount();
 200 WB_END
 201 
 202 
 203 WB_ENTRY(void, WB_AddToBootstrapClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
 204 #if INCLUDE_JVMTI
 205   ResourceMark rm;
 206   const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
 207   JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
 208   jvmtiError err = jvmti_env->AddToBootstrapClassLoaderSearch(seg);
 209   assert(err == JVMTI_ERROR_NONE, "must not fail");
 210 #endif
 211 }
 212 WB_END
 213 
 214 WB_ENTRY(void, WB_AddToSystemClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
 215 #if INCLUDE_JVMTI
 216   ResourceMark rm;
 217   const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
 218   JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
 219   jvmtiError err = jvmti_env->AddToSystemClassLoaderSearch(seg);
 220   assert(err == JVMTI_ERROR_NONE, "must not fail");
 221 #endif
 222 }
 223 WB_END
 224 
 225 
 226 WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
 227   return (jlong)Arguments::max_heap_for_compressed_oops();
 228 }
 229 WB_END
 230 
 231 WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
 232   tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap " SIZE_FORMAT " "
 233                 "Maximum heap " SIZE_FORMAT " Space alignment " SIZE_FORMAT " Heap alignment " SIZE_FORMAT,
 234                 MinHeapSize,
 235                 InitialHeapSize,
 236                 MaxHeapSize,
 237                 SpaceAlignment,
 238                 HeapAlignment);
 239 }
 240 WB_END
 241 
 242 #ifndef PRODUCT
 243 // Forward declaration
 244 void TestReservedSpace_test();
 245 void TestReserveMemorySpecial_test();
 246 void TestVirtualSpace_test();
 247 #endif
 248 
 249 WB_ENTRY(void, WB_RunMemoryUnitTests(JNIEnv* env, jobject o))
 250 #ifndef PRODUCT
 251   TestReservedSpace_test();
 252   TestReserveMemorySpecial_test();
 253   TestVirtualSpace_test();
 254 #endif
 255 WB_END
 256 
 257 WB_ENTRY(void, WB_ReadFromNoaccessArea(JNIEnv* env, jobject o))
 258   size_t granularity = os::vm_allocation_granularity();
 259   ReservedHeapSpace rhs(100 * granularity, granularity, false);
 260   VirtualSpace vs;
 261   vs.initialize(rhs, 50 * granularity);
 262 
 263   // Check if constraints are complied
 264   if (!( UseCompressedOops && rhs.base() != NULL &&
 265          CompressedOops::base() != NULL &&
 266          CompressedOops::use_implicit_null_checks() )) {
 267     tty->print_cr("WB_ReadFromNoaccessArea method is useless:\n "
 268                   "\tUseCompressedOops is %d\n"
 269                   "\trhs.base() is " PTR_FORMAT "\n"
 270                   "\tCompressedOops::base() is " PTR_FORMAT "\n"
 271                   "\tCompressedOops::use_implicit_null_checks() is %d",
 272                   UseCompressedOops,
 273                   p2i(rhs.base()),
 274                   p2i(CompressedOops::base()),
 275                   CompressedOops::use_implicit_null_checks());
 276     return;
 277   }
 278   tty->print_cr("Reading from no access area... ");
 279   tty->print_cr("*(vs.low_boundary() - rhs.noaccess_prefix() / 2 ) = %c",
 280                 *(vs.low_boundary() - rhs.noaccess_prefix() / 2 ));
 281 WB_END
 282 
 283 static jint wb_stress_virtual_space_resize(size_t reserved_space_size,
 284                                            size_t magnitude, size_t iterations) {
 285   size_t granularity = os::vm_allocation_granularity();
 286   ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false);
 287   VirtualSpace vs;
 288   if (!vs.initialize(rhs, 0)) {
 289     tty->print_cr("Failed to initialize VirtualSpace. Can't proceed.");
 290     return 3;
 291   }
 292 
 293   int seed = os::random();
 294   tty->print_cr("Random seed is %d", seed);
 295   os::init_random(seed);
 296 
 297   for (size_t i = 0; i < iterations; i++) {
 298 
 299     // Whether we will shrink or grow
 300     bool shrink = os::random() % 2L == 0;
 301 
 302     // Get random delta to resize virtual space
 303     size_t delta = (size_t)os::random() % magnitude;
 304 
 305     // If we are about to shrink virtual space below zero, then expand instead
 306     if (shrink && vs.committed_size() < delta) {
 307       shrink = false;
 308     }
 309 
 310     // Resizing by delta
 311     if (shrink) {
 312       vs.shrink_by(delta);
 313     } else {
 314       // If expanding fails expand_by will silently return false
 315       vs.expand_by(delta, true);
 316     }
 317   }
 318   return 0;
 319 }
 320 
 321 WB_ENTRY(jint, WB_StressVirtualSpaceResize(JNIEnv* env, jobject o,
 322         jlong reserved_space_size, jlong magnitude, jlong iterations))
 323   tty->print_cr("reservedSpaceSize=" JLONG_FORMAT ", magnitude=" JLONG_FORMAT ", "
 324                 "iterations=" JLONG_FORMAT "\n", reserved_space_size, magnitude,
 325                 iterations);
 326   if (reserved_space_size < 0 || magnitude < 0 || iterations < 0) {
 327     tty->print_cr("One of variables printed above is negative. Can't proceed.\n");
 328     return 1;
 329   }
 330 
 331   // sizeof(size_t) depends on whether OS is 32bit or 64bit. sizeof(jlong) is
 332   // always 8 byte. That's why we should avoid overflow in case of 32bit platform.
 333   if (sizeof(size_t) < sizeof(jlong)) {
 334     jlong size_t_max_value = (jlong) SIZE_T_MAX_VALUE;
 335     if (reserved_space_size > size_t_max_value || magnitude > size_t_max_value
 336         || iterations > size_t_max_value) {
 337       tty->print_cr("One of variables printed above overflows size_t. Can't proceed.\n");
 338       return 2;
 339     }
 340   }
 341 
 342   return wb_stress_virtual_space_resize((size_t) reserved_space_size,
 343                                         (size_t) magnitude, (size_t) iterations);
 344 WB_END
 345 
 346 WB_ENTRY(jboolean, WB_IsGCSupported(JNIEnv* env, jobject o, jint name))
 347   return GCConfig::is_gc_supported((CollectedHeap::Name)name);
 348 WB_END
 349 
 350 WB_ENTRY(jboolean, WB_IsGCSelected(JNIEnv* env, jobject o, jint name))
 351   return GCConfig::is_gc_selected((CollectedHeap::Name)name);
 352 WB_END
 353 
 354 WB_ENTRY(jboolean, WB_IsGCSelectedErgonomically(JNIEnv* env, jobject o))
 355   return GCConfig::is_gc_selected_ergonomically();
 356 WB_END
 357 
 358 WB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj))
 359   oop p = JNIHandles::resolve(obj);
 360 #if INCLUDE_G1GC
 361   if (UseG1GC) {
 362     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 363     const HeapRegion* hr = g1h->heap_region_containing(p);
 364     if (hr == NULL) {
 365       return false;
 366     }
 367     return !(hr->is_young());
 368   }
 369 #endif
 370 #if INCLUDE_PARALLELGC
 371   if (UseParallelGC) {
 372     ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
 373     return !psh->is_in_young(p);
 374   }
 375 #endif
 376 #if INCLUDE_ZGC
 377   if (UseZGC) {
 378     return Universe::heap()->is_in(p);
 379   }
 380 #endif
 381   GenCollectedHeap* gch = GenCollectedHeap::heap();
 382   return !gch->is_in_young(p);
 383 WB_END
 384 
 385 WB_ENTRY(jlong, WB_GetObjectSize(JNIEnv* env, jobject o, jobject obj))
 386   oop p = JNIHandles::resolve(obj);
 387   return Universe::heap()->obj_size(p) * HeapWordSize;
 388 WB_END
 389 
 390 WB_ENTRY(jlong, WB_GetHeapSpaceAlignment(JNIEnv* env, jobject o))
 391   return (jlong)SpaceAlignment;
 392 WB_END
 393 
 394 WB_ENTRY(jlong, WB_GetHeapAlignment(JNIEnv* env, jobject o))
 395   return (jlong)HeapAlignment;
 396 WB_END
 397 
 398 WB_ENTRY(jboolean, WB_SupportsConcurrentGCBreakpoints(JNIEnv* env, jobject o))
 399   return Universe::heap()->supports_concurrent_gc_breakpoints();
 400 WB_END
 401 
 402 WB_ENTRY(void, WB_ConcurrentGCAcquireControl(JNIEnv* env, jobject o))
 403   ConcurrentGCBreakpoints::acquire_control();
 404 WB_END
 405 
 406 WB_ENTRY(void, WB_ConcurrentGCReleaseControl(JNIEnv* env, jobject o))
 407   ConcurrentGCBreakpoints::release_control();
 408 WB_END
 409 
 410 WB_ENTRY(void, WB_ConcurrentGCRunToIdle(JNIEnv* env, jobject o))
 411   ConcurrentGCBreakpoints::run_to_idle();
 412 WB_END
 413 
 414 WB_ENTRY(jboolean, WB_ConcurrentGCRunTo(JNIEnv* env, jobject o, jobject at))
 415   Handle h_name(THREAD, JNIHandles::resolve(at));
 416   ResourceMark rm;
 417   const char* c_name = java_lang_String::as_utf8_string(h_name());
 418   return ConcurrentGCBreakpoints::run_to(c_name);
 419 WB_END
 420 
 421 #if INCLUDE_G1GC
 422 
 423 WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
 424   if (UseG1GC) {
 425     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 426     oop result = JNIHandles::resolve(obj);
 427     const HeapRegion* hr = g1h->heap_region_containing(result);
 428     return hr->is_humongous();
 429   }
 430   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1IsHumongous: G1 GC is not enabled");
 431 WB_END
 432 
 433 WB_ENTRY(jboolean, WB_G1BelongsToHumongousRegion(JNIEnv* env, jobject o, jlong addr))
 434   if (UseG1GC) {
 435     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 436     const HeapRegion* hr = g1h->heap_region_containing((void*) addr);
 437     return hr->is_humongous();
 438   }
 439   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1BelongsToHumongousRegion: G1 GC is not enabled");
 440 WB_END
 441 
 442 WB_ENTRY(jboolean, WB_G1BelongsToFreeRegion(JNIEnv* env, jobject o, jlong addr))
 443   if (UseG1GC) {
 444     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 445     const HeapRegion* hr = g1h->heap_region_containing((void*) addr);
 446     return hr->is_free();
 447   }
 448   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1BelongsToFreeRegion: G1 GC is not enabled");
 449 WB_END
 450 
 451 WB_ENTRY(jlong, WB_G1NumMaxRegions(JNIEnv* env, jobject o))
 452   if (UseG1GC) {
 453     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 454     size_t nr = g1h->max_regions();
 455     return (jlong)nr;
 456   }
 457   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1NumMaxRegions: G1 GC is not enabled");
 458 WB_END
 459 
 460 WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o))
 461   if (UseG1GC) {
 462     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 463     size_t nr = g1h->num_free_regions();
 464     return (jlong)nr;
 465   }
 466   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1NumFreeRegions: G1 GC is not enabled");
 467 WB_END
 468 
 469 WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
 470   if (UseG1GC) {
 471     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 472     return g1h->concurrent_mark()->cm_thread()->during_cycle();
 473   }
 474   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1InConcurrentMark: G1 GC is not enabled");
 475 WB_END
 476 
 477 WB_ENTRY(jboolean, WB_G1StartMarkCycle(JNIEnv* env, jobject o))
 478   if (UseG1GC) {
 479     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 480     if (!g1h->concurrent_mark()->cm_thread()->during_cycle()) {
 481       g1h->collect(GCCause::_wb_conc_mark);
 482       return true;
 483     }
 484     return false;
 485   }
 486   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1StartMarkCycle: G1 GC is not enabled");
 487 WB_END
 488 
 489 WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
 490   if (UseG1GC) {
 491     return (jint)HeapRegion::GrainBytes;
 492   }
 493   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1RegionSize: G1 GC is not enabled");
 494 WB_END
 495 
 496 #endif // INCLUDE_G1GC
 497 
 498 #if INCLUDE_G1GC || INCLUDE_PARALLELGC
 499 WB_ENTRY(jlong, WB_DramReservedStart(JNIEnv* env, jobject o))
 500 #if INCLUDE_G1GC
 501   if (UseG1GC) {
 502     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 503     if (g1h->is_heterogeneous_heap()) {
 504       uint start_region = HeterogeneousHeapRegionManager::manager()->start_index_of_dram();
 505       return (jlong)(g1h->base() + start_region * HeapRegion::GrainBytes);
 506     } else {
 507       return (jlong)g1h->base();
 508     }
 509   }
 510 #endif // INCLUDE_G1GC
 511 #if INCLUDE_PARALLELGC
 512   if (UseParallelGC) {
 513     ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
 514     if (AllocateOldGenAt != NULL) {
 515       MemRegion reserved = ps_heap->young_gen()->reserved();
 516       return (jlong)reserved.start();
 517     } else {
 518       return (jlong)ps_heap->base();
 519     }
 520   }
 521 #endif // INCLUDE_PARALLELGC
 522   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_DramReservedStart: enabled only for G1 and Parallel GC");
 523 WB_END
 524 
 525 WB_ENTRY(jlong, WB_DramReservedEnd(JNIEnv* env, jobject o))
 526 #if INCLUDE_G1GC
 527   if (UseG1GC) {
 528     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 529     if (g1h->is_heterogeneous_heap()) {
 530       uint end_region = HeterogeneousHeapRegionManager::manager()->end_index_of_dram();
 531       return (jlong)(g1h->base() + (end_region + 1) * HeapRegion::GrainBytes - 1);
 532     } else {
 533       return (jlong)g1h->base() + G1Arguments::heap_max_size_bytes();
 534     }
 535   }
 536 #endif // INCLUDE_G1GC
 537 #if INCLUDE_PARALLELGC
 538   if (UseParallelGC) {
 539     ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
 540     if (AllocateOldGenAt != NULL) {
 541       MemRegion reserved = ps_heap->young_gen()->reserved();
 542       return (jlong)reserved.end();
 543     } else {
 544       return (jlong)ps_heap->reserved_region().end();
 545     }
 546   }
 547 #endif // INCLUDE_PARALLELGC
 548   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_DramReservedEnd: enabled only for G1 and Parallel GC");
 549 WB_END
 550 
 551 WB_ENTRY(jlong, WB_NvdimmReservedStart(JNIEnv* env, jobject o))
 552 #if INCLUDE_G1GC
 553   if (UseG1GC) {
 554     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 555     if (g1h->is_heterogeneous_heap()) {
 556       uint start_region = HeterogeneousHeapRegionManager::manager()->start_index_of_nvdimm();
 557       return (jlong)(g1h->base() + start_region * HeapRegion::GrainBytes);
 558     } else {
 559       THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedStart: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
 560     }
 561   }
 562 #endif // INCLUDE_G1GC
 563 #if INCLUDE_PARALLELGC
 564   if (UseParallelGC) {
 565     ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
 566     if (AllocateOldGenAt != NULL) {
 567       MemRegion reserved = ps_heap->old_gen()->reserved();
 568       return (jlong)reserved.start();
 569     } else {
 570       THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedStart: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
 571     }
 572   }
 573 #endif // INCLUDE_PARALLELGC
 574   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedStart: enabled only for G1 and Parallel GC");
 575 WB_END
 576 
 577 WB_ENTRY(jlong, WB_NvdimmReservedEnd(JNIEnv* env, jobject o))
 578 #if INCLUDE_G1GC
 579   if (UseG1GC) {
 580     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 581     if (g1h->is_heterogeneous_heap()) {
 582       uint end_region = HeterogeneousHeapRegionManager::manager()->start_index_of_nvdimm();
 583       return (jlong)(g1h->base() + (end_region + 1) * HeapRegion::GrainBytes - 1);
 584     } else {
 585       THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedEnd: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
 586     }
 587   }
 588 #endif // INCLUDE_G1GC
 589 #if INCLUDE_PARALLELGC
 590   if (UseParallelGC) {
 591     ParallelScavengeHeap* ps_heap = ParallelScavengeHeap::heap();
 592     if (AllocateOldGenAt != NULL) {
 593       MemRegion reserved = ps_heap->old_gen()->reserved();
 594       return (jlong)reserved.end();
 595       } else {
 596       THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedEnd: Old gen is not allocated on NV-DIMM using AllocateOldGenAt flag");
 597     }
 598   }
 599 #endif // INCLUDE_PARALLELGC
 600   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_NvdimmReservedEnd: enabled only for G1 and Parallel GC");
 601 WB_END
 602 
 603 #endif // INCLUDE_G1GC || INCLUDE_PARALLELGC
 604 
 605 #if INCLUDE_PARALLELGC
 606 
 607 WB_ENTRY(jlong, WB_PSVirtualSpaceAlignment(JNIEnv* env, jobject o))
 608   if (UseParallelGC) {
 609     return GenAlignment;
 610   }
 611   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSVirtualSpaceAlignment: Parallel GC is not enabled");
 612 WB_END
 613 
 614 WB_ENTRY(jlong, WB_PSHeapGenerationAlignment(JNIEnv* env, jobject o))
 615   if (UseParallelGC) {
 616     return GenAlignment;
 617   }
 618   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSHeapGenerationAlignment: Parallel GC is not enabled");
 619 WB_END
 620 
 621 #endif // INCLUDE_PARALLELGC
 622 
 623 #if INCLUDE_G1GC
 624 
 625 WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env))
 626   if (UseG1GC) {
 627     ResourceMark rm(THREAD);
 628     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 629     MemoryUsage usage = g1h->get_auxiliary_data_memory_usage();
 630     Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
 631     return JNIHandles::make_local(env, h());
 632   }
 633   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1AuxiliaryMemoryUsage: G1 GC is not enabled");
 634 WB_END
 635 
 636 WB_ENTRY(jint, WB_G1ActiveMemoryNodeCount(JNIEnv* env, jobject o))
 637   if (UseG1GC) {
 638     G1NUMA* numa = G1NUMA::numa();
 639     return (jint)numa->num_active_nodes();
 640   }
 641   THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1ActiveMemoryNodeCount: G1 GC is not enabled");
 642 WB_END
 643 
 644 WB_ENTRY(jintArray, WB_G1MemoryNodeIds(JNIEnv* env, jobject o))
 645   if (UseG1GC) {
 646     G1NUMA* numa = G1NUMA::numa();
 647     int num_node_ids = (int)numa->num_active_nodes();
 648     const int* node_ids = numa->node_ids();
 649 
 650     typeArrayOop result = oopFactory::new_intArray(num_node_ids, CHECK_NULL);
 651     for (int i = 0; i < num_node_ids; i++) {
 652       result->int_at_put(i, (jint)node_ids[i]);
 653     }
 654     return (jintArray) JNIHandles::make_local(env, result);
 655   }
 656   THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1MemoryNodeIds: G1 GC is not enabled");
 657 WB_END
 658 
 659 class OldRegionsLivenessClosure: public HeapRegionClosure {
 660 
 661  private:
 662   const int _liveness;
 663   size_t _total_count;
 664   size_t _total_memory;
 665   size_t _total_memory_to_free;
 666 
 667  public:
 668   OldRegionsLivenessClosure(int liveness) :
 669     _liveness(liveness),
 670     _total_count(0),
 671     _total_memory(0),
 672     _total_memory_to_free(0) { }
 673 
 674     size_t total_count() { return _total_count; }
 675     size_t total_memory() { return _total_memory; }
 676     size_t total_memory_to_free() { return _total_memory_to_free; }
 677 
 678   bool do_heap_region(HeapRegion* r) {
 679     if (r->is_old()) {
 680       size_t prev_live = r->marked_bytes();
 681       size_t live = r->live_bytes();
 682       size_t size = r->used();
 683       size_t reg_size = HeapRegion::GrainBytes;
 684       if (size > 0 && ((int)(live * 100 / size) < _liveness)) {
 685         _total_memory += size;
 686         ++_total_count;
 687         if (size == reg_size) {
 688         // we don't include non-full regions since they are unlikely included in mixed gc
 689         // for testing purposes it's enough to have lowest estimation of total memory that is expected to be freed
 690           _total_memory_to_free += size - prev_live;
 691         }
 692       }
 693     }
 694     return false;
 695   }
 696 };
 697 
 698 
 699 WB_ENTRY(jlongArray, WB_G1GetMixedGCInfo(JNIEnv* env, jobject o, jint liveness))
 700   if (!UseG1GC) {
 701     THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1GetMixedGCInfo: G1 GC is not enabled");
 702   }
 703   if (liveness < 0) {
 704     THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "liveness value should be non-negative");
 705   }
 706 
 707   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 708   OldRegionsLivenessClosure rli(liveness);
 709   g1h->heap_region_iterate(&rli);
 710 
 711   typeArrayOop result = oopFactory::new_longArray(3, CHECK_NULL);
 712   result->long_at_put(0, rli.total_count());
 713   result->long_at_put(1, rli.total_memory());
 714   result->long_at_put(2, rli.total_memory_to_free());
 715   return (jlongArray) JNIHandles::make_local(env, result);
 716 WB_END
 717 
 718 #endif // INCLUDE_G1GC
 719 
 720 #if INCLUDE_NMT
 721 // Alloc memory using the test memory type so that we can use that to see if
 722 // NMT picks it up correctly
 723 WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
 724   jlong addr = 0;
 725   addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
 726   return addr;
 727 WB_END
 728 
 729 // Alloc memory with pseudo call stack. The test can create psudo malloc
 730 // allocation site to stress the malloc tracking.
 731 WB_ENTRY(jlong, WB_NMTMallocWithPseudoStack(JNIEnv* env, jobject o, jlong size, jint pseudo_stack))
 732   address pc = (address)(size_t)pseudo_stack;
 733   NativeCallStack stack(&pc, 1);
 734   return (jlong)(uintptr_t)os::malloc(size, mtTest, stack);
 735 WB_END
 736 
 737 // Alloc memory with pseudo call stack and specific memory type.
 738 WB_ENTRY(jlong, WB_NMTMallocWithPseudoStackAndType(JNIEnv* env, jobject o, jlong size, jint pseudo_stack, jint type))
 739   address pc = (address)(size_t)pseudo_stack;
 740   NativeCallStack stack(&pc, 1);
 741   return (jlong)(uintptr_t)os::malloc(size, (MEMFLAGS)type, stack);
 742 WB_END
 743 
 744 // Free the memory allocated by NMTAllocTest
 745 WB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem))
 746   os::free((void*)(uintptr_t)mem);
 747 WB_END
 748 
 749 WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
 750   jlong addr = 0;
 751 
 752   addr = (jlong)(uintptr_t)os::reserve_memory(size);
 753   MemTracker::record_virtual_memory_type((address)addr, mtTest);
 754 
 755   return addr;
 756 WB_END
 757 
 758 WB_ENTRY(jlong, WB_NMTAttemptReserveMemoryAt(JNIEnv* env, jobject o, jlong addr, jlong size))
 759   addr = (jlong)(uintptr_t)os::attempt_reserve_memory_at((size_t)size, (char*)(uintptr_t)addr);
 760   MemTracker::record_virtual_memory_type((address)addr, mtTest);
 761 
 762   return addr;
 763 WB_END
 764 
 765 WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
 766   os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
 767   MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
 768 WB_END
 769 
 770 WB_ENTRY(void, WB_NMTUncommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
 771   os::uncommit_memory((char *)(uintptr_t)addr, size);
 772 WB_END
 773 
 774 WB_ENTRY(void, WB_NMTReleaseMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
 775   os::release_memory((char *)(uintptr_t)addr, size);
 776 WB_END
 777 
 778 WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env))
 779   // Test that we can downgrade NMT levels but not upgrade them.
 780   if (MemTracker::tracking_level() == NMT_off) {
 781     MemTracker::transition_to(NMT_off);
 782     return MemTracker::tracking_level() == NMT_off;
 783   } else {
 784     assert(MemTracker::tracking_level() == NMT_detail, "Should start out as detail tracking");
 785     MemTracker::transition_to(NMT_summary);
 786     assert(MemTracker::tracking_level() == NMT_summary, "Should be summary now");
 787 
 788     // Can't go to detail once NMT is set to summary.
 789     MemTracker::transition_to(NMT_detail);
 790     assert(MemTracker::tracking_level() == NMT_summary, "Should still be summary now");
 791 
 792     // Shutdown sets tracking level to minimal.
 793     MemTracker::shutdown();
 794     assert(MemTracker::tracking_level() == NMT_minimal, "Should be minimal now");
 795 
 796     // Once the tracking level is minimal, we cannot increase to summary.
 797     // The code ignores this request instead of asserting because if the malloc site
 798     // table overflows in another thread, it tries to change the code to summary.
 799     MemTracker::transition_to(NMT_summary);
 800     assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
 801 
 802     // Really can never go up to detail, verify that the code would never do this.
 803     MemTracker::transition_to(NMT_detail);
 804     assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
 805     return MemTracker::tracking_level() == NMT_minimal;
 806   }
 807 WB_END
 808 
 809 WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o))
 810   int hash_size = MallocSiteTable::hash_buckets();
 811   assert(hash_size > 0, "NMT hash_size should be > 0");
 812   return (jint)hash_size;
 813 WB_END
 814 
 815 WB_ENTRY(jlong, WB_NMTNewArena(JNIEnv* env, jobject o, jlong init_size))
 816   Arena* arena =  new (mtTest) Arena(mtTest, size_t(init_size));
 817   return (jlong)arena;
 818 WB_END
 819 
 820 WB_ENTRY(void, WB_NMTFreeArena(JNIEnv* env, jobject o, jlong arena))
 821   Arena* a = (Arena*)arena;
 822   delete a;
 823 WB_END
 824 
 825 WB_ENTRY(void, WB_NMTArenaMalloc(JNIEnv* env, jobject o, jlong arena, jlong size))
 826   Arena* a = (Arena*)arena;
 827   a->Amalloc(size_t(size));
 828 WB_END
 829 #endif // INCLUDE_NMT
 830 
 831 static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
 832   assert(method != NULL, "method should not be null");
 833   ThreadToNativeFromVM ttn(thread);
 834   return env->FromReflectedMethod(method);
 835 }
 836 
 837 static CompLevel highestCompLevel() {
 838   return TieredCompilation ? MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier) : CompLevel_highest_tier;
 839 }
 840 
 841 // Deoptimizes all compiled frames and makes nmethods not entrant if it's requested
 842 class VM_WhiteBoxDeoptimizeFrames : public VM_WhiteBoxOperation {
 843  private:
 844   int _result;
 845   const bool _make_not_entrant;
 846  public:
 847   VM_WhiteBoxDeoptimizeFrames(bool make_not_entrant) :
 848         _result(0), _make_not_entrant(make_not_entrant) { }
 849   int  result() const { return _result; }
 850 
 851   void doit() {
 852     for (JavaThreadIteratorWithHandle jtiwh; JavaThread *t = jtiwh.next(); ) {
 853       if (t->has_last_Java_frame()) {
 854         for (StackFrameStream fst(t, false); !fst.is_done(); fst.next()) {
 855           frame* f = fst.current();
 856           if (f->can_be_deoptimized() && !f->is_deoptimized_frame()) {
 857             Deoptimization::deoptimize(t, *f);
 858             if (_make_not_entrant) {
 859                 CompiledMethod* cm = CodeCache::find_compiled(f->pc());
 860                 assert(cm != NULL, "sanity check");
 861                 cm->make_not_entrant();
 862             }
 863             ++_result;
 864           }
 865         }
 866       }
 867     }
 868   }
 869 };
 870 
 871 WB_ENTRY(jint, WB_DeoptimizeFrames(JNIEnv* env, jobject o, jboolean make_not_entrant))
 872   VM_WhiteBoxDeoptimizeFrames op(make_not_entrant == JNI_TRUE);
 873   VMThread::execute(&op);
 874   return op.result();
 875 WB_END
 876 
 877 WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
 878   CodeCache::mark_all_nmethods_for_deoptimization();
 879   Deoptimization::deoptimize_all_marked();
 880 WB_END
 881 
 882 WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
 883   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 884   int result = 0;
 885   CHECK_JNI_EXCEPTION_(env, result);
 886   MutexLocker mu(Compile_lock);
 887   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 888   if (is_osr) {
 889     result += mh->mark_osr_nmethods();
 890   } else if (mh->code() != NULL) {
 891     mh->code()->mark_for_deoptimization();
 892     ++result;
 893   }
 894   result += CodeCache::mark_for_deoptimization(mh());
 895   if (result > 0) {
 896     Deoptimization::deoptimize_all_marked();
 897   }
 898   return result;
 899 WB_END
 900 
 901 WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
 902   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 903   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
 904   MutexLocker mu(Compile_lock);
 905   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 906   CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
 907   if (code == NULL) {
 908     return JNI_FALSE;
 909   }
 910   return (code->is_alive() && !code->is_marked_for_deoptimization());
 911 WB_END
 912 
 913 WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
 914   if (method == NULL || comp_level > highestCompLevel()) {
 915     return false;
 916   }
 917   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 918   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
 919   MutexLocker mu(Compile_lock);
 920   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 921   if (is_osr) {
 922     return CompilationPolicy::can_be_osr_compiled(mh, comp_level);
 923   } else {
 924     return CompilationPolicy::can_be_compiled(mh, comp_level);
 925   }
 926 WB_END
 927 
 928 WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
 929   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 930   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
 931   MutexLocker mu(Compile_lock);
 932   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 933   return mh->queued_for_compilation();
 934 WB_END
 935 
 936 WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject method, jobject compilation_context, jint compLevel))
 937   if (compLevel < CompLevel_none || compLevel > highestCompLevel()) {
 938     return false; // Intrinsic is not available on a non-existent compilation level.
 939   }
 940   jmethodID method_id, compilation_context_id;
 941   method_id = reflected_method_to_jmid(thread, env, method);
 942   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
 943   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(method_id));
 944 
 945   DirectiveSet* directive;
 946   AbstractCompiler* comp = CompileBroker::compiler((int)compLevel);
 947   assert(comp != NULL, "compiler not available");
 948   if (compilation_context != NULL) {
 949     compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context);
 950     CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
 951     methodHandle cch(THREAD, Method::checked_resolve_jmethod_id(compilation_context_id));
 952     directive = DirectivesStack::getMatchingDirective(cch, comp);
 953   } else {
 954     // Calling with NULL matches default directive
 955     directive = DirectivesStack::getDefaultDirective(comp);
 956   }
 957   bool result = comp->is_intrinsic_available(mh, directive);
 958   DirectivesStack::release(directive);
 959   return result;
 960 WB_END
 961 
 962 WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
 963   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 964   CHECK_JNI_EXCEPTION_(env, CompLevel_none);
 965   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 966   CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
 967   return (code != NULL ? code->comp_level() : CompLevel_none);
 968 WB_END
 969 
 970 WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
 971   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 972   CHECK_JNI_EXCEPTION(env);
 973   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 974   if (is_osr) {
 975     mh->set_not_osr_compilable("WhiteBox", comp_level);
 976   } else {
 977     mh->set_not_compilable("WhiteBox", comp_level);
 978   }
 979 WB_END
 980 
 981 WB_ENTRY(jint, WB_GetMethodEntryBci(JNIEnv* env, jobject o, jobject method))
 982   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 983   CHECK_JNI_EXCEPTION_(env, InvocationEntryBci);
 984   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 985   CompiledMethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false);
 986   return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci);
 987 WB_END
 988 
 989 WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
 990   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 991   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
 992   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 993   bool result = mh->dont_inline();
 994   mh->set_dont_inline(value == JNI_TRUE);
 995   return result;
 996 WB_END
 997 
 998 WB_ENTRY(jint, WB_GetCompileQueueSize(JNIEnv* env, jobject o, jint comp_level))
 999   if (comp_level == CompLevel_any) {
1000     return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
1001         CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
1002   } else {
1003     return CompileBroker::queue_size(comp_level);
1004   }
1005 WB_END
1006 
1007 WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
1008   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1009   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
1010   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1011   bool result = mh->force_inline();
1012   mh->set_force_inline(value == JNI_TRUE);
1013   return result;
1014 WB_END
1015 
1016 #ifdef LINUX
1017 bool WhiteBox::validate_cgroup(const char* proc_cgroups,
1018                                const char* proc_self_cgroup,
1019                                const char* proc_self_mountinfo,
1020                                u1* cg_flags) {
1021   CgroupInfo cg_infos[4];
1022   return CgroupSubsystemFactory::determine_type(cg_infos, proc_cgroups,
1023                                                     proc_self_cgroup,
1024                                                     proc_self_mountinfo, cg_flags);
1025 }
1026 #endif
1027 
1028 bool WhiteBox::compile_method(Method* method, int comp_level, int bci, Thread* THREAD) {
1029   // Screen for unavailable/bad comp level or null method
1030   AbstractCompiler* comp = CompileBroker::compiler(comp_level);
1031   if (method == NULL) {
1032     tty->print_cr("WB error: request to compile NULL method");
1033     return false;
1034   }
1035   if (comp_level > highestCompLevel()) {
1036     tty->print_cr("WB error: invalid compilation level %d", comp_level);
1037     return false;
1038   }
1039   if (comp == NULL) {
1040     tty->print_cr("WB error: no compiler for requested compilation level %d", comp_level);
1041     return false;
1042   }
1043 
1044   // Check if compilation is blocking
1045   methodHandle mh(THREAD, method);
1046   DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, comp);
1047   bool is_blocking = !directive->BackgroundCompilationOption;
1048   DirectivesStack::release(directive);
1049 
1050   // Compile method and check result
1051   nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), CompileTask::Reason_Whitebox, THREAD);
1052   MutexLocker mu(THREAD, Compile_lock);
1053   bool is_queued = mh->queued_for_compilation();
1054   if ((!is_blocking && is_queued) || nm != NULL) {
1055     return true;
1056   }
1057   tty->print("WB error: failed to %s compile at level %d method ", is_blocking ? "blocking" : "", comp_level);
1058   mh->print_short_name(tty);
1059   tty->cr();
1060   if (is_blocking && is_queued) {
1061     tty->print_cr("WB error: blocking compilation is still in queue!");
1062   }
1063   return false;
1064 }
1065 
1066 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
1067   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1068   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
1069   return WhiteBox::compile_method(Method::checked_resolve_jmethod_id(jmid), comp_level, bci, THREAD);
1070 WB_END
1071 
1072 WB_ENTRY(jboolean, WB_EnqueueInitializerForCompilation(JNIEnv* env, jobject o, jclass klass, jint comp_level))
1073   InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
1074   Method* clinit = ik->class_initializer();
1075   if (clinit == NULL) {
1076     return false;
1077   }
1078   return WhiteBox::compile_method(clinit, comp_level, InvocationEntryBci, THREAD);
1079 WB_END
1080 
1081 WB_ENTRY(jboolean, WB_ShouldPrintAssembly(JNIEnv* env, jobject o, jobject method, jint comp_level))
1082   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1083   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
1084 
1085   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1086   DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, CompileBroker::compiler(comp_level));
1087   bool result = directive->PrintAssemblyOption;
1088   DirectivesStack::release(directive);
1089 
1090   return result;
1091 WB_END
1092 
1093 WB_ENTRY(jint, WB_MatchesInline(JNIEnv* env, jobject o, jobject method, jstring pattern))
1094   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1095   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
1096 
1097   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1098 
1099   ResourceMark rm(THREAD);
1100   const char* error_msg = NULL;
1101   char* method_str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(pattern));
1102   InlineMatcher* m = InlineMatcher::parse_inline_pattern(method_str, error_msg);
1103 
1104   if (m == NULL) {
1105     assert(error_msg != NULL, "Always have an error message");
1106     tty->print_cr("Got error: %s", error_msg);
1107     return -1; // Pattern failed
1108   }
1109 
1110   // Pattern works - now check if it matches
1111   int result;
1112   if (m->match(mh, InlineMatcher::force_inline)) {
1113     result = 2; // Force inline match
1114   } else if (m->match(mh, InlineMatcher::dont_inline)) {
1115     result = 1; // Dont inline match
1116   } else {
1117     result = 0; // No match
1118   }
1119   delete m;
1120   return result;
1121 WB_END
1122 
1123 WB_ENTRY(jint, WB_MatchesMethod(JNIEnv* env, jobject o, jobject method, jstring pattern))
1124   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1125   CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
1126 
1127   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1128 
1129   ResourceMark rm;
1130   char* method_str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(pattern));
1131 
1132   const char* error_msg = NULL;
1133 
1134   BasicMatcher* m = BasicMatcher::parse_method_pattern(method_str, error_msg);
1135   if (m == NULL) {
1136     assert(error_msg != NULL, "Must have error_msg");
1137     tty->print_cr("Got error: %s", error_msg);
1138     return -1;
1139   }
1140 
1141   // Pattern works - now check if it matches
1142   int result = m->matches(mh);
1143   delete m;
1144   assert(result == 0 || result == 1, "Result out of range");
1145   return result;
1146 WB_END
1147 
1148 WB_ENTRY(void, WB_MarkMethodProfiled(JNIEnv* env, jobject o, jobject method))
1149   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1150   CHECK_JNI_EXCEPTION(env);
1151   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1152 
1153   MethodData* mdo = mh->method_data();
1154   if (mdo == NULL) {
1155     Method::build_interpreter_method_data(mh, CHECK_AND_CLEAR);
1156     mdo = mh->method_data();
1157   }
1158   mdo->init();
1159   InvocationCounter* icnt = mdo->invocation_counter();
1160   InvocationCounter* bcnt = mdo->backedge_counter();
1161   // set i-counter according to TieredThresholdPolicy::is_method_profiled
1162   icnt->set(Tier4MinInvocationThreshold);
1163   bcnt->set(Tier4CompileThreshold);
1164 WB_END
1165 
1166 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
1167   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1168   CHECK_JNI_EXCEPTION(env);
1169   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1170   MutexLocker mu(THREAD, Compile_lock);
1171   MethodData* mdo = mh->method_data();
1172   MethodCounters* mcs = mh->method_counters();
1173 
1174   if (mdo != NULL) {
1175     mdo->init();
1176     ResourceMark rm(THREAD);
1177     int arg_count = mdo->method()->size_of_parameters();
1178     for (int i = 0; i < arg_count; i++) {
1179       mdo->set_arg_modified(i, 0);
1180     }
1181     MutexLocker mu(THREAD, mdo->extra_data_lock());
1182     mdo->clean_method_data(/*always_clean*/true);
1183   }
1184 
1185   mh->clear_not_c1_compilable();
1186   mh->clear_not_c2_compilable();
1187   mh->clear_not_c2_osr_compilable();
1188   NOT_PRODUCT(mh->set_compiled_invocation_count(0));
1189   if (mcs != NULL) {
1190     mcs->backedge_counter()->init();
1191     mcs->invocation_counter()->init();
1192     mcs->set_interpreter_invocation_count(0);
1193     mcs->set_interpreter_throwout_count(0);
1194 
1195 #ifdef TIERED
1196     mcs->set_rate(0.0F);
1197     mh->set_prev_event_count(0);
1198     mh->set_prev_time(0);
1199 #endif
1200   }
1201 WB_END
1202 
1203 template <typename T>
1204 static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAt)(const JVMFlag*, T*)) {
1205   if (name == NULL) {
1206     return false;
1207   }
1208   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1209   const char* flag_name = env->GetStringUTFChars(name, NULL);
1210   CHECK_JNI_EXCEPTION_(env, false);
1211   const JVMFlag* flag = JVMFlag::find_declared_flag(flag_name);
1212   JVMFlag::Error result = (*TAt)(flag, value);
1213   env->ReleaseStringUTFChars(name, flag_name);
1214   return (result == JVMFlag::SUCCESS);
1215 }
1216 
1217 template <typename T>
1218 static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, JVMFlag::Error (*TAtPut)(JVMFlag* flag, T*, JVMFlag::Flags)) {
1219   if (name == NULL) {
1220     return false;
1221   }
1222   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1223   const char* flag_name = env->GetStringUTFChars(name, NULL);
1224   CHECK_JNI_EXCEPTION_(env, false);
1225   JVMFlag* flag = JVMFlag::find_flag(flag_name);
1226   JVMFlag::Error result = (*TAtPut)(flag, value, JVMFlag::INTERNAL);
1227   env->ReleaseStringUTFChars(name, flag_name);
1228   return (result == JVMFlag::SUCCESS);
1229 }
1230 
1231 template <typename T>
1232 static jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) {
1233   ResourceMark rm(thread);
1234   jclass clazz = env->FindClass(name->as_C_string());
1235   CHECK_JNI_EXCEPTION_(env, NULL);
1236   jmethodID methodID = env->GetStaticMethodID(clazz,
1237         vmSymbols::valueOf_name()->as_C_string(),
1238         sig->as_C_string());
1239   CHECK_JNI_EXCEPTION_(env, NULL);
1240   jobject result = env->CallStaticObjectMethod(clazz, methodID, value);
1241   CHECK_JNI_EXCEPTION_(env, NULL);
1242   return result;
1243 }
1244 
1245 static jobject booleanBox(JavaThread* thread, JNIEnv* env, jboolean value) {
1246   return box(thread, env, vmSymbols::java_lang_Boolean(), vmSymbols::Boolean_valueOf_signature(), value);
1247 }
1248 static jobject integerBox(JavaThread* thread, JNIEnv* env, jint value) {
1249   return box(thread, env, vmSymbols::java_lang_Integer(), vmSymbols::Integer_valueOf_signature(), value);
1250 }
1251 static jobject longBox(JavaThread* thread, JNIEnv* env, jlong value) {
1252   return box(thread, env, vmSymbols::java_lang_Long(), vmSymbols::Long_valueOf_signature(), value);
1253 }
1254 /* static jobject floatBox(JavaThread* thread, JNIEnv* env, jfloat value) {
1255   return box(thread, env, vmSymbols::java_lang_Float(), vmSymbols::Float_valueOf_signature(), value);
1256 }*/
1257 static jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) {
1258   return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value);
1259 }
1260 
1261 static const JVMFlag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) {
1262   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1263   const char* flag_name = env->GetStringUTFChars(name, NULL);
1264   CHECK_JNI_EXCEPTION_(env, NULL);
1265   const JVMFlag* result = JVMFlag::find_declared_flag(flag_name);
1266   env->ReleaseStringUTFChars(name, flag_name);
1267   return result;
1268 }
1269 
1270 WB_ENTRY(jboolean, WB_IsConstantVMFlag(JNIEnv* env, jobject o, jstring name))
1271   const JVMFlag* flag = getVMFlag(thread, env, name);
1272   return (flag != NULL) && flag->is_constant_in_binary();
1273 WB_END
1274 
1275 WB_ENTRY(jboolean, WB_IsLockedVMFlag(JNIEnv* env, jobject o, jstring name))
1276   const JVMFlag* flag = getVMFlag(thread, env, name);
1277   return (flag != NULL) && !(flag->is_unlocked() || flag->is_unlocker());
1278 WB_END
1279 
1280 WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name))
1281   bool result;
1282   if (GetVMFlag <bool> (thread, env, name, &result, &JVMFlag::boolAt)) {
1283     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1284     return booleanBox(thread, env, result);
1285   }
1286   return NULL;
1287 WB_END
1288 
1289 WB_ENTRY(jobject, WB_GetIntVMFlag(JNIEnv* env, jobject o, jstring name))
1290   int result;
1291   if (GetVMFlag <int> (thread, env, name, &result, &JVMFlag::intAt)) {
1292     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1293     return longBox(thread, env, result);
1294   }
1295   return NULL;
1296 WB_END
1297 
1298 WB_ENTRY(jobject, WB_GetUintVMFlag(JNIEnv* env, jobject o, jstring name))
1299   uint result;
1300   if (GetVMFlag <uint> (thread, env, name, &result, &JVMFlag::uintAt)) {
1301     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1302     return longBox(thread, env, result);
1303   }
1304   return NULL;
1305 WB_END
1306 
1307 WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name))
1308   intx result;
1309   if (GetVMFlag <intx> (thread, env, name, &result, &JVMFlag::intxAt)) {
1310     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1311     return longBox(thread, env, result);
1312   }
1313   return NULL;
1314 WB_END
1315 
1316 WB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name))
1317   uintx result;
1318   if (GetVMFlag <uintx> (thread, env, name, &result, &JVMFlag::uintxAt)) {
1319     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1320     return longBox(thread, env, result);
1321   }
1322   return NULL;
1323 WB_END
1324 
1325 WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name))
1326   uint64_t result;
1327   if (GetVMFlag <uint64_t> (thread, env, name, &result, &JVMFlag::uint64_tAt)) {
1328     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1329     return longBox(thread, env, result);
1330   }
1331   return NULL;
1332 WB_END
1333 
1334 WB_ENTRY(jobject, WB_GetSizeTVMFlag(JNIEnv* env, jobject o, jstring name))
1335   size_t result;
1336   if (GetVMFlag <size_t> (thread, env, name, &result, &JVMFlag::size_tAt)) {
1337     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1338     return longBox(thread, env, result);
1339   }
1340   return NULL;
1341 WB_END
1342 
1343 WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name))
1344   double result;
1345   if (GetVMFlag <double> (thread, env, name, &result, &JVMFlag::doubleAt)) {
1346     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1347     return doubleBox(thread, env, result);
1348   }
1349   return NULL;
1350 WB_END
1351 
1352 WB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name))
1353   ccstr ccstrResult;
1354   if (GetVMFlag <ccstr> (thread, env, name, &ccstrResult, &JVMFlag::ccstrAt)) {
1355     ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1356     jstring result = env->NewStringUTF(ccstrResult);
1357     CHECK_JNI_EXCEPTION_(env, NULL);
1358     return result;
1359   }
1360   return NULL;
1361 WB_END
1362 
1363 WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value))
1364   bool result = value == JNI_TRUE ? true : false;
1365   SetVMFlag <bool> (thread, env, name, &result, &JVMFlag::boolAtPut);
1366 WB_END
1367 
1368 WB_ENTRY(void, WB_SetIntVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1369   int result = value;
1370   SetVMFlag <int> (thread, env, name, &result, &JVMFlag::intAtPut);
1371 WB_END
1372 
1373 WB_ENTRY(void, WB_SetUintVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1374   uint result = value;
1375   SetVMFlag <uint> (thread, env, name, &result, &JVMFlag::uintAtPut);
1376 WB_END
1377 
1378 WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1379   intx result = value;
1380   SetVMFlag <intx> (thread, env, name, &result, &JVMFlag::intxAtPut);
1381 WB_END
1382 
1383 WB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1384   uintx result = value;
1385   SetVMFlag <uintx> (thread, env, name, &result, &JVMFlag::uintxAtPut);
1386 WB_END
1387 
1388 WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1389   uint64_t result = value;
1390   SetVMFlag <uint64_t> (thread, env, name, &result, &JVMFlag::uint64_tAtPut);
1391 WB_END
1392 
1393 WB_ENTRY(void, WB_SetSizeTVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1394   size_t result = value;
1395   SetVMFlag <size_t> (thread, env, name, &result, &JVMFlag::size_tAtPut);
1396 WB_END
1397 
1398 WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value))
1399   double result = value;
1400   SetVMFlag <double> (thread, env, name, &result, &JVMFlag::doubleAtPut);
1401 WB_END
1402 
1403 WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value))
1404   ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1405   const char* ccstrValue;
1406   if (value == NULL) {
1407     ccstrValue = NULL;
1408   }
1409   else {
1410     ccstrValue = env->GetStringUTFChars(value, NULL);
1411     CHECK_JNI_EXCEPTION(env);
1412   }
1413   ccstr ccstrResult = ccstrValue;
1414   bool needFree;
1415   {
1416     ThreadInVMfromNative ttvfn(thread); // back to VM
1417     needFree = SetVMFlag <ccstr> (thread, env, name, &ccstrResult, &JVMFlag::ccstrAtPut);
1418   }
1419   if (value != NULL) {
1420     env->ReleaseStringUTFChars(value, ccstrValue);
1421   }
1422   if (needFree) {
1423     FREE_C_HEAP_ARRAY(char, ccstrResult);
1424   }
1425 WB_END
1426 
1427 WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
1428   WhiteBox::compilation_locked = true;
1429 WB_END
1430 
1431 WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
1432   MonitorLocker mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
1433   WhiteBox::compilation_locked = false;
1434   mo.notify_all();
1435 WB_END
1436 
1437 WB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
1438   // Force a code cache sweep and block until it finished
1439   NMethodSweeper::force_sweep();
1440 WB_END
1441 
1442 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
1443   ResourceMark rm(THREAD);
1444   int len;
1445   jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false);
1446   return (StringTable::lookup(name, len) != NULL);
1447 WB_END
1448 
1449 WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
1450   Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(true);
1451   Universe::heap()->collect(GCCause::_wb_full_gc);
1452 #if INCLUDE_G1GC
1453   if (UseG1GC) {
1454     // Needs to be cleared explicitly for G1
1455     Universe::heap()->soft_ref_policy()->set_should_clear_all_soft_refs(false);
1456   }
1457 #endif // INCLUDE_G1GC
1458 WB_END
1459 
1460 WB_ENTRY(void, WB_YoungGC(JNIEnv* env, jobject o))
1461   Universe::heap()->collect(GCCause::_wb_young_gc);
1462 WB_END
1463 
1464 WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
1465   // static+volatile in order to force the read to happen
1466   // (not be eliminated by the compiler)
1467   static char c;
1468   static volatile char* p;
1469 
1470   p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
1471   if (p == NULL) {
1472     THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
1473   }
1474 
1475   c = *p;
1476 WB_END
1477 
1478 WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o))
1479   const char* features = VM_Version::features_string();
1480   ThreadToNativeFromVM ttn(thread);
1481   jstring features_string = env->NewStringUTF(features);
1482 
1483   CHECK_JNI_EXCEPTION_(env, NULL);
1484 
1485   return features_string;
1486 WB_END
1487 
1488 int WhiteBox::get_blob_type(const CodeBlob* code) {
1489   guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
1490   if (code->is_aot()) {
1491     return -1;
1492   }
1493   return CodeCache::get_code_heap(code)->code_blob_type();
1494 }
1495 
1496 CodeHeap* WhiteBox::get_code_heap(int blob_type) {
1497   guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
1498   return CodeCache::get_code_heap(blob_type);
1499 }
1500 
1501 struct CodeBlobStub {
1502   CodeBlobStub(const CodeBlob* blob) :
1503       name(os::strdup(blob->name())),
1504       size(blob->size()),
1505       blob_type(WhiteBox::get_blob_type(blob)),
1506       address((jlong) blob) { }
1507   ~CodeBlobStub() { os::free((void*) name); }
1508   const char* const name;
1509   const jint        size;
1510   const jint        blob_type;
1511   const jlong       address;
1512 };
1513 
1514 static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) {
1515   ResourceMark rm;
1516   jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
1517   CHECK_JNI_EXCEPTION_(env, NULL);
1518   jobjectArray result = env->NewObjectArray(4, clazz, NULL);
1519 
1520   jstring name = env->NewStringUTF(cb->name);
1521   CHECK_JNI_EXCEPTION_(env, NULL);
1522   env->SetObjectArrayElement(result, 0, name);
1523 
1524   jobject obj = integerBox(thread, env, cb->size);
1525   CHECK_JNI_EXCEPTION_(env, NULL);
1526   env->SetObjectArrayElement(result, 1, obj);
1527 
1528   obj = integerBox(thread, env, cb->blob_type);
1529   CHECK_JNI_EXCEPTION_(env, NULL);
1530   env->SetObjectArrayElement(result, 2, obj);
1531 
1532   obj = longBox(thread, env, cb->address);
1533   CHECK_JNI_EXCEPTION_(env, NULL);
1534   env->SetObjectArrayElement(result, 3, obj);
1535 
1536   return result;
1537 }
1538 
1539 WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
1540   ResourceMark rm(THREAD);
1541   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1542   CHECK_JNI_EXCEPTION_(env, NULL);
1543   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1544   CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
1545   jobjectArray result = NULL;
1546   if (code == NULL) {
1547     return result;
1548   }
1549   int comp_level = code->comp_level();
1550   int insts_size = comp_level == CompLevel_aot ? code->code_end() - code->code_begin() : code->insts_size();
1551 
1552   ThreadToNativeFromVM ttn(thread);
1553   jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
1554   CHECK_JNI_EXCEPTION_(env, NULL);
1555   result = env->NewObjectArray(5, clazz, NULL);
1556   if (result == NULL) {
1557     return result;
1558   }
1559 
1560   CodeBlobStub stub(code);
1561   jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub);
1562   CHECK_JNI_EXCEPTION_(env, NULL);
1563   env->SetObjectArrayElement(result, 0, codeBlob);
1564 
1565   jobject level = integerBox(thread, env, comp_level);
1566   CHECK_JNI_EXCEPTION_(env, NULL);
1567   env->SetObjectArrayElement(result, 1, level);
1568 
1569   jbyteArray insts = env->NewByteArray(insts_size);
1570   CHECK_JNI_EXCEPTION_(env, NULL);
1571   env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin());
1572   env->SetObjectArrayElement(result, 2, insts);
1573 
1574   jobject id = integerBox(thread, env, code->compile_id());
1575   CHECK_JNI_EXCEPTION_(env, NULL);
1576   env->SetObjectArrayElement(result, 3, id);
1577 
1578   jobject entry_point = longBox(thread, env, (jlong) code->entry_point());
1579   CHECK_JNI_EXCEPTION_(env, NULL);
1580   env->SetObjectArrayElement(result, 4, entry_point);
1581 
1582   return result;
1583 WB_END
1584 
1585 CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) {
1586   guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
1587   BufferBlob* blob;
1588   int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob));
1589   if (full_size < size) {
1590     full_size += align_up(size - full_size, oopSize);
1591   }
1592   {
1593     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1594     blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type);
1595     if (blob != NULL) {
1596       ::new (blob) BufferBlob("WB::DummyBlob", full_size);
1597     }
1598   }
1599   // Track memory usage statistic after releasing CodeCache_lock
1600   MemoryService::track_code_cache_memory_usage();
1601   return blob;
1602 }
1603 
1604 WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type))
1605   if (size < 0) {
1606     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1607       err_msg("WB_AllocateCodeBlob: size is negative: " INT32_FORMAT, size));
1608   }
1609   return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
1610 WB_END
1611 
1612 WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr))
1613   if (addr == 0) {
1614     return;
1615   }
1616   BufferBlob::free((BufferBlob*) addr);
1617 WB_END
1618 
1619 WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type))
1620   ResourceMark rm;
1621   GrowableArray<CodeBlobStub*> blobs;
1622   {
1623     MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1624     CodeHeap* heap = WhiteBox::get_code_heap(blob_type);
1625     if (heap == NULL) {
1626       return NULL;
1627     }
1628     for (CodeBlob* cb = (CodeBlob*) heap->first();
1629          cb != NULL; cb = (CodeBlob*) heap->next(cb)) {
1630       CodeBlobStub* stub = NEW_RESOURCE_OBJ(CodeBlobStub);
1631       new (stub) CodeBlobStub(cb);
1632       blobs.append(stub);
1633     }
1634   }
1635   ThreadToNativeFromVM ttn(thread);
1636   jobjectArray result = NULL;
1637   jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
1638   CHECK_JNI_EXCEPTION_(env, NULL);
1639   result = env->NewObjectArray(blobs.length(), clazz, NULL);
1640   CHECK_JNI_EXCEPTION_(env, NULL);
1641   if (result == NULL) {
1642     return result;
1643   }
1644   int i = 0;
1645   for (GrowableArrayIterator<CodeBlobStub*> it = blobs.begin();
1646        it != blobs.end(); ++it) {
1647     jobjectArray obj = codeBlob2objectArray(thread, env, *it);
1648     CHECK_JNI_EXCEPTION_(env, NULL);
1649     env->SetObjectArrayElement(result, i, obj);
1650     CHECK_JNI_EXCEPTION_(env, NULL);
1651     ++i;
1652   }
1653   return result;
1654 WB_END
1655 
1656 WB_ENTRY(jint, WB_GetCompilationActivityMode(JNIEnv* env, jobject o))
1657   return CompileBroker::get_compilation_activity_mode();
1658 WB_END
1659 
1660 WB_ENTRY(jobjectArray, WB_GetCodeBlob(JNIEnv* env, jobject o, jlong addr))
1661   if (addr == 0) {
1662     THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),
1663       "WB_GetCodeBlob: addr is null");
1664   }
1665   ThreadToNativeFromVM ttn(thread);
1666   CodeBlobStub stub((CodeBlob*) addr);
1667   return codeBlob2objectArray(thread, env, &stub);
1668 WB_END
1669 
1670 WB_ENTRY(jlong, WB_GetMethodData(JNIEnv* env, jobject wv, jobject method))
1671   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1672   CHECK_JNI_EXCEPTION_(env, 0);
1673   methodHandle mh(thread, Method::checked_resolve_jmethod_id(jmid));
1674   return (jlong) mh->method_data();
1675 WB_END
1676 
1677 WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o))
1678   return (jlong) Thread::current()->stack_size();
1679 WB_END
1680 
1681 WB_ENTRY(jlong, WB_GetThreadRemainingStackSize(JNIEnv* env, jobject o))
1682   JavaThread* t = JavaThread::current();
1683   return (jlong) t->stack_available(os::current_stack_pointer()) - (jlong)JavaThread::stack_shadow_zone_size();
1684 WB_END
1685 
1686 
1687 int WhiteBox::array_bytes_to_length(size_t bytes) {
1688   return Array<u1>::bytes_to_length(bytes);
1689 }
1690 
1691 WB_ENTRY(jlong, WB_AllocateMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong size))
1692   if (size < 0) {
1693     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1694         err_msg("WB_AllocateMetaspace: size is negative: " JLONG_FORMAT, size));
1695   }
1696 
1697   oop class_loader_oop = JNIHandles::resolve(class_loader);
1698   ClassLoaderData* cld = class_loader_oop != NULL
1699       ? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
1700       : ClassLoaderData::the_null_class_loader_data();
1701 
1702   void* metadata = MetadataFactory::new_array<u1>(cld, WhiteBox::array_bytes_to_length((size_t)size), thread);
1703 
1704   return (jlong)(uintptr_t)metadata;
1705 WB_END
1706 
1707 WB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size))
1708   oop class_loader_oop = JNIHandles::resolve(class_loader);
1709   ClassLoaderData* cld = class_loader_oop != NULL
1710       ? java_lang_ClassLoader::loader_data_acquire(class_loader_oop)
1711       : ClassLoaderData::the_null_class_loader_data();
1712 
1713   MetadataFactory::free_array(cld, (Array<u1>*)(uintptr_t)addr);
1714 WB_END
1715 
1716 WB_ENTRY(void, WB_DefineModule(JNIEnv* env, jobject o, jobject module, jboolean is_open,
1717                                 jstring version, jstring location, jobjectArray packages))
1718   Modules::define_module(module, is_open, version, location, packages, CHECK);
1719 WB_END
1720 
1721 WB_ENTRY(void, WB_AddModuleExports(JNIEnv* env, jobject o, jobject from_module, jstring package, jobject to_module))
1722   Modules::add_module_exports_qualified(from_module, package, to_module, CHECK);
1723 WB_END
1724 
1725 WB_ENTRY(void, WB_AddModuleExportsToAllUnnamed(JNIEnv* env, jobject o, jclass module, jstring package))
1726   Modules::add_module_exports_to_all_unnamed(module, package, CHECK);
1727 WB_END
1728 
1729 WB_ENTRY(void, WB_AddModuleExportsToAll(JNIEnv* env, jobject o, jclass module, jstring package))
1730   Modules::add_module_exports(module, package, NULL, CHECK);
1731 WB_END
1732 
1733 WB_ENTRY(void, WB_AddReadsModule(JNIEnv* env, jobject o, jobject from_module, jobject source_module))
1734   Modules::add_reads_module(from_module, source_module, CHECK);
1735 WB_END
1736 
1737 WB_ENTRY(jlong, WB_IncMetaspaceCapacityUntilGC(JNIEnv* env, jobject wb, jlong inc))
1738   if (inc < 0) {
1739     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1740         err_msg("WB_IncMetaspaceCapacityUntilGC: inc is negative: " JLONG_FORMAT, inc));
1741   }
1742 
1743   jlong max_size_t = (jlong) ((size_t) -1);
1744   if (inc > max_size_t) {
1745     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1746         err_msg("WB_IncMetaspaceCapacityUntilGC: inc does not fit in size_t: " JLONG_FORMAT, inc));
1747   }
1748 
1749   size_t new_cap_until_GC = 0;
1750   size_t aligned_inc = align_down((size_t) inc, Metaspace::commit_alignment());
1751   bool success = MetaspaceGC::inc_capacity_until_GC(aligned_inc, &new_cap_until_GC);
1752   if (!success) {
1753     THROW_MSG_0(vmSymbols::java_lang_IllegalStateException(),
1754                 "WB_IncMetaspaceCapacityUntilGC: could not increase capacity until GC "
1755                 "due to contention with another thread");
1756   }
1757   return (jlong) new_cap_until_GC;
1758 WB_END
1759 
1760 WB_ENTRY(jlong, WB_MetaspaceCapacityUntilGC(JNIEnv* env, jobject wb))
1761   return (jlong) MetaspaceGC::capacity_until_GC();
1762 WB_END
1763 
1764 WB_ENTRY(jlong, WB_MetaspaceReserveAlignment(JNIEnv* env, jobject wb))
1765   return (jlong)Metaspace::reserve_alignment();
1766 WB_END
1767 
1768 WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue))
1769   Mutex::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ?
1770                                            Mutex::_safepoint_check_always :
1771                                            Mutex::_safepoint_check_never;
1772   Mutex::SafepointCheckFlag sfpt_check_attempted = attemptedNoSafepointValue ?
1773                                            Mutex::_no_safepoint_check_flag :
1774                                            Mutex::_safepoint_check_flag;
1775   MutexLocker ml(new Mutex(Mutex::leaf, "SFPT_Test_lock", true, sfpt_check_required),
1776                  sfpt_check_attempted);
1777 WB_END
1778 
1779 WB_ENTRY(void, WB_AssertSpecialLock(JNIEnv* env, jobject o, jboolean allowVMBlock, jboolean safepointCheck))
1780   // Create a special lock violating condition in value
1781   Mutex::SafepointCheckRequired sfpt_check_required = safepointCheck ?
1782                                            Mutex::_safepoint_check_always :
1783                                            Mutex::_safepoint_check_never;
1784   Mutex::SafepointCheckFlag safepoint_check = safepointCheck ?
1785                                            Monitor::_safepoint_check_flag :
1786                                            Monitor::_no_safepoint_check_flag;
1787 
1788   MutexLocker ml(new Mutex(Mutex::special, "SpecialTest_lock", allowVMBlock, sfpt_check_required), safepoint_check);
1789   // If the lock above succeeds, try to safepoint to test the NSV implied with this special lock.
1790   ThreadBlockInVM tbivm(JavaThread::current());
1791 WB_END
1792 
1793 WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj))
1794   oop obj_oop = JNIHandles::resolve(obj);
1795   return (jboolean) obj_oop->mark().has_monitor();
1796 WB_END
1797 
1798 WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb))
1799   VM_ForceSafepoint force_safepoint_op;
1800   VMThread::execute(&force_safepoint_op);
1801 WB_END
1802 
1803 WB_ENTRY(jlong, WB_GetConstantPool(JNIEnv* env, jobject wb, jclass klass))
1804   InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
1805   return (jlong) ik->constants();
1806 WB_END
1807 
1808 WB_ENTRY(jint, WB_GetConstantPoolCacheIndexTag(JNIEnv* env, jobject wb))
1809   return ConstantPool::CPCACHE_INDEX_TAG;
1810 WB_END
1811 
1812 WB_ENTRY(jint, WB_GetConstantPoolCacheLength(JNIEnv* env, jobject wb, jclass klass))
1813   InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
1814   ConstantPool* cp = ik->constants();
1815   if (cp->cache() == NULL) {
1816       return -1;
1817   }
1818   return cp->cache()->length();
1819 WB_END
1820 
1821 WB_ENTRY(jint, WB_ConstantPoolRemapInstructionOperandFromCache(JNIEnv* env, jobject wb, jclass klass, jint index))
1822   InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
1823   ConstantPool* cp = ik->constants();
1824   if (cp->cache() == NULL) {
1825     THROW_MSG_0(vmSymbols::java_lang_IllegalStateException(), "Constant pool does not have a cache");
1826   }
1827   jint cpci = index;
1828   jint cpciTag = ConstantPool::CPCACHE_INDEX_TAG;
1829   if (cpciTag > cpci || cpci >= cp->cache()->length() + cpciTag) {
1830     THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool cache index is out of range");
1831   }
1832   jint cpi = cp->remap_instruction_operand_from_cache(cpci);
1833   return cpi;
1834 WB_END
1835 
1836 WB_ENTRY(jint, WB_ConstantPoolEncodeIndyIndex(JNIEnv* env, jobject wb, jint index))
1837   return ConstantPool::encode_invokedynamic_index(index);
1838 WB_END
1839 
1840 WB_ENTRY(void, WB_ClearInlineCaches(JNIEnv* env, jobject wb, jboolean preserve_static_stubs))
1841   VM_ClearICs clear_ics(preserve_static_stubs == JNI_TRUE);
1842   VMThread::execute(&clear_ics);
1843 WB_END
1844 
1845 template <typename T>
1846 static bool GetMethodOption(JavaThread* thread, JNIEnv* env, jobject method, jstring name, T* value) {
1847   assert(value != NULL, "sanity");
1848   if (method == NULL || name == NULL) {
1849     return false;
1850   }
1851   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1852   CHECK_JNI_EXCEPTION_(env, false);
1853   methodHandle mh(thread, Method::checked_resolve_jmethod_id(jmid));
1854   // can't be in VM when we call JNI
1855   ThreadToNativeFromVM ttnfv(thread);
1856   const char* flag_name = env->GetStringUTFChars(name, NULL);
1857   CHECK_JNI_EXCEPTION_(env, false);
1858   bool result =  CompilerOracle::has_option_value(mh, flag_name, *value);
1859   env->ReleaseStringUTFChars(name, flag_name);
1860   return result;
1861 }
1862 
1863 WB_ENTRY(jobject, WB_GetMethodBooleaneOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1864   bool result;
1865   if (GetMethodOption<bool> (thread, env, method, name, &result)) {
1866     // can't be in VM when we call JNI
1867     ThreadToNativeFromVM ttnfv(thread);
1868     return booleanBox(thread, env, result);
1869   }
1870   return NULL;
1871 WB_END
1872 
1873 WB_ENTRY(jobject, WB_GetMethodIntxOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1874   intx result;
1875   if (GetMethodOption <intx> (thread, env, method, name, &result)) {
1876     // can't be in VM when we call JNI
1877     ThreadToNativeFromVM ttnfv(thread);
1878     return longBox(thread, env, result);
1879   }
1880   return NULL;
1881 WB_END
1882 
1883 WB_ENTRY(jobject, WB_GetMethodUintxOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1884   uintx result;
1885   if (GetMethodOption <uintx> (thread, env, method, name, &result)) {
1886     // can't be in VM when we call JNI
1887     ThreadToNativeFromVM ttnfv(thread);
1888     return longBox(thread, env, result);
1889   }
1890   return NULL;
1891 WB_END
1892 
1893 WB_ENTRY(jobject, WB_GetMethodDoubleOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1894   double result;
1895   if (GetMethodOption <double> (thread, env, method, name, &result)) {
1896     // can't be in VM when we call JNI
1897     ThreadToNativeFromVM ttnfv(thread);
1898     return doubleBox(thread, env, result);
1899   }
1900   return NULL;
1901 WB_END
1902 
1903 WB_ENTRY(jobject, WB_GetMethodStringOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1904   ccstr ccstrResult;
1905   if (GetMethodOption <ccstr> (thread, env, method, name, &ccstrResult)) {
1906     // can't be in VM when we call JNI
1907     ThreadToNativeFromVM ttnfv(thread);
1908     jstring result = env->NewStringUTF(ccstrResult);
1909     CHECK_JNI_EXCEPTION_(env, NULL);
1910     return result;
1911   }
1912   return NULL;
1913 WB_END
1914 
1915 WB_ENTRY(jobject, WB_GetDefaultArchivePath(JNIEnv* env, jobject wb))
1916   const char* p = Arguments::get_default_shared_archive_path();
1917   ThreadToNativeFromVM ttn(thread);
1918   jstring path_string = env->NewStringUTF(p);
1919 
1920   CHECK_JNI_EXCEPTION_(env, NULL);
1921 
1922   return path_string;
1923 WB_END
1924 
1925 WB_ENTRY(jboolean, WB_IsSharingEnabled(JNIEnv* env, jobject wb))
1926   return UseSharedSpaces;
1927 WB_END
1928 
1929 WB_ENTRY(jboolean, WB_CDSMemoryMappingFailed(JNIEnv* env, jobject wb))
1930   return FileMapInfo::memory_mapping_failed();
1931 WB_END
1932 
1933 WB_ENTRY(jboolean, WB_IsShared(JNIEnv* env, jobject wb, jobject obj))
1934   oop obj_oop = JNIHandles::resolve(obj);
1935   return HeapShared::is_archived_object(obj_oop);
1936 WB_END
1937 
1938 WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz))
1939   return (jboolean)MetaspaceShared::is_in_shared_metaspace(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
1940 WB_END
1941 
1942 WB_ENTRY(jboolean, WB_AreSharedStringsIgnored(JNIEnv* env))
1943   return !HeapShared::closed_archive_heap_region_mapped();
1944 WB_END
1945 
1946 WB_ENTRY(jobject, WB_GetResolvedReferences(JNIEnv* env, jobject wb, jclass clazz))
1947   Klass *k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1948   if (k->is_instance_klass()) {
1949     InstanceKlass *ik = InstanceKlass::cast(k);
1950     ConstantPool *cp = ik->constants();
1951     objArrayOop refs =  cp->resolved_references();
1952     return (jobject)JNIHandles::make_local(env, refs);
1953   } else {
1954     return NULL;
1955   }
1956 WB_END
1957 
1958 WB_ENTRY(void, WB_LinkClass(JNIEnv* env, jobject wb, jclass clazz))
1959   Klass *k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz));
1960   if (!k->is_instance_klass()) {
1961     return;
1962   }
1963   InstanceKlass *ik = InstanceKlass::cast(k);
1964   ik->link_class(THREAD); // may throw verification error
1965 WB_END
1966 
1967 WB_ENTRY(jboolean, WB_AreOpenArchiveHeapObjectsMapped(JNIEnv* env))
1968   return HeapShared::open_archive_heap_region_mapped();
1969 WB_END
1970 
1971 WB_ENTRY(jboolean, WB_IsCDSIncludedInVmBuild(JNIEnv* env))
1972 #if INCLUDE_CDS
1973   return true;
1974 #else
1975   return false;
1976 #endif // INCLUDE_CDS
1977 WB_END
1978 
1979 WB_ENTRY(jboolean, WB_isC2OrJVMCIIncludedInVmBuild(JNIEnv* env))
1980 #if COMPILER2_OR_JVMCI
1981   return true;
1982 #else
1983   return false;
1984 #endif
1985 WB_END
1986 
1987 WB_ENTRY(jboolean, WB_IsJavaHeapArchiveSupported(JNIEnv* env))
1988   return HeapShared::is_heap_object_archiving_allowed();
1989 WB_END
1990 
1991 
1992 WB_ENTRY(jboolean, WB_IsJFRIncludedInVmBuild(JNIEnv* env))
1993 #if INCLUDE_JFR
1994   return true;
1995 #else
1996   return false;
1997 #endif // INCLUDE_JFR
1998 WB_END
1999 
2000 #if INCLUDE_CDS
2001 
2002 WB_ENTRY(jint, WB_GetOffsetForName(JNIEnv* env, jobject o, jstring name))
2003   ResourceMark rm;
2004   char* c_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(name));
2005   int result = CDSOffsets::find_offset(c_name);
2006   return (jint)result;
2007 WB_END
2008 
2009 #endif // INCLUDE_CDS
2010 
2011 WB_ENTRY(jint, WB_HandshakeWalkStack(JNIEnv* env, jobject wb, jobject thread_handle, jboolean all_threads))
2012   class TraceSelfClosure : public HandshakeClosure {
2013     jint _num_threads_completed;
2014 
2015     void do_thread(Thread* th) {
2016       assert(th->is_Java_thread(), "sanity");
2017       JavaThread* jt = (JavaThread*)th;
2018       ResourceMark rm;
2019 
2020       jt->print_on(tty);
2021       jt->print_stack_on(tty);
2022       tty->cr();
2023       Atomic::inc(&_num_threads_completed);
2024     }
2025 
2026   public:
2027     TraceSelfClosure() : HandshakeClosure("WB_TraceSelf"), _num_threads_completed(0) {}
2028 
2029     jint num_threads_completed() const { return _num_threads_completed; }
2030   };
2031   TraceSelfClosure tsc;
2032 
2033   if (all_threads) {
2034     Handshake::execute(&tsc);
2035   } else {
2036     oop thread_oop = JNIHandles::resolve(thread_handle);
2037     if (thread_oop != NULL) {
2038       JavaThread* target = java_lang_Thread::thread(thread_oop);
2039       Handshake::execute(&tsc, target);
2040     }
2041   }
2042   return tsc.num_threads_completed();
2043 WB_END
2044 
2045 //Some convenience methods to deal with objects from java
2046 int WhiteBox::offset_for_field(const char* field_name, oop object,
2047     Symbol* signature_symbol) {
2048   assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid");
2049   Thread* THREAD = Thread::current();
2050 
2051   //Get the class of our object
2052   Klass* arg_klass = object->klass();
2053   //Turn it into an instance-klass
2054   InstanceKlass* ik = InstanceKlass::cast(arg_klass);
2055 
2056   //Create symbols to look for in the class
2057   TempNewSymbol name_symbol = SymbolTable::new_symbol(field_name);
2058 
2059   //To be filled in with an offset of the field we're looking for
2060   fieldDescriptor fd;
2061 
2062   Klass* res = ik->find_field(name_symbol, signature_symbol, &fd);
2063   if (res == NULL) {
2064     tty->print_cr("Invalid layout of %s at %s", ik->external_name(),
2065         name_symbol->as_C_string());
2066     vm_exit_during_initialization("Invalid layout of preloaded class: use -Xlog:class+load=info to see the origin of the problem class");
2067   }
2068 
2069   //fetch the field at the offset we've found
2070   int dest_offset = fd.offset();
2071 
2072   return dest_offset;
2073 }
2074 
2075 
2076 const char* WhiteBox::lookup_jstring(const char* field_name, oop object) {
2077   int offset = offset_for_field(field_name, object,
2078       vmSymbols::string_signature());
2079   oop string = object->obj_field(offset);
2080   if (string == NULL) {
2081     return NULL;
2082   }
2083   const char* ret = java_lang_String::as_utf8_string(string);
2084   return ret;
2085 }
2086 
2087 bool WhiteBox::lookup_bool(const char* field_name, oop object) {
2088   int offset =
2089       offset_for_field(field_name, object, vmSymbols::bool_signature());
2090   bool ret = (object->bool_field(offset) == JNI_TRUE);
2091   return ret;
2092 }
2093 
2094 void WhiteBox::register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count) {
2095   ResourceMark rm;
2096   ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
2097 
2098   //  one by one registration natives for exception catching
2099   jclass no_such_method_error_klass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string());
2100   CHECK_JNI_EXCEPTION(env);
2101   for (int i = 0, n = method_count; i < n; ++i) {
2102     // Skip dummy entries
2103     if (method_array[i].fnPtr == NULL) continue;
2104     if (env->RegisterNatives(wbclass, &method_array[i], 1) != 0) {
2105       jthrowable throwable_obj = env->ExceptionOccurred();
2106       if (throwable_obj != NULL) {
2107         env->ExceptionClear();
2108         if (env->IsInstanceOf(throwable_obj, no_such_method_error_klass)) {
2109           // NoSuchMethodError is thrown when a method can't be found or a method is not native.
2110           // Ignoring the exception since it is not preventing use of other WhiteBox methods.
2111           tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s",
2112               method_array[i].name, method_array[i].signature);
2113         }
2114       } else {
2115         // Registration failed unexpectedly.
2116         tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered",
2117             method_array[i].name, method_array[i].signature);
2118         env->UnregisterNatives(wbclass);
2119         break;
2120       }
2121     }
2122   }
2123 }
2124 
2125 WB_ENTRY(jint, WB_AddCompilerDirective(JNIEnv* env, jobject o, jstring compDirect))
2126   // can't be in VM when we call JNI
2127   ThreadToNativeFromVM ttnfv(thread);
2128   const char* dir = env->GetStringUTFChars(compDirect, NULL);
2129   CHECK_JNI_EXCEPTION_(env, 0);
2130   int ret;
2131   {
2132     ThreadInVMfromNative ttvfn(thread); // back to VM
2133     ret = DirectivesParser::parse_string(dir, tty);
2134   }
2135   env->ReleaseStringUTFChars(compDirect, dir);
2136   // -1 for error parsing directive. Return 0 as number of directives added.
2137   if (ret == -1) {
2138     ret = 0;
2139   }
2140   return (jint) ret;
2141 WB_END
2142 
2143 WB_ENTRY(void, WB_RemoveCompilerDirective(JNIEnv* env, jobject o, jint count))
2144   DirectivesStack::pop(count);
2145 WB_END
2146 
2147 // Checks that the library libfile has the noexecstack bit set.
2148 WB_ENTRY(jboolean, WB_CheckLibSpecifiesNoexecstack(JNIEnv* env, jobject o, jstring libfile))
2149   jboolean ret = false;
2150 #ifdef LINUX
2151   // Can't be in VM when we call JNI.
2152   ThreadToNativeFromVM ttnfv(thread);
2153   const char* lf = env->GetStringUTFChars(libfile, NULL);
2154   CHECK_JNI_EXCEPTION_(env, 0);
2155   ret = (jboolean) ElfFile::specifies_noexecstack(lf);
2156   env->ReleaseStringUTFChars(libfile, lf);
2157 #endif
2158   return ret;
2159 WB_END
2160 
2161 WB_ENTRY(jboolean, WB_IsContainerized(JNIEnv* env, jobject o))
2162   LINUX_ONLY(return OSContainer::is_containerized();)
2163   return false;
2164 WB_END
2165 
2166 WB_ENTRY(jint, WB_ValidateCgroup(JNIEnv* env,
2167                                     jobject o,
2168                                     jstring proc_cgroups,
2169                                     jstring proc_self_cgroup,
2170                                     jstring proc_self_mountinfo))
2171   jint ret = 0;
2172 #ifdef LINUX
2173   ThreadToNativeFromVM ttnfv(thread);
2174   const char* p_cgroups = env->GetStringUTFChars(proc_cgroups, NULL);
2175   CHECK_JNI_EXCEPTION_(env, 0);
2176   const char* p_s_cgroup = env->GetStringUTFChars(proc_self_cgroup, NULL);
2177   CHECK_JNI_EXCEPTION_(env, 0);
2178   const char* p_s_mountinfo = env->GetStringUTFChars(proc_self_mountinfo, NULL);
2179   CHECK_JNI_EXCEPTION_(env, 0);
2180   u1 cg_type_flags = 0;
2181   // This sets cg_type_flags
2182   WhiteBox::validate_cgroup(p_cgroups, p_s_cgroup, p_s_mountinfo, &cg_type_flags);
2183   ret = (jint)cg_type_flags;
2184   env->ReleaseStringUTFChars(proc_cgroups, p_cgroups);
2185   env->ReleaseStringUTFChars(proc_self_cgroup, p_s_cgroup);
2186   env->ReleaseStringUTFChars(proc_self_mountinfo, p_s_mountinfo);
2187 #endif
2188   return ret;
2189 WB_END
2190 
2191 WB_ENTRY(void, WB_PrintOsInfo(JNIEnv* env, jobject o))
2192   os::print_os_info(tty);
2193 WB_END
2194 
2195 // Elf decoder
2196 WB_ENTRY(void, WB_DisableElfSectionCache(JNIEnv* env))
2197 #if !defined(_WINDOWS) && !defined(__APPLE__) && !defined(_AIX)
2198   ElfFile::_do_not_cache_elf_section = true;
2199 #endif
2200 WB_END
2201 
2202 WB_ENTRY(jlong, WB_ResolvedMethodItemsCount(JNIEnv* env, jobject o))
2203   return (jlong) ResolvedMethodTable::items_count();
2204 WB_END
2205 
2206 WB_ENTRY(jint, WB_ProtectionDomainRemovedCount(JNIEnv* env, jobject o))
2207   return (jint) SystemDictionary::pd_cache_table()->removed_entries_count();
2208 WB_END
2209 
2210 WB_ENTRY(jint, WB_AotLibrariesCount(JNIEnv* env, jobject o))
2211   jint result = 0;
2212 #if INCLUDE_AOT
2213   result = (jint) AOTLoader::heaps_count();
2214 #endif
2215   return result;
2216 WB_END
2217 
2218 WB_ENTRY(jint, WB_GetKlassMetadataSize(JNIEnv* env, jobject wb, jclass mirror))
2219   Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(mirror));
2220   // Return size in bytes.
2221   return k->size() * wordSize;
2222 WB_END
2223 
2224 #define CC (char*)
2225 
2226 static JNINativeMethod methods[] = {
2227   {CC"getObjectAddress0",                CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress  },
2228   {CC"getObjectSize0",                   CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize     },
2229   {CC"isObjectInOldGen0",                CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen  },
2230   {CC"getHeapOopSize",                   CC"()I",                   (void*)&WB_GetHeapOopSize    },
2231   {CC"getVMPageSize",                    CC"()I",                   (void*)&WB_GetVMPageSize     },
2232   {CC"getVMAllocationGranularity",       CC"()J",                   (void*)&WB_GetVMAllocationGranularity },
2233   {CC"getVMLargePageSize",               CC"()J",                   (void*)&WB_GetVMLargePageSize},
2234   {CC"getHeapSpaceAlignment",            CC"()J",                   (void*)&WB_GetHeapSpaceAlignment},
2235   {CC"getHeapAlignment",                 CC"()J",                   (void*)&WB_GetHeapAlignment},
2236   {CC"countAliveClasses0",               CC"(Ljava/lang/String;)I", (void*)&WB_CountAliveClasses },
2237   {CC"getSymbolRefcount",                CC"(Ljava/lang/String;)I", (void*)&WB_GetSymbolRefcount },
2238   {CC"parseCommandLine0",
2239       CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
2240       (void*) &WB_ParseCommandLine
2241   },
2242   {CC"addToBootstrapClassLoaderSearch0", CC"(Ljava/lang/String;)V",
2243                                                       (void*)&WB_AddToBootstrapClassLoaderSearch},
2244   {CC"addToSystemClassLoaderSearch0",    CC"(Ljava/lang/String;)V",
2245                                                       (void*)&WB_AddToSystemClassLoaderSearch},
2246   {CC"getCompressedOopsMaxHeapSize", CC"()J",
2247       (void*)&WB_GetCompressedOopsMaxHeapSize},
2248   {CC"printHeapSizes",     CC"()V",                   (void*)&WB_PrintHeapSizes    },
2249   {CC"runMemoryUnitTests", CC"()V",                   (void*)&WB_RunMemoryUnitTests},
2250   {CC"readFromNoaccessArea",CC"()V",                  (void*)&WB_ReadFromNoaccessArea},
2251   {CC"stressVirtualSpaceResize",CC"(JJJ)I",           (void*)&WB_StressVirtualSpaceResize},
2252 #if INCLUDE_CDS
2253   {CC"getOffsetForName0", CC"(Ljava/lang/String;)I",  (void*)&WB_GetOffsetForName},
2254 #endif
2255 #if INCLUDE_G1GC
2256   {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
2257   {CC"g1IsHumongous0",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
2258   {CC"g1BelongsToHumongousRegion0", CC"(J)Z",         (void*)&WB_G1BelongsToHumongousRegion},
2259   {CC"g1BelongsToFreeRegion0", CC"(J)Z",              (void*)&WB_G1BelongsToFreeRegion},
2260   {CC"g1NumMaxRegions",    CC"()J",                   (void*)&WB_G1NumMaxRegions  },
2261   {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
2262   {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
2263   {CC"g1StartConcMarkCycle",       CC"()Z",           (void*)&WB_G1StartMarkCycle  },
2264   {CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;",
2265                                                       (void*)&WB_G1AuxiliaryMemoryUsage  },
2266   {CC"g1ActiveMemoryNodeCount", CC"()I",              (void*)&WB_G1ActiveMemoryNodeCount },
2267   {CC"g1MemoryNodeIds",    CC"()[I",                  (void*)&WB_G1MemoryNodeIds },
2268   {CC"g1GetMixedGCInfo",   CC"(I)[J",                 (void*)&WB_G1GetMixedGCInfo },
2269 #endif // INCLUDE_G1GC
2270 #if INCLUDE_G1GC || INCLUDE_PARALLELGC
2271   {CC"dramReservedStart",   CC"()J",                  (void*)&WB_DramReservedStart },
2272   {CC"dramReservedEnd",     CC"()J",                  (void*)&WB_DramReservedEnd },
2273   {CC"nvdimmReservedStart", CC"()J",                  (void*)&WB_NvdimmReservedStart },
2274   {CC"nvdimmReservedEnd",   CC"()J",                  (void*)&WB_NvdimmReservedEnd },
2275 #endif // INCLUDE_G1GC || INCLUDE_PARALLELGC
2276 #if INCLUDE_PARALLELGC
2277   {CC"psVirtualSpaceAlignment",CC"()J",               (void*)&WB_PSVirtualSpaceAlignment},
2278   {CC"psHeapGenerationAlignment",CC"()J",             (void*)&WB_PSHeapGenerationAlignment},
2279 #endif
2280 #if INCLUDE_NMT
2281   {CC"NMTMalloc",           CC"(J)J",                 (void*)&WB_NMTMalloc          },
2282   {CC"NMTMallocWithPseudoStack", CC"(JI)J",           (void*)&WB_NMTMallocWithPseudoStack},
2283   {CC"NMTMallocWithPseudoStackAndType", CC"(JII)J",   (void*)&WB_NMTMallocWithPseudoStackAndType},
2284   {CC"NMTFree",             CC"(J)V",                 (void*)&WB_NMTFree            },
2285   {CC"NMTReserveMemory",    CC"(J)J",                 (void*)&WB_NMTReserveMemory   },
2286   {CC"NMTAttemptReserveMemoryAt",    CC"(JJ)J",       (void*)&WB_NMTAttemptReserveMemoryAt },
2287   {CC"NMTCommitMemory",     CC"(JJ)V",                (void*)&WB_NMTCommitMemory    },
2288   {CC"NMTUncommitMemory",   CC"(JJ)V",                (void*)&WB_NMTUncommitMemory  },
2289   {CC"NMTReleaseMemory",    CC"(JJ)V",                (void*)&WB_NMTReleaseMemory   },
2290   {CC"NMTChangeTrackingLevel", CC"()Z",               (void*)&WB_NMTChangeTrackingLevel},
2291   {CC"NMTGetHashSize",      CC"()I",                  (void*)&WB_NMTGetHashSize     },
2292   {CC"NMTNewArena",         CC"(J)J",                 (void*)&WB_NMTNewArena        },
2293   {CC"NMTFreeArena",        CC"(J)V",                 (void*)&WB_NMTFreeArena       },
2294   {CC"NMTArenaMalloc",      CC"(JJ)V",                (void*)&WB_NMTArenaMalloc     },
2295 #endif // INCLUDE_NMT
2296   {CC"deoptimizeFrames",   CC"(Z)I",                  (void*)&WB_DeoptimizeFrames  },
2297   {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
2298   {CC"deoptimizeMethod0",   CC"(Ljava/lang/reflect/Executable;Z)I",
2299                                                       (void*)&WB_DeoptimizeMethod  },
2300   {CC"isMethodCompiled0",   CC"(Ljava/lang/reflect/Executable;Z)Z",
2301                                                       (void*)&WB_IsMethodCompiled  },
2302   {CC"isMethodCompilable0", CC"(Ljava/lang/reflect/Executable;IZ)Z",
2303                                                       (void*)&WB_IsMethodCompilable},
2304   {CC"isMethodQueuedForCompilation0",
2305       CC"(Ljava/lang/reflect/Executable;)Z",          (void*)&WB_IsMethodQueuedForCompilation},
2306   {CC"isIntrinsicAvailable0",
2307       CC"(Ljava/lang/reflect/Executable;Ljava/lang/reflect/Executable;I)Z",
2308                                                       (void*)&WB_IsIntrinsicAvailable},
2309   {CC"makeMethodNotCompilable0",
2310       CC"(Ljava/lang/reflect/Executable;IZ)V",        (void*)&WB_MakeMethodNotCompilable},
2311   {CC"testSetDontInlineMethod0",
2312       CC"(Ljava/lang/reflect/Executable;Z)Z",         (void*)&WB_TestSetDontInlineMethod},
2313   {CC"getMethodCompilationLevel0",
2314       CC"(Ljava/lang/reflect/Executable;Z)I",         (void*)&WB_GetMethodCompilationLevel},
2315   {CC"getMethodEntryBci0",
2316       CC"(Ljava/lang/reflect/Executable;)I",          (void*)&WB_GetMethodEntryBci},
2317   {CC"getCompileQueueSize",
2318       CC"(I)I",                                       (void*)&WB_GetCompileQueueSize},
2319   {CC"testSetForceInlineMethod0",
2320       CC"(Ljava/lang/reflect/Executable;Z)Z",         (void*)&WB_TestSetForceInlineMethod},
2321   {CC"enqueueMethodForCompilation0",
2322       CC"(Ljava/lang/reflect/Executable;II)Z",        (void*)&WB_EnqueueMethodForCompilation},
2323   {CC"enqueueInitializerForCompilation0",
2324       CC"(Ljava/lang/Class;I)Z",                      (void*)&WB_EnqueueInitializerForCompilation},
2325   {CC"markMethodProfiled",
2326       CC"(Ljava/lang/reflect/Executable;)V",          (void*)&WB_MarkMethodProfiled},
2327   {CC"clearMethodState0",
2328       CC"(Ljava/lang/reflect/Executable;)V",          (void*)&WB_ClearMethodState},
2329   {CC"lockCompilation",    CC"()V",                   (void*)&WB_LockCompilation},
2330   {CC"unlockCompilation",  CC"()V",                   (void*)&WB_UnlockCompilation},
2331   {CC"matchesMethod",
2332       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)I",
2333                                                       (void*)&WB_MatchesMethod},
2334   {CC"matchesInline",
2335       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)I",
2336                                                       (void*)&WB_MatchesInline},
2337   {CC"shouldPrintAssembly",
2338         CC"(Ljava/lang/reflect/Executable;I)Z",
2339                                                         (void*)&WB_ShouldPrintAssembly},
2340 
2341   {CC"isConstantVMFlag",   CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag},
2342   {CC"isLockedVMFlag",     CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag},
2343   {CC"setBooleanVMFlag",   CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
2344   {CC"setIntVMFlag",       CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntVMFlag},
2345   {CC"setUintVMFlag",      CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintVMFlag},
2346   {CC"setIntxVMFlag",      CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag},
2347   {CC"setUintxVMFlag",     CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag},
2348   {CC"setUint64VMFlag",    CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag},
2349   {CC"setSizeTVMFlag",     CC"(Ljava/lang/String;J)V",(void*)&WB_SetSizeTVMFlag},
2350   {CC"setDoubleVMFlag",    CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag},
2351   {CC"setStringVMFlag",    CC"(Ljava/lang/String;Ljava/lang/String;)V",
2352                                                       (void*)&WB_SetStringVMFlag},
2353   {CC"getBooleanVMFlag",   CC"(Ljava/lang/String;)Ljava/lang/Boolean;",
2354                                                       (void*)&WB_GetBooleanVMFlag},
2355   {CC"getIntVMFlag",       CC"(Ljava/lang/String;)Ljava/lang/Long;",
2356                                                       (void*)&WB_GetIntVMFlag},
2357   {CC"getUintVMFlag",      CC"(Ljava/lang/String;)Ljava/lang/Long;",
2358                                                       (void*)&WB_GetUintVMFlag},
2359   {CC"getIntxVMFlag",      CC"(Ljava/lang/String;)Ljava/lang/Long;",
2360                                                       (void*)&WB_GetIntxVMFlag},
2361   {CC"getUintxVMFlag",     CC"(Ljava/lang/String;)Ljava/lang/Long;",
2362                                                       (void*)&WB_GetUintxVMFlag},
2363   {CC"getUint64VMFlag",    CC"(Ljava/lang/String;)Ljava/lang/Long;",
2364                                                       (void*)&WB_GetUint64VMFlag},
2365   {CC"getSizeTVMFlag",     CC"(Ljava/lang/String;)Ljava/lang/Long;",
2366                                                       (void*)&WB_GetSizeTVMFlag},
2367   {CC"getDoubleVMFlag",    CC"(Ljava/lang/String;)Ljava/lang/Double;",
2368                                                       (void*)&WB_GetDoubleVMFlag},
2369   {CC"getStringVMFlag",    CC"(Ljava/lang/String;)Ljava/lang/String;",
2370                                                       (void*)&WB_GetStringVMFlag},
2371   {CC"isInStringTable",    CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable  },
2372   {CC"fullGC",   CC"()V",                             (void*)&WB_FullGC },
2373   {CC"youngGC",  CC"()V",                             (void*)&WB_YoungGC },
2374   {CC"readReservedMemory", CC"()V",                   (void*)&WB_ReadReservedMemory },
2375   {CC"allocateMetaspace",
2376      CC"(Ljava/lang/ClassLoader;J)J",                 (void*)&WB_AllocateMetaspace },
2377   {CC"freeMetaspace",
2378      CC"(Ljava/lang/ClassLoader;JJ)V",                (void*)&WB_FreeMetaspace },
2379   {CC"incMetaspaceCapacityUntilGC", CC"(J)J",         (void*)&WB_IncMetaspaceCapacityUntilGC },
2380   {CC"metaspaceCapacityUntilGC", CC"()J",             (void*)&WB_MetaspaceCapacityUntilGC },
2381   {CC"metaspaceReserveAlignment", CC"()J",            (void*)&WB_MetaspaceReserveAlignment },
2382   {CC"getCPUFeatures",     CC"()Ljava/lang/String;",  (void*)&WB_GetCPUFeatures     },
2383   {CC"getNMethod0",         CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
2384                                                       (void*)&WB_GetNMethod         },
2385   {CC"forceNMethodSweep",  CC"()V",                   (void*)&WB_ForceNMethodSweep  },
2386   {CC"allocateCodeBlob",   CC"(II)J",                 (void*)&WB_AllocateCodeBlob   },
2387   {CC"freeCodeBlob",       CC"(J)V",                  (void*)&WB_FreeCodeBlob       },
2388   {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
2389   {CC"getCompilationActivityMode",
2390                            CC"()I",                   (void*)&WB_GetCompilationActivityMode},
2391   {CC"getMethodData0",     CC"(Ljava/lang/reflect/Executable;)J",
2392                                                       (void*)&WB_GetMethodData      },
2393   {CC"getCodeBlob",        CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob        },
2394   {CC"getThreadStackSize", CC"()J",                   (void*)&WB_GetThreadStackSize },
2395   {CC"getThreadRemainingStackSize", CC"()J",          (void*)&WB_GetThreadRemainingStackSize },
2396   {CC"DefineModule",       CC"(Ljava/lang/Object;ZLjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V",
2397                                                       (void*)&WB_DefineModule },
2398   {CC"AddModuleExports",   CC"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V",
2399                                                       (void*)&WB_AddModuleExports },
2400   {CC"AddReadsModule",     CC"(Ljava/lang/Object;Ljava/lang/Object;)V",
2401                                                       (void*)&WB_AddReadsModule },
2402   {CC"AddModuleExportsToAllUnnamed", CC"(Ljava/lang/Object;Ljava/lang/String;)V",
2403                                                       (void*)&WB_AddModuleExportsToAllUnnamed },
2404   {CC"AddModuleExportsToAll", CC"(Ljava/lang/Object;Ljava/lang/String;)V",
2405                                                       (void*)&WB_AddModuleExportsToAll },
2406   {CC"assertMatchingSafepointCalls", CC"(ZZ)V",       (void*)&WB_AssertMatchingSafepointCalls },
2407   {CC"assertSpecialLock",  CC"(ZZ)V",                 (void*)&WB_AssertSpecialLock },
2408   {CC"isMonitorInflated0", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
2409   {CC"forceSafepoint",     CC"()V",                   (void*)&WB_ForceSafepoint     },
2410   {CC"getConstantPool0",   CC"(Ljava/lang/Class;)J",  (void*)&WB_GetConstantPool    },
2411   {CC"getConstantPoolCacheIndexTag0", CC"()I",  (void*)&WB_GetConstantPoolCacheIndexTag},
2412   {CC"getConstantPoolCacheLength0", CC"(Ljava/lang/Class;)I",  (void*)&WB_GetConstantPoolCacheLength},
2413   {CC"remapInstructionOperandFromCPCache0",
2414       CC"(Ljava/lang/Class;I)I",                      (void*)&WB_ConstantPoolRemapInstructionOperandFromCache},
2415   {CC"encodeConstantPoolIndyIndex0",
2416       CC"(I)I",                      (void*)&WB_ConstantPoolEncodeIndyIndex},
2417   {CC"getMethodBooleanOption",
2418       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Boolean;",
2419                                                       (void*)&WB_GetMethodBooleaneOption},
2420   {CC"getMethodIntxOption",
2421       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Long;",
2422                                                       (void*)&WB_GetMethodIntxOption},
2423   {CC"getMethodUintxOption",
2424       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Long;",
2425                                                       (void*)&WB_GetMethodUintxOption},
2426   {CC"getMethodDoubleOption",
2427       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Double;",
2428                                                       (void*)&WB_GetMethodDoubleOption},
2429   {CC"getMethodStringOption",
2430       CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/String;",
2431                                                       (void*)&WB_GetMethodStringOption},
2432   {CC"getDefaultArchivePath",             CC"()Ljava/lang/String;",
2433                                                       (void*)&WB_GetDefaultArchivePath},
2434   {CC"isSharingEnabled",   CC"()Z",                   (void*)&WB_IsSharingEnabled},
2435   {CC"isShared",           CC"(Ljava/lang/Object;)Z", (void*)&WB_IsShared },
2436   {CC"isSharedClass",      CC"(Ljava/lang/Class;)Z",  (void*)&WB_IsSharedClass },
2437   {CC"areSharedStringsIgnored",           CC"()Z",    (void*)&WB_AreSharedStringsIgnored },
2438   {CC"getResolvedReferences", CC"(Ljava/lang/Class;)Ljava/lang/Object;", (void*)&WB_GetResolvedReferences},
2439   {CC"linkClass",          CC"(Ljava/lang/Class;)V",  (void*)&WB_LinkClass},
2440   {CC"areOpenArchiveHeapObjectsMapped",   CC"()Z",    (void*)&WB_AreOpenArchiveHeapObjectsMapped},
2441   {CC"isCDSIncludedInVmBuild",            CC"()Z",    (void*)&WB_IsCDSIncludedInVmBuild },
2442   {CC"isJFRIncludedInVmBuild",            CC"()Z",    (void*)&WB_IsJFRIncludedInVmBuild },
2443   {CC"isC2OrJVMCIIncludedInVmBuild",      CC"()Z",    (void*)&WB_isC2OrJVMCIIncludedInVmBuild },
2444   {CC"isJavaHeapArchiveSupported",        CC"()Z",    (void*)&WB_IsJavaHeapArchiveSupported },
2445   {CC"cdsMemoryMappingFailed",            CC"()Z",    (void*)&WB_CDSMemoryMappingFailed },
2446 
2447   {CC"clearInlineCaches0",  CC"(Z)V",                 (void*)&WB_ClearInlineCaches },
2448   {CC"handshakeWalkStack", CC"(Ljava/lang/Thread;Z)I", (void*)&WB_HandshakeWalkStack },
2449   {CC"addCompilerDirective",    CC"(Ljava/lang/String;)I",
2450                                                       (void*)&WB_AddCompilerDirective },
2451   {CC"removeCompilerDirective",   CC"(I)V",           (void*)&WB_RemoveCompilerDirective },
2452   {CC"isGCSupported",             CC"(I)Z",           (void*)&WB_IsGCSupported},
2453   {CC"isGCSelected",              CC"(I)Z",           (void*)&WB_IsGCSelected},
2454   {CC"isGCSelectedErgonomically", CC"()Z",            (void*)&WB_IsGCSelectedErgonomically},
2455   {CC"supportsConcurrentGCBreakpoints", CC"()Z",      (void*)&WB_SupportsConcurrentGCBreakpoints},
2456   {CC"concurrentGCAcquireControl0", CC"()V",          (void*)&WB_ConcurrentGCAcquireControl},
2457   {CC"concurrentGCReleaseControl0", CC"()V",          (void*)&WB_ConcurrentGCReleaseControl},
2458   {CC"concurrentGCRunToIdle0",    CC"()V",            (void*)&WB_ConcurrentGCRunToIdle},
2459   {CC"concurrentGCRunTo0",        CC"(Ljava/lang/String;)Z",
2460                                                       (void*)&WB_ConcurrentGCRunTo},
2461   {CC"checkLibSpecifiesNoexecstack", CC"(Ljava/lang/String;)Z",
2462                                                       (void*)&WB_CheckLibSpecifiesNoexecstack},
2463   {CC"isContainerized",           CC"()Z",            (void*)&WB_IsContainerized },
2464   {CC"validateCgroup",
2465       CC"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I",
2466                                                       (void*)&WB_ValidateCgroup },
2467   {CC"printOsInfo",               CC"()V",            (void*)&WB_PrintOsInfo },
2468   {CC"disableElfSectionCache",    CC"()V",            (void*)&WB_DisableElfSectionCache },
2469   {CC"resolvedMethodItemsCount",  CC"()J",            (void*)&WB_ResolvedMethodItemsCount },
2470   {CC"protectionDomainRemovedCount",   CC"()I",       (void*)&WB_ProtectionDomainRemovedCount },
2471   {CC"aotLibrariesCount", CC"()I",                    (void*)&WB_AotLibrariesCount },
2472   {CC"getKlassMetadataSize", CC"(Ljava/lang/Class;)I",(void*)&WB_GetKlassMetadataSize},
2473 };
2474 
2475 
2476 #undef CC
2477 
2478 JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
2479   {
2480     if (WhiteBoxAPI) {
2481       // Make sure that wbclass is loaded by the null classloader
2482       InstanceKlass* ik = InstanceKlass::cast(JNIHandles::resolve(wbclass)->klass());
2483       Handle loader(THREAD, ik->class_loader());
2484       if (loader.is_null()) {
2485         WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0]));
2486         WhiteBox::set_used();
2487       }
2488     }
2489   }
2490 JVM_END