whitebox.cpp revision 13243:7235bc30c0d7
1/*
2 * Copyright (c) 2012, 2017, 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/classLoaderData.hpp"
30#include "classfile/modules.hpp"
31#include "classfile/stringTable.hpp"
32#include "code/codeCache.hpp"
33#include "compiler/methodMatcher.hpp"
34#include "compiler/directivesParser.hpp"
35#include "jvmtifiles/jvmtiEnv.hpp"
36#include "memory/metadataFactory.hpp"
37#include "memory/metaspaceShared.hpp"
38#include "memory/iterator.hpp"
39#include "memory/resourceArea.hpp"
40#include "memory/universe.hpp"
41#include "memory/oopFactory.hpp"
42#include "oops/array.hpp"
43#include "oops/constantPool.hpp"
44#include "oops/objArrayKlass.hpp"
45#include "oops/objArrayOop.inline.hpp"
46#include "oops/oop.inline.hpp"
47#include "prims/wbtestmethods/parserTests.hpp"
48#include "prims/whitebox.hpp"
49#include "runtime/arguments.hpp"
50#include "runtime/compilationPolicy.hpp"
51#include "runtime/deoptimization.hpp"
52#include "runtime/interfaceSupport.hpp"
53#include "runtime/javaCalls.hpp"
54#include "runtime/os.hpp"
55#include "runtime/sweeper.hpp"
56#include "runtime/thread.hpp"
57#include "runtime/vm_version.hpp"
58#include "utilities/debug.hpp"
59#include "utilities/exceptions.hpp"
60#include "utilities/macros.hpp"
61#if INCLUDE_ALL_GCS
62#include "gc/g1/concurrentMarkThread.hpp"
63#include "gc/g1/g1CollectedHeap.inline.hpp"
64#include "gc/g1/g1ConcurrentMark.hpp"
65#include "gc/g1/heapRegionRemSet.hpp"
66#include "gc/parallel/parallelScavengeHeap.inline.hpp"
67#include "gc/parallel/adjoiningGenerations.hpp"
68#endif // INCLUDE_ALL_GCS
69#if INCLUDE_NMT
70#include "services/mallocSiteTable.hpp"
71#include "services/memTracker.hpp"
72#include "utilities/nativeCallStack.hpp"
73#endif // INCLUDE_NMT
74
75
76#define SIZE_T_MAX_VALUE ((size_t) -1)
77
78bool WhiteBox::_used = false;
79volatile bool WhiteBox::compilation_locked = false;
80
81class VM_WhiteBoxOperation : public VM_Operation {
82 public:
83  VM_WhiteBoxOperation()                         { }
84  VMOp_Type type()                  const        { return VMOp_WhiteBoxOperation; }
85  bool allow_nested_vm_operations() const        { return true; }
86};
87
88
89WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
90  return (jlong)(void*)JNIHandles::resolve(obj);
91WB_END
92
93WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
94  return heapOopSize;
95WB_END
96
97WB_ENTRY(jint, WB_GetVMPageSize(JNIEnv* env, jobject o))
98  return os::vm_page_size();
99WB_END
100
101WB_ENTRY(jlong, WB_GetVMAllocationGranularity(JNIEnv* env, jobject o))
102  return os::vm_allocation_granularity();
103WB_END
104
105WB_ENTRY(jlong, WB_GetVMLargePageSize(JNIEnv* env, jobject o))
106  return os::large_page_size();
107WB_END
108
109class WBIsKlassAliveClosure : public KlassClosure {
110    Symbol* _name;
111    bool _found;
112public:
113    WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {}
114
115    void do_klass(Klass* k) {
116      if (_found) return;
117      Symbol* ksym = k->name();
118      if (ksym->fast_compare(_name) == 0) {
119        _found = true;
120      }
121    }
122
123    bool found() const {
124        return _found;
125    }
126};
127
128WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name))
129  oop h_name = JNIHandles::resolve(name);
130  if (h_name == NULL) return false;
131  Symbol* sym = java_lang_String::as_symbol(h_name, CHECK_false);
132  TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return
133
134  WBIsKlassAliveClosure closure(sym);
135  ClassLoaderDataGraph::classes_do(&closure);
136
137  return closure.found();
138WB_END
139
140WB_ENTRY(void, WB_AddToBootstrapClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
141#if INCLUDE_JVMTI
142  ResourceMark rm;
143  const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
144  JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
145  jvmtiError err = jvmti_env->AddToBootstrapClassLoaderSearch(seg);
146  assert(err == JVMTI_ERROR_NONE, "must not fail");
147#endif
148}
149WB_END
150
151WB_ENTRY(void, WB_AddToSystemClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) {
152#if INCLUDE_JVMTI
153  ResourceMark rm;
154  const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment));
155  JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION);
156  jvmtiError err = jvmti_env->AddToSystemClassLoaderSearch(seg);
157  assert(err == JVMTI_ERROR_NONE, "must not fail");
158#endif
159}
160WB_END
161
162
163WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) {
164  return (jlong)Arguments::max_heap_for_compressed_oops();
165}
166WB_END
167
168WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) {
169  CollectorPolicy * p = Universe::heap()->collector_policy();
170  tty->print_cr("Minimum heap " SIZE_FORMAT " Initial heap "
171    SIZE_FORMAT " Maximum heap " SIZE_FORMAT " Space alignment " SIZE_FORMAT " Heap alignment " SIZE_FORMAT,
172    p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(),
173    p->space_alignment(), p->heap_alignment());
174}
175WB_END
176
177#ifndef PRODUCT
178// Forward declaration
179void TestReservedSpace_test();
180void TestReserveMemorySpecial_test();
181void TestVirtualSpace_test();
182void TestMetaspaceAux_test();
183#endif
184
185WB_ENTRY(void, WB_RunMemoryUnitTests(JNIEnv* env, jobject o))
186#ifndef PRODUCT
187  TestReservedSpace_test();
188  TestReserveMemorySpecial_test();
189  TestVirtualSpace_test();
190  TestMetaspaceAux_test();
191#endif
192WB_END
193
194WB_ENTRY(void, WB_ReadFromNoaccessArea(JNIEnv* env, jobject o))
195  size_t granularity = os::vm_allocation_granularity();
196  ReservedHeapSpace rhs(100 * granularity, granularity, false);
197  VirtualSpace vs;
198  vs.initialize(rhs, 50 * granularity);
199
200  // Check if constraints are complied
201  if (!( UseCompressedOops && rhs.base() != NULL &&
202         Universe::narrow_oop_base() != NULL &&
203         Universe::narrow_oop_use_implicit_null_checks() )) {
204    tty->print_cr("WB_ReadFromNoaccessArea method is useless:\n "
205                  "\tUseCompressedOops is %d\n"
206                  "\trhs.base() is " PTR_FORMAT "\n"
207                  "\tUniverse::narrow_oop_base() is " PTR_FORMAT "\n"
208                  "\tUniverse::narrow_oop_use_implicit_null_checks() is %d",
209                  UseCompressedOops,
210                  p2i(rhs.base()),
211                  p2i(Universe::narrow_oop_base()),
212                  Universe::narrow_oop_use_implicit_null_checks());
213    return;
214  }
215  tty->print_cr("Reading from no access area... ");
216  tty->print_cr("*(vs.low_boundary() - rhs.noaccess_prefix() / 2 ) = %c",
217                *(vs.low_boundary() - rhs.noaccess_prefix() / 2 ));
218WB_END
219
220static jint wb_stress_virtual_space_resize(size_t reserved_space_size,
221                                           size_t magnitude, size_t iterations) {
222  size_t granularity = os::vm_allocation_granularity();
223  ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false);
224  VirtualSpace vs;
225  if (!vs.initialize(rhs, 0)) {
226    tty->print_cr("Failed to initialize VirtualSpace. Can't proceed.");
227    return 3;
228  }
229
230  int seed = os::random();
231  tty->print_cr("Random seed is %d", seed);
232  os::init_random(seed);
233
234  for (size_t i = 0; i < iterations; i++) {
235
236    // Whether we will shrink or grow
237    bool shrink = os::random() % 2L == 0;
238
239    // Get random delta to resize virtual space
240    size_t delta = (size_t)os::random() % magnitude;
241
242    // If we are about to shrink virtual space below zero, then expand instead
243    if (shrink && vs.committed_size() < delta) {
244      shrink = false;
245    }
246
247    // Resizing by delta
248    if (shrink) {
249      vs.shrink_by(delta);
250    } else {
251      // If expanding fails expand_by will silently return false
252      vs.expand_by(delta, true);
253    }
254  }
255  return 0;
256}
257
258WB_ENTRY(jint, WB_StressVirtualSpaceResize(JNIEnv* env, jobject o,
259        jlong reserved_space_size, jlong magnitude, jlong iterations))
260  tty->print_cr("reservedSpaceSize=" JLONG_FORMAT ", magnitude=" JLONG_FORMAT ", "
261                "iterations=" JLONG_FORMAT "\n", reserved_space_size, magnitude,
262                iterations);
263  if (reserved_space_size < 0 || magnitude < 0 || iterations < 0) {
264    tty->print_cr("One of variables printed above is negative. Can't proceed.\n");
265    return 1;
266  }
267
268  // sizeof(size_t) depends on whether OS is 32bit or 64bit. sizeof(jlong) is
269  // always 8 byte. That's why we should avoid overflow in case of 32bit platform.
270  if (sizeof(size_t) < sizeof(jlong)) {
271    jlong size_t_max_value = (jlong) SIZE_T_MAX_VALUE;
272    if (reserved_space_size > size_t_max_value || magnitude > size_t_max_value
273        || iterations > size_t_max_value) {
274      tty->print_cr("One of variables printed above overflows size_t. Can't proceed.\n");
275      return 2;
276    }
277  }
278
279  return wb_stress_virtual_space_resize((size_t) reserved_space_size,
280                                        (size_t) magnitude, (size_t) iterations);
281WB_END
282
283static const jint serial_code   = 1;
284static const jint parallel_code = 2;
285static const jint cms_code      = 4;
286static const jint g1_code       = 8;
287
288WB_ENTRY(jint, WB_CurrentGC(JNIEnv* env, jobject o, jobject obj))
289  if (UseSerialGC) {
290    return serial_code;
291  } else if (UseParallelGC || UseParallelOldGC) {
292    return parallel_code;
293  } if (UseConcMarkSweepGC) {
294    return cms_code;
295  } else if (UseG1GC) {
296    return g1_code;
297  }
298  ShouldNotReachHere();
299  return 0;
300WB_END
301
302WB_ENTRY(jint, WB_AllSupportedGC(JNIEnv* env, jobject o, jobject obj))
303#if INCLUDE_ALL_GCS
304  return serial_code | parallel_code | cms_code | g1_code;
305#else
306  return serial_code;
307#endif // INCLUDE_ALL_GCS
308WB_END
309
310WB_ENTRY(jboolean, WB_GCSelectedByErgo(JNIEnv* env, jobject o, jobject obj))
311  if (UseSerialGC) {
312    return FLAG_IS_ERGO(UseSerialGC);
313  } else if (UseParallelGC) {
314    return FLAG_IS_ERGO(UseParallelGC);
315  } else if (UseParallelOldGC) {
316    return FLAG_IS_ERGO(UseParallelOldGC);
317  } else if (UseConcMarkSweepGC) {
318    return FLAG_IS_ERGO(UseConcMarkSweepGC);
319  } else if (UseG1GC) {
320    return FLAG_IS_ERGO(UseG1GC);
321  }
322  ShouldNotReachHere();
323  return false;
324WB_END
325
326WB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj))
327  oop p = JNIHandles::resolve(obj);
328#if INCLUDE_ALL_GCS
329  if (UseG1GC) {
330    G1CollectedHeap* g1 = G1CollectedHeap::heap();
331    const HeapRegion* hr = g1->heap_region_containing(p);
332    if (hr == NULL) {
333      return false;
334    }
335    return !(hr->is_young());
336  } else if (UseParallelGC) {
337    ParallelScavengeHeap* psh = ParallelScavengeHeap::heap();
338    return !psh->is_in_young(p);
339  }
340#endif // INCLUDE_ALL_GCS
341  GenCollectedHeap* gch = GenCollectedHeap::heap();
342  return !gch->is_in_young(p);
343WB_END
344
345WB_ENTRY(jlong, WB_GetObjectSize(JNIEnv* env, jobject o, jobject obj))
346  oop p = JNIHandles::resolve(obj);
347  return p->size() * HeapWordSize;
348WB_END
349
350WB_ENTRY(jlong, WB_GetHeapSpaceAlignment(JNIEnv* env, jobject o))
351  size_t alignment = Universe::heap()->collector_policy()->space_alignment();
352  return (jlong)alignment;
353WB_END
354
355WB_ENTRY(jlong, WB_GetHeapAlignment(JNIEnv* env, jobject o))
356  size_t alignment = Universe::heap()->collector_policy()->heap_alignment();
357  return (jlong)alignment;
358WB_END
359
360WB_ENTRY(jboolean, WB_SupportsConcurrentGCPhaseControl(JNIEnv* env, jobject o))
361  return Universe::heap()->supports_concurrent_phase_control();
362WB_END
363
364WB_ENTRY(jobjectArray, WB_GetConcurrentGCPhases(JNIEnv* env, jobject o))
365  const char* const* phases = Universe::heap()->concurrent_phases();
366  jint nphases = 0;
367  for ( ; phases[nphases] != NULL; ++nphases) ;
368
369  ResourceMark rm(thread);
370  ThreadToNativeFromVM ttn(thread);
371  jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
372  CHECK_JNI_EXCEPTION_(env, NULL);
373
374  jobjectArray result = env->NewObjectArray(nphases, clazz, NULL);
375  CHECK_JNI_EXCEPTION_(env, NULL);
376
377  // If push fails, return with pending exception.
378  if (env->PushLocalFrame(nphases) < 0) return NULL;
379  for (jint i = 0; i < nphases; ++i) {
380    jstring phase = env->NewStringUTF(phases[i]);
381    CHECK_JNI_EXCEPTION_(env, NULL);
382    env->SetObjectArrayElement(result, i, phase);
383    CHECK_JNI_EXCEPTION_(env, NULL);
384  }
385  env->PopLocalFrame(NULL);
386
387  return result;
388WB_END
389
390WB_ENTRY(jboolean, WB_RequestConcurrentGCPhase(JNIEnv* env, jobject o, jstring name))
391  Handle h_name(THREAD, JNIHandles::resolve(name));
392  ResourceMark rm;
393  const char* c_name = java_lang_String::as_utf8_string(h_name());
394  return Universe::heap()->request_concurrent_phase(c_name);
395WB_END
396
397#if INCLUDE_ALL_GCS
398WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
399  if (UseG1GC) {
400    G1CollectedHeap* g1 = G1CollectedHeap::heap();
401    oop result = JNIHandles::resolve(obj);
402    const HeapRegion* hr = g1->heap_region_containing(result);
403    return hr->is_humongous();
404  }
405  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1IsHumongous: G1 GC is not enabled");
406WB_END
407
408WB_ENTRY(jboolean, WB_G1BelongsToHumongousRegion(JNIEnv* env, jobject o, jlong addr))
409  if (UseG1GC) {
410    G1CollectedHeap* g1 = G1CollectedHeap::heap();
411    const HeapRegion* hr = g1->heap_region_containing((void*) addr);
412    return hr->is_humongous();
413  }
414  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1BelongsToHumongousRegion: G1 GC is not enabled");
415WB_END
416
417WB_ENTRY(jboolean, WB_G1BelongsToFreeRegion(JNIEnv* env, jobject o, jlong addr))
418  if (UseG1GC) {
419    G1CollectedHeap* g1 = G1CollectedHeap::heap();
420    const HeapRegion* hr = g1->heap_region_containing((void*) addr);
421    return hr->is_free();
422  }
423  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1BelongsToFreeRegion: G1 GC is not enabled");
424WB_END
425
426WB_ENTRY(jlong, WB_G1NumMaxRegions(JNIEnv* env, jobject o))
427  if (UseG1GC) {
428    G1CollectedHeap* g1 = G1CollectedHeap::heap();
429    size_t nr = g1->max_regions();
430    return (jlong)nr;
431  }
432  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1NumMaxRegions: G1 GC is not enabled");
433WB_END
434
435WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o))
436  if (UseG1GC) {
437    G1CollectedHeap* g1 = G1CollectedHeap::heap();
438    size_t nr = g1->num_free_regions();
439    return (jlong)nr;
440  }
441  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1NumFreeRegions: G1 GC is not enabled");
442WB_END
443
444WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
445  if (UseG1GC) {
446    G1CollectedHeap* g1h = G1CollectedHeap::heap();
447    return g1h->concurrent_mark()->cmThread()->during_cycle();
448  }
449  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1InConcurrentMark: G1 GC is not enabled");
450WB_END
451
452WB_ENTRY(jboolean, WB_G1StartMarkCycle(JNIEnv* env, jobject o))
453  if (UseG1GC) {
454    G1CollectedHeap* g1h = G1CollectedHeap::heap();
455    if (!g1h->concurrent_mark()->cmThread()->during_cycle()) {
456      g1h->collect(GCCause::_wb_conc_mark);
457      return true;
458    }
459    return false;
460  }
461  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1StartMarkCycle: G1 GC is not enabled");
462WB_END
463
464WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
465  if (UseG1GC) {
466    return (jint)HeapRegion::GrainBytes;
467  }
468  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1RegionSize: G1 GC is not enabled");
469WB_END
470
471WB_ENTRY(jlong, WB_PSVirtualSpaceAlignment(JNIEnv* env, jobject o))
472#if INCLUDE_ALL_GCS
473  if (UseParallelGC) {
474    return ParallelScavengeHeap::heap()->gens()->virtual_spaces()->alignment();
475  }
476#endif // INCLUDE_ALL_GCS
477  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSVirtualSpaceAlignment: Parallel GC is not enabled");
478WB_END
479
480WB_ENTRY(jlong, WB_PSHeapGenerationAlignment(JNIEnv* env, jobject o))
481#if INCLUDE_ALL_GCS
482  if (UseParallelGC) {
483    return ParallelScavengeHeap::heap()->generation_alignment();
484  }
485#endif // INCLUDE_ALL_GCS
486  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_PSHeapGenerationAlignment: Parallel GC is not enabled");
487WB_END
488
489WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env))
490#if INCLUDE_ALL_GCS
491  if (UseG1GC) {
492    ResourceMark rm(THREAD);
493    G1CollectedHeap* g1h = G1CollectedHeap::heap();
494    MemoryUsage usage = g1h->get_auxiliary_data_memory_usage();
495    Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL);
496    return JNIHandles::make_local(env, h());
497  }
498#endif // INCLUDE_ALL_GCS
499  THROW_MSG_0(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1AuxiliaryMemoryUsage: G1 GC is not enabled");
500WB_END
501
502class OldRegionsLivenessClosure: public HeapRegionClosure {
503
504 private:
505  const int _liveness;
506  size_t _total_count;
507  size_t _total_memory;
508  size_t _total_memory_to_free;
509
510 public:
511  OldRegionsLivenessClosure(int liveness) :
512    _liveness(liveness),
513    _total_count(0),
514    _total_memory(0),
515    _total_memory_to_free(0) { }
516
517    size_t total_count() { return _total_count; }
518    size_t total_memory() { return _total_memory; }
519    size_t total_memory_to_free() { return _total_memory_to_free; }
520
521  bool doHeapRegion(HeapRegion* r) {
522    if (r->is_old()) {
523      size_t prev_live = r->marked_bytes();
524      size_t live = r->live_bytes();
525      size_t size = r->used();
526      size_t reg_size = HeapRegion::GrainBytes;
527      if (size > 0 && ((int)(live * 100 / size) < _liveness)) {
528        _total_memory += size;
529        ++_total_count;
530        if (size == reg_size) {
531        // we don't include non-full regions since they are unlikely included in mixed gc
532        // for testing purposes it's enough to have lowest estimation of total memory that is expected to be freed
533          _total_memory_to_free += size - prev_live;
534        }
535      }
536    }
537    return false;
538  }
539};
540
541
542WB_ENTRY(jlongArray, WB_G1GetMixedGCInfo(JNIEnv* env, jobject o, jint liveness))
543  if (!UseG1GC) {
544    THROW_MSG_NULL(vmSymbols::java_lang_UnsupportedOperationException(), "WB_G1GetMixedGCInfo: G1 GC is not enabled");
545  }
546  if (liveness < 0) {
547    THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), "liveness value should be non-negative");
548  }
549
550  G1CollectedHeap* g1h = G1CollectedHeap::heap();
551  OldRegionsLivenessClosure rli(liveness);
552  g1h->heap_region_iterate(&rli);
553
554  typeArrayOop result = oopFactory::new_longArray(3, CHECK_NULL);
555  result->long_at_put(0, rli.total_count());
556  result->long_at_put(1, rli.total_memory());
557  result->long_at_put(2, rli.total_memory_to_free());
558  return (jlongArray) JNIHandles::make_local(env, result);
559WB_END
560
561#endif // INCLUDE_ALL_GCS
562
563#if INCLUDE_NMT
564// Alloc memory using the test memory type so that we can use that to see if
565// NMT picks it up correctly
566WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size))
567  jlong addr = 0;
568  addr = (jlong)(uintptr_t)os::malloc(size, mtTest);
569  return addr;
570WB_END
571
572// Alloc memory with pseudo call stack. The test can create psudo malloc
573// allocation site to stress the malloc tracking.
574WB_ENTRY(jlong, WB_NMTMallocWithPseudoStack(JNIEnv* env, jobject o, jlong size, jint pseudo_stack))
575  address pc = (address)(size_t)pseudo_stack;
576  NativeCallStack stack(&pc, 1);
577  return (jlong)(uintptr_t)os::malloc(size, mtTest, stack);
578WB_END
579
580// Free the memory allocated by NMTAllocTest
581WB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem))
582  os::free((void*)(uintptr_t)mem);
583WB_END
584
585WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
586  jlong addr = 0;
587
588  addr = (jlong)(uintptr_t)os::reserve_memory(size);
589  MemTracker::record_virtual_memory_type((address)addr, mtTest);
590
591  return addr;
592WB_END
593
594WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
595  os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
596  MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
597WB_END
598
599WB_ENTRY(void, WB_NMTUncommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
600  os::uncommit_memory((char *)(uintptr_t)addr, size);
601WB_END
602
603WB_ENTRY(void, WB_NMTReleaseMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
604  os::release_memory((char *)(uintptr_t)addr, size);
605WB_END
606
607WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env))
608  // Test that we can downgrade NMT levels but not upgrade them.
609  if (MemTracker::tracking_level() == NMT_off) {
610    MemTracker::transition_to(NMT_off);
611    return MemTracker::tracking_level() == NMT_off;
612  } else {
613    assert(MemTracker::tracking_level() == NMT_detail, "Should start out as detail tracking");
614    MemTracker::transition_to(NMT_summary);
615    assert(MemTracker::tracking_level() == NMT_summary, "Should be summary now");
616
617    // Can't go to detail once NMT is set to summary.
618    MemTracker::transition_to(NMT_detail);
619    assert(MemTracker::tracking_level() == NMT_summary, "Should still be summary now");
620
621    // Shutdown sets tracking level to minimal.
622    MemTracker::shutdown();
623    assert(MemTracker::tracking_level() == NMT_minimal, "Should be minimal now");
624
625    // Once the tracking level is minimal, we cannot increase to summary.
626    // The code ignores this request instead of asserting because if the malloc site
627    // table overflows in another thread, it tries to change the code to summary.
628    MemTracker::transition_to(NMT_summary);
629    assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
630
631    // Really can never go up to detail, verify that the code would never do this.
632    MemTracker::transition_to(NMT_detail);
633    assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
634    return MemTracker::tracking_level() == NMT_minimal;
635  }
636WB_END
637
638WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o))
639  int hash_size = MallocSiteTable::hash_buckets();
640  assert(hash_size > 0, "NMT hash_size should be > 0");
641  return (jint)hash_size;
642WB_END
643#endif // INCLUDE_NMT
644
645static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
646  assert(method != NULL, "method should not be null");
647  ThreadToNativeFromVM ttn(thread);
648  return env->FromReflectedMethod(method);
649}
650
651// Deoptimizes all compiled frames and makes nmethods not entrant if it's requested
652class VM_WhiteBoxDeoptimizeFrames : public VM_WhiteBoxOperation {
653 private:
654  int _result;
655  const bool _make_not_entrant;
656 public:
657  VM_WhiteBoxDeoptimizeFrames(bool make_not_entrant) :
658        _result(0), _make_not_entrant(make_not_entrant) { }
659  int  result() const { return _result; }
660
661  void doit() {
662    for (JavaThread* t = Threads::first(); t != NULL; t = t->next()) {
663      if (t->has_last_Java_frame()) {
664        for (StackFrameStream fst(t, UseBiasedLocking); !fst.is_done(); fst.next()) {
665          frame* f = fst.current();
666          if (f->can_be_deoptimized() && !f->is_deoptimized_frame()) {
667            RegisterMap* reg_map = fst.register_map();
668            Deoptimization::deoptimize(t, *f, reg_map);
669            if (_make_not_entrant) {
670                CompiledMethod* cm = CodeCache::find_compiled(f->pc());
671                assert(cm != NULL, "sanity check");
672                cm->make_not_entrant();
673            }
674            ++_result;
675          }
676        }
677      }
678    }
679  }
680};
681
682WB_ENTRY(jint, WB_DeoptimizeFrames(JNIEnv* env, jobject o, jboolean make_not_entrant))
683  VM_WhiteBoxDeoptimizeFrames op(make_not_entrant == JNI_TRUE);
684  VMThread::execute(&op);
685  return op.result();
686WB_END
687
688WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
689  MutexLockerEx mu(Compile_lock);
690  CodeCache::mark_all_nmethods_for_deoptimization();
691  VM_Deoptimize op;
692  VMThread::execute(&op);
693WB_END
694
695WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
696  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
697  int result = 0;
698  CHECK_JNI_EXCEPTION_(env, result);
699  MutexLockerEx mu(Compile_lock);
700  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
701  if (is_osr) {
702    result += mh->mark_osr_nmethods();
703  } else if (mh->code() != NULL) {
704    mh->code()->mark_for_deoptimization();
705    ++result;
706  }
707  result += CodeCache::mark_for_deoptimization(mh());
708  if (result > 0) {
709    VM_Deoptimize op;
710    VMThread::execute(&op);
711  }
712  return result;
713WB_END
714
715WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
716  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
717  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
718  MutexLockerEx mu(Compile_lock);
719  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
720  CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
721  if (code == NULL) {
722    return JNI_FALSE;
723  }
724  return (code->is_alive() && !code->is_marked_for_deoptimization());
725WB_END
726
727WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
728  if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) {
729    return false;
730  }
731  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
732  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
733  MutexLockerEx mu(Compile_lock);
734  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
735  if (is_osr) {
736    return CompilationPolicy::can_be_osr_compiled(mh, comp_level);
737  } else {
738    return CompilationPolicy::can_be_compiled(mh, comp_level);
739  }
740WB_END
741
742WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
743  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
744  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
745  MutexLockerEx mu(Compile_lock);
746  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
747  return mh->queued_for_compilation();
748WB_END
749
750WB_ENTRY(jboolean, WB_IsIntrinsicAvailable(JNIEnv* env, jobject o, jobject method, jobject compilation_context, jint compLevel))
751  if (compLevel < CompLevel_none || compLevel > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) {
752    return false; // Intrinsic is not available on a non-existent compilation level.
753  }
754  jmethodID method_id, compilation_context_id;
755  method_id = reflected_method_to_jmid(thread, env, method);
756  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
757  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(method_id));
758
759  DirectiveSet* directive;
760  AbstractCompiler* comp = CompileBroker::compiler((int)compLevel);
761  assert(comp != NULL, "compiler not available");
762  if (compilation_context != NULL) {
763    compilation_context_id = reflected_method_to_jmid(thread, env, compilation_context);
764    CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
765    methodHandle cch(THREAD, Method::checked_resolve_jmethod_id(compilation_context_id));
766    directive = DirectivesStack::getMatchingDirective(cch, comp);
767  } else {
768    // Calling with NULL matches default directive
769    directive = DirectivesStack::getDefaultDirective(comp);
770  }
771  bool result = comp->is_intrinsic_available(mh, directive);
772  DirectivesStack::release(directive);
773  return result;
774WB_END
775
776WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
777  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
778  CHECK_JNI_EXCEPTION_(env, CompLevel_none);
779  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
780  CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
781  return (code != NULL ? code->comp_level() : CompLevel_none);
782WB_END
783
784WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr))
785  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
786  CHECK_JNI_EXCEPTION(env);
787  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
788  if (is_osr) {
789    mh->set_not_osr_compilable(comp_level, true /* report */, "WhiteBox");
790  } else {
791    mh->set_not_compilable(comp_level, true /* report */, "WhiteBox");
792  }
793WB_END
794
795WB_ENTRY(jint, WB_GetMethodEntryBci(JNIEnv* env, jobject o, jobject method))
796  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
797  CHECK_JNI_EXCEPTION_(env, InvocationEntryBci);
798  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
799  CompiledMethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false);
800  return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci);
801WB_END
802
803WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
804  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
805  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
806  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
807  bool result = mh->dont_inline();
808  mh->set_dont_inline(value == JNI_TRUE);
809  return result;
810WB_END
811
812WB_ENTRY(jint, WB_GetCompileQueueSize(JNIEnv* env, jobject o, jint comp_level))
813  if (comp_level == CompLevel_any) {
814    return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
815        CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
816  } else {
817    return CompileBroker::queue_size(comp_level);
818  }
819WB_END
820
821WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
822  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
823  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
824  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
825  bool result = mh->force_inline();
826  mh->set_force_inline(value == JNI_TRUE);
827  return result;
828WB_END
829
830bool WhiteBox::compile_method(Method* method, int comp_level, int bci, Thread* THREAD) {
831  // Screen for unavailable/bad comp level or null method
832  if (method == NULL || comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier) ||
833      CompileBroker::compiler(comp_level) == NULL) {
834    return false;
835  }
836  methodHandle mh(THREAD, method);
837  nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), CompileTask::Reason_Whitebox, THREAD);
838  MutexLockerEx mu(Compile_lock);
839  return (mh->queued_for_compilation() || nm != NULL);
840}
841
842WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
843  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
844  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
845  return WhiteBox::compile_method(Method::checked_resolve_jmethod_id(jmid), comp_level, bci, THREAD);
846WB_END
847
848WB_ENTRY(jboolean, WB_EnqueueInitializerForCompilation(JNIEnv* env, jobject o, jclass klass, jint comp_level))
849  InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
850  return WhiteBox::compile_method(ik->class_initializer(), comp_level, InvocationEntryBci, THREAD);
851WB_END
852
853WB_ENTRY(jboolean, WB_ShouldPrintAssembly(JNIEnv* env, jobject o, jobject method, jint comp_level))
854  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
855  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
856
857  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
858  DirectiveSet* directive = DirectivesStack::getMatchingDirective(mh, CompileBroker::compiler(comp_level));
859  bool result = directive->PrintAssemblyOption;
860  DirectivesStack::release(directive);
861
862  return result;
863WB_END
864
865WB_ENTRY(jint, WB_MatchesInline(JNIEnv* env, jobject o, jobject method, jstring pattern))
866  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
867  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
868
869  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
870
871  ResourceMark rm;
872  const char* error_msg = NULL;
873  char* method_str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(pattern));
874  InlineMatcher* m = InlineMatcher::parse_inline_pattern(method_str, error_msg);
875
876  if (m == NULL) {
877    assert(error_msg != NULL, "Always have an error message");
878    tty->print_cr("Got error: %s", error_msg);
879    return -1; // Pattern failed
880  }
881
882  // Pattern works - now check if it matches
883  int result;
884  if (m->match(mh, InlineMatcher::force_inline)) {
885    result = 2; // Force inline match
886  } else if (m->match(mh, InlineMatcher::dont_inline)) {
887    result = 1; // Dont inline match
888  } else {
889    result = 0; // No match
890  }
891  delete m;
892  return result;
893WB_END
894
895WB_ENTRY(jint, WB_MatchesMethod(JNIEnv* env, jobject o, jobject method, jstring pattern))
896  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
897  CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
898
899  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
900
901  ResourceMark rm;
902  char* method_str = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(pattern));
903
904  const char* error_msg = NULL;
905
906  BasicMatcher* m = BasicMatcher::parse_method_pattern(method_str, error_msg);
907  if (m == NULL) {
908    assert(error_msg != NULL, "Must have error_msg");
909    tty->print_cr("Got error: %s", error_msg);
910    return -1;
911  }
912
913  // Pattern works - now check if it matches
914  int result = m->matches(mh);
915  delete m;
916  assert(result == 0 || result == 1, "Result out of range");
917  return result;
918WB_END
919
920static AlwaysFalseClosure always_false;
921
922WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
923  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
924  CHECK_JNI_EXCEPTION(env);
925  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
926  MutexLockerEx mu(Compile_lock);
927  MethodData* mdo = mh->method_data();
928  MethodCounters* mcs = mh->method_counters();
929
930  if (mdo != NULL) {
931    mdo->init();
932    ResourceMark rm;
933    int arg_count = mdo->method()->size_of_parameters();
934    for (int i = 0; i < arg_count; i++) {
935      mdo->set_arg_modified(i, 0);
936    }
937    MutexLockerEx mu(mdo->extra_data_lock());
938    mdo->clean_method_data(&always_false);
939  }
940
941  mh->clear_not_c1_compilable();
942  mh->clear_not_c2_compilable();
943  mh->clear_not_c2_osr_compilable();
944  NOT_PRODUCT(mh->set_compiled_invocation_count(0));
945  if (mcs != NULL) {
946    mcs->backedge_counter()->init();
947    mcs->invocation_counter()->init();
948    mcs->set_interpreter_invocation_count(0);
949    mcs->set_interpreter_throwout_count(0);
950
951#ifdef TIERED
952    mcs->set_rate(0.0F);
953    mh->set_prev_event_count(0);
954    mh->set_prev_time(0);
955#endif
956  }
957WB_END
958
959template <typename T>
960static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, Flag::Error (*TAt)(const char*, T*, bool, bool)) {
961  if (name == NULL) {
962    return false;
963  }
964  ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
965  const char* flag_name = env->GetStringUTFChars(name, NULL);
966  CHECK_JNI_EXCEPTION_(env, false);
967  Flag::Error result = (*TAt)(flag_name, value, true, true);
968  env->ReleaseStringUTFChars(name, flag_name);
969  return (result == Flag::SUCCESS);
970}
971
972template <typename T>
973static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, Flag::Error (*TAtPut)(const char*, T*, Flag::Flags)) {
974  if (name == NULL) {
975    return false;
976  }
977  ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
978  const char* flag_name = env->GetStringUTFChars(name, NULL);
979  CHECK_JNI_EXCEPTION_(env, false);
980  Flag::Error result = (*TAtPut)(flag_name, value, Flag::INTERNAL);
981  env->ReleaseStringUTFChars(name, flag_name);
982  return (result == Flag::SUCCESS);
983}
984
985template <typename T>
986static jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) {
987  ResourceMark rm(thread);
988  jclass clazz = env->FindClass(name->as_C_string());
989  CHECK_JNI_EXCEPTION_(env, NULL);
990  jmethodID methodID = env->GetStaticMethodID(clazz,
991        vmSymbols::valueOf_name()->as_C_string(),
992        sig->as_C_string());
993  CHECK_JNI_EXCEPTION_(env, NULL);
994  jobject result = env->CallStaticObjectMethod(clazz, methodID, value);
995  CHECK_JNI_EXCEPTION_(env, NULL);
996  return result;
997}
998
999static jobject booleanBox(JavaThread* thread, JNIEnv* env, jboolean value) {
1000  return box(thread, env, vmSymbols::java_lang_Boolean(), vmSymbols::Boolean_valueOf_signature(), value);
1001}
1002static jobject integerBox(JavaThread* thread, JNIEnv* env, jint value) {
1003  return box(thread, env, vmSymbols::java_lang_Integer(), vmSymbols::Integer_valueOf_signature(), value);
1004}
1005static jobject longBox(JavaThread* thread, JNIEnv* env, jlong value) {
1006  return box(thread, env, vmSymbols::java_lang_Long(), vmSymbols::Long_valueOf_signature(), value);
1007}
1008/* static jobject floatBox(JavaThread* thread, JNIEnv* env, jfloat value) {
1009  return box(thread, env, vmSymbols::java_lang_Float(), vmSymbols::Float_valueOf_signature(), value);
1010}*/
1011static jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) {
1012  return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value);
1013}
1014
1015static Flag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) {
1016  ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1017  const char* flag_name = env->GetStringUTFChars(name, NULL);
1018  CHECK_JNI_EXCEPTION_(env, NULL);
1019  Flag* result = Flag::find_flag(flag_name, strlen(flag_name), true, true);
1020  env->ReleaseStringUTFChars(name, flag_name);
1021  return result;
1022}
1023
1024WB_ENTRY(jboolean, WB_IsConstantVMFlag(JNIEnv* env, jobject o, jstring name))
1025  Flag* flag = getVMFlag(thread, env, name);
1026  return (flag != NULL) && flag->is_constant_in_binary();
1027WB_END
1028
1029WB_ENTRY(jboolean, WB_IsLockedVMFlag(JNIEnv* env, jobject o, jstring name))
1030  Flag* flag = getVMFlag(thread, env, name);
1031  return (flag != NULL) && !(flag->is_unlocked() || flag->is_unlocker());
1032WB_END
1033
1034WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name))
1035  bool result;
1036  if (GetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAt)) {
1037    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1038    return booleanBox(thread, env, result);
1039  }
1040  return NULL;
1041WB_END
1042
1043WB_ENTRY(jobject, WB_GetIntVMFlag(JNIEnv* env, jobject o, jstring name))
1044  int result;
1045  if (GetVMFlag <int> (thread, env, name, &result, &CommandLineFlags::intAt)) {
1046    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1047    return longBox(thread, env, result);
1048  }
1049  return NULL;
1050WB_END
1051
1052WB_ENTRY(jobject, WB_GetUintVMFlag(JNIEnv* env, jobject o, jstring name))
1053  uint result;
1054  if (GetVMFlag <uint> (thread, env, name, &result, &CommandLineFlags::uintAt)) {
1055    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1056    return longBox(thread, env, result);
1057  }
1058  return NULL;
1059WB_END
1060
1061WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name))
1062  intx result;
1063  if (GetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAt)) {
1064    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1065    return longBox(thread, env, result);
1066  }
1067  return NULL;
1068WB_END
1069
1070WB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name))
1071  uintx result;
1072  if (GetVMFlag <uintx> (thread, env, name, &result, &CommandLineFlags::uintxAt)) {
1073    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1074    return longBox(thread, env, result);
1075  }
1076  return NULL;
1077WB_END
1078
1079WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name))
1080  uint64_t result;
1081  if (GetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAt)) {
1082    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1083    return longBox(thread, env, result);
1084  }
1085  return NULL;
1086WB_END
1087
1088WB_ENTRY(jobject, WB_GetSizeTVMFlag(JNIEnv* env, jobject o, jstring name))
1089  uintx result;
1090  if (GetVMFlag <size_t> (thread, env, name, &result, &CommandLineFlags::size_tAt)) {
1091    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1092    return longBox(thread, env, result);
1093  }
1094  return NULL;
1095WB_END
1096
1097WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name))
1098  double result;
1099  if (GetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAt)) {
1100    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1101    return doubleBox(thread, env, result);
1102  }
1103  return NULL;
1104WB_END
1105
1106WB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name))
1107  ccstr ccstrResult;
1108  if (GetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAt)) {
1109    ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1110    jstring result = env->NewStringUTF(ccstrResult);
1111    CHECK_JNI_EXCEPTION_(env, NULL);
1112    return result;
1113  }
1114  return NULL;
1115WB_END
1116
1117WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value))
1118  bool result = value == JNI_TRUE ? true : false;
1119  SetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAtPut);
1120WB_END
1121
1122WB_ENTRY(void, WB_SetIntVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1123  int result = value;
1124  SetVMFlag <int> (thread, env, name, &result, &CommandLineFlags::intAtPut);
1125WB_END
1126
1127WB_ENTRY(void, WB_SetUintVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1128  uint result = value;
1129  SetVMFlag <uint> (thread, env, name, &result, &CommandLineFlags::uintAtPut);
1130WB_END
1131
1132WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1133  intx result = value;
1134  SetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAtPut);
1135WB_END
1136
1137WB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1138  uintx result = value;
1139  SetVMFlag <uintx> (thread, env, name, &result, &CommandLineFlags::uintxAtPut);
1140WB_END
1141
1142WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1143  uint64_t result = value;
1144  SetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAtPut);
1145WB_END
1146
1147WB_ENTRY(void, WB_SetSizeTVMFlag(JNIEnv* env, jobject o, jstring name, jlong value))
1148  size_t result = value;
1149  SetVMFlag <size_t> (thread, env, name, &result, &CommandLineFlags::size_tAtPut);
1150WB_END
1151
1152WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value))
1153  double result = value;
1154  SetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAtPut);
1155WB_END
1156
1157WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value))
1158  ThreadToNativeFromVM ttnfv(thread);   // can't be in VM when we call JNI
1159  const char* ccstrValue;
1160  if (value == NULL) {
1161    ccstrValue = NULL;
1162  }
1163  else {
1164    ccstrValue = env->GetStringUTFChars(value, NULL);
1165    CHECK_JNI_EXCEPTION(env);
1166  }
1167  ccstr ccstrResult = ccstrValue;
1168  bool needFree;
1169  {
1170    ThreadInVMfromNative ttvfn(thread); // back to VM
1171    needFree = SetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAtPut);
1172  }
1173  if (value != NULL) {
1174    env->ReleaseStringUTFChars(value, ccstrValue);
1175  }
1176  if (needFree) {
1177    FREE_C_HEAP_ARRAY(char, ccstrResult);
1178  }
1179WB_END
1180
1181WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
1182  WhiteBox::compilation_locked = true;
1183WB_END
1184
1185WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
1186  MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
1187  WhiteBox::compilation_locked = false;
1188  mo.notify_all();
1189WB_END
1190
1191WB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
1192  // Force a code cache sweep and block until it finished
1193  NMethodSweeper::force_sweep();
1194WB_END
1195
1196WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
1197  ResourceMark rm(THREAD);
1198  int len;
1199  jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false);
1200  return (StringTable::lookup(name, len) != NULL);
1201WB_END
1202
1203WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
1204  Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
1205  Universe::heap()->collect(GCCause::_wb_full_gc);
1206#if INCLUDE_ALL_GCS
1207  if (UseG1GC) {
1208    // Needs to be cleared explicitly for G1
1209    Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false);
1210  }
1211#endif // INCLUDE_ALL_GCS
1212WB_END
1213
1214WB_ENTRY(void, WB_YoungGC(JNIEnv* env, jobject o))
1215  Universe::heap()->collect(GCCause::_wb_young_gc);
1216WB_END
1217
1218WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
1219  // static+volatile in order to force the read to happen
1220  // (not be eliminated by the compiler)
1221  static char c;
1222  static volatile char* p;
1223
1224  p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
1225  if (p == NULL) {
1226    THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
1227  }
1228
1229  c = *p;
1230WB_END
1231
1232WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o))
1233  const char* features = VM_Version::features_string();
1234  ThreadToNativeFromVM ttn(thread);
1235  jstring features_string = env->NewStringUTF(features);
1236
1237  CHECK_JNI_EXCEPTION_(env, NULL);
1238
1239  return features_string;
1240WB_END
1241
1242int WhiteBox::get_blob_type(const CodeBlob* code) {
1243  guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
1244  if (code->is_aot()) {
1245    return -1;
1246  }
1247  return CodeCache::get_code_heap(code)->code_blob_type();
1248}
1249
1250CodeHeap* WhiteBox::get_code_heap(int blob_type) {
1251  guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
1252  return CodeCache::get_code_heap(blob_type);
1253}
1254
1255struct CodeBlobStub {
1256  CodeBlobStub(const CodeBlob* blob) :
1257      name(os::strdup(blob->name())),
1258      size(blob->size()),
1259      blob_type(WhiteBox::get_blob_type(blob)),
1260      address((jlong) blob) { }
1261  ~CodeBlobStub() { os::free((void*) name); }
1262  const char* const name;
1263  const jint        size;
1264  const jint        blob_type;
1265  const jlong       address;
1266};
1267
1268static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) {
1269  jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
1270  CHECK_JNI_EXCEPTION_(env, NULL);
1271  jobjectArray result = env->NewObjectArray(4, clazz, NULL);
1272
1273  jstring name = env->NewStringUTF(cb->name);
1274  CHECK_JNI_EXCEPTION_(env, NULL);
1275  env->SetObjectArrayElement(result, 0, name);
1276
1277  jobject obj = integerBox(thread, env, cb->size);
1278  CHECK_JNI_EXCEPTION_(env, NULL);
1279  env->SetObjectArrayElement(result, 1, obj);
1280
1281  obj = integerBox(thread, env, cb->blob_type);
1282  CHECK_JNI_EXCEPTION_(env, NULL);
1283  env->SetObjectArrayElement(result, 2, obj);
1284
1285  obj = longBox(thread, env, cb->address);
1286  CHECK_JNI_EXCEPTION_(env, NULL);
1287  env->SetObjectArrayElement(result, 3, obj);
1288
1289  return result;
1290}
1291
1292WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
1293  ResourceMark rm(THREAD);
1294  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1295  CHECK_JNI_EXCEPTION_(env, NULL);
1296  methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
1297  CompiledMethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code();
1298  jobjectArray result = NULL;
1299  if (code == NULL) {
1300    return result;
1301  }
1302  int comp_level = code->comp_level();
1303  int insts_size = comp_level == CompLevel_aot ? code->code_end() - code->code_begin() : code->insts_size();
1304
1305  ThreadToNativeFromVM ttn(thread);
1306  jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
1307  CHECK_JNI_EXCEPTION_(env, NULL);
1308  result = env->NewObjectArray(5, clazz, NULL);
1309  if (result == NULL) {
1310    return result;
1311  }
1312
1313  CodeBlobStub stub(code);
1314  jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub);
1315  CHECK_JNI_EXCEPTION_(env, NULL);
1316  env->SetObjectArrayElement(result, 0, codeBlob);
1317
1318  jobject level = integerBox(thread, env, comp_level);
1319  CHECK_JNI_EXCEPTION_(env, NULL);
1320  env->SetObjectArrayElement(result, 1, level);
1321
1322  jbyteArray insts = env->NewByteArray(insts_size);
1323  CHECK_JNI_EXCEPTION_(env, NULL);
1324  env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin());
1325  env->SetObjectArrayElement(result, 2, insts);
1326
1327  jobject id = integerBox(thread, env, code->compile_id());
1328  CHECK_JNI_EXCEPTION_(env, NULL);
1329  env->SetObjectArrayElement(result, 3, id);
1330
1331  jobject entry_point = longBox(thread, env, (jlong) code->entry_point());
1332  CHECK_JNI_EXCEPTION_(env, NULL);
1333  env->SetObjectArrayElement(result, 4, entry_point);
1334
1335  return result;
1336WB_END
1337
1338CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) {
1339  guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
1340  BufferBlob* blob;
1341  int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob));
1342  if (full_size < size) {
1343    full_size += round_to(size - full_size, oopSize);
1344  }
1345  {
1346    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1347    blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type);
1348    ::new (blob) BufferBlob("WB::DummyBlob", full_size);
1349  }
1350  // Track memory usage statistic after releasing CodeCache_lock
1351  MemoryService::track_code_cache_memory_usage();
1352  return blob;
1353}
1354
1355WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type))
1356  if (size < 0) {
1357    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1358      err_msg("WB_AllocateCodeBlob: size is negative: " INT32_FORMAT, size));
1359  }
1360  return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
1361WB_END
1362
1363WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr))
1364  if (addr == 0) {
1365    return;
1366  }
1367  BufferBlob::free((BufferBlob*) addr);
1368WB_END
1369
1370WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type))
1371  ResourceMark rm;
1372  GrowableArray<CodeBlobStub*> blobs;
1373  {
1374    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
1375    CodeHeap* heap = WhiteBox::get_code_heap(blob_type);
1376    if (heap == NULL) {
1377      return NULL;
1378    }
1379    for (CodeBlob* cb = (CodeBlob*) heap->first();
1380         cb != NULL; cb = (CodeBlob*) heap->next(cb)) {
1381      CodeBlobStub* stub = NEW_RESOURCE_OBJ(CodeBlobStub);
1382      new (stub) CodeBlobStub(cb);
1383      blobs.append(stub);
1384    }
1385  }
1386  if (blobs.length() == 0) {
1387    return NULL;
1388  }
1389  ThreadToNativeFromVM ttn(thread);
1390  jobjectArray result = NULL;
1391  jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
1392  CHECK_JNI_EXCEPTION_(env, NULL);
1393  result = env->NewObjectArray(blobs.length(), clazz, NULL);
1394  CHECK_JNI_EXCEPTION_(env, NULL);
1395  if (result == NULL) {
1396    return result;
1397  }
1398  int i = 0;
1399  for (GrowableArrayIterator<CodeBlobStub*> it = blobs.begin();
1400       it != blobs.end(); ++it) {
1401    jobjectArray obj = codeBlob2objectArray(thread, env, *it);
1402    CHECK_JNI_EXCEPTION_(env, NULL);
1403    env->SetObjectArrayElement(result, i, obj);
1404    CHECK_JNI_EXCEPTION_(env, NULL);
1405    ++i;
1406  }
1407  return result;
1408WB_END
1409
1410WB_ENTRY(jint, WB_GetCompilationActivityMode(JNIEnv* env, jobject o))
1411  return CompileBroker::get_compilation_activity_mode();
1412WB_END
1413
1414WB_ENTRY(jobjectArray, WB_GetCodeBlob(JNIEnv* env, jobject o, jlong addr))
1415  if (addr == 0) {
1416    THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(),
1417      "WB_GetCodeBlob: addr is null");
1418  }
1419  ThreadToNativeFromVM ttn(thread);
1420  CodeBlobStub stub((CodeBlob*) addr);
1421  return codeBlob2objectArray(thread, env, &stub);
1422WB_END
1423
1424WB_ENTRY(jlong, WB_GetMethodData(JNIEnv* env, jobject wv, jobject method))
1425  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1426  CHECK_JNI_EXCEPTION_(env, 0);
1427  methodHandle mh(thread, Method::checked_resolve_jmethod_id(jmid));
1428  return (jlong) mh->method_data();
1429WB_END
1430
1431WB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o))
1432  return (jlong) Thread::current()->stack_size();
1433WB_END
1434
1435WB_ENTRY(jlong, WB_GetThreadRemainingStackSize(JNIEnv* env, jobject o))
1436  JavaThread* t = JavaThread::current();
1437  return (jlong) t->stack_available(os::current_stack_pointer()) - (jlong)JavaThread::stack_shadow_zone_size();
1438WB_END
1439
1440
1441int WhiteBox::array_bytes_to_length(size_t bytes) {
1442  return Array<u1>::bytes_to_length(bytes);
1443}
1444
1445WB_ENTRY(jlong, WB_AllocateMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong size))
1446  if (size < 0) {
1447    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1448        err_msg("WB_AllocateMetaspace: size is negative: " JLONG_FORMAT, size));
1449  }
1450
1451  oop class_loader_oop = JNIHandles::resolve(class_loader);
1452  ClassLoaderData* cld = class_loader_oop != NULL
1453      ? java_lang_ClassLoader::loader_data(class_loader_oop)
1454      : ClassLoaderData::the_null_class_loader_data();
1455
1456  void* metadata = MetadataFactory::new_writeable_array<u1>(cld, WhiteBox::array_bytes_to_length((size_t)size), thread);
1457
1458  return (jlong)(uintptr_t)metadata;
1459WB_END
1460
1461WB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size))
1462  oop class_loader_oop = JNIHandles::resolve(class_loader);
1463  ClassLoaderData* cld = class_loader_oop != NULL
1464      ? java_lang_ClassLoader::loader_data(class_loader_oop)
1465      : ClassLoaderData::the_null_class_loader_data();
1466
1467  MetadataFactory::free_array(cld, (Array<u1>*)(uintptr_t)addr);
1468WB_END
1469
1470WB_ENTRY(void, WB_DefineModule(JNIEnv* env, jobject o, jobject module, jboolean is_open,
1471                                jstring version, jstring location, jobjectArray packages))
1472  ResourceMark rm(THREAD);
1473
1474  objArrayOop packages_oop = objArrayOop(JNIHandles::resolve(packages));
1475  objArrayHandle packages_h(THREAD, packages_oop);
1476  int num_packages = (packages_h == NULL ? 0 : packages_h->length());
1477
1478  char** pkgs = NULL;
1479  if (num_packages > 0) {
1480    pkgs = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char*, num_packages);
1481    for (int x = 0; x < num_packages; x++) {
1482      oop pkg_str = packages_h->obj_at(x);
1483      if (pkg_str == NULL || !pkg_str->is_a(SystemDictionary::String_klass())) {
1484        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
1485                  err_msg("Bad package name"));
1486      }
1487      pkgs[x] = java_lang_String::as_utf8_string(pkg_str);
1488    }
1489  }
1490  Modules::define_module(module, is_open, version, location, (const char* const*)pkgs, num_packages, CHECK);
1491WB_END
1492
1493WB_ENTRY(void, WB_AddModuleExports(JNIEnv* env, jobject o, jobject from_module, jstring package, jobject to_module))
1494  ResourceMark rm(THREAD);
1495  char* package_name = NULL;
1496  if (package != NULL) {
1497      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
1498  }
1499  Modules::add_module_exports_qualified(from_module, package_name, to_module, CHECK);
1500WB_END
1501
1502WB_ENTRY(void, WB_AddModuleExportsToAllUnnamed(JNIEnv* env, jobject o, jclass module, jstring package))
1503  ResourceMark rm(THREAD);
1504  char* package_name = NULL;
1505  if (package != NULL) {
1506      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
1507  }
1508  Modules::add_module_exports_to_all_unnamed(module, package_name, CHECK);
1509WB_END
1510
1511WB_ENTRY(void, WB_AddModuleExportsToAll(JNIEnv* env, jobject o, jclass module, jstring package))
1512  ResourceMark rm(THREAD);
1513  char* package_name = NULL;
1514  if (package != NULL) {
1515      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
1516  }
1517  Modules::add_module_exports(module, package_name, NULL, CHECK);
1518WB_END
1519
1520WB_ENTRY(void, WB_AddReadsModule(JNIEnv* env, jobject o, jobject from_module, jobject source_module))
1521  Modules::add_reads_module(from_module, source_module, CHECK);
1522WB_END
1523
1524WB_ENTRY(void, WB_AddModulePackage(JNIEnv* env, jobject o, jclass module, jstring package))
1525  ResourceMark rm(THREAD);
1526  char* package_name = NULL;
1527  if (package != NULL) {
1528      package_name = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(package));
1529  }
1530  Modules::add_module_package(module, package_name, CHECK);
1531WB_END
1532
1533WB_ENTRY(jlong, WB_IncMetaspaceCapacityUntilGC(JNIEnv* env, jobject wb, jlong inc))
1534  if (inc < 0) {
1535    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1536        err_msg("WB_IncMetaspaceCapacityUntilGC: inc is negative: " JLONG_FORMAT, inc));
1537  }
1538
1539  jlong max_size_t = (jlong) ((size_t) -1);
1540  if (inc > max_size_t) {
1541    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(),
1542        err_msg("WB_IncMetaspaceCapacityUntilGC: inc does not fit in size_t: " JLONG_FORMAT, inc));
1543  }
1544
1545  size_t new_cap_until_GC = 0;
1546  size_t aligned_inc = align_down((size_t) inc, Metaspace::commit_alignment());
1547  bool success = MetaspaceGC::inc_capacity_until_GC(aligned_inc, &new_cap_until_GC);
1548  if (!success) {
1549    THROW_MSG_0(vmSymbols::java_lang_IllegalStateException(),
1550                "WB_IncMetaspaceCapacityUntilGC: could not increase capacity until GC "
1551                "due to contention with another thread");
1552  }
1553  return (jlong) new_cap_until_GC;
1554WB_END
1555
1556WB_ENTRY(jlong, WB_MetaspaceCapacityUntilGC(JNIEnv* env, jobject wb))
1557  return (jlong) MetaspaceGC::capacity_until_GC();
1558WB_END
1559
1560WB_ENTRY(jboolean, WB_MetaspaceShouldConcurrentCollect(JNIEnv* env, jobject wb))
1561  return MetaspaceGC::should_concurrent_collect();
1562WB_END
1563
1564
1565WB_ENTRY(void, WB_AssertMatchingSafepointCalls(JNIEnv* env, jobject o, jboolean mutexSafepointValue, jboolean attemptedNoSafepointValue))
1566  Monitor::SafepointCheckRequired sfpt_check_required = mutexSafepointValue ?
1567                                           Monitor::_safepoint_check_always :
1568                                           Monitor::_safepoint_check_never;
1569  MutexLockerEx ml(new Mutex(Mutex::leaf, "SFPT_Test_lock", true, sfpt_check_required),
1570                   attemptedNoSafepointValue == JNI_TRUE);
1571WB_END
1572
1573WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj))
1574  oop obj_oop = JNIHandles::resolve(obj);
1575  return (jboolean) obj_oop->mark()->has_monitor();
1576WB_END
1577
1578WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb))
1579  VM_ForceSafepoint force_safepoint_op;
1580  VMThread::execute(&force_safepoint_op);
1581WB_END
1582
1583WB_ENTRY(jlong, WB_GetConstantPool(JNIEnv* env, jobject wb, jclass klass))
1584  InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
1585  return (jlong) ik->constants();
1586WB_END
1587
1588WB_ENTRY(jint, WB_GetConstantPoolCacheIndexTag(JNIEnv* env, jobject wb))
1589  return ConstantPool::CPCACHE_INDEX_TAG;
1590WB_END
1591
1592WB_ENTRY(jint, WB_GetConstantPoolCacheLength(JNIEnv* env, jobject wb, jclass klass))
1593  InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
1594  ConstantPool* cp = ik->constants();
1595  if (cp->cache() == NULL) {
1596      return -1;
1597  }
1598  return cp->cache()->length();
1599WB_END
1600
1601WB_ENTRY(jint, WB_ConstantPoolRemapInstructionOperandFromCache(JNIEnv* env, jobject wb, jclass klass, jint index))
1602  InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass)));
1603  ConstantPool* cp = ik->constants();
1604  if (cp->cache() == NULL) {
1605    THROW_MSG_0(vmSymbols::java_lang_IllegalStateException(), "Constant pool does not have a cache");
1606  }
1607  jint cpci = index;
1608  jint cpciTag = ConstantPool::CPCACHE_INDEX_TAG;
1609  if (cpciTag > cpci || cpci >= cp->cache()->length() + cpciTag) {
1610    THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), "Constant pool cache index is out of range");
1611  }
1612  jint cpi = cp->remap_instruction_operand_from_cache(cpci);
1613  return cpi;
1614WB_END
1615
1616WB_ENTRY(jint, WB_ConstantPoolEncodeIndyIndex(JNIEnv* env, jobject wb, jint index))
1617  return ConstantPool::encode_invokedynamic_index(index);
1618WB_END
1619
1620WB_ENTRY(void, WB_ClearInlineCaches(JNIEnv* env, jobject wb, jboolean preserve_static_stubs))
1621  VM_ClearICs clear_ics(preserve_static_stubs == JNI_TRUE);
1622  VMThread::execute(&clear_ics);
1623WB_END
1624
1625template <typename T>
1626static bool GetMethodOption(JavaThread* thread, JNIEnv* env, jobject method, jstring name, T* value) {
1627  assert(value != NULL, "sanity");
1628  if (method == NULL || name == NULL) {
1629    return false;
1630  }
1631  jmethodID jmid = reflected_method_to_jmid(thread, env, method);
1632  CHECK_JNI_EXCEPTION_(env, false);
1633  methodHandle mh(thread, Method::checked_resolve_jmethod_id(jmid));
1634  // can't be in VM when we call JNI
1635  ThreadToNativeFromVM ttnfv(thread);
1636  const char* flag_name = env->GetStringUTFChars(name, NULL);
1637  CHECK_JNI_EXCEPTION_(env, false);
1638  bool result =  CompilerOracle::has_option_value(mh, flag_name, *value);
1639  env->ReleaseStringUTFChars(name, flag_name);
1640  return result;
1641}
1642
1643WB_ENTRY(jobject, WB_GetMethodBooleaneOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1644  bool result;
1645  if (GetMethodOption<bool> (thread, env, method, name, &result)) {
1646    // can't be in VM when we call JNI
1647    ThreadToNativeFromVM ttnfv(thread);
1648    return booleanBox(thread, env, result);
1649  }
1650  return NULL;
1651WB_END
1652
1653WB_ENTRY(jobject, WB_GetMethodIntxOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1654  intx result;
1655  if (GetMethodOption <intx> (thread, env, method, name, &result)) {
1656    // can't be in VM when we call JNI
1657    ThreadToNativeFromVM ttnfv(thread);
1658    return longBox(thread, env, result);
1659  }
1660  return NULL;
1661WB_END
1662
1663WB_ENTRY(jobject, WB_GetMethodUintxOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1664  uintx result;
1665  if (GetMethodOption <uintx> (thread, env, method, name, &result)) {
1666    // can't be in VM when we call JNI
1667    ThreadToNativeFromVM ttnfv(thread);
1668    return longBox(thread, env, result);
1669  }
1670  return NULL;
1671WB_END
1672
1673WB_ENTRY(jobject, WB_GetMethodDoubleOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1674  double result;
1675  if (GetMethodOption <double> (thread, env, method, name, &result)) {
1676    // can't be in VM when we call JNI
1677    ThreadToNativeFromVM ttnfv(thread);
1678    return doubleBox(thread, env, result);
1679  }
1680  return NULL;
1681WB_END
1682
1683WB_ENTRY(jobject, WB_GetMethodStringOption(JNIEnv* env, jobject wb, jobject method, jstring name))
1684  ccstr ccstrResult;
1685  if (GetMethodOption <ccstr> (thread, env, method, name, &ccstrResult)) {
1686    // can't be in VM when we call JNI
1687    ThreadToNativeFromVM ttnfv(thread);
1688    jstring result = env->NewStringUTF(ccstrResult);
1689    CHECK_JNI_EXCEPTION_(env, NULL);
1690    return result;
1691  }
1692  return NULL;
1693WB_END
1694
1695WB_ENTRY(jboolean, WB_IsShared(JNIEnv* env, jobject wb, jobject obj))
1696  oop obj_oop = JNIHandles::resolve(obj);
1697  return MetaspaceShared::is_in_shared_space((void*)obj_oop);
1698WB_END
1699
1700WB_ENTRY(jboolean, WB_IsSharedClass(JNIEnv* env, jobject wb, jclass clazz))
1701  return (jboolean)MetaspaceShared::is_in_shared_space(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz)));
1702WB_END
1703
1704WB_ENTRY(jboolean, WB_AreSharedStringsIgnored(JNIEnv* env))
1705  return StringTable::shared_string_ignored();
1706WB_END
1707
1708//Some convenience methods to deal with objects from java
1709int WhiteBox::offset_for_field(const char* field_name, oop object,
1710    Symbol* signature_symbol) {
1711  assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid");
1712  Thread* THREAD = Thread::current();
1713
1714  //Get the class of our object
1715  Klass* arg_klass = object->klass();
1716  //Turn it into an instance-klass
1717  InstanceKlass* ik = InstanceKlass::cast(arg_klass);
1718
1719  //Create symbols to look for in the class
1720  TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name),
1721      THREAD);
1722
1723  //To be filled in with an offset of the field we're looking for
1724  fieldDescriptor fd;
1725
1726  Klass* res = ik->find_field(name_symbol, signature_symbol, &fd);
1727  if (res == NULL) {
1728    tty->print_cr("Invalid layout of %s at %s", ik->external_name(),
1729        name_symbol->as_C_string());
1730    vm_exit_during_initialization("Invalid layout of preloaded class: use -Xlog:class+load=info to see the origin of the problem class");
1731  }
1732
1733  //fetch the field at the offset we've found
1734  int dest_offset = fd.offset();
1735
1736  return dest_offset;
1737}
1738
1739
1740const char* WhiteBox::lookup_jstring(const char* field_name, oop object) {
1741  int offset = offset_for_field(field_name, object,
1742      vmSymbols::string_signature());
1743  oop string = object->obj_field(offset);
1744  if (string == NULL) {
1745    return NULL;
1746  }
1747  const char* ret = java_lang_String::as_utf8_string(string);
1748  return ret;
1749}
1750
1751bool WhiteBox::lookup_bool(const char* field_name, oop object) {
1752  int offset =
1753      offset_for_field(field_name, object, vmSymbols::bool_signature());
1754  bool ret = (object->bool_field(offset) == JNI_TRUE);
1755  return ret;
1756}
1757
1758void WhiteBox::register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count) {
1759  ResourceMark rm;
1760  ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
1761
1762  //  one by one registration natives for exception catching
1763  jclass no_such_method_error_klass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string());
1764  CHECK_JNI_EXCEPTION(env);
1765  for (int i = 0, n = method_count; i < n; ++i) {
1766    // Skip dummy entries
1767    if (method_array[i].fnPtr == NULL) continue;
1768    if (env->RegisterNatives(wbclass, &method_array[i], 1) != 0) {
1769      jthrowable throwable_obj = env->ExceptionOccurred();
1770      if (throwable_obj != NULL) {
1771        env->ExceptionClear();
1772        if (env->IsInstanceOf(throwable_obj, no_such_method_error_klass)) {
1773          // NoSuchMethodError is thrown when a method can't be found or a method is not native.
1774          // Ignoring the exception since it is not preventing use of other WhiteBox methods.
1775          tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s",
1776              method_array[i].name, method_array[i].signature);
1777        }
1778      } else {
1779        // Registration failed unexpectedly.
1780        tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered",
1781            method_array[i].name, method_array[i].signature);
1782        env->UnregisterNatives(wbclass);
1783        break;
1784      }
1785    }
1786  }
1787}
1788
1789WB_ENTRY(jint, WB_AddCompilerDirective(JNIEnv* env, jobject o, jstring compDirect))
1790  // can't be in VM when we call JNI
1791  ThreadToNativeFromVM ttnfv(thread);
1792  const char* dir = env->GetStringUTFChars(compDirect, NULL);
1793  CHECK_JNI_EXCEPTION_(env, 0);
1794  int ret;
1795  {
1796    ThreadInVMfromNative ttvfn(thread); // back to VM
1797    ret = DirectivesParser::parse_string(dir, tty);
1798  }
1799  env->ReleaseStringUTFChars(compDirect, dir);
1800  // -1 for error parsing directive. Return 0 as number of directives added.
1801  if (ret == -1) {
1802    ret = 0;
1803  }
1804  return (jint) ret;
1805WB_END
1806
1807WB_ENTRY(void, WB_RemoveCompilerDirective(JNIEnv* env, jobject o, jint count))
1808  DirectivesStack::pop(count);
1809WB_END
1810
1811#define CC (char*)
1812
1813static JNINativeMethod methods[] = {
1814  {CC"getObjectAddress0",                CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress  },
1815  {CC"getObjectSize0",                   CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize     },
1816  {CC"isObjectInOldGen0",                CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen  },
1817  {CC"getHeapOopSize",                   CC"()I",                   (void*)&WB_GetHeapOopSize    },
1818  {CC"getVMPageSize",                    CC"()I",                   (void*)&WB_GetVMPageSize     },
1819  {CC"getVMAllocationGranularity",       CC"()J",                   (void*)&WB_GetVMAllocationGranularity },
1820  {CC"getVMLargePageSize",               CC"()J",                   (void*)&WB_GetVMLargePageSize},
1821  {CC"getHeapSpaceAlignment",            CC"()J",                   (void*)&WB_GetHeapSpaceAlignment},
1822  {CC"getHeapAlignment",                 CC"()J",                   (void*)&WB_GetHeapAlignment},
1823  {CC"isClassAlive0",                    CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive      },
1824  {CC"parseCommandLine0",
1825      CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
1826      (void*) &WB_ParseCommandLine
1827  },
1828  {CC"addToBootstrapClassLoaderSearch0", CC"(Ljava/lang/String;)V",
1829                                                      (void*)&WB_AddToBootstrapClassLoaderSearch},
1830  {CC"addToSystemClassLoaderSearch0",    CC"(Ljava/lang/String;)V",
1831                                                      (void*)&WB_AddToSystemClassLoaderSearch},
1832  {CC"getCompressedOopsMaxHeapSize", CC"()J",
1833      (void*)&WB_GetCompressedOopsMaxHeapSize},
1834  {CC"printHeapSizes",     CC"()V",                   (void*)&WB_PrintHeapSizes    },
1835  {CC"runMemoryUnitTests", CC"()V",                   (void*)&WB_RunMemoryUnitTests},
1836  {CC"readFromNoaccessArea",CC"()V",                  (void*)&WB_ReadFromNoaccessArea},
1837  {CC"stressVirtualSpaceResize",CC"(JJJ)I",           (void*)&WB_StressVirtualSpaceResize},
1838#if INCLUDE_ALL_GCS
1839  {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
1840  {CC"g1IsHumongous0",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
1841  {CC"g1BelongsToHumongousRegion0", CC"(J)Z",         (void*)&WB_G1BelongsToHumongousRegion},
1842  {CC"g1BelongsToFreeRegion0", CC"(J)Z",              (void*)&WB_G1BelongsToFreeRegion},
1843  {CC"g1NumMaxRegions",    CC"()J",                   (void*)&WB_G1NumMaxRegions  },
1844  {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
1845  {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
1846  {CC"g1StartConcMarkCycle",       CC"()Z",           (void*)&WB_G1StartMarkCycle  },
1847  {CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;",
1848                                                      (void*)&WB_G1AuxiliaryMemoryUsage  },
1849  {CC"psVirtualSpaceAlignment",CC"()J",               (void*)&WB_PSVirtualSpaceAlignment},
1850  {CC"psHeapGenerationAlignment",CC"()J",             (void*)&WB_PSHeapGenerationAlignment},
1851  {CC"g1GetMixedGCInfo",   CC"(I)[J",                 (void*)&WB_G1GetMixedGCInfo },
1852#endif // INCLUDE_ALL_GCS
1853#if INCLUDE_NMT
1854  {CC"NMTMalloc",           CC"(J)J",                 (void*)&WB_NMTMalloc          },
1855  {CC"NMTMallocWithPseudoStack", CC"(JI)J",           (void*)&WB_NMTMallocWithPseudoStack},
1856  {CC"NMTFree",             CC"(J)V",                 (void*)&WB_NMTFree            },
1857  {CC"NMTReserveMemory",    CC"(J)J",                 (void*)&WB_NMTReserveMemory   },
1858  {CC"NMTCommitMemory",     CC"(JJ)V",                (void*)&WB_NMTCommitMemory    },
1859  {CC"NMTUncommitMemory",   CC"(JJ)V",                (void*)&WB_NMTUncommitMemory  },
1860  {CC"NMTReleaseMemory",    CC"(JJ)V",                (void*)&WB_NMTReleaseMemory   },
1861  {CC"NMTChangeTrackingLevel", CC"()Z",               (void*)&WB_NMTChangeTrackingLevel},
1862  {CC"NMTGetHashSize",      CC"()I",                  (void*)&WB_NMTGetHashSize     },
1863#endif // INCLUDE_NMT
1864  {CC"deoptimizeFrames",   CC"(Z)I",                  (void*)&WB_DeoptimizeFrames  },
1865  {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
1866  {CC"deoptimizeMethod0",   CC"(Ljava/lang/reflect/Executable;Z)I",
1867                                                      (void*)&WB_DeoptimizeMethod  },
1868  {CC"isMethodCompiled0",   CC"(Ljava/lang/reflect/Executable;Z)Z",
1869                                                      (void*)&WB_IsMethodCompiled  },
1870  {CC"isMethodCompilable0", CC"(Ljava/lang/reflect/Executable;IZ)Z",
1871                                                      (void*)&WB_IsMethodCompilable},
1872  {CC"isMethodQueuedForCompilation0",
1873      CC"(Ljava/lang/reflect/Executable;)Z",          (void*)&WB_IsMethodQueuedForCompilation},
1874  {CC"isIntrinsicAvailable0",
1875      CC"(Ljava/lang/reflect/Executable;Ljava/lang/reflect/Executable;I)Z",
1876                                                      (void*)&WB_IsIntrinsicAvailable},
1877  {CC"makeMethodNotCompilable0",
1878      CC"(Ljava/lang/reflect/Executable;IZ)V",        (void*)&WB_MakeMethodNotCompilable},
1879  {CC"testSetDontInlineMethod0",
1880      CC"(Ljava/lang/reflect/Executable;Z)Z",         (void*)&WB_TestSetDontInlineMethod},
1881  {CC"getMethodCompilationLevel0",
1882      CC"(Ljava/lang/reflect/Executable;Z)I",         (void*)&WB_GetMethodCompilationLevel},
1883  {CC"getMethodEntryBci0",
1884      CC"(Ljava/lang/reflect/Executable;)I",          (void*)&WB_GetMethodEntryBci},
1885  {CC"getCompileQueueSize",
1886      CC"(I)I",                                       (void*)&WB_GetCompileQueueSize},
1887  {CC"testSetForceInlineMethod0",
1888      CC"(Ljava/lang/reflect/Executable;Z)Z",         (void*)&WB_TestSetForceInlineMethod},
1889  {CC"enqueueMethodForCompilation0",
1890      CC"(Ljava/lang/reflect/Executable;II)Z",        (void*)&WB_EnqueueMethodForCompilation},
1891  {CC"enqueueInitializerForCompilation0",
1892      CC"(Ljava/lang/Class;I)Z",                      (void*)&WB_EnqueueInitializerForCompilation},
1893  {CC"clearMethodState0",
1894      CC"(Ljava/lang/reflect/Executable;)V",          (void*)&WB_ClearMethodState},
1895  {CC"lockCompilation",    CC"()V",                   (void*)&WB_LockCompilation},
1896  {CC"unlockCompilation",  CC"()V",                   (void*)&WB_UnlockCompilation},
1897  {CC"matchesMethod",
1898      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)I",
1899                                                      (void*)&WB_MatchesMethod},
1900  {CC"matchesInline",
1901      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)I",
1902                                                      (void*)&WB_MatchesInline},
1903  {CC"shouldPrintAssembly",
1904        CC"(Ljava/lang/reflect/Executable;I)Z",
1905                                                        (void*)&WB_ShouldPrintAssembly},
1906
1907  {CC"isConstantVMFlag",   CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag},
1908  {CC"isLockedVMFlag",     CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag},
1909  {CC"setBooleanVMFlag",   CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
1910  {CC"setIntVMFlag",       CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntVMFlag},
1911  {CC"setUintVMFlag",      CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintVMFlag},
1912  {CC"setIntxVMFlag",      CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag},
1913  {CC"setUintxVMFlag",     CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag},
1914  {CC"setUint64VMFlag",    CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag},
1915  {CC"setSizeTVMFlag",     CC"(Ljava/lang/String;J)V",(void*)&WB_SetSizeTVMFlag},
1916  {CC"setDoubleVMFlag",    CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag},
1917  {CC"setStringVMFlag",    CC"(Ljava/lang/String;Ljava/lang/String;)V",
1918                                                      (void*)&WB_SetStringVMFlag},
1919  {CC"getBooleanVMFlag",   CC"(Ljava/lang/String;)Ljava/lang/Boolean;",
1920                                                      (void*)&WB_GetBooleanVMFlag},
1921  {CC"getIntVMFlag",       CC"(Ljava/lang/String;)Ljava/lang/Long;",
1922                                                      (void*)&WB_GetIntVMFlag},
1923  {CC"getUintVMFlag",      CC"(Ljava/lang/String;)Ljava/lang/Long;",
1924                                                      (void*)&WB_GetUintVMFlag},
1925  {CC"getIntxVMFlag",      CC"(Ljava/lang/String;)Ljava/lang/Long;",
1926                                                      (void*)&WB_GetIntxVMFlag},
1927  {CC"getUintxVMFlag",     CC"(Ljava/lang/String;)Ljava/lang/Long;",
1928                                                      (void*)&WB_GetUintxVMFlag},
1929  {CC"getUint64VMFlag",    CC"(Ljava/lang/String;)Ljava/lang/Long;",
1930                                                      (void*)&WB_GetUint64VMFlag},
1931  {CC"getSizeTVMFlag",     CC"(Ljava/lang/String;)Ljava/lang/Long;",
1932                                                      (void*)&WB_GetSizeTVMFlag},
1933  {CC"getDoubleVMFlag",    CC"(Ljava/lang/String;)Ljava/lang/Double;",
1934                                                      (void*)&WB_GetDoubleVMFlag},
1935  {CC"getStringVMFlag",    CC"(Ljava/lang/String;)Ljava/lang/String;",
1936                                                      (void*)&WB_GetStringVMFlag},
1937  {CC"isInStringTable",    CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable  },
1938  {CC"fullGC",   CC"()V",                             (void*)&WB_FullGC },
1939  {CC"youngGC",  CC"()V",                             (void*)&WB_YoungGC },
1940  {CC"readReservedMemory", CC"()V",                   (void*)&WB_ReadReservedMemory },
1941  {CC"allocateMetaspace",
1942     CC"(Ljava/lang/ClassLoader;J)J",                 (void*)&WB_AllocateMetaspace },
1943  {CC"freeMetaspace",
1944     CC"(Ljava/lang/ClassLoader;JJ)V",                (void*)&WB_FreeMetaspace },
1945  {CC"incMetaspaceCapacityUntilGC", CC"(J)J",         (void*)&WB_IncMetaspaceCapacityUntilGC },
1946  {CC"metaspaceCapacityUntilGC", CC"()J",             (void*)&WB_MetaspaceCapacityUntilGC },
1947  {CC"metaspaceShouldConcurrentCollect", CC"()Z",     (void*)&WB_MetaspaceShouldConcurrentCollect },
1948  {CC"getCPUFeatures",     CC"()Ljava/lang/String;",  (void*)&WB_GetCPUFeatures     },
1949  {CC"getNMethod0",         CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
1950                                                      (void*)&WB_GetNMethod         },
1951  {CC"forceNMethodSweep",  CC"()V",                   (void*)&WB_ForceNMethodSweep  },
1952  {CC"allocateCodeBlob",   CC"(II)J",                 (void*)&WB_AllocateCodeBlob   },
1953  {CC"freeCodeBlob",       CC"(J)V",                  (void*)&WB_FreeCodeBlob       },
1954  {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
1955  {CC"getCompilationActivityMode",
1956                           CC"()I",                   (void*)&WB_GetCompilationActivityMode},
1957  {CC"getMethodData0",     CC"(Ljava/lang/reflect/Executable;)J",
1958                                                      (void*)&WB_GetMethodData      },
1959  {CC"getCodeBlob",        CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob        },
1960  {CC"getThreadStackSize", CC"()J",                   (void*)&WB_GetThreadStackSize },
1961  {CC"getThreadRemainingStackSize", CC"()J",          (void*)&WB_GetThreadRemainingStackSize },
1962  {CC"DefineModule",       CC"(Ljava/lang/Object;ZLjava/lang/String;Ljava/lang/String;[Ljava/lang/Object;)V",
1963                                                      (void*)&WB_DefineModule },
1964  {CC"AddModuleExports",   CC"(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/Object;)V",
1965                                                      (void*)&WB_AddModuleExports },
1966  {CC"AddReadsModule",     CC"(Ljava/lang/Object;Ljava/lang/Object;)V",
1967                                                      (void*)&WB_AddReadsModule },
1968  {CC"AddModulePackage",   CC"(Ljava/lang/Object;Ljava/lang/String;)V",
1969                                                      (void*)&WB_AddModulePackage },
1970  {CC"AddModuleExportsToAllUnnamed", CC"(Ljava/lang/Object;Ljava/lang/String;)V",
1971                                                      (void*)&WB_AddModuleExportsToAllUnnamed },
1972  {CC"AddModuleExportsToAll", CC"(Ljava/lang/Object;Ljava/lang/String;)V",
1973                                                      (void*)&WB_AddModuleExportsToAll },
1974  {CC"assertMatchingSafepointCalls", CC"(ZZ)V",       (void*)&WB_AssertMatchingSafepointCalls },
1975  {CC"isMonitorInflated0", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated  },
1976  {CC"forceSafepoint",     CC"()V",                   (void*)&WB_ForceSafepoint     },
1977  {CC"getConstantPool0",   CC"(Ljava/lang/Class;)J",  (void*)&WB_GetConstantPool    },
1978  {CC"getConstantPoolCacheIndexTag0", CC"()I",  (void*)&WB_GetConstantPoolCacheIndexTag},
1979  {CC"getConstantPoolCacheLength0", CC"(Ljava/lang/Class;)I",  (void*)&WB_GetConstantPoolCacheLength},
1980  {CC"remapInstructionOperandFromCPCache0",
1981      CC"(Ljava/lang/Class;I)I",                      (void*)&WB_ConstantPoolRemapInstructionOperandFromCache},
1982  {CC"encodeConstantPoolIndyIndex0",
1983      CC"(I)I",                      (void*)&WB_ConstantPoolEncodeIndyIndex},
1984  {CC"getMethodBooleanOption",
1985      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Boolean;",
1986                                                      (void*)&WB_GetMethodBooleaneOption},
1987  {CC"getMethodIntxOption",
1988      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Long;",
1989                                                      (void*)&WB_GetMethodIntxOption},
1990  {CC"getMethodUintxOption",
1991      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Long;",
1992                                                      (void*)&WB_GetMethodUintxOption},
1993  {CC"getMethodDoubleOption",
1994      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/Double;",
1995                                                      (void*)&WB_GetMethodDoubleOption},
1996  {CC"getMethodStringOption",
1997      CC"(Ljava/lang/reflect/Executable;Ljava/lang/String;)Ljava/lang/String;",
1998                                                      (void*)&WB_GetMethodStringOption},
1999  {CC"isShared",           CC"(Ljava/lang/Object;)Z", (void*)&WB_IsShared },
2000  {CC"isSharedClass",      CC"(Ljava/lang/Class;)Z",  (void*)&WB_IsSharedClass },
2001  {CC"areSharedStringsIgnored",           CC"()Z",    (void*)&WB_AreSharedStringsIgnored },
2002  {CC"clearInlineCaches0",  CC"(Z)V",                 (void*)&WB_ClearInlineCaches },
2003  {CC"addCompilerDirective",    CC"(Ljava/lang/String;)I",
2004                                                      (void*)&WB_AddCompilerDirective },
2005  {CC"removeCompilerDirective",   CC"(I)V",             (void*)&WB_RemoveCompilerDirective },
2006  {CC"currentGC",                 CC"()I",            (void*)&WB_CurrentGC},
2007  {CC"allSupportedGC",            CC"()I",            (void*)&WB_AllSupportedGC},
2008  {CC"gcSelectedByErgo",          CC"()Z",            (void*)&WB_GCSelectedByErgo},
2009  {CC"supportsConcurrentGCPhaseControl", CC"()Z",     (void*)&WB_SupportsConcurrentGCPhaseControl},
2010  {CC"getConcurrentGCPhases",     CC"()[Ljava/lang/String;",
2011                                                      (void*)&WB_GetConcurrentGCPhases},
2012  {CC"requestConcurrentGCPhase0", CC"(Ljava/lang/String;)Z",
2013                                                      (void*)&WB_RequestConcurrentGCPhase},
2014};
2015
2016#undef CC
2017
2018JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
2019  {
2020    if (WhiteBoxAPI) {
2021      // Make sure that wbclass is loaded by the null classloader
2022      InstanceKlass* ik = InstanceKlass::cast(JNIHandles::resolve(wbclass)->klass());
2023      Handle loader(THREAD, ik->class_loader());
2024      if (loader.is_null()) {
2025        WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0]));
2026        WhiteBox::register_extended(env, wbclass, thread);
2027        WhiteBox::set_used();
2028      }
2029    }
2030  }
2031JVM_END
2032