mgerdin@3619: /* iignatyev@6525: * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. mgerdin@3619: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. mgerdin@3619: * mgerdin@3619: * This code is free software; you can redistribute it and/or modify it mgerdin@3619: * under the terms of the GNU General Public License version 2 only, as mgerdin@3619: * published by the Free Software Foundation. mgerdin@3619: * mgerdin@3619: * This code is distributed in the hope that it will be useful, but WITHOUT mgerdin@3619: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or mgerdin@3619: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License mgerdin@3619: * version 2 for more details (a copy is included in the LICENSE file that mgerdin@3619: * accompanied this code). mgerdin@3619: * mgerdin@3619: * You should have received a copy of the GNU General Public License version mgerdin@3619: * 2 along with this work; if not, write to the Free Software Foundation, mgerdin@3619: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. mgerdin@3619: * mgerdin@3619: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA mgerdin@3619: * or visit www.oracle.com if you need additional information or have any mgerdin@3619: * questions. mgerdin@3619: * mgerdin@3619: */ mgerdin@3619: mgerdin@3619: #include "precompiled.hpp" mgerdin@3619: stefank@6992: #include "memory/metadataFactory.hpp" mgerdin@3619: #include "memory/universe.hpp" mgerdin@3619: #include "oops/oop.inline.hpp" nloodin@3681: nloodin@3681: #include "classfile/symbolTable.hpp" coleenp@4037: #include "classfile/classLoaderData.hpp" nloodin@3681: mgerdin@3619: #include "prims/whitebox.hpp" nloodin@3681: #include "prims/wbtestmethods/parserTests.hpp" nloodin@3681: tschatzl@5701: #include "runtime/arguments.hpp" mgerdin@3619: #include "runtime/interfaceSupport.hpp" mgerdin@3619: #include "runtime/os.hpp" stefank@6992: #include "utilities/array.hpp" mgerdin@3619: #include "utilities/debug.hpp" jprovino@4542: #include "utilities/macros.hpp" mikael@5174: #include "utilities/exceptions.hpp" mgerdin@3619: jprovino@4542: #if INCLUDE_ALL_GCS tschatzl@7071: #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp" mgerdin@3619: #include "gc_implementation/g1/concurrentMark.hpp" mgerdin@3619: #include "gc_implementation/g1/g1CollectedHeap.inline.hpp" mgerdin@3619: #include "gc_implementation/g1/heapRegionRemSet.hpp" jprovino@4542: #endif // INCLUDE_ALL_GCS mgerdin@3619: zgu@7074: #if INCLUDE_NMT zgu@7074: #include "services/mallocSiteTable.hpp" ctornqvi@4512: #include "services/memTracker.hpp" zgu@7074: #include "utilities/nativeCallStack.hpp" ctornqvi@4512: #endif // INCLUDE_NMT ctornqvi@4512: iignatyev@4592: #include "compiler/compileBroker.hpp" iklam@7381: #include "jvmtifiles/jvmtiEnv.hpp" iignatyev@4908: #include "runtime/compilationPolicy.hpp" iignatyev@4592: drchase@6680: PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC drchase@6680: mgerdin@6078: #define SIZE_T_MAX_VALUE ((size_t) -1) mgerdin@6078: mgerdin@3619: bool WhiteBox::_used = false; mgerdin@3619: mgerdin@3619: WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj)) mgerdin@3619: return (jlong)(void*)JNIHandles::resolve(obj); mgerdin@3619: WB_END mgerdin@3619: mgerdin@3619: WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o)) mgerdin@3619: return heapOopSize; mgerdin@3619: WB_END mgerdin@3619: minqi@7779: WB_ENTRY(jint, WB_GetVMPageSize(JNIEnv* env, jobject o)) minqi@7779: return os::vm_page_size(); minqi@7779: WB_END coleenp@4037: tschatzl@7781: WB_ENTRY(jlong, WB_GetVMLargePageSize(JNIEnv* env, jobject o)) tschatzl@7781: return os::large_page_size(); tschatzl@7781: WB_END tschatzl@7781: coleenp@4037: class WBIsKlassAliveClosure : public KlassClosure { coleenp@4037: Symbol* _name; coleenp@4037: bool _found; coleenp@4037: public: coleenp@4037: WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {} coleenp@4037: coleenp@4037: void do_klass(Klass* k) { coleenp@4037: if (_found) return; coleenp@4037: Symbol* ksym = k->name(); coleenp@4037: if (ksym->fast_compare(_name) == 0) { coleenp@4037: _found = true; coleenp@4037: } coleenp@4037: } coleenp@4037: coleenp@4037: bool found() const { coleenp@4037: return _found; coleenp@4037: } coleenp@4037: }; coleenp@4037: coleenp@4037: WB_ENTRY(jboolean, WB_IsClassAlive(JNIEnv* env, jobject target, jstring name)) coleenp@4037: Handle h_name = JNIHandles::resolve(name); coleenp@4037: if (h_name.is_null()) return false; coleenp@4037: Symbol* sym = java_lang_String::as_symbol(h_name, CHECK_false); coleenp@4037: TempNewSymbol tsym(sym); // Make sure to decrement reference count on sym on return coleenp@4037: coleenp@4037: WBIsKlassAliveClosure closure(sym); coleenp@4037: ClassLoaderDataGraph::classes_do(&closure); coleenp@4037: coleenp@4037: return closure.found(); coleenp@4037: WB_END coleenp@4037: iklam@7322: WB_ENTRY(jboolean, WB_ClassKnownToNotExist(JNIEnv* env, jobject o, jobject loader, jstring name)) iklam@7322: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iklam@7322: const char* class_name = env->GetStringUTFChars(name, NULL); iklam@7322: jboolean result = JVM_KnownToNotExist(env, loader, class_name); iklam@7322: env->ReleaseStringUTFChars(name, class_name); iklam@7322: return result; iklam@7322: WB_END iklam@7322: iklam@7322: WB_ENTRY(jobjectArray, WB_GetLookupCacheURLs(JNIEnv* env, jobject o, jobject loader)) iklam@7322: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iklam@7322: return JVM_GetResourceLookupCacheURLs(env, loader); iklam@7322: WB_END iklam@7322: iklam@7322: WB_ENTRY(jintArray, WB_GetLookupCacheMatches(JNIEnv* env, jobject o, jobject loader, jstring name)) iklam@7322: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iklam@7322: const char* resource_name = env->GetStringUTFChars(name, NULL); iklam@7322: jintArray result = JVM_GetResourceLookupCache(env, loader, resource_name); iklam@7322: iklam@7322: env->ReleaseStringUTFChars(name, resource_name); iklam@7322: return result; iklam@7322: WB_END iklam@7322: iklam@7381: WB_ENTRY(void, WB_AddToBootstrapClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) { iklam@7381: #if INCLUDE_JVMTI iklam@7382: ResourceMark rm; iklam@7382: const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment)); iklam@7381: JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION); iklam@7381: jvmtiError err = jvmti_env->AddToBootstrapClassLoaderSearch(seg); iklam@7381: assert(err == JVMTI_ERROR_NONE, "must not fail"); iklam@7381: #endif iklam@7381: } iklam@7381: WB_END iklam@7381: iklam@7381: WB_ENTRY(void, WB_AddToSystemClassLoaderSearch(JNIEnv* env, jobject o, jstring segment)) { iklam@7381: #if INCLUDE_JVMTI iklam@7382: ResourceMark rm; iklam@7382: const char* seg = java_lang_String::as_utf8_string(JNIHandles::resolve_non_null(segment)); iklam@7381: JvmtiEnv* jvmti_env = JvmtiEnv::create_a_jvmti(JVMTI_VERSION); iklam@7381: jvmtiError err = jvmti_env->AddToSystemClassLoaderSearch(seg); iklam@7381: assert(err == JVMTI_ERROR_NONE, "must not fail"); iklam@7381: #endif iklam@7381: } iklam@7381: WB_END iklam@7381: iklam@7381: tschatzl@5701: WB_ENTRY(jlong, WB_GetCompressedOopsMaxHeapSize(JNIEnv* env, jobject o)) { tschatzl@5701: return (jlong)Arguments::max_heap_for_compressed_oops(); tschatzl@5701: } tschatzl@5701: WB_END tschatzl@5701: tschatzl@5073: WB_ENTRY(void, WB_PrintHeapSizes(JNIEnv* env, jobject o)) { tschatzl@5073: CollectorPolicy * p = Universe::heap()->collector_policy(); tschatzl@5073: gclog_or_tty->print_cr("Minimum heap "SIZE_FORMAT" Initial heap " tschatzl@5073: SIZE_FORMAT" Maximum heap "SIZE_FORMAT" Min alignment "SIZE_FORMAT" Max alignment "SIZE_FORMAT, tschatzl@5073: p->min_heap_byte_size(), p->initial_heap_byte_size(), p->max_heap_byte_size(), jwilhelm@6085: p->space_alignment(), p->heap_alignment()); tschatzl@5073: } tschatzl@5073: WB_END tschatzl@5073: mgerdin@6078: #ifndef PRODUCT mgerdin@6078: // Forward declaration mgerdin@6078: void TestReservedSpace_test(); mgerdin@6078: void TestReserveMemorySpecial_test(); mgerdin@6078: void TestVirtualSpace_test(); mgerdin@6078: void TestMetaspaceAux_test(); mgerdin@6078: #endif mgerdin@6078: mgerdin@6078: WB_ENTRY(void, WB_RunMemoryUnitTests(JNIEnv* env, jobject o)) mgerdin@6078: #ifndef PRODUCT mgerdin@6078: TestReservedSpace_test(); mgerdin@6078: TestReserveMemorySpecial_test(); mgerdin@6078: TestVirtualSpace_test(); mgerdin@6078: TestMetaspaceAux_test(); mgerdin@6078: #endif mgerdin@6078: WB_END mgerdin@6078: mgerdin@6078: WB_ENTRY(void, WB_ReadFromNoaccessArea(JNIEnv* env, jobject o)) mgerdin@6078: size_t granularity = os::vm_allocation_granularity(); mgerdin@6078: ReservedHeapSpace rhs(100 * granularity, granularity, false, NULL); mgerdin@6078: VirtualSpace vs; mgerdin@6078: vs.initialize(rhs, 50 * granularity); mgerdin@6078: mgerdin@6078: //Check if constraints are complied mgerdin@6078: if (!( UseCompressedOops && rhs.base() != NULL && mgerdin@6078: Universe::narrow_oop_base() != NULL && mgerdin@6078: Universe::narrow_oop_use_implicit_null_checks() )) { mgerdin@6078: tty->print_cr("WB_ReadFromNoaccessArea method is useless:\n " mgerdin@6078: "\tUseCompressedOops is %d\n" mgerdin@6078: "\trhs.base() is "PTR_FORMAT"\n" mgerdin@6078: "\tUniverse::narrow_oop_base() is "PTR_FORMAT"\n" mgerdin@6078: "\tUniverse::narrow_oop_use_implicit_null_checks() is %d", mgerdin@6078: UseCompressedOops, mgerdin@6078: rhs.base(), mgerdin@6078: Universe::narrow_oop_base(), mgerdin@6078: Universe::narrow_oop_use_implicit_null_checks()); mgerdin@6078: return; mgerdin@6078: } mgerdin@6078: tty->print_cr("Reading from no access area... "); mgerdin@6078: tty->print_cr("*(vs.low_boundary() - rhs.noaccess_prefix() / 2 ) = %c", mgerdin@6078: *(vs.low_boundary() - rhs.noaccess_prefix() / 2 )); mgerdin@6078: WB_END mgerdin@6078: mgerdin@6078: static jint wb_stress_virtual_space_resize(size_t reserved_space_size, mgerdin@6078: size_t magnitude, size_t iterations) { mgerdin@6078: size_t granularity = os::vm_allocation_granularity(); mgerdin@6078: ReservedHeapSpace rhs(reserved_space_size * granularity, granularity, false, NULL); mgerdin@6078: VirtualSpace vs; mgerdin@6078: if (!vs.initialize(rhs, 0)) { mgerdin@6078: tty->print_cr("Failed to initialize VirtualSpace. Can't proceed."); mgerdin@6078: return 3; mgerdin@6078: } mgerdin@6078: mgerdin@6078: long seed = os::random(); mgerdin@6078: tty->print_cr("Random seed is %ld", seed); mgerdin@6078: os::init_random(seed); mgerdin@6078: mgerdin@6078: for (size_t i = 0; i < iterations; i++) { mgerdin@6078: mgerdin@6078: // Whether we will shrink or grow mgerdin@6078: bool shrink = os::random() % 2L == 0; mgerdin@6078: mgerdin@6078: // Get random delta to resize virtual space mgerdin@6078: size_t delta = (size_t)os::random() % magnitude; mgerdin@6078: mgerdin@6078: // If we are about to shrink virtual space below zero, then expand instead mgerdin@6078: if (shrink && vs.committed_size() < delta) { mgerdin@6078: shrink = false; mgerdin@6078: } mgerdin@6078: mgerdin@6078: // Resizing by delta mgerdin@6078: if (shrink) { mgerdin@6078: vs.shrink_by(delta); mgerdin@6078: } else { mgerdin@6078: // If expanding fails expand_by will silently return false mgerdin@6078: vs.expand_by(delta, true); mgerdin@6078: } mgerdin@6078: } mgerdin@6078: return 0; mgerdin@6078: } mgerdin@6078: mgerdin@6078: WB_ENTRY(jint, WB_StressVirtualSpaceResize(JNIEnv* env, jobject o, mgerdin@6078: jlong reserved_space_size, jlong magnitude, jlong iterations)) mgerdin@6078: tty->print_cr("reservedSpaceSize="JLONG_FORMAT", magnitude="JLONG_FORMAT", " mgerdin@6078: "iterations="JLONG_FORMAT"\n", reserved_space_size, magnitude, mgerdin@6078: iterations); mgerdin@6078: if (reserved_space_size < 0 || magnitude < 0 || iterations < 0) { mgerdin@6078: tty->print_cr("One of variables printed above is negative. Can't proceed.\n"); mgerdin@6078: return 1; mgerdin@6078: } mgerdin@6078: mgerdin@6078: // sizeof(size_t) depends on whether OS is 32bit or 64bit. sizeof(jlong) is mgerdin@6078: // always 8 byte. That's why we should avoid overflow in case of 32bit platform. mgerdin@6078: if (sizeof(size_t) < sizeof(jlong)) { mgerdin@6078: jlong size_t_max_value = (jlong) SIZE_T_MAX_VALUE; mgerdin@6078: if (reserved_space_size > size_t_max_value || magnitude > size_t_max_value mgerdin@6078: || iterations > size_t_max_value) { mgerdin@6078: tty->print_cr("One of variables printed above overflows size_t. Can't proceed.\n"); mgerdin@6078: return 2; mgerdin@6078: } mgerdin@6078: } mgerdin@6078: mgerdin@6078: return wb_stress_virtual_space_resize((size_t) reserved_space_size, mgerdin@6078: (size_t) magnitude, (size_t) iterations); mgerdin@6078: WB_END mgerdin@6078: tschatzl@7071: WB_ENTRY(jboolean, WB_isObjectInOldGen(JNIEnv* env, jobject o, jobject obj)) tschatzl@7071: oop p = JNIHandles::resolve(obj); tschatzl@7071: #if INCLUDE_ALL_GCS tschatzl@7071: if (UseG1GC) { tschatzl@7071: G1CollectedHeap* g1 = G1CollectedHeap::heap(); tschatzl@7071: const HeapRegion* hr = g1->heap_region_containing(p); tschatzl@7071: if (hr == NULL) { tschatzl@7071: return false; tschatzl@7071: } tschatzl@7071: return !(hr->is_young()); tschatzl@7071: } else if (UseParallelGC) { tschatzl@7071: ParallelScavengeHeap* psh = ParallelScavengeHeap::heap(); tschatzl@7071: return !psh->is_in_young(p); tschatzl@7071: } tschatzl@7071: #endif // INCLUDE_ALL_GCS tschatzl@7071: GenCollectedHeap* gch = GenCollectedHeap::heap(); tschatzl@7071: return !gch->is_in_young(p); tschatzl@7071: WB_END tschatzl@7071: tschatzl@7071: WB_ENTRY(jlong, WB_GetObjectSize(JNIEnv* env, jobject o, jobject obj)) tschatzl@7071: oop p = JNIHandles::resolve(obj); tschatzl@7071: return p->size() * HeapWordSize; tschatzl@7071: WB_END tschatzl@7071: jprovino@4542: #if INCLUDE_ALL_GCS mgerdin@3619: WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj)) mgerdin@3619: G1CollectedHeap* g1 = G1CollectedHeap::heap(); mgerdin@3619: oop result = JNIHandles::resolve(obj); mgerdin@3619: const HeapRegion* hr = g1->heap_region_containing(result); mgerdin@3619: return hr->isHumongous(); mgerdin@3619: WB_END mgerdin@3619: azakharov@7835: WB_ENTRY(jlong, WB_G1NumMaxRegions(JNIEnv* env, jobject o)) azakharov@7835: G1CollectedHeap* g1 = G1CollectedHeap::heap(); azakharov@7835: size_t nr = g1->max_regions(); azakharov@7835: return (jlong)nr; azakharov@7835: WB_END azakharov@7835: mgerdin@3619: WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o)) mgerdin@3619: G1CollectedHeap* g1 = G1CollectedHeap::heap(); tschatzl@7050: size_t nr = g1->num_free_regions(); mgerdin@3619: return (jlong)nr; mgerdin@3619: WB_END mgerdin@3619: mgerdin@3619: WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o)) mgerdin@3619: G1CollectedHeap* g1 = G1CollectedHeap::heap(); mgerdin@3619: ConcurrentMark* cm = g1->concurrent_mark(); mgerdin@3619: return cm->concurrent_marking_in_progress(); mgerdin@3619: WB_END mgerdin@3619: mgerdin@3619: WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o)) mgerdin@3619: return (jint)HeapRegion::GrainBytes; mgerdin@3619: WB_END azakharov@7835: azakharov@7835: WB_ENTRY(jobject, WB_G1AuxiliaryMemoryUsage(JNIEnv* env)) azakharov@7835: ResourceMark rm(THREAD); azakharov@7835: G1CollectedHeap* g1h = G1CollectedHeap::heap(); azakharov@7835: MemoryUsage usage = g1h->get_auxiliary_data_memory_usage(); azakharov@7835: Handle h = MemoryService::create_MemoryUsage_obj(usage, CHECK_NULL); azakharov@7835: return JNIHandles::make_local(env, h()); azakharov@7835: WB_END jprovino@4542: #endif // INCLUDE_ALL_GCS mgerdin@3619: cjplummer@5586: #if INCLUDE_NMT ctornqvi@4512: // Alloc memory using the test memory type so that we can use that to see if ctornqvi@4512: // NMT picks it up correctly ctornqvi@4885: WB_ENTRY(jlong, WB_NMTMalloc(JNIEnv* env, jobject o, jlong size)) ctornqvi@4885: jlong addr = 0; ctornqvi@7344: addr = (jlong)(uintptr_t)os::malloc(size, mtTest); zgu@7074: return addr; zgu@7074: WB_END ctornqvi@4512: zgu@7074: // Alloc memory with pseudo call stack. The test can create psudo malloc zgu@7074: // allocation site to stress the malloc tracking. zgu@7074: WB_ENTRY(jlong, WB_NMTMallocWithPseudoStack(JNIEnv* env, jobject o, jlong size, jint pseudo_stack)) zgu@7074: address pc = (address)(size_t)pseudo_stack; zgu@7074: NativeCallStack stack(&pc, 1); ctornqvi@7344: return (jlong)(uintptr_t)os::malloc(size, mtTest, stack); ctornqvi@4512: WB_END ctornqvi@4512: ctornqvi@4512: // Free the memory allocated by NMTAllocTest ctornqvi@4885: WB_ENTRY(void, WB_NMTFree(JNIEnv* env, jobject o, jlong mem)) ctornqvi@4885: os::free((void*)(uintptr_t)mem, mtTest); ctornqvi@4885: WB_END ctornqvi@4512: ctornqvi@4885: WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size)) ctornqvi@4885: jlong addr = 0; ctornqvi@4885: ctornqvi@4885: addr = (jlong)(uintptr_t)os::reserve_memory(size); ctornqvi@4885: MemTracker::record_virtual_memory_type((address)addr, mtTest); ctornqvi@4512: ctornqvi@4885: return addr; ctornqvi@4885: WB_END ctornqvi@4512: ctornqvi@4885: ctornqvi@4885: WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size)) dcubed@5255: os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem); ctornqvi@4885: MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest); ctornqvi@4885: WB_END ctornqvi@4885: ctornqvi@4885: WB_ENTRY(void, WB_NMTUncommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size)) ctornqvi@4885: os::uncommit_memory((char *)(uintptr_t)addr, size); ctornqvi@4885: WB_END ctornqvi@4885: ctornqvi@4885: WB_ENTRY(void, WB_NMTReleaseMemory(JNIEnv* env, jobject o, jlong addr, jlong size)) ctornqvi@4885: os::release_memory((char *)(uintptr_t)addr, size); ctornqvi@4512: WB_END ctornqvi@4512: zgu@7074: WB_ENTRY(jboolean, WB_NMTIsDetailSupported(JNIEnv* env)) zgu@7074: return MemTracker::tracking_level() == NMT_detail; ctornqvi@4512: WB_END ctornqvi@4512: coleenp@7267: WB_ENTRY(jboolean, WB_NMTChangeTrackingLevel(JNIEnv* env)) coleenp@7267: // Test that we can downgrade NMT levels but not upgrade them. coleenp@7267: if (MemTracker::tracking_level() == NMT_off) { coleenp@7267: MemTracker::transition_to(NMT_off); coleenp@7267: return MemTracker::tracking_level() == NMT_off; coleenp@7267: } else { coleenp@7267: assert(MemTracker::tracking_level() == NMT_detail, "Should start out as detail tracking"); coleenp@7267: MemTracker::transition_to(NMT_summary); coleenp@7267: assert(MemTracker::tracking_level() == NMT_summary, "Should be summary now"); zgu@7074: coleenp@7267: // Can't go to detail once NMT is set to summary. coleenp@7267: MemTracker::transition_to(NMT_detail); coleenp@7267: assert(MemTracker::tracking_level() == NMT_summary, "Should still be summary now"); coleenp@7267: coleenp@7267: // Shutdown sets tracking level to minimal. coleenp@7267: MemTracker::shutdown(); coleenp@7267: assert(MemTracker::tracking_level() == NMT_minimal, "Should be minimal now"); coleenp@7267: coleenp@7267: // Once the tracking level is minimal, we cannot increase to summary. coleenp@7267: // The code ignores this request instead of asserting because if the malloc site coleenp@7267: // table overflows in another thread, it tries to change the code to summary. coleenp@7267: MemTracker::transition_to(NMT_summary); coleenp@7267: assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now"); coleenp@7267: coleenp@7267: // Really can never go up to detail, verify that the code would never do this. coleenp@7267: MemTracker::transition_to(NMT_detail); coleenp@7267: assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now"); coleenp@7267: return MemTracker::tracking_level() == NMT_minimal; coleenp@7267: } coleenp@7267: WB_END gtriantafill@7342: gtriantafill@7342: WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o)) gtriantafill@7342: int hash_size = MallocSiteTable::hash_buckets(); gtriantafill@7342: assert(hash_size > 0, "NMT hash_size should be > 0"); gtriantafill@7342: return (jint)hash_size; gtriantafill@7342: WB_END ctornqvi@4512: #endif // INCLUDE_NMT ctornqvi@4512: iignatyev@4592: static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) { iignatyev@4592: assert(method != NULL, "method should not be null"); iignatyev@4592: ThreadToNativeFromVM ttn(thread); iignatyev@4592: return env->FromReflectedMethod(method); iignatyev@4592: } iignatyev@4592: iignatyev@4592: WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o)) iignatyev@4592: MutexLockerEx mu(Compile_lock); iignatyev@4592: CodeCache::mark_all_nmethods_for_deoptimization(); iignatyev@4592: VM_Deoptimize op; iignatyev@4592: VMThread::execute(&op); iignatyev@4592: WB_END iignatyev@4592: iignatyev@5541: WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) iignatyev@4592: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: int result = 0; ccheung@6346: CHECK_JNI_EXCEPTION_(env, result); iignatyev@4592: MutexLockerEx mu(Compile_lock); iignatyev@4592: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@5541: if (is_osr) { thartmann@7325: result += mh->mark_osr_nmethods(); thartmann@7325: } else if (mh->code() != NULL) { thartmann@7325: mh->code()->mark_for_deoptimization(); iignatyev@4592: ++result; iignatyev@4592: } iignatyev@4592: result += CodeCache::mark_for_deoptimization(mh()); iignatyev@4592: if (result > 0) { iignatyev@4592: VM_Deoptimize op; iignatyev@4592: VMThread::execute(&op); iignatyev@4592: } iignatyev@4592: return result; iignatyev@4592: WB_END iignatyev@4592: iignatyev@5541: WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) iignatyev@4592: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, JNI_FALSE); iignatyev@4592: MutexLockerEx mu(Compile_lock); iignatyev@4592: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@5541: nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); iignatyev@4592: if (code == NULL) { iignatyev@4592: return JNI_FALSE; iignatyev@4592: } iignatyev@4592: return (code->is_alive() && !code->is_marked_for_deoptimization()); iignatyev@4592: WB_END iignatyev@4592: iignatyev@5541: WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr)) iignatyev@4592: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, JNI_FALSE); iignatyev@4592: MutexLockerEx mu(Compile_lock); iignatyev@4592: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@5541: if (is_osr) { iignatyev@5541: return CompilationPolicy::can_be_osr_compiled(mh, comp_level); iignatyev@5541: } else { iignatyev@5541: return CompilationPolicy::can_be_compiled(mh, comp_level); iignatyev@5541: } iignatyev@4592: WB_END iignatyev@4592: iignatyev@4592: WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method)) iignatyev@4592: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, JNI_FALSE); iignatyev@4592: MutexLockerEx mu(Compile_lock); iignatyev@4592: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@4592: return mh->queued_for_compilation(); iignatyev@4592: WB_END iignatyev@4592: iignatyev@5541: WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) iignatyev@4592: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, CompLevel_none); iignatyev@4592: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@5541: nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); iignatyev@4592: return (code != NULL ? code->comp_level() : CompLevel_none); iignatyev@4592: WB_END iignatyev@4592: iignatyev@5541: WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level, jboolean is_osr)) iignatyev@4592: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION(env); iignatyev@4592: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@5541: if (is_osr) { iignatyev@5541: mh->set_not_osr_compilable(comp_level, true /* report */, "WhiteBox"); iignatyev@5541: } else { iignatyev@5541: mh->set_not_compilable(comp_level, true /* report */, "WhiteBox"); iignatyev@5541: } iignatyev@5541: WB_END iignatyev@5541: iignatyev@5541: WB_ENTRY(jint, WB_GetMethodEntryBci(JNIEnv* env, jobject o, jobject method)) iignatyev@5541: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, InvocationEntryBci); iignatyev@5541: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@5541: nmethod* code = mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false); iignatyev@5541: return (code != NULL && code->is_osr_method() ? code->osr_entry_bci() : InvocationEntryBci); iignatyev@4592: WB_END iignatyev@4592: iignatyev@4908: WB_ENTRY(jboolean, WB_TestSetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) iignatyev@4592: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, JNI_FALSE); iignatyev@4592: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@4592: bool result = mh->dont_inline(); iignatyev@4592: mh->set_dont_inline(value == JNI_TRUE); iignatyev@4592: return result; iignatyev@4592: WB_END iignatyev@4592: iignatyev@5541: WB_ENTRY(jint, WB_GetCompileQueueSize(JNIEnv* env, jobject o, jint comp_level)) iignatyev@5541: if (comp_level == CompLevel_any) { iignatyev@5541: return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ + iignatyev@5541: CompileBroker::queue_size(CompLevel_full_profile) /* C1 */; iignatyev@5541: } else { iignatyev@5541: return CompileBroker::queue_size(comp_level); iignatyev@5541: } iignatyev@4592: WB_END iignatyev@4592: iignatyev@4908: WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value)) iignatyev@4908: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, JNI_FALSE); iignatyev@4908: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@4908: bool result = mh->force_inline(); iignatyev@4908: mh->set_force_inline(value == JNI_TRUE); iignatyev@4908: return result; iignatyev@4908: WB_END iignatyev@4908: iignatyev@5541: WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci)) iignatyev@4908: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION_(env, JNI_FALSE); iignatyev@4908: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@5541: nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD); iignatyev@4908: MutexLockerEx mu(Compile_lock); iignatyev@4908: return (mh->queued_for_compilation() || nm != NULL); iignatyev@4908: WB_END iignatyev@4908: iignatyev@6610: class VM_WhiteBoxOperation : public VM_Operation { iignatyev@6610: public: iignatyev@6610: VM_WhiteBoxOperation() { } iignatyev@6610: VMOp_Type type() const { return VMOp_WhiteBoxOperation; } iignatyev@6610: bool allow_nested_vm_operations() const { return true; } iignatyev@6610: }; iignatyev@6610: iignatyev@6610: class AlwaysFalseClosure : public BoolObjectClosure { iignatyev@6610: public: iignatyev@6610: bool do_object_b(oop p) { return false; } iignatyev@6610: }; iignatyev@6610: iignatyev@6610: static AlwaysFalseClosure always_false; iignatyev@6610: iignatyev@6610: class VM_WhiteBoxCleanMethodData : public VM_WhiteBoxOperation { iignatyev@6610: public: iignatyev@6610: VM_WhiteBoxCleanMethodData(MethodData* mdo) : _mdo(mdo) { } iignatyev@6610: void doit() { iignatyev@6610: _mdo->clean_method_data(&always_false); iignatyev@6610: } iignatyev@6610: private: iignatyev@6610: MethodData* _mdo; iignatyev@6610: }; iignatyev@6610: iignatyev@4908: WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method)) iignatyev@4908: jmethodID jmid = reflected_method_to_jmid(thread, env, method); ccheung@6346: CHECK_JNI_EXCEPTION(env); iignatyev@4908: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@4908: MutexLockerEx mu(Compile_lock); iignatyev@4908: MethodData* mdo = mh->method_data(); jiangli@4938: MethodCounters* mcs = mh->method_counters(); iignatyev@4908: iignatyev@4908: if (mdo != NULL) { iignatyev@4908: mdo->init(); iignatyev@4908: ResourceMark rm; iignatyev@4908: int arg_count = mdo->method()->size_of_parameters(); iignatyev@4908: for (int i = 0; i < arg_count; i++) { iignatyev@4908: mdo->set_arg_modified(i, 0); iignatyev@4908: } iignatyev@6610: VM_WhiteBoxCleanMethodData op(mdo); iignatyev@6610: VMThread::execute(&op); iignatyev@4908: } iignatyev@4908: iignatyev@4908: mh->clear_not_c1_compilable(); iignatyev@4908: mh->clear_not_c2_compilable(); iignatyev@4908: mh->clear_not_c2_osr_compilable(); iignatyev@4908: NOT_PRODUCT(mh->set_compiled_invocation_count(0)); jiangli@4938: if (mcs != NULL) { jiangli@4938: mcs->backedge_counter()->init(); jiangli@4938: mcs->invocation_counter()->init(); jiangli@4938: mcs->set_interpreter_invocation_count(0); jiangli@4938: mcs->set_interpreter_throwout_count(0); iignatyev@4908: iignatyev@4908: #ifdef TIERED jiangli@4938: mcs->set_rate(0.0F); vlivanov@7179: mh->set_prev_event_count(0); vlivanov@7179: mh->set_prev_time(0); iignatyev@4908: #endif jiangli@4938: } iignatyev@4908: WB_END iignatyev@4908: iignatyev@6963: template iignatyev@6963: static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) { iignatyev@6963: if (name == NULL) { iignatyev@6963: return false; iignatyev@6963: } iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: const char* flag_name = env->GetStringUTFChars(name, NULL); iignatyev@6963: bool result = (*TAt)(flag_name, value); iignatyev@6963: env->ReleaseStringUTFChars(name, flag_name); iignatyev@6963: return result; iignatyev@6963: } iignatyev@6963: iignatyev@6963: template iignatyev@6963: static bool SetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAtPut)(const char*, T*, Flag::Flags)) { iignatyev@6963: if (name == NULL) { iignatyev@6963: return false; iignatyev@6963: } iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: const char* flag_name = env->GetStringUTFChars(name, NULL); iignatyev@6963: bool result = (*TAtPut)(flag_name, value, Flag::INTERNAL); iignatyev@6963: env->ReleaseStringUTFChars(name, flag_name); iignatyev@6963: return result; iignatyev@6963: } iignatyev@6963: iignatyev@6963: template iignatyev@6963: static jobject box(JavaThread* thread, JNIEnv* env, Symbol* name, Symbol* sig, T value) { iignatyev@6963: ResourceMark rm(thread); iignatyev@6963: jclass clazz = env->FindClass(name->as_C_string()); iignatyev@6963: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6963: jmethodID methodID = env->GetStaticMethodID(clazz, iignatyev@6963: vmSymbols::valueOf_name()->as_C_string(), iignatyev@6963: sig->as_C_string()); iignatyev@6963: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6963: jobject result = env->CallStaticObjectMethod(clazz, methodID, value); iignatyev@6963: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6963: return result; iignatyev@6963: } iignatyev@6963: iignatyev@6963: static jobject booleanBox(JavaThread* thread, JNIEnv* env, jboolean value) { iignatyev@6963: return box(thread, env, vmSymbols::java_lang_Boolean(), vmSymbols::Boolean_valueOf_signature(), value); iignatyev@6963: } iignatyev@6963: static jobject integerBox(JavaThread* thread, JNIEnv* env, jint value) { iignatyev@6963: return box(thread, env, vmSymbols::java_lang_Integer(), vmSymbols::Integer_valueOf_signature(), value); iignatyev@6963: } iignatyev@6963: static jobject longBox(JavaThread* thread, JNIEnv* env, jlong value) { iignatyev@6963: return box(thread, env, vmSymbols::java_lang_Long(), vmSymbols::Long_valueOf_signature(), value); iignatyev@6963: } iignatyev@6963: /* static jobject floatBox(JavaThread* thread, JNIEnv* env, jfloat value) { iignatyev@6963: return box(thread, env, vmSymbols::java_lang_Float(), vmSymbols::Float_valueOf_signature(), value); iignatyev@6963: }*/ iignatyev@6963: static jobject doubleBox(JavaThread* thread, JNIEnv* env, jdouble value) { iignatyev@6963: return box(thread, env, vmSymbols::java_lang_Double(), vmSymbols::Double_valueOf_signature(), value); iignatyev@6963: } iignatyev@6963: iignatyev@6963: WB_ENTRY(jobject, WB_GetBooleanVMFlag(JNIEnv* env, jobject o, jstring name)) iignatyev@6963: bool result; iignatyev@6963: if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::boolAt)) { iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: return booleanBox(thread, env, result); iignatyev@6963: } iignatyev@6963: return NULL; iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(jobject, WB_GetIntxVMFlag(JNIEnv* env, jobject o, jstring name)) iignatyev@6963: intx result; iignatyev@6963: if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::intxAt)) { iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: return longBox(thread, env, result); iignatyev@6963: } iignatyev@6963: return NULL; iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(jobject, WB_GetUintxVMFlag(JNIEnv* env, jobject o, jstring name)) iignatyev@6963: uintx result; iignatyev@6963: if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::uintxAt)) { iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: return longBox(thread, env, result); iignatyev@6963: } iignatyev@6963: return NULL; iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(jobject, WB_GetUint64VMFlag(JNIEnv* env, jobject o, jstring name)) iignatyev@6963: uint64_t result; iignatyev@6963: if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::uint64_tAt)) { iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: return longBox(thread, env, result); iignatyev@6963: } iignatyev@6963: return NULL; iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(jobject, WB_GetDoubleVMFlag(JNIEnv* env, jobject o, jstring name)) iignatyev@6963: double result; iignatyev@6963: if (GetVMFlag (thread, env, name, &result, &CommandLineFlags::doubleAt)) { iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: return doubleBox(thread, env, result); iignatyev@6963: } iignatyev@6963: return NULL; iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(jstring, WB_GetStringVMFlag(JNIEnv* env, jobject o, jstring name)) iignatyev@6963: ccstr ccstrResult; iignatyev@6963: if (GetVMFlag (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAt)) { iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: jstring result = env->NewStringUTF(ccstrResult); iignatyev@6963: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6963: return result; iignatyev@6963: } iignatyev@6963: return NULL; iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(void, WB_SetBooleanVMFlag(JNIEnv* env, jobject o, jstring name, jboolean value)) iignatyev@6963: bool result = value == JNI_TRUE ? true : false; iignatyev@6963: SetVMFlag (thread, env, name, &result, &CommandLineFlags::boolAtPut); iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(void, WB_SetIntxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) iignatyev@6963: intx result = value; iignatyev@6963: SetVMFlag (thread, env, name, &result, &CommandLineFlags::intxAtPut); iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(void, WB_SetUintxVMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) iignatyev@6963: uintx result = value; iignatyev@6963: SetVMFlag (thread, env, name, &result, &CommandLineFlags::uintxAtPut); iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(void, WB_SetUint64VMFlag(JNIEnv* env, jobject o, jstring name, jlong value)) iignatyev@6963: uint64_t result = value; iignatyev@6963: SetVMFlag (thread, env, name, &result, &CommandLineFlags::uint64_tAtPut); iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(void, WB_SetDoubleVMFlag(JNIEnv* env, jobject o, jstring name, jdouble value)) iignatyev@6963: double result = value; iignatyev@6963: SetVMFlag (thread, env, name, &result, &CommandLineFlags::doubleAtPut); iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value)) iignatyev@6963: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI iignatyev@6963: const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL); iignatyev@6963: ccstr ccstrResult = ccstrValue; iignatyev@6963: bool needFree; iignatyev@6963: { iignatyev@6963: ThreadInVMfromNative ttvfn(thread); // back to VM iignatyev@6963: needFree = SetVMFlag (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAtPut); iignatyev@6963: } iignatyev@6963: if (value != NULL) { iignatyev@6963: env->ReleaseStringUTFChars(value, ccstrValue); iignatyev@6963: } iignatyev@6963: if (needFree) { iignatyev@6963: FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal); iignatyev@6963: } iignatyev@6963: WB_END iignatyev@6963: iignatyev@6963: mgerdin@4850: WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) mgerdin@4850: ResourceMark rm(THREAD); mgerdin@4850: int len; hseigel@4987: jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false); hseigel@4987: return (StringTable::lookup(name, len) != NULL); mgerdin@4850: WB_END mgerdin@4850: mgerdin@4850: WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o)) mgerdin@4850: Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true); mgerdin@4850: Universe::heap()->collect(GCCause::_last_ditch_collection); sjohanss@7165: #if INCLUDE_ALL_GCS sjohanss@7165: if (UseG1GC) { sjohanss@7165: // Needs to be cleared explicitly for G1 sjohanss@7165: Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false); sjohanss@7165: } sjohanss@7165: #endif // INCLUDE_ALL_GCS mgerdin@4850: WB_END mgerdin@4850: tschatzl@7071: WB_ENTRY(void, WB_YoungGC(JNIEnv* env, jobject o)) tschatzl@7071: Universe::heap()->collect(GCCause::_wb_young_gc); tschatzl@7071: WB_END mikael@4989: mikael@5174: WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o)) mikael@5174: // static+volatile in order to force the read to happen mikael@5174: // (not be eliminated by the compiler) mikael@5174: static char c; mikael@5174: static volatile char* p; mikael@5174: mikael@5174: p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0); mikael@5174: if (p == NULL) { mikael@5174: THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory"); mikael@5174: } mikael@5174: mikael@5174: c = *p; mikael@4989: WB_END mikael@4989: iignatyev@6427: WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o)) iignatyev@6427: const char* cpu_features = VM_Version::cpu_features(); iignatyev@6427: ThreadToNativeFromVM ttn(thread); iignatyev@6427: jstring features_string = env->NewStringUTF(cpu_features); iignatyev@6427: iignatyev@6427: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6427: iignatyev@6427: return features_string; iignatyev@6427: WB_END iignatyev@6427: iignatyev@6525: iignatyev@6525: WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) iignatyev@6525: ResourceMark rm(THREAD); iignatyev@6525: jmethodID jmid = reflected_method_to_jmid(thread, env, method); iignatyev@6525: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6525: methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); iignatyev@6525: nmethod* code = is_osr ? mh->lookup_osr_nmethod_for(InvocationEntryBci, CompLevel_none, false) : mh->code(); iignatyev@6525: jobjectArray result = NULL; iignatyev@6525: if (code == NULL) { iignatyev@6525: return result; iignatyev@6525: } iignatyev@6525: int insts_size = code->insts_size(); iignatyev@6525: iignatyev@6525: ThreadToNativeFromVM ttn(thread); iignatyev@6525: jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); iignatyev@6525: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6525: result = env->NewObjectArray(2, clazz, NULL); iignatyev@6525: if (result == NULL) { iignatyev@6525: return result; iignatyev@6525: } iignatyev@6525: iignatyev@6963: jobject obj = integerBox(thread, env, code->comp_level()); iignatyev@6525: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6525: env->SetObjectArrayElement(result, 0, obj); iignatyev@6525: iignatyev@6525: jbyteArray insts = env->NewByteArray(insts_size); iignatyev@6525: CHECK_JNI_EXCEPTION_(env, NULL); iignatyev@6525: env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin()); iignatyev@6525: env->SetObjectArrayElement(result, 1, insts); iignatyev@6525: iignatyev@6525: return result; iignatyev@6525: WB_END iignatyev@6525: iignatyev@6525: stefank@6992: int WhiteBox::array_bytes_to_length(size_t bytes) { stefank@6992: return Array::bytes_to_length(bytes); stefank@6992: } stefank@6992: stefank@6992: WB_ENTRY(jlong, WB_AllocateMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong size)) stefank@6992: if (size < 0) { stefank@6992: THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), stefank@6992: err_msg("WB_AllocateMetaspace: size is negative: " JLONG_FORMAT, size)); stefank@6992: } stefank@6992: stefank@6992: oop class_loader_oop = JNIHandles::resolve(class_loader); stefank@6992: ClassLoaderData* cld = class_loader_oop != NULL stefank@6992: ? java_lang_ClassLoader::loader_data(class_loader_oop) stefank@6992: : ClassLoaderData::the_null_class_loader_data(); stefank@6992: stefank@6992: void* metadata = MetadataFactory::new_writeable_array(cld, WhiteBox::array_bytes_to_length((size_t)size), thread); stefank@6992: stefank@6992: return (jlong)(uintptr_t)metadata; stefank@6992: WB_END stefank@6992: stefank@6992: WB_ENTRY(void, WB_FreeMetaspace(JNIEnv* env, jobject wb, jobject class_loader, jlong addr, jlong size)) stefank@6992: oop class_loader_oop = JNIHandles::resolve(class_loader); stefank@6992: ClassLoaderData* cld = class_loader_oop != NULL stefank@6992: ? java_lang_ClassLoader::loader_data(class_loader_oop) stefank@6992: : ClassLoaderData::the_null_class_loader_data(); stefank@6992: stefank@6992: MetadataFactory::free_array(cld, (Array*)(uintptr_t)addr); stefank@6992: WB_END stefank@6992: ehelin@7254: WB_ENTRY(jlong, WB_IncMetaspaceCapacityUntilGC(JNIEnv* env, jobject wb, jlong inc)) ehelin@7254: if (inc < 0) { ehelin@7254: THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), ehelin@7254: err_msg("WB_IncMetaspaceCapacityUntilGC: inc is negative: " JLONG_FORMAT, inc)); ehelin@7254: } ehelin@7254: ehelin@7254: jlong max_size_t = (jlong) ((size_t) -1); ehelin@7254: if (inc > max_size_t) { ehelin@7254: THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), ehelin@7254: err_msg("WB_IncMetaspaceCapacityUntilGC: inc does not fit in size_t: " JLONG_FORMAT, inc)); ehelin@7254: } ehelin@7254: ehelin@7254: size_t new_cap_until_GC = 0; ehelin@7254: size_t aligned_inc = align_size_down((size_t) inc, Metaspace::commit_alignment()); ehelin@7254: bool success = MetaspaceGC::inc_capacity_until_GC(aligned_inc, &new_cap_until_GC); ehelin@7254: if (!success) { ehelin@7254: THROW_MSG_0(vmSymbols::java_lang_IllegalStateException(), ehelin@7254: "WB_IncMetaspaceCapacityUntilGC: could not increase capacity until GC " ehelin@7254: "due to contention with another thread"); ehelin@7254: } ehelin@7254: return (jlong) new_cap_until_GC; ehelin@7254: WB_END ehelin@7254: ehelin@7254: WB_ENTRY(jlong, WB_MetaspaceCapacityUntilGC(JNIEnv* env, jobject wb)) ehelin@7254: return (jlong) MetaspaceGC::capacity_until_GC(); ehelin@7254: WB_END ehelin@7254: bmoloden@7797: WB_ENTRY(jboolean, WB_IsMonitorInflated(JNIEnv* env, jobject wb, jobject obj)) bmoloden@7797: oop obj_oop = JNIHandles::resolve(obj); bmoloden@7797: return (jboolean) obj_oop->mark()->has_monitor(); bmoloden@7797: WB_END bmoloden@7797: bmoloden@7797: WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb)) bmoloden@7797: VM_ForceSafepoint force_safepoint_op; bmoloden@7797: VMThread::execute(&force_safepoint_op); bmoloden@7797: WB_END bmoloden@7797: nloodin@3681: //Some convenience methods to deal with objects from java nloodin@3681: int WhiteBox::offset_for_field(const char* field_name, oop object, nloodin@3681: Symbol* signature_symbol) { nloodin@3681: assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid"); nloodin@3681: Thread* THREAD = Thread::current(); nloodin@3681: nloodin@3681: //Get the class of our object coleenp@4037: Klass* arg_klass = object->klass(); nloodin@3681: //Turn it into an instance-klass coleenp@4037: InstanceKlass* ik = InstanceKlass::cast(arg_klass); nloodin@3681: nloodin@3681: //Create symbols to look for in the class nloodin@3681: TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name), nloodin@3681: THREAD); nloodin@3681: nloodin@3681: //To be filled in with an offset of the field we're looking for nloodin@3681: fieldDescriptor fd; nloodin@3681: coleenp@4037: Klass* res = ik->find_field(name_symbol, signature_symbol, &fd); nloodin@3681: if (res == NULL) { nloodin@3681: tty->print_cr("Invalid layout of %s at %s", ik->external_name(), nloodin@3681: name_symbol->as_C_string()); dbuck@7788: vm_exit_during_initialization("Invalid layout of preloaded class: use -XX:+TraceClassLoading to see the origin of the problem class"); nloodin@3681: } nloodin@3681: nloodin@3681: //fetch the field at the offset we've found nloodin@3681: int dest_offset = fd.offset(); nloodin@3681: nloodin@3681: return dest_offset; nloodin@3681: } nloodin@3681: nloodin@3681: nloodin@3681: const char* WhiteBox::lookup_jstring(const char* field_name, oop object) { nloodin@3681: int offset = offset_for_field(field_name, object, nloodin@3681: vmSymbols::string_signature()); nloodin@3681: oop string = object->obj_field(offset); sla@3905: if (string == NULL) { sla@3905: return NULL; sla@3905: } nloodin@3681: const char* ret = java_lang_String::as_utf8_string(string); nloodin@3681: return ret; nloodin@3681: } nloodin@3681: nloodin@3681: bool WhiteBox::lookup_bool(const char* field_name, oop object) { nloodin@3681: int offset = nloodin@3681: offset_for_field(field_name, object, vmSymbols::bool_signature()); nloodin@3681: bool ret = (object->bool_field(offset) == JNI_TRUE); nloodin@3681: return ret; nloodin@3681: } nloodin@3681: sjohanss@7165: void WhiteBox::register_methods(JNIEnv* env, jclass wbclass, JavaThread* thread, JNINativeMethod* method_array, int method_count) { sjohanss@7165: ResourceMark rm; sjohanss@7165: ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI sjohanss@7165: sjohanss@7165: // one by one registration natives for exception catching sjohanss@7165: jclass no_such_method_error_klass = env->FindClass(vmSymbols::java_lang_NoSuchMethodError()->as_C_string()); sjohanss@7165: CHECK_JNI_EXCEPTION(env); sjohanss@7165: for (int i = 0, n = method_count; i < n; ++i) { sjohanss@7165: // Skip dummy entries sjohanss@7165: if (method_array[i].fnPtr == NULL) continue; sjohanss@7165: if (env->RegisterNatives(wbclass, &method_array[i], 1) != 0) { sjohanss@7165: jthrowable throwable_obj = env->ExceptionOccurred(); sjohanss@7165: if (throwable_obj != NULL) { sjohanss@7165: env->ExceptionClear(); sjohanss@7165: if (env->IsInstanceOf(throwable_obj, no_such_method_error_klass)) { sjohanss@7165: // NoSuchMethodError is thrown when a method can't be found or a method is not native. sjohanss@7165: // Ignoring the exception since it is not preventing use of other WhiteBox methods. sjohanss@7165: tty->print_cr("Warning: 'NoSuchMethodError' on register of sun.hotspot.WhiteBox::%s%s", sjohanss@7165: method_array[i].name, method_array[i].signature); sjohanss@7165: } sjohanss@7165: } else { sjohanss@7165: // Registration failed unexpectedly. sjohanss@7165: tty->print_cr("Warning: unexpected error on register of sun.hotspot.WhiteBox::%s%s. All methods will be unregistered", sjohanss@7165: method_array[i].name, method_array[i].signature); sjohanss@7165: env->UnregisterNatives(wbclass); sjohanss@7165: break; sjohanss@7165: } sjohanss@7165: } sjohanss@7165: } sjohanss@7165: } nloodin@3681: mgerdin@3619: #define CC (char*) mgerdin@3619: mgerdin@3619: static JNINativeMethod methods[] = { mgerdin@3619: {CC"getObjectAddress", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress }, tschatzl@7071: {CC"getObjectSize", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize }, tschatzl@7071: {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen }, mgerdin@3619: {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize }, minqi@7779: {CC"getVMPageSize", CC"()I", (void*)&WB_GetVMPageSize }, tschatzl@7781: {CC"getVMLargePageSize", CC"()J", (void*)&WB_GetVMLargePageSize}, iignatyev@4592: {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, iklam@7322: {CC"classKnownToNotExist", iklam@7322: CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)Z",(void*)&WB_ClassKnownToNotExist}, iklam@7322: {CC"getLookupCacheURLs", CC"(Ljava/lang/ClassLoader;)[Ljava/net/URL;", (void*)&WB_GetLookupCacheURLs}, iklam@7322: {CC"getLookupCacheMatches", CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)[I", iklam@7322: (void*)&WB_GetLookupCacheMatches}, iignatyev@4592: {CC"parseCommandLine", iignatyev@4592: CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;", nloodin@3681: (void*) &WB_ParseCommandLine nloodin@3681: }, iklam@7381: {CC"addToBootstrapClassLoaderSearch", CC"(Ljava/lang/String;)V", iklam@7381: (void*)&WB_AddToBootstrapClassLoaderSearch}, iklam@7381: {CC"addToSystemClassLoaderSearch", CC"(Ljava/lang/String;)V", iklam@7381: (void*)&WB_AddToSystemClassLoaderSearch}, tschatzl@5701: {CC"getCompressedOopsMaxHeapSize", CC"()J", tschatzl@5701: (void*)&WB_GetCompressedOopsMaxHeapSize}, tschatzl@5073: {CC"printHeapSizes", CC"()V", (void*)&WB_PrintHeapSizes }, mgerdin@6078: {CC"runMemoryUnitTests", CC"()V", (void*)&WB_RunMemoryUnitTests}, mgerdin@6078: {CC"readFromNoaccessArea",CC"()V", (void*)&WB_ReadFromNoaccessArea}, mgerdin@6078: {CC"stressVirtualSpaceResize",CC"(JJJ)I", (void*)&WB_StressVirtualSpaceResize}, jprovino@4542: #if INCLUDE_ALL_GCS mgerdin@3619: {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark}, mgerdin@3619: {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous }, azakharov@7835: {CC"g1NumMaxRegions", CC"()J", (void*)&WB_G1NumMaxRegions }, mgerdin@3619: {CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions }, mgerdin@3619: {CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize }, azakharov@7835: {CC"g1AuxiliaryMemoryUsage", CC"()Ljava/lang/management/MemoryUsage;", azakharov@7835: (void*)&WB_G1AuxiliaryMemoryUsage }, jprovino@4542: #endif // INCLUDE_ALL_GCS cjplummer@5586: #if INCLUDE_NMT ctornqvi@4885: {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc }, zgu@7074: {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack}, ctornqvi@4885: {CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree }, ctornqvi@4885: {CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory }, ctornqvi@4885: {CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory }, ctornqvi@4885: {CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory }, ctornqvi@4885: {CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory }, cjplummer@5586: {CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported}, coleenp@7267: {CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel}, gtriantafill@7342: {CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize }, ctornqvi@4512: #endif // INCLUDE_NMT iignatyev@4592: {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll }, iignatyev@5541: {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I", iignatyev@4592: (void*)&WB_DeoptimizeMethod }, iignatyev@5541: {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;Z)Z", iignatyev@4592: (void*)&WB_IsMethodCompiled }, iignatyev@5541: {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;IZ)Z", iignatyev@4592: (void*)&WB_IsMethodCompilable}, iignatyev@4592: {CC"isMethodQueuedForCompilation", iignatyev@4951: CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation}, iignatyev@4592: {CC"makeMethodNotCompilable", iignatyev@5541: CC"(Ljava/lang/reflect/Executable;IZ)V", (void*)&WB_MakeMethodNotCompilable}, iignatyev@4908: {CC"testSetDontInlineMethod", iignatyev@4951: CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod}, iignatyev@4592: {CC"getMethodCompilationLevel", iignatyev@5541: CC"(Ljava/lang/reflect/Executable;Z)I", (void*)&WB_GetMethodCompilationLevel}, iignatyev@5541: {CC"getMethodEntryBci", iignatyev@5541: CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci}, iignatyev@5541: {CC"getCompileQueueSize", iignatyev@5541: CC"(I)I", (void*)&WB_GetCompileQueueSize}, iignatyev@4908: {CC"testSetForceInlineMethod", iignatyev@4951: CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod}, iignatyev@4908: {CC"enqueueMethodForCompilation", iignatyev@5541: CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, iignatyev@4908: {CC"clearMethodState", iignatyev@4951: CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, iignatyev@6963: {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, iignatyev@6963: {CC"setIntxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetIntxVMFlag}, iignatyev@6963: {CC"setUintxVMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUintxVMFlag}, iignatyev@6963: {CC"setUint64VMFlag", CC"(Ljava/lang/String;J)V",(void*)&WB_SetUint64VMFlag}, iignatyev@6963: {CC"setDoubleVMFlag", CC"(Ljava/lang/String;D)V",(void*)&WB_SetDoubleVMFlag}, iignatyev@6963: {CC"setStringVMFlag", CC"(Ljava/lang/String;Ljava/lang/String;)V", iignatyev@6963: (void*)&WB_SetStringVMFlag}, iignatyev@6963: {CC"getBooleanVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Boolean;", iignatyev@6963: (void*)&WB_GetBooleanVMFlag}, iignatyev@6963: {CC"getIntxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", iignatyev@6963: (void*)&WB_GetIntxVMFlag}, iignatyev@6963: {CC"getUintxVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", iignatyev@6963: (void*)&WB_GetUintxVMFlag}, iignatyev@6963: {CC"getUint64VMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;", iignatyev@6963: (void*)&WB_GetUint64VMFlag}, iignatyev@6963: {CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;", iignatyev@6963: (void*)&WB_GetDoubleVMFlag}, iignatyev@6963: {CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;", iignatyev@6963: (void*)&WB_GetStringVMFlag}, iignatyev@6963: {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, mgerdin@4850: {CC"fullGC", CC"()V", (void*)&WB_FullGC }, tschatzl@7071: {CC"youngGC", CC"()V", (void*)&WB_YoungGC }, mikael@5174: {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory }, stefank@6992: {CC"allocateMetaspace", stefank@6992: CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace }, stefank@6992: {CC"freeMetaspace", stefank@6992: CC"(Ljava/lang/ClassLoader;JJ)V", (void*)&WB_FreeMetaspace }, ehelin@7254: {CC"incMetaspaceCapacityUntilGC", CC"(J)J", (void*)&WB_IncMetaspaceCapacityUntilGC }, ehelin@7254: {CC"metaspaceCapacityUntilGC", CC"()J", (void*)&WB_MetaspaceCapacityUntilGC }, iignatyev@6427: {CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures }, iignatyev@6525: {CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;", iignatyev@6525: (void*)&WB_GetNMethod }, bmoloden@7797: {CC"isMonitorInflated", CC"(Ljava/lang/Object;)Z", (void*)&WB_IsMonitorInflated }, bmoloden@7797: {CC"forceSafepoint", CC"()V", (void*)&WB_ForceSafepoint }, mgerdin@3619: }; mgerdin@3619: mgerdin@3619: #undef CC mgerdin@3619: mgerdin@3619: JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass)) mgerdin@3619: { mgerdin@3619: if (WhiteBoxAPI) { mgerdin@3619: // Make sure that wbclass is loaded by the null classloader mgerdin@3619: instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass()); mgerdin@3619: Handle loader(ikh->class_loader()); mgerdin@3619: if (loader.is_null()) { sjohanss@7165: WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0])); sjohanss@7165: WhiteBox::register_extended(env, wbclass, thread); sjohanss@7165: WhiteBox::set_used(); mgerdin@3619: } mgerdin@3619: } mgerdin@3619: } mgerdin@3619: JVM_END