whitebox.cpp revision 7462:a0dd995271c4
1216295Ssyrinx/* 2216295Ssyrinx * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. 3216295Ssyrinx * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4216295Ssyrinx * 5216295Ssyrinx * This code is free software; you can redistribute it and/or modify it 6216295Ssyrinx * under the terms of the GNU General Public License version 2 only, as 7216295Ssyrinx * published by the Free Software Foundation. 8216295Ssyrinx * 9216295Ssyrinx * This code is distributed in the hope that it will be useful, but WITHOUT 10216295Ssyrinx * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11216295Ssyrinx * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12216295Ssyrinx * version 2 for more details (a copy is included in the LICENSE file that 13216295Ssyrinx * accompanied this code). 14216295Ssyrinx * 15216295Ssyrinx * You should have received a copy of the GNU General Public License version 16216295Ssyrinx * 2 along with this work; if not, write to the Free Software Foundation, 17216295Ssyrinx * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18216295Ssyrinx * 19216295Ssyrinx * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20216295Ssyrinx * or visit www.oracle.com if you need additional information or have any 21216295Ssyrinx * questions. 22216295Ssyrinx * 23216295Ssyrinx */ 24216295Ssyrinx 25216295Ssyrinx#include "precompiled.hpp" 26216295Ssyrinx 27216295Ssyrinx#include <new> 28216295Ssyrinx 29216295Ssyrinx#include "code/codeCache.hpp" 30216295Ssyrinx#include "memory/metadataFactory.hpp" 31216295Ssyrinx#include "memory/universe.hpp" 32216295Ssyrinx#include "oops/oop.inline.hpp" 33216295Ssyrinx 34216295Ssyrinx#include "classfile/stringTable.hpp" 35216295Ssyrinx#include "classfile/classLoaderData.hpp" 36216295Ssyrinx 37216295Ssyrinx#include "prims/whitebox.hpp" 38216295Ssyrinx#include "prims/wbtestmethods/parserTests.hpp" 39216295Ssyrinx 40216295Ssyrinx#include "runtime/thread.hpp" 41216295Ssyrinx#include "runtime/arguments.hpp" 42216295Ssyrinx#include "runtime/deoptimization.hpp" 43216295Ssyrinx#include "runtime/interfaceSupport.hpp" 44216295Ssyrinx#include "runtime/os.hpp" 45216295Ssyrinx#include "runtime/vm_version.hpp" 46216295Ssyrinx#include "runtime/sweeper.hpp" 47216295Ssyrinx 48216295Ssyrinx#include "utilities/array.hpp" 49216295Ssyrinx#include "utilities/debug.hpp" 50216295Ssyrinx#include "utilities/macros.hpp" 51216295Ssyrinx#include "utilities/exceptions.hpp" 52216295Ssyrinx 53216295Ssyrinx#if INCLUDE_ALL_GCS 54216295Ssyrinx#include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" 55216295Ssyrinx#include "gc_implementation/g1/concurrentMark.hpp" 56216295Ssyrinx#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 57216295Ssyrinx#include "gc_implementation/g1/heapRegionRemSet.hpp" 58216295Ssyrinx#endif // INCLUDE_ALL_GCS 59216295Ssyrinx 60216295Ssyrinx#if INCLUDE_NMT 61216295Ssyrinx#include "services/mallocSiteTable.hpp" 62216295Ssyrinx#include "services/memTracker.hpp" 63216295Ssyrinx#include "utilities/nativeCallStack.hpp" 64216295Ssyrinx#endif // INCLUDE_NMT 65216295Ssyrinx 66216295Ssyrinx#include "compiler/compileBroker.hpp" 67216295Ssyrinx#include "jvmtifiles/jvmtiEnv.hpp" 68216295Ssyrinx#include "runtime/compilationPolicy.hpp" 69216295Ssyrinx 70216295SsyrinxPRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC 71216295Ssyrinx 72216295Ssyrinx#define SIZE_T_MAX_VALUE ((size_t) -1) 73216295Ssyrinx 74216295Ssyrinxbool WhiteBox::_used = false; 75216295Ssyrinxvolatile bool WhiteBox::compilation_locked = false; 76216295Ssyrinx 77216295SsyrinxWB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj)) 78216295Ssyrinx return (jlong)(void*)JNIHandles::resolve(obj); 79216295SsyrinxWB_END 80216295Ssyrinx 81216295SsyrinxWB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o)) 82216295Ssyrinx return heapOopSize; 83216295SsyrinxWB_END 84216295Ssyrinx 85216295SsyrinxWB_ENTRY(jint, WB_GetVMPageSize(JNIEnv* env, jobject o)) 86216295Ssyrinx return os::vm_page_size(); 87216295SsyrinxWB_END 88216295Ssyrinx 89216295Ssyrinxclass WBIsKlassAliveClosure : public KlassClosure { 90228990Suqs Symbol* _name; 91216295Ssyrinx bool _found; 92216295Ssyrinxpublic: 93216295Ssyrinx WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {} 94216295Ssyrinx 95216295Ssyrinx void do_klass(Klass* k) { 96216295Ssyrinx if (_found) return; 97216295Ssyrinx Symbol* ksym = k->name(); 98216295Ssyrinx if (ksym->fast_compare(_name) == 0) { 99216295Ssyrinx _found = true; 100216295Ssyrinx } 101216295Ssyrinx } 102216295Ssyrinx 103216295Ssyrinx bool found() const { 104216295Ssyrinx return _found; 105216295Ssyrinx } 106216295Ssyrinx}; 107216295Ssyrinx 108216295SsyrinxWB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name)) 109216295Ssyrinx Handle h_name = JNIHandles::resolve(name); 110216295Ssyrinx if (h_name.is_null()) return false; 111216295Ssyrinx Symbol* sym = java_lang_String::as_symbol(h_name, CHECK_false); 112216295Ssyrinx TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return 113216295Ssyrinx 114216295Ssyrinx WBIsKlassAliveClosure closure(sym); 115216295Ssyrinx ClassLoaderDataGraph::classes_do(&closure); 116216295Ssyrinx 117216295Ssyrinx return closure.found(); 118216295SsyrinxWB_END 119216295Ssyrinx 120216295SsyrinxWB_ENTRY(void, WB_AddToBootstrapClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) { 121216295Ssyrinx#if INCLUDE_JVMTI 122216295Ssyrinx ResourceMark rm; 123216295Ssyrinx const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment)); 124216295Ssyrinx JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION); 125216295Ssyrinx jvmtiError err = jvmti_env->AddToBootstrapClassLoaderSearch(seg); 126216295Ssyrinx assert(err == JVMTI_ERROR_NONE, "must not fail"); 127216295Ssyrinx#endif 128216295Ssyrinx} 129216295SsyrinxWB_END 130216295Ssyrinx 131216295SsyrinxWB_ENTRY(void, WB_AddToSystemClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) { 132216295Ssyrinx#if INCLUDE_JVMTI 133216295Ssyrinx ResourceMark rm; 134216295Ssyrinx const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment)); 135229933Ssyrinx JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION); 136216295Ssyrinx jvmtiError err = jvmti_env->AddToSystemClassLoaderSearch(seg); 137216295Ssyrinx assert(err == JVMTI_ERROR_NONE, "must not fail"); 138216295Ssyrinx#endif 139216295Ssyrinx} 140216295SsyrinxWB_END 141216295Ssyrinx 142216295Ssyrinx 143216295SsyrinxWB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { 144216295Ssyrinx return (jlong)Arguments::max_heap_for_compressed_oops(); 145216295Ssyrinx} 146216295SsyrinxWB_END 147216295Ssyrinx 148216295SsyrinxWB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) { 149216295Ssyrinx CollectorPolicy * p = Universe::heap()->collector_policy(); 150216295Ssyrinx gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap " 151216295Ssyrinx SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Space alignment "SIZE_FORMAT" Heap alignment "SIZE_FORMAT, 152216295Ssyrinx p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(), 153216295Ssyrinx p->space_alignment(), p->heap_alignment()); 154216295Ssyrinx} 155216295SsyrinxWB_END 156216295Ssyrinx 157216295Ssyrinx#ifndef PRODUCT 158216295Ssyrinx// Forward declaration 159216295Ssyrinxvoid TestReservedSpace_test(); 160216295Ssyrinxvoid TestReserveMemorySpecial_test(); 161216295Ssyrinxvoid TestVirtualSpace_test(); 162216295Ssyrinxvoid TestMetaspaceAux_test(); 163216295Ssyrinx#endif 164216295Ssyrinx 165216295SsyrinxWB_ENTRY(void, WB_RunMemoryUnitTests(JNIEnv* env, jobject o)) 166216295Ssyrinx#ifndef PRODUCT 167216295Ssyrinx TestReservedSpace_test(); 168216295Ssyrinx TestReserveMemorySpecial_test(); 169216295Ssyrinx TestVirtualSpace_test(); 170216295Ssyrinx TestMetaspaceAux_test(); 171216295Ssyrinx#endif 172216295SsyrinxWB_END 173216295Ssyrinx 174216295SsyrinxWB_ENTRY(void, WB_ReadFromNoaccessArea(JNIEnv* env, jobject o)) 175216295Ssyrinx size_t granularity = os::vm_allocation_granularity(); 176216295Ssyrinx ReservedHeapSpace rhs(100 * granularity, granularity, false, NULL); 177216295Ssyrinx VirtualSpace vs; 178216295Ssyrinx vs.initialize(rhs, 50 * granularity); 179216295Ssyrinx 180216295Ssyrinx //Check if constraints are complied 181216295Ssyrinx if (!( UseCompressedOops && rhs.base() != NULL && 182216295Ssyrinx Universe::narrow_oop_base() != NULL && 183216295Ssyrinx Universe::narrow_oop_use_implicit_null_checks() )) { 184216295Ssyrinx tty->print_cr("WB_ReadFromNoaccessArea method is useless:\n " 185216295Ssyrinx "\tUseCompressedOops is %d\n" 186216295Ssyrinx "\trhs.base() is "PTR_FORMAT"\n" 187216295Ssyrinx "\tUniverse::narrow_oop_base() is "PTR_FORMAT"\n" 188216295Ssyrinx "\tUniverse::narrow_oop_use_implicit_null_checks() is %d", 189216295Ssyrinx UseCompressedOops, 190216295Ssyrinx rhs.base(), 191216295Ssyrinx Universe::narrow_oop_base(), 192216295Ssyrinx Universe::narrow_oop_use_implicit_null_checks()); 193216295Ssyrinx return; 194216295Ssyrinx } 195216295Ssyrinx tty->print_cr("Reading from no access area... "); 196216295Ssyrinx tty->print_cr("*(vs.low_boundary() - rhs.noaccess_prefix() / 2 ) = %c", 197216295Ssyrinx *(vs.low_boundary() - rhs.noaccess_prefix() / 2 )); 198216295SsyrinxWB_END 199216295Ssyrinx 200216295Ssyrinxstatic jint wb_stress_virtual_space_resize(size_t reserved_space_size, 201216295Ssyrinx size_t magnitude, size_t iterations) { 202216295Ssyrinx size_t granularity = os::vm_allocation_granularity(); 203216295Ssyrinx ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false, NULL); 204216295Ssyrinx VirtualSpace vs; 205216295Ssyrinx if (!vs.initialize(rhs, 0)) { 206216295Ssyrinx tty->print_cr("Failed to initialize VirtualSpace. Can't proceed."); 207216295Ssyrinx return 3; 208216295Ssyrinx } 209216295Ssyrinx 210216295Ssyrinx long seed = os::random(); 211216295Ssyrinx tty->print_cr("Random seed is %ld", seed); 212216295Ssyrinx os::init_random(seed); 213216295Ssyrinx 214216295Ssyrinx for (size_t i = 0; i < iterations; i++) { 215216295Ssyrinx 216216295Ssyrinx // Whether we will shrink or grow 217216295Ssyrinx bool shrink = os::random() % 2L == 0; 218216295Ssyrinx 219216295Ssyrinx // Get random delta to resize virtual space 220216295Ssyrinx size_t delta = (size_t)os::random() % magnitude; 221216295Ssyrinx 222216295Ssyrinx // If we are about to shrink virtual space below zero, then expand instead 223216295Ssyrinx if (shrink && vs.committed_size() < delta) { 224216295Ssyrinx shrink = false; 225216295Ssyrinx } 226216295Ssyrinx 227216295Ssyrinx // Resizing by delta 228216295Ssyrinx if (shrink) { 229216295Ssyrinx vs.shrink_by(delta); 230216295Ssyrinx } else { 231228990Suqs // If expanding fails expand_by will silently return false 232216295Ssyrinx vs.expand_by(delta, true); 233216295Ssyrinx } 234216295Ssyrinx } 235216295Ssyrinx return 0; 236228990Suqs} 237216295Ssyrinx 238216295SsyrinxWB_ENTRY(jint, WB_StressVirtualSpaceResize(JNIEnv* env, jobject o, 239216295Ssyrinx jlong reserved_space_size, jlong magnitude, jlong iterations)) 240216295Ssyrinx tty->print_cr("reservedSpaceSize="JLONG_FORMAT", magnitude="JLONG_FORMAT", " 241216295Ssyrinx "iterations="JLONG_FORMAT"\n", reserved_space_size, magnitude, 242216295Ssyrinx iterations); 243216295Ssyrinx if (reserved_space_size < 0 || magnitude < 0 || iterations < 0) { 244216295Ssyrinx tty->print_cr("One of variables printed above is negative. Can't proceed.\n"); 245216295Ssyrinx return 1; 246216295Ssyrinx } 247216295Ssyrinx 248216295Ssyrinx // sizeof(size_t) depends on whether OS is 32bit or 64bit. sizeof(jlong) is 249216295Ssyrinx // always 8 byte. That's why we should avoid overflow in case of 32bit platform. 250216295Ssyrinx if (sizeof(size_t) < sizeof(jlong)) { 251216295Ssyrinx jlong size_t_max_value = (jlong) SIZE_T_MAX_VALUE; 252216295Ssyrinx if (reserved_space_size > size_t_max_value || magnitude > size_t_max_value 253216295Ssyrinx || iterations > size_t_max_value) { 254216295Ssyrinx tty->print_cr("One of variables printed above overflows size_t. Can't proceed.\n"); 255216295Ssyrinx return 2; 256216295Ssyrinx } 257216295Ssyrinx } 258216295Ssyrinx 259216295Ssyrinx return wb_stress_virtual_space_resize((size_t) reserved_space_size, 260216295Ssyrinx (size_t) magnitude, (size_t) iterations); 261216295SsyrinxWB_END 262216295Ssyrinx 263216295SsyrinxWB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj)) 264216295Ssyrinx oop p = JNIHandles::resolve(obj); 265216295Ssyrinx#if INCLUDE_ALL_GCS 266216295Ssyrinx if (UseG1GC) { 267216295Ssyrinx G1CollectedHeap* g1 = G1CollectedHeap::heap(); 268216295Ssyrinx const HeapRegion* hr = g1->heap_region_containing(p); 269216295Ssyrinx if (hr == NULL) { 270216295Ssyrinx return false; 271216295Ssyrinx } 272216295Ssyrinx return !(hr->is_young()); 273216295Ssyrinx } else if (UseParallelGC) { 274216295Ssyrinx ParallelScavengeHeap* psh = ParallelScavengeHeap::heap(); 275216295Ssyrinx return !psh->is_in_young(p); 276216295Ssyrinx } 277216295Ssyrinx#endif // INCLUDE_ALL_GCS 278216295Ssyrinx GenCollectedHeap* gch = GenCollectedHeap::heap(); 279216295Ssyrinx return !gch->is_in_young(p); 280216295SsyrinxWB_END 281216295Ssyrinx 282216295SsyrinxWB_ENTRY(jlong, WB_GetObjectSize(JNIEnv* env, jobject o, jobject obj)) 283216295Ssyrinx oop p = JNIHandles::resolve(obj); 284216295Ssyrinx return p->size() * HeapWordSize; 285216295SsyrinxWB_END 286216295Ssyrinx 287216295Ssyrinx#if INCLUDE_ALL_GCS 288216295SsyrinxWB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj)) 289216295Ssyrinx G1CollectedHeap* g1 = G1CollectedHeap::heap(); 290216295Ssyrinx oop result = JNIHandles::resolve(obj); 291216295Ssyrinx const HeapRegion* hr = g1->heap_region_containing(result); 292216295Ssyrinx return hr->is_humongous(); 293216295SsyrinxWB_END 294216295Ssyrinx 295216295SsyrinxWB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o)) 296216295Ssyrinx G1CollectedHeap* g1 = G1CollectedHeap::heap(); 297216295Ssyrinx size_t nr = g1->num_free_regions(); 298216295Ssyrinx return (jlong)nr; 299216295SsyrinxWB_END 300216295Ssyrinx 301216295SsyrinxWB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o)) 302216295Ssyrinx G1CollectedHeap* g1 = G1CollectedHeap::heap(); 303216295Ssyrinx ConcurrentMark* cm = g1->concurrent_mark(); 304216295Ssyrinx return cm->concurrent_marking_in_progress(); 305216295SsyrinxWB_END 306216295Ssyrinx 307216295SsyrinxWB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o)) 308216295Ssyrinx return (jint)HeapRegion::GrainBytes; 309216295SsyrinxWB_END 310216295Ssyrinx#endif // INCLUDE_ALL_GCS 311216295Ssyrinx 312216295Ssyrinx#if INCLUDE_NMT 313216295Ssyrinx// Alloc memory using the test memory type so that we can use that to see if 314216295Ssyrinx// NMT picks it up correctly 315216295SsyrinxWB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size)) 316216295Ssyrinx jlong addr = 0; 317216295Ssyrinx addr = (jlong)(uintptr_t)os::malloc(size, mtTest); 318216295Ssyrinx return addr; 319216295SsyrinxWB_END 320216295Ssyrinx 321216295Ssyrinx// Alloc memory with pseudo call stack. The test can create psudo malloc 322216295Ssyrinx// allocation site to stress the malloc tracking. 323216295SsyrinxWB_ENTRY(jlong, WB_NMTMallocWithPseudoStack(JNIEnv* env, jobject o, jlong size, jint pseudo_stack)) 324216295Ssyrinx address pc = (address)(size_t)pseudo_stack; 325216295Ssyrinx NativeCallStack stack(&pc, 1); 326216295Ssyrinx return (jlong)(uintptr_t)os::malloc(size, mtTest, stack); 327216295SsyrinxWB_END 328216295Ssyrinx 329216295Ssyrinx// Free the memory allocated by NMTAllocTest 330216295SsyrinxWB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem)) 331216295Ssyrinx os::free((void*)(uintptr_t)mem); 332216295SsyrinxWB_END 333216295Ssyrinx 334216295SsyrinxWB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size)) 335216295Ssyrinx jlong addr = 0; 336216295Ssyrinx 337216295Ssyrinx addr = (jlong)(uintptr_t)os::reserve_memory(size); 338216295Ssyrinx MemTracker::record_virtual_memory_type((address)addr, mtTest); 339216295Ssyrinx 340216295Ssyrinx return addr; 341216295SsyrinxWB_END 342216295Ssyrinx 343216295SsyrinxWB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size)) 344216295Ssyrinx os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem); 345216295Ssyrinx MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest); 346216295SsyrinxWB_END 347216295Ssyrinx 348216295SsyrinxWB_ENTRY(void, WB_NMTUncommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size)) 349216295Ssyrinx os::uncommit_memory((char *)(uintptr_t)addr, size); 350216295SsyrinxWB_END 351216295Ssyrinx 352216295SsyrinxWB_ENTRY(void, WB_NMTReleaseMemory(JNIEnv* env, jobject o, jlong addr, jlong size)) 353216295Ssyrinx os::release_memory((char *)(uintptr_t)addr, size); 354216295SsyrinxWB_END 355216295Ssyrinx 356216295SsyrinxWB_ENTRY(jboolean, WB_NMTIsDetailSupported(JNIEnv* env)) 357216295Ssyrinx return MemTracker::tracking_level() == NMT_detail; 358216295SsyrinxWB_END 359216295Ssyrinx 360216295SsyrinxWB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env)) 361216295Ssyrinx // Test that we can downgrade NMT levels but not upgrade them. 362216295Ssyrinx if (MemTracker::tracking_level() == NMT_off) { 363216295Ssyrinx MemTracker::transition_to(NMT_off); 364216295Ssyrinx return MemTracker::tracking_level() == NMT_off; 365216295Ssyrinx } else { 366216295Ssyrinx assert(MemTracker::tracking_level() == NMT_detail, "Should start out as detail tracking"); 367216295Ssyrinx MemTracker::transition_to(NMT_summary); 368216295Ssyrinx assert(MemTracker::tracking_level() == NMT_summary, "Should be summary now"); 369216295Ssyrinx 370216295Ssyrinx // Can't go to detail once NMT is set to summary. 371216295Ssyrinx MemTracker::transition_to(NMT_detail); 372216295Ssyrinx assert(MemTracker::tracking_level() == NMT_summary, "Should still be summary now"); 373216295Ssyrinx 374216295Ssyrinx // Shutdown sets tracking level to minimal. 375216295Ssyrinx MemTracker::shutdown(); 376216295Ssyrinx assert(MemTracker::tracking_level() == NMT_minimal, "Should be minimal now"); 377216295Ssyrinx 378216295Ssyrinx // Once the tracking level is minimal, we cannot increase to summary. 379216295Ssyrinx // The code ignores this request instead of asserting because if the malloc site 380216295Ssyrinx // table overflows in another thread, it tries to change the code to summary. 381216295Ssyrinx MemTracker::transition_to(NMT_summary); 382216295Ssyrinx assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now"); 383216295Ssyrinx 384216295Ssyrinx // Really can never go up to detail, verify that the code would never do this. 385216295Ssyrinx MemTracker::transition_to(NMT_detail); 386216295Ssyrinx assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now"); 387216295Ssyrinx return MemTracker::tracking_level() == NMT_minimal; 388216295Ssyrinx } 389216295SsyrinxWB_END 390216295Ssyrinx 391216295SsyrinxWB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o)) 392216295Ssyrinx int hash_size = MallocSiteTable::hash_buckets(); 393216295Ssyrinx assert(hash_size > 0, "NMT hash_size should be > 0"); 394216295Ssyrinx return (jint)hash_size; 395216295SsyrinxWB_END 396216295Ssyrinx#endif // INCLUDE_NMT 397216295Ssyrinx 398216295Ssyrinxstatic jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) { 399216295Ssyrinx assert(method != NULL, "method should not be null"); 400216295Ssyrinx ThreadToNativeFromVM ttn(thread); 401216295Ssyrinx return env->FromReflectedMethod(method); 402216295Ssyrinx} 403216295Ssyrinx 404216295SsyrinxWB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o)) 405216295Ssyrinx MutexLockerEx mu(Compile_lock); 406216295Ssyrinx CodeCache::mark_all_nmethods_for_deoptimization(); 407216295Ssyrinx VM_Deoptimize op; 408216295Ssyrinx VMThread::execute(&op); 409216295SsyrinxWB_END 410216295Ssyrinx 411216295SsyrinxWB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 412216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 413216295Ssyrinx int result = 0; 414216295Ssyrinx CHECK_JNI_EXCEPTION_(env, result); 415216295Ssyrinx MutexLockerEx mu(Compile_lock); 416216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 417216295Ssyrinx if (is_osr) { 418216295Ssyrinx result += mh->mark_osr_nmethods(); 419216295Ssyrinx } else if (mh->code() != NULL) { 420216295Ssyrinx mh->code()->mark_for_deoptimization(); 421216295Ssyrinx ++result; 422216295Ssyrinx } 423216295Ssyrinx result += CodeCache::mark_for_deoptimization(mh()); 424216295Ssyrinx if (result > 0) { 425216295Ssyrinx VM_Deoptimize op; 426216295Ssyrinx VMThread::execute(&op); 427216295Ssyrinx } 428216295Ssyrinx return result; 429216295SsyrinxWB_END 430216295Ssyrinx 431216295SsyrinxWB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 432216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 433216295Ssyrinx CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 434216295Ssyrinx MutexLockerEx mu(Compile_lock); 435216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 436216295Ssyrinx nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); 437216295Ssyrinx if (code == NULL) { 438216295Ssyrinx return JNI_FALSE; 439216295Ssyrinx } 440216295Ssyrinx return (code->is_alive() && !code->is_marked_for_deoptimization()); 441216295SsyrinxWB_END 442216295Ssyrinx 443216295SsyrinxWB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr)) 444216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 445216295Ssyrinx CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 446216295Ssyrinx MutexLockerEx mu(Compile_lock); 447216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 448216295Ssyrinx if (is_osr) { 449216295Ssyrinx return CompilationPolicy::can_be_osr_compiled(mh, comp_level); 450216295Ssyrinx } else { 451216295Ssyrinx return CompilationPolicy::can_be_compiled(mh, comp_level); 452216295Ssyrinx } 453228990SuqsWB_END 454216295Ssyrinx 455216295SsyrinxWB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method)) 456216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 457216295Ssyrinx CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 458216295Ssyrinx MutexLockerEx mu(Compile_lock); 459216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 460216295Ssyrinx return mh->queued_for_compilation(); 461216295SsyrinxWB_END 462216295Ssyrinx 463216295SsyrinxWB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 464216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 465216295Ssyrinx CHECK_JNI_EXCEPTION_(env, CompLevel_none); 466216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 467216295Ssyrinx nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); 468216295Ssyrinx return (code != NULL ? code->comp_level() : CompLevel_none); 469216295SsyrinxWB_END 470216295Ssyrinx 471216295SsyrinxWB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr)) 472228990Suqs jmethodID jmid = reflected_method_to_jmid(thread, env, method); 473216295Ssyrinx CHECK_JNI_EXCEPTION(env); 474216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 475216295Ssyrinx if (is_osr) { 476216295Ssyrinx mh->set_not_osr_compilable(comp_level, true /* report */, "WhiteBox"); 477216295Ssyrinx } else { 478216295Ssyrinx mh->set_not_compilable(comp_level, true /* report */, "WhiteBox"); 479216295Ssyrinx } 480216295SsyrinxWB_END 481216295Ssyrinx 482216295SsyrinxWB_ENTRY(jint, WB_GetMethodEntryBci(JNIEnv* env, jobject o, jobject method)) 483216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 484216295Ssyrinx CHECK_JNI_EXCEPTION_(env, InvocationEntryBci); 485216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 486216295Ssyrinx nmethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false); 487216295Ssyrinx return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci); 488216295SsyrinxWB_END 489216295Ssyrinx 490216295SsyrinxWB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) 491216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 492216295Ssyrinx CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 493216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 494216295Ssyrinx bool result = mh->dont_inline(); 495216295Ssyrinx mh->set_dont_inline(value == JNI_TRUE); 496216295Ssyrinx return result; 497216295SsyrinxWB_END 498216295Ssyrinx 499216295SsyrinxWB_ENTRY(jint, WB_GetCompileQueueSize(JNIEnv* env, jobject o, jint comp_level)) 500216295Ssyrinx if (comp_level == CompLevel_any) { 501216295Ssyrinx return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ + 502216295Ssyrinx CompileBroker::queue_size(CompLevel_full_profile) /* C1 */; 503216295Ssyrinx } else { 504216295Ssyrinx return CompileBroker::queue_size(comp_level); 505216295Ssyrinx } 506216295SsyrinxWB_END 507216295Ssyrinx 508216295SsyrinxWB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) 509216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 510216295Ssyrinx CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 511216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 512216295Ssyrinx bool result = mh->force_inline(); 513216295Ssyrinx mh->set_force_inline(value == JNI_TRUE); 514216295Ssyrinx return result; 515216295SsyrinxWB_END 516216295Ssyrinx 517216295SsyrinxWB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci)) 518216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 519216295Ssyrinx CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 520216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 521216295Ssyrinx nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD); 522216295Ssyrinx MutexLockerEx mu(Compile_lock); 523216295Ssyrinx return (mh->queued_for_compilation() || nm != NULL); 524216295SsyrinxWB_END 525216295Ssyrinx 526216295Ssyrinxclass VM_WhiteBoxOperation : public VM_Operation { 527216295Ssyrinx public: 528216295Ssyrinx VM_WhiteBoxOperation() { } 529216295Ssyrinx VMOp_Type type() const { return VMOp_WhiteBoxOperation; } 530216295Ssyrinx bool allow_nested_vm_operations() const { return true; } 531216295Ssyrinx}; 532216295Ssyrinx 533216295Ssyrinxclass AlwaysFalseClosure : public BoolObjectClosure { 534216295Ssyrinx public: 535216295Ssyrinx bool do_object_b(oop p) { return false; } 536216295Ssyrinx}; 537216295Ssyrinx 538216295Ssyrinxstatic AlwaysFalseClosure always_false; 539216295Ssyrinx 540216295SsyrinxWB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method)) 541216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 542216295Ssyrinx CHECK_JNI_EXCEPTION(env); 543216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 544216295Ssyrinx MutexLockerEx mu(Compile_lock); 545216295Ssyrinx MethodData* mdo = mh->method_data(); 546216295Ssyrinx MethodCounters* mcs = mh->method_counters(); 547216295Ssyrinx 548216295Ssyrinx if (mdo != NULL) { 549216295Ssyrinx mdo->init(); 550216295Ssyrinx ResourceMark rm; 551216295Ssyrinx int arg_count = mdo->method()->size_of_parameters(); 552216295Ssyrinx for (int i = 0; i < arg_count; i++) { 553216295Ssyrinx mdo->set_arg_modified(i, 0); 554216295Ssyrinx } 555216295Ssyrinx MutexLockerEx mu(mdo->extra_data_lock()); 556216295Ssyrinx mdo->clean_method_data(&always_false); 557216295Ssyrinx } 558216295Ssyrinx 559216295Ssyrinx mh->clear_not_c1_compilable(); 560216295Ssyrinx mh->clear_not_c2_compilable(); 561216295Ssyrinx mh->clear_not_c2_osr_compilable(); 562216295Ssyrinx NOT_PRODUCT(mh->set_compiled_invocation_count(0)); 563216295Ssyrinx if (mcs != NULL) { 564216295Ssyrinx mcs->backedge_counter()->init(); 565216295Ssyrinx mcs->invocation_counter()->init(); 566216295Ssyrinx mcs->set_interpreter_invocation_count(0); 567216295Ssyrinx mcs->set_interpreter_throwout_count(0); 568216295Ssyrinx 569216295Ssyrinx#ifdef TIERED 570216295Ssyrinx mcs->set_rate(0.0F); 571216295Ssyrinx mh->set_prev_event_count(0); 572216295Ssyrinx mh->set_prev_time(0); 573216295Ssyrinx#endif 574216295Ssyrinx } 575216295SsyrinxWB_END 576216295Ssyrinx 577216295Ssyrinxtemplate <typename T> 578216295Ssyrinxstatic bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*, bool, bool)) { 579216295Ssyrinx if (name == NULL) { 580216295Ssyrinx return false; 581216295Ssyrinx } 582216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 583216295Ssyrinx const char* flag_name = env->GetStringUTFChars(name, NULL); 584216295Ssyrinx bool result = (*TAt)(flag_name, value, true, true); 585216295Ssyrinx env->ReleaseStringUTFChars(name, flag_name); 586216295Ssyrinx return result; 587216295Ssyrinx} 588216295Ssyrinx 589216295Ssyrinxtemplate <typename T> 590216295Ssyrinxstatic bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAtPut)(const char*, T*, Flag::Flags)) { 591216295Ssyrinx if (name == NULL) { 592216295Ssyrinx return false; 593216295Ssyrinx } 594216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 595216295Ssyrinx const char* flag_name = env->GetStringUTFChars(name, NULL); 596216295Ssyrinx bool result = (*TAtPut)(flag_name, value, Flag::INTERNAL); 597216295Ssyrinx env->ReleaseStringUTFChars(name, flag_name); 598216295Ssyrinx return result; 599216295Ssyrinx} 600216295Ssyrinx 601216295Ssyrinxtemplate <typename T> 602216295Ssyrinxstatic jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) { 603216295Ssyrinx ResourceMark rm(thread); 604216295Ssyrinx jclass clazz = env->FindClass(name->as_C_string()); 605216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 606216295Ssyrinx jmethodID methodID = env->GetStaticMethodID(clazz, 607216295Ssyrinx vmSymbols::valueOf_name()->as_C_string(), 608216295Ssyrinx sig->as_C_string()); 609216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 610216295Ssyrinx jobject result = env->CallStaticObjectMethod(clazz, methodID, value); 611216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 612216295Ssyrinx return result; 613216295Ssyrinx} 614216295Ssyrinx 615216295Ssyrinxstatic jobject booleanBox(JavaThread* thread, JNIEnv* env, jboolean value) { 616216295Ssyrinx return box(thread, env, vmSymbols::java_lang_Boolean(), vmSymbols::Boolean_valueOf_signature(), value); 617216295Ssyrinx} 618216295Ssyrinxstatic jobject integerBox(JavaThread* thread, JNIEnv* env, jint value) { 619216295Ssyrinx return box(thread, env, vmSymbols::java_lang_Integer(), vmSymbols::Integer_valueOf_signature(), value); 620216295Ssyrinx} 621216295Ssyrinxstatic jobject longBox(JavaThread* thread, JNIEnv* env, jlong value) { 622216295Ssyrinx return box(thread, env, vmSymbols::java_lang_Long(), vmSymbols::Long_valueOf_signature(), value); 623216295Ssyrinx} 624216295Ssyrinx/* static jobject floatBox(JavaThread* thread, JNIEnv* env, jfloat value) { 625216295Ssyrinx return box(thread, env, vmSymbols::java_lang_Float(), vmSymbols::Float_valueOf_signature(), value); 626216295Ssyrinx}*/ 627216295Ssyrinxstatic jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) { 628216295Ssyrinx return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value); 629216295Ssyrinx} 630216295Ssyrinx 631216295Ssyrinxstatic Flag* getVMFlag(JavaThread* thread, JNIEnv* env, jstring name) { 632216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 633216295Ssyrinx const char* flag_name = env->GetStringUTFChars(name, NULL); 634216295Ssyrinx Flag* result = Flag::find_flag(flag_name, strlen(flag_name), true, true); 635216295Ssyrinx env->ReleaseStringUTFChars(name, flag_name); 636216295Ssyrinx return result; 637216295Ssyrinx} 638216295Ssyrinx 639216295SsyrinxWB_ENTRY(jboolean, WB_IsConstantVMFlag(JNIEnv* env, jobject o, jstring name)) 640216295Ssyrinx Flag* flag = getVMFlag(thread, env, name); 641216295Ssyrinx return (flag != NULL) && flag->is_constant_in_binary(); 642216295SsyrinxWB_END 643216295Ssyrinx 644216295SsyrinxWB_ENTRY(jboolean, WB_IsLockedVMFlag(JNIEnv* env, jobject o, jstring name)) 645216295Ssyrinx Flag* flag = getVMFlag(thread, env, name); 646216295Ssyrinx return (flag != NULL) && !(flag->is_unlocked() || flag->is_unlocker()); 647216295SsyrinxWB_END 648216295Ssyrinx 649216295SsyrinxWB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name)) 650216295Ssyrinx bool result; 651216295Ssyrinx if (GetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAt)) { 652216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 653216295Ssyrinx return booleanBox(thread, env, result); 654216295Ssyrinx } 655216295Ssyrinx return NULL; 656216295SsyrinxWB_END 657216295Ssyrinx 658216295SsyrinxWB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name)) 659216295Ssyrinx intx result; 660216295Ssyrinx if (GetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAt)) { 661216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 662216295Ssyrinx return longBox(thread, env, result); 663216295Ssyrinx } 664216295Ssyrinx return NULL; 665216295SsyrinxWB_END 666216295Ssyrinx 667216295SsyrinxWB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name)) 668216295Ssyrinx uintx result; 669216295Ssyrinx if (GetVMFlag <uintx> (thread, env, name, &result, &CommandLineFlags::uintxAt)) { 670216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 671216295Ssyrinx return longBox(thread, env, result); 672216295Ssyrinx } 673216295Ssyrinx return NULL; 674216295SsyrinxWB_END 675216295Ssyrinx 676216295SsyrinxWB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name)) 677216295Ssyrinx uint64_t result; 678216295Ssyrinx if (GetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAt)) { 679216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 680216295Ssyrinx return longBox(thread, env, result); 681216295Ssyrinx } 682216295Ssyrinx return NULL; 683216295SsyrinxWB_END 684216295Ssyrinx 685216295SsyrinxWB_ENTRY(jobject, WB_GetSizeTVMFlag(JNIEnv* env, jobject o, jstring name)) 686216295Ssyrinx uintx result; 687216295Ssyrinx if (GetVMFlag <size_t> (thread, env, name, &result, &CommandLineFlags::size_tAt)) { 688216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 689216295Ssyrinx return longBox(thread, env, result); 690216295Ssyrinx } 691216295Ssyrinx return NULL; 692216295SsyrinxWB_END 693216295Ssyrinx 694216295SsyrinxWB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name)) 695216295Ssyrinx double result; 696216295Ssyrinx if (GetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAt)) { 697216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 698216295Ssyrinx return doubleBox(thread, env, result); 699216295Ssyrinx } 700216295Ssyrinx return NULL; 701216295SsyrinxWB_END 702216295Ssyrinx 703216295SsyrinxWB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name)) 704216295Ssyrinx ccstr ccstrResult; 705216295Ssyrinx if (GetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAt)) { 706216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 707216295Ssyrinx jstring result = env->NewStringUTF(ccstrResult); 708216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 709216295Ssyrinx return result; 710216295Ssyrinx } 711216295Ssyrinx return NULL; 712216295SsyrinxWB_END 713216295Ssyrinx 714216295SsyrinxWB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value)) 715216295Ssyrinx bool result = value == JNI_TRUE ? true : false; 716216295Ssyrinx SetVMFlag <bool> (thread, env, name, &result, &CommandLineFlags::boolAtPut); 717216295SsyrinxWB_END 718216295Ssyrinx 719216295SsyrinxWB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) 720216295Ssyrinx intx result = value; 721216295Ssyrinx SetVMFlag <intx> (thread, env, name, &result, &CommandLineFlags::intxAtPut); 722216295SsyrinxWB_END 723216295Ssyrinx 724216295SsyrinxWB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) 725216295Ssyrinx uintx result = value; 726216295Ssyrinx SetVMFlag <uintx> (thread, env, name, &result, &CommandLineFlags::uintxAtPut); 727216295SsyrinxWB_END 728216295Ssyrinx 729216295SsyrinxWB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) 730216295Ssyrinx uint64_t result = value; 731216295Ssyrinx SetVMFlag <uint64_t> (thread, env, name, &result, &CommandLineFlags::uint64_tAtPut); 732216295SsyrinxWB_END 733216295Ssyrinx 734216295SsyrinxWB_ENTRY(void, WB_SetSizeTVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) 735216295Ssyrinx size_t result = value; 736216295Ssyrinx SetVMFlag <size_t> (thread, env, name, &result, &CommandLineFlags::size_tAtPut); 737216295SsyrinxWB_END 738216295Ssyrinx 739216295SsyrinxWB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value)) 740216295Ssyrinx double result = value; 741216295Ssyrinx SetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAtPut); 742216295SsyrinxWB_END 743216295Ssyrinx 744216295SsyrinxWB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value)) 745216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 746216295Ssyrinx const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL); 747216295Ssyrinx ccstr ccstrResult = ccstrValue; 748216295Ssyrinx bool needFree; 749216295Ssyrinx { 750216295Ssyrinx ThreadInVMfromNative ttvfn(thread); // back to VM 751216295Ssyrinx needFree = SetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAtPut); 752216295Ssyrinx } 753216295Ssyrinx if (value != NULL) { 754216295Ssyrinx env->ReleaseStringUTFChars(value, ccstrValue); 755216295Ssyrinx } 756216295Ssyrinx if (needFree) { 757216295Ssyrinx FREE_C_HEAP_ARRAY(char, ccstrResult); 758216295Ssyrinx } 759216295SsyrinxWB_END 760216295Ssyrinx 761216295Ssyrinx 762216295SsyrinxWB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout)) 763216295Ssyrinx WhiteBox::compilation_locked = true; 764216295SsyrinxWB_END 765216295Ssyrinx 766216295SsyrinxWB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o)) 767216295Ssyrinx MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag); 768216295Ssyrinx WhiteBox::compilation_locked = false; 769216295Ssyrinx mo.notify_all(); 770216295SsyrinxWB_END 771216295Ssyrinx 772216295Ssyrinxvoid WhiteBox::force_sweep() { 773216295Ssyrinx guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); 774216295Ssyrinx { 775216295Ssyrinx MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 776216295Ssyrinx NMethodSweeper::_should_sweep = true; 777216295Ssyrinx } 778216295Ssyrinx NMethodSweeper::possibly_sweep(); 779216295Ssyrinx} 780216295Ssyrinx 781216295SsyrinxWB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o)) 782216295Ssyrinx WhiteBox::force_sweep(); 783216295SsyrinxWB_END 784216295Ssyrinx 785216295SsyrinxWB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) 786216295Ssyrinx ResourceMark rm(THREAD); 787216295Ssyrinx int len; 788216295Ssyrinx jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false); 789216295Ssyrinx return (StringTable::lookup(name, len) != NULL); 790216295SsyrinxWB_END 791216295Ssyrinx 792216295SsyrinxWB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o)) 793216295Ssyrinx Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true); 794216295Ssyrinx Universe::heap()->collect(GCCause::_last_ditch_collection); 795216295Ssyrinx#if INCLUDE_ALL_GCS 796216295Ssyrinx if (UseG1GC) { 797216295Ssyrinx // Needs to be cleared explicitly for G1 798216295Ssyrinx Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false); 799216295Ssyrinx } 800216295Ssyrinx#endif // INCLUDE_ALL_GCS 801216295SsyrinxWB_END 802216295Ssyrinx 803216295SsyrinxWB_ENTRY(void, WB_YoungGC(JNIEnv* env, jobject o)) 804216295Ssyrinx Universe::heap()->collect(GCCause::_wb_young_gc); 805216295SsyrinxWB_END 806216295Ssyrinx 807216295SsyrinxWB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o)) 808216295Ssyrinx // static+volatile in order to force the read to happen 809216295Ssyrinx // (not be eliminated by the compiler) 810216295Ssyrinx static char c; 811216295Ssyrinx static volatile char* p; 812216295Ssyrinx 813216295Ssyrinx p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0); 814216295Ssyrinx if (p == NULL) { 815216295Ssyrinx THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory"); 816216295Ssyrinx } 817216295Ssyrinx 818216295Ssyrinx c = *p; 819216295SsyrinxWB_END 820216295Ssyrinx 821216295SsyrinxWB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o)) 822216295Ssyrinx const char* cpu_features = VM_Version::cpu_features(); 823216295Ssyrinx ThreadToNativeFromVM ttn(thread); 824216295Ssyrinx jstring features_string = env->NewStringUTF(cpu_features); 825216295Ssyrinx 826216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 827216295Ssyrinx 828216295Ssyrinx return features_string; 829216295SsyrinxWB_END 830216295Ssyrinx 831216295Ssyrinxint WhiteBox::get_blob_type(const CodeBlob* code) { 832216295Ssyrinx guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); 833216295Ssyrinx return CodeCache::get_code_heap(code)->code_blob_type(); 834216295Ssyrinx} 835216295Ssyrinx 836216295SsyrinxCodeHeap* WhiteBox::get_code_heap(int blob_type) { 837216295Ssyrinx guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); 838216295Ssyrinx return CodeCache::get_code_heap(blob_type); 839216295Ssyrinx} 840216295Ssyrinx 841216295Ssyrinxstruct CodeBlobStub { 842216295Ssyrinx CodeBlobStub(const CodeBlob* blob) : 843216295Ssyrinx name(os::strdup(blob->name())), 844216295Ssyrinx size(blob->size()), 845216295Ssyrinx blob_type(WhiteBox::get_blob_type(blob)) { } 846216295Ssyrinx ~CodeBlobStub() { os::free((void*) name); } 847216295Ssyrinx const char* const name; 848216295Ssyrinx const int size; 849216295Ssyrinx const int blob_type; 850216295Ssyrinx}; 851216295Ssyrinx 852216295Ssyrinxstatic jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) { 853216295Ssyrinx jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); 854216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 855216295Ssyrinx jobjectArray result = env->NewObjectArray(3, clazz, NULL); 856216295Ssyrinx 857216295Ssyrinx jstring name = env->NewStringUTF(cb->name); 858216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 859216295Ssyrinx env->SetObjectArrayElement(result, 0, name); 860216295Ssyrinx 861216295Ssyrinx jobject obj = integerBox(thread, env, cb->size); 862216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 863216295Ssyrinx env->SetObjectArrayElement(result, 1, obj); 864216295Ssyrinx 865216295Ssyrinx obj = integerBox(thread, env, cb->blob_type); 866216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 867216295Ssyrinx env->SetObjectArrayElement(result, 2, obj); 868216295Ssyrinx 869216295Ssyrinx return result; 870216295Ssyrinx} 871216295Ssyrinx 872216295SsyrinxWB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 873216295Ssyrinx ResourceMark rm(THREAD); 874216295Ssyrinx jmethodID jmid = reflected_method_to_jmid(thread, env, method); 875216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 876216295Ssyrinx methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 877216295Ssyrinx nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); 878216295Ssyrinx jobjectArray result = NULL; 879216295Ssyrinx if (code == NULL) { 880216295Ssyrinx return result; 881216295Ssyrinx } 882216295Ssyrinx int insts_size = code->insts_size(); 883216295Ssyrinx 884216295Ssyrinx ThreadToNativeFromVM ttn(thread); 885216295Ssyrinx jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); 886216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 887216295Ssyrinx result = env->NewObjectArray(4, clazz, NULL); 888216295Ssyrinx if (result == NULL) { 889216295Ssyrinx return result; 890216295Ssyrinx } 891216295Ssyrinx 892216295Ssyrinx CodeBlobStub stub(code); 893216295Ssyrinx jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub); 894216295Ssyrinx env->SetObjectArrayElement(result, 0, codeBlob); 895216295Ssyrinx 896216295Ssyrinx jobject level = integerBox(thread, env, code->comp_level()); 897216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 898216295Ssyrinx env->SetObjectArrayElement(result, 1, level); 899216295Ssyrinx 900216295Ssyrinx jbyteArray insts = env->NewByteArray(insts_size); 901216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 902216295Ssyrinx env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin()); 903216295Ssyrinx env->SetObjectArrayElement(result, 2, insts); 904216295Ssyrinx 905216295Ssyrinx jobject id = integerBox(thread, env, code->compile_id()); 906216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 907216295Ssyrinx env->SetObjectArrayElement(result, 3, id); 908216295Ssyrinx 909216295Ssyrinx return result; 910216295SsyrinxWB_END 911216295Ssyrinx 912216295SsyrinxCodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) { 913216295Ssyrinx guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled"); 914216295Ssyrinx BufferBlob* blob; 915216295Ssyrinx int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob)); 916216295Ssyrinx if (full_size < size) { 917216295Ssyrinx full_size += round_to(size - full_size, oopSize); 918216295Ssyrinx } 919216295Ssyrinx { 920216295Ssyrinx MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 921216295Ssyrinx blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type); 922216295Ssyrinx } 923216295Ssyrinx // Track memory usage statistic after releasing CodeCache_lock 924216295Ssyrinx MemoryService::track_code_cache_memory_usage(); 925216295Ssyrinx ::new (blob) BufferBlob("WB::DummyBlob", full_size); 926216295Ssyrinx return blob; 927216295Ssyrinx} 928216295Ssyrinx 929216295SsyrinxWB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type)) 930216295Ssyrinx return (jlong) WhiteBox::allocate_code_blob(size, blob_type); 931216295SsyrinxWB_END 932216295Ssyrinx 933216295SsyrinxWB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr)) 934216295Ssyrinx BufferBlob::free((BufferBlob*) addr); 935216295SsyrinxWB_END 936216295Ssyrinx 937216295SsyrinxWB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type)) 938216295Ssyrinx ResourceMark rm; 939216295Ssyrinx GrowableArray<CodeBlobStub*> blobs; 940216295Ssyrinx { 941216295Ssyrinx MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 942216295Ssyrinx CodeHeap* heap = WhiteBox::get_code_heap(blob_type); 943216295Ssyrinx if (heap == NULL) { 944216295Ssyrinx return NULL; 945216295Ssyrinx } 946216295Ssyrinx for (CodeBlob* cb = (CodeBlob*) heap->first(); 947216295Ssyrinx cb != NULL; cb = (CodeBlob*) heap->next(cb)) { 948216295Ssyrinx CodeBlobStub* stub = NEW_RESOURCE_OBJ(CodeBlobStub); 949216295Ssyrinx new (stub) CodeBlobStub(cb); 950216295Ssyrinx blobs.append(stub); 951216295Ssyrinx } 952216295Ssyrinx } 953216295Ssyrinx if (blobs.length() == 0) { 954216295Ssyrinx return NULL; 955216295Ssyrinx } 956216295Ssyrinx ThreadToNativeFromVM ttn(thread); 957216295Ssyrinx jobjectArray result = NULL; 958216295Ssyrinx jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); 959216295Ssyrinx CHECK_JNI_EXCEPTION_(env, NULL); 960216295Ssyrinx result = env->NewObjectArray(blobs.length(), clazz, NULL); 961216295Ssyrinx if (result == NULL) { 962216295Ssyrinx return result; 963216295Ssyrinx } 964216295Ssyrinx int i = 0; 965216295Ssyrinx for (GrowableArrayIterator<CodeBlobStub*> it = blobs.begin(); 966216295Ssyrinx it != blobs.end(); ++it) { 967216295Ssyrinx jobjectArray obj = codeBlob2objectArray(thread, env, *it); 968216295Ssyrinx env->SetObjectArrayElement(result, i, obj); 969216295Ssyrinx ++i; 970216295Ssyrinx } 971216295Ssyrinx return result; 972216295SsyrinxWB_END 973216295Ssyrinx 974216295SsyrinxWB_ENTRY(jlong, WB_GetThreadStackSize(JNIEnv* env, jobject o)) 975216295Ssyrinx return (jlong) Thread::current()->stack_size(); 976216295SsyrinxWB_END 977216295Ssyrinx 978216295SsyrinxWB_ENTRY(jlong, WB_GetThreadRemainingStackSize(JNIEnv* env, jobject o)) 979216295Ssyrinx JavaThread* t = JavaThread::current(); 980216295Ssyrinx return (jlong) t->stack_available(os::current_stack_pointer()) - (jlong) StackShadowPages * os::vm_page_size(); 981216295SsyrinxWB_END 982216295Ssyrinx 983216295Ssyrinxint WhiteBox::array_bytes_to_length(size_t bytes) { 984216295Ssyrinx return Array<u1>::bytes_to_length(bytes); 985216295Ssyrinx} 986216295Ssyrinx 987216295SsyrinxWB_ENTRY(jlong, WB_AllocateMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong size)) 988216295Ssyrinx if (size < 0) { 989216295Ssyrinx THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 990216295Ssyrinx err_msg("WB_AllocateMetaspace: size is negative: " JLONG_FORMAT, size)); 991216295Ssyrinx } 992216295Ssyrinx 993216295Ssyrinx oop class_loader_oop = JNIHandles::resolve(class_loader); 994216295Ssyrinx ClassLoaderData* cld = class_loader_oop != NULL 995216295Ssyrinx ? java_lang_ClassLoader::loader_data(class_loader_oop) 996216295Ssyrinx : ClassLoaderData::the_null_class_loader_data(); 997216295Ssyrinx 998216295Ssyrinx void* metadata = MetadataFactory::new_writeable_array<u1>(cld, WhiteBox::array_bytes_to_length((size_t)size), thread); 999216295Ssyrinx 1000216295Ssyrinx return (jlong)(uintptr_t)metadata; 1001216295SsyrinxWB_END 1002216295Ssyrinx 1003216295SsyrinxWB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size)) 1004216295Ssyrinx oop class_loader_oop = JNIHandles::resolve(class_loader); 1005216295Ssyrinx ClassLoaderData* cld = class_loader_oop != NULL 1006216295Ssyrinx ? java_lang_ClassLoader::loader_data(class_loader_oop) 1007216295Ssyrinx : ClassLoaderData::the_null_class_loader_data(); 1008216295Ssyrinx 1009216295Ssyrinx MetadataFactory::free_array(cld, (Array<u1>*)(uintptr_t)addr); 1010216295SsyrinxWB_END 1011216295Ssyrinx 1012216295SsyrinxWB_ENTRY(jlong, WB_IncMetaspaceCapacityUntilGC(JNIEnv* env, jobject wb, jlong inc)) 1013216295Ssyrinx if (inc < 0) { 1014216295Ssyrinx THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 1015216295Ssyrinx err_msg("WB_IncMetaspaceCapacityUntilGC: inc is negative: " JLONG_FORMAT, inc)); 1016216295Ssyrinx } 1017216295Ssyrinx 1018216295Ssyrinx jlong max_size_t = (jlong) ((size_t) -1); 1019216295Ssyrinx if (inc > max_size_t) { 1020216295Ssyrinx THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 1021216295Ssyrinx err_msg("WB_IncMetaspaceCapacityUntilGC: inc does not fit in size_t: " JLONG_FORMAT, inc)); 1022216295Ssyrinx } 1023216295Ssyrinx 1024216295Ssyrinx size_t new_cap_until_GC = 0; 1025216295Ssyrinx size_t aligned_inc = align_size_down((size_t) inc, Metaspace::commit_alignment()); 1026216295Ssyrinx bool success = MetaspaceGC::inc_capacity_until_GC(aligned_inc, &new_cap_until_GC); 1027216295Ssyrinx if (!success) { 1028216295Ssyrinx THROW_MSG_0(vmSymbols::java_lang_IllegalStateException(), 1029216295Ssyrinx "WB_IncMetaspaceCapacityUntilGC: could not increase capacity until GC " 1030216295Ssyrinx "due to contention with another thread"); 1031216295Ssyrinx } 1032216295Ssyrinx return (jlong) new_cap_until_GC; 1033216295SsyrinxWB_END 1034216295Ssyrinx 1035216295SsyrinxWB_ENTRY(jlong, WB_MetaspaceCapacityUntilGC(JNIEnv* env, jobject wb)) 1036216295Ssyrinx return (jlong) MetaspaceGC::capacity_until_GC(); 1037216295SsyrinxWB_END 1038216295Ssyrinx 1039216295Ssyrinx//Some convenience methods to deal with objects from java 1040216295Ssyrinxint WhiteBox::offset_for_field(const char* field_name, oop object, 1041216295Ssyrinx Symbol* signature_symbol) { 1042216295Ssyrinx assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid"); 1043216295Ssyrinx Thread* THREAD = Thread::current(); 1044216295Ssyrinx 1045216295Ssyrinx //Get the class of our object 1046216295Ssyrinx Klass* arg_klass = object->klass(); 1047216295Ssyrinx //Turn it into an instance-klass 1048216295Ssyrinx InstanceKlass* ik = InstanceKlass::cast(arg_klass); 1049216295Ssyrinx 1050216295Ssyrinx //Create symbols to look for in the class 1051216295Ssyrinx TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name), 1052216295Ssyrinx THREAD); 1053216295Ssyrinx 1054216295Ssyrinx //To be filled in with an offset of the field we're looking for 1055216295Ssyrinx fieldDescriptor fd; 1056216295Ssyrinx 1057216295Ssyrinx Klass* res = ik->find_field(name_symbol, signature_symbol, &fd); 1058216295Ssyrinx if (res == NULL) { 1059216295Ssyrinx tty->print_cr("Invalid layout of %s at %s", ik->external_name(), 1060216295Ssyrinx name_symbol->as_C_string()); 1061216295Ssyrinx fatal("Invalid layout of preloaded class"); 1062216295Ssyrinx } 1063216295Ssyrinx 1064216295Ssyrinx //fetch the field at the offset we've found 1065216295Ssyrinx int dest_offset = fd.offset(); 1066216295Ssyrinx 1067216295Ssyrinx return dest_offset; 1068216295Ssyrinx} 1069216295Ssyrinx 1070216295Ssyrinx 1071216295Ssyrinxconst char* WhiteBox::lookup_jstring(const char* field_name, oop object) { 1072216295Ssyrinx int offset = offset_for_field(field_name, object, 1073216295Ssyrinx vmSymbols::string_signature()); 1074216295Ssyrinx oop string = object->obj_field(offset); 1075216295Ssyrinx if (string == NULL) { 1076216295Ssyrinx return NULL; 1077216295Ssyrinx } 1078216295Ssyrinx const char* ret = java_lang_String::as_utf8_string(string); 1079216295Ssyrinx return ret; 1080216295Ssyrinx} 1081216295Ssyrinx 1082216295Ssyrinxbool WhiteBox::lookup_bool(const char* field_name, oop object) { 1083216295Ssyrinx int offset = 1084216295Ssyrinx offset_for_field(field_name, object, vmSymbols::bool_signature()); 1085216295Ssyrinx bool ret = (object->bool_field(offset) == JNI_TRUE); 1086216295Ssyrinx return ret; 1087216295Ssyrinx} 1088216295Ssyrinx 1089216295Ssyrinxvoid WhiteBox::register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count) { 1090216295Ssyrinx ResourceMark rm; 1091216295Ssyrinx ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 1092216295Ssyrinx 1093216295Ssyrinx // one by one registration natives for exception catching 1094216295Ssyrinx jclass no_such_method_error_klass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string()); 1095216295Ssyrinx CHECK_JNI_EXCEPTION(env); 1096216295Ssyrinx for (int i = 0, n = method_count; i < n; ++i) { 1097216295Ssyrinx // Skip dummy entries 1098216295Ssyrinx if (method_array[i].fnPtr == NULL) continue; 1099216295Ssyrinx if (env->RegisterNatives(wbclass, &method_array[i], 1) != 0) { 1100216295Ssyrinx jthrowable throwable_obj = env->ExceptionOccurred(); 1101216295Ssyrinx if (throwable_obj != NULL) { 1102216295Ssyrinx env->ExceptionClear(); 1103216295Ssyrinx if (env->IsInstanceOf(throwable_obj, no_such_method_error_klass)) { 1104216295Ssyrinx // NoSuchMethodError is thrown when a method can't be found or a method is not native. 1105216295Ssyrinx // Ignoring the exception since it is not preventing use of other WhiteBox methods. 1106216295Ssyrinx tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", 1107216295Ssyrinx method_array[i].name, method_array[i].signature); 1108216295Ssyrinx } 1109216295Ssyrinx } else { 1110216295Ssyrinx // Registration failed unexpectedly. 1111216295Ssyrinx tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered", 1112216295Ssyrinx method_array[i].name, method_array[i].signature); 1113216295Ssyrinx env->UnregisterNatives(wbclass); 1114216295Ssyrinx break; 1115216295Ssyrinx } 1116216295Ssyrinx } 1117216295Ssyrinx } 1118216295Ssyrinx} 1119216295Ssyrinx 1120216295Ssyrinx#define CC (char*) 1121216295Ssyrinx 1122216295Ssyrinxstatic JNINativeMethod methods[] = { 1123216295Ssyrinx {CC"getObjectAddress", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress }, 1124216295Ssyrinx {CC"getObjectSize", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize }, 1125216295Ssyrinx {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen }, 1126216295Ssyrinx {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize }, 1127216295Ssyrinx {CC"getVMPageSize", CC"()I", (void*)&WB_GetVMPageSize }, 1128216295Ssyrinx {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, 1129216295Ssyrinx {CC"parseCommandLine", 1130216295Ssyrinx CC"(Ljava/lang/String;C[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", 1131216295Ssyrinx (void*) &WB_ParseCommandLine 1132216295Ssyrinx }, 1133216295Ssyrinx {CC"addToBootstrapClassLoaderSearch", CC"(Ljava/lang/String;)V", 1134216295Ssyrinx (void*)&WB_AddToBootstrapClassLoaderSearch}, 1135216295Ssyrinx {CC"addToSystemClassLoaderSearch", CC"(Ljava/lang/String;)V", 1136216295Ssyrinx (void*)&WB_AddToSystemClassLoaderSearch}, 1137216295Ssyrinx {CC"getCompressedOopsMaxHeapSize", CC"()J", 1138216295Ssyrinx (void*)&WB_GetCompressedOopsMaxHeapSize}, 1139216295Ssyrinx {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes }, 1140216295Ssyrinx {CC"runMemoryUnitTests", CC"()V", (void*)&WB_RunMemoryUnitTests}, 1141216295Ssyrinx {CC"readFromNoaccessArea",CC"()V", (void*)&WB_ReadFromNoaccessArea}, 1142216295Ssyrinx {CC"stressVirtualSpaceResize",CC"(JJJ)I", (void*)&WB_StressVirtualSpaceResize}, 1143216295Ssyrinx#if INCLUDE_ALL_GCS 1144216295Ssyrinx {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, 1145216295Ssyrinx {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous }, 1146216295Ssyrinx {CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions }, 1147216295Ssyrinx {CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize }, 1148216295Ssyrinx#endif // INCLUDE_ALL_GCS 1149216295Ssyrinx#if INCLUDE_NMT 1150216295Ssyrinx {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc }, 1151216295Ssyrinx {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack}, 1152216295Ssyrinx {CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree }, 1153216295Ssyrinx {CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory }, 1154216295Ssyrinx {CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory }, 1155216295Ssyrinx {CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory }, 1156216295Ssyrinx {CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory }, 1157216295Ssyrinx {CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported}, 1158216295Ssyrinx {CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel}, 1159216295Ssyrinx {CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize }, 1160216295Ssyrinx#endif // INCLUDE_NMT 1161216295Ssyrinx {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll }, 1162216295Ssyrinx {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I", 1163216295Ssyrinx (void*)&WB_DeoptimizeMethod }, 1164216295Ssyrinx {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;Z)Z", 1165216295Ssyrinx (void*)&WB_IsMethodCompiled }, 1166216295Ssyrinx {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;IZ)Z", 1167216295Ssyrinx (void*)&WB_IsMethodCompilable}, 1168216295Ssyrinx {CC"isMethodQueuedForCompilation", 1169216295Ssyrinx CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation}, 1170216295Ssyrinx {CC"makeMethodNotCompilable", 1171216295Ssyrinx CC"(Ljava/lang/reflect/Executable;IZ)V", (void*)&WB_MakeMethodNotCompilable}, 1172216295Ssyrinx {CC"testSetDontInlineMethod", 1173216295Ssyrinx CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod}, 1174216295Ssyrinx {CC"getMethodCompilationLevel", 1175216295Ssyrinx CC"(Ljava/lang/reflect/Executable;Z)I", (void*)&WB_GetMethodCompilationLevel}, 1176216295Ssyrinx {CC"getMethodEntryBci", 1177216295Ssyrinx CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci}, 1178216295Ssyrinx {CC"getCompileQueueSize", 1179216295Ssyrinx CC"(I)I", (void*)&WB_GetCompileQueueSize}, 1180216295Ssyrinx {CC"testSetForceInlineMethod", 1181216295Ssyrinx CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod}, 1182216295Ssyrinx {CC"enqueueMethodForCompilation", 1183216295Ssyrinx CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, 1184216295Ssyrinx {CC"clearMethodState", 1185216295Ssyrinx CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, 1186216295Ssyrinx {CC"lockCompilation", CC"()V", (void*)&WB_LockCompilation}, 1187216295Ssyrinx {CC"unlockCompilation", CC"()V", (void*)&WB_UnlockCompilation}, 1188216295Ssyrinx {CC"isConstantVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag}, 1189216295Ssyrinx {CC"isLockedVMFlag", CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag}, 1190216295Ssyrinx {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, 1191216295Ssyrinx {CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag}, 1192216295Ssyrinx {CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag}, 1193216295Ssyrinx {CC"setUint64VMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag}, 1194216295Ssyrinx {CC"setSizeTVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetSizeTVMFlag}, 1195216295Ssyrinx {CC"setDoubleVMFlag", CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag}, 1196216295Ssyrinx {CC"setStringVMFlag", CC"(Ljava/lang/String;Ljava/lang/String;)V", 1197216295Ssyrinx (void*)&WB_SetStringVMFlag}, 1198216295Ssyrinx {CC"getBooleanVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Boolean;", 1199216295Ssyrinx (void*)&WB_GetBooleanVMFlag}, 1200216295Ssyrinx {CC"getIntxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", 1201216295Ssyrinx (void*)&WB_GetIntxVMFlag}, 1202216295Ssyrinx {CC"getUintxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", 1203216295Ssyrinx (void*)&WB_GetUintxVMFlag}, 1204216295Ssyrinx {CC"getUint64VMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", 1205216295Ssyrinx (void*)&WB_GetUint64VMFlag}, 1206216295Ssyrinx {CC"getSizeTVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", 1207216295Ssyrinx (void*)&WB_GetSizeTVMFlag}, 1208216295Ssyrinx {CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;", 1209216295Ssyrinx (void*)&WB_GetDoubleVMFlag}, 1210216295Ssyrinx {CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;", 1211216295Ssyrinx (void*)&WB_GetStringVMFlag}, 1212216295Ssyrinx {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, 1213216295Ssyrinx {CC"fullGC", CC"()V", (void*)&WB_FullGC }, 1214216295Ssyrinx {CC"youngGC", CC"()V", (void*)&WB_YoungGC }, 1215216295Ssyrinx {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory }, 1216216295Ssyrinx {CC"allocateMetaspace", 1217216295Ssyrinx CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace }, 1218216295Ssyrinx {CC"freeMetaspace", 1219216295Ssyrinx CC"(Ljava/lang/ClassLoader;JJ)V", (void*)&WB_FreeMetaspace }, 1220216295Ssyrinx {CC"incMetaspaceCapacityUntilGC", CC"(J)J", (void*)&WB_IncMetaspaceCapacityUntilGC }, 1221216295Ssyrinx {CC"metaspaceCapacityUntilGC", CC"()J", (void*)&WB_MetaspaceCapacityUntilGC }, 1222216295Ssyrinx {CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures }, 1223216295Ssyrinx {CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;", 1224216295Ssyrinx (void*)&WB_GetNMethod }, 1225216295Ssyrinx {CC"forceNMethodSweep", CC"()V", (void*)&WB_ForceNMethodSweep }, 1226216295Ssyrinx {CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob }, 1227216295Ssyrinx {CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob }, 1228216295Ssyrinx {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries }, 1229216295Ssyrinx {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize }, 1230216295Ssyrinx {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize }, 1231216295Ssyrinx}; 1232216295Ssyrinx 1233216295Ssyrinx#undef CC 1234216295Ssyrinx 1235216295SsyrinxJVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass)) 1236216295Ssyrinx { 1237216295Ssyrinx if (WhiteBoxAPI) { 1238216295Ssyrinx // Make sure that wbclass is loaded by the null classloader 1239216295Ssyrinx instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass()); 1240216295Ssyrinx Handle loader(ikh->class_loader()); 1241216295Ssyrinx if (loader.is_null()) { 1242216295Ssyrinx WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0])); 1243216295Ssyrinx WhiteBox::register_extended(env, wbclass, thread); 1244216295Ssyrinx WhiteBox::set_used(); 1245216295Ssyrinx } 1246216295Ssyrinx } 1247216295Ssyrinx } 1248216295SsyrinxJVM_END 1249216295Ssyrinx