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