52 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
53 #include "gc_implementation/g1/concurrentMark.hpp"
54 #include "gc_implementation/g1/concurrentMarkThread.hpp"
55 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
56 #include "gc_implementation/g1/heapRegionRemSet.hpp"
57 #endif // INCLUDE_ALL_GCS
58 #if INCLUDE_NMT
59 #include "services/mallocSiteTable.hpp"
60 #include "services/memTracker.hpp"
61 #include "utilities/nativeCallStack.hpp"
62 #endif // INCLUDE_NMT
63
64
65 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
66
67 #define SIZE_T_MAX_VALUE ((size_t) -1)
68
69 bool WhiteBox::_used = false;
70 volatile bool WhiteBox::compilation_locked = false;
71
72 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
73 return (jlong)(void*)JNIHandles::resolve(obj);
74 WB_END
75
76 WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
77 return heapOopSize;
78 WB_END
79
80 WB_ENTRY(jint, WB_GetVMPageSize(JNIEnv* env, jobject o))
81 return os::vm_page_size();
82 WB_END
83
84 class WBIsKlassAliveClosure : public KlassClosure {
85 Symbol* _name;
86 bool _found;
87 public:
88 WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {}
89
90 void do_klass(Klass* k) {
91 if (_found) return;
387 // Really can never go up to detail, verify that the code would never do this.
388 MemTracker::transition_to(NMT_detail);
389 assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
390 return MemTracker::tracking_level() == NMT_minimal;
391 }
392 WB_END
393
394 WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o))
395 int hash_size = MallocSiteTable::hash_buckets();
396 assert(hash_size > 0, "NMT hash_size should be > 0");
397 return (jint)hash_size;
398 WB_END
399 #endif // INCLUDE_NMT
400
401 static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
402 assert(method != NULL, "method should not be null");
403 ThreadToNativeFromVM ttn(thread);
404 return env->FromReflectedMethod(method);
405 }
406
407 WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
408 MutexLockerEx mu(Compile_lock);
409 CodeCache::mark_all_nmethods_for_deoptimization();
410 VM_Deoptimize op;
411 VMThread::execute(&op);
412 WB_END
413
414 WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
415 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
416 int result = 0;
417 CHECK_JNI_EXCEPTION_(env, result);
418 MutexLockerEx mu(Compile_lock);
419 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
420 if (is_osr) {
421 result += mh->mark_osr_nmethods();
422 } else if (mh->code() != NULL) {
423 mh->code()->mark_for_deoptimization();
424 ++result;
425 }
426 result += CodeCache::mark_for_deoptimization(mh());
509 WB_END
510
511 WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
512 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
513 CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
514 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
515 bool result = mh->force_inline();
516 mh->set_force_inline(value == JNI_TRUE);
517 return result;
518 WB_END
519
520 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
521 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
522 CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
523 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
524 nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
525 MutexLockerEx mu(Compile_lock);
526 return (mh->queued_for_compilation() || nm != NULL);
527 WB_END
528
529 class VM_WhiteBoxOperation : public VM_Operation {
530 public:
531 VM_WhiteBoxOperation() { }
532 VMOp_Type type() const { return VMOp_WhiteBoxOperation; }
533 bool allow_nested_vm_operations() const { return true; }
534 };
535
536 class AlwaysFalseClosure : public BoolObjectClosure {
537 public:
538 bool do_object_b(oop p) { return false; }
539 };
540
541 static AlwaysFalseClosure always_false;
542
543 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
544 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
545 CHECK_JNI_EXCEPTION(env);
546 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
547 MutexLockerEx mu(Compile_lock);
548 MethodData* mdo = mh->method_data();
549 MethodCounters* mcs = mh->method_counters();
550
551 if (mdo != NULL) {
552 mdo->init();
553 ResourceMark rm;
554 int arg_count = mdo->method()->size_of_parameters();
555 for (int i = 0; i < arg_count; i++) {
744 SetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAtPut);
745 WB_END
746
747 WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value))
748 ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
749 const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL);
750 ccstr ccstrResult = ccstrValue;
751 bool needFree;
752 {
753 ThreadInVMfromNative ttvfn(thread); // back to VM
754 needFree = SetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAtPut);
755 }
756 if (value != NULL) {
757 env->ReleaseStringUTFChars(value, ccstrValue);
758 }
759 if (needFree) {
760 FREE_C_HEAP_ARRAY(char, ccstrResult);
761 }
762 WB_END
763
764
765 WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
766 WhiteBox::compilation_locked = true;
767 WB_END
768
769 WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
770 MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
771 WhiteBox::compilation_locked = false;
772 mo.notify_all();
773 WB_END
774
775 void WhiteBox::sweeper_thread_entry(JavaThread* thread, TRAPS) {
776 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
777 {
778 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
779 NMethodSweeper::_should_sweep = true;
780 }
781 NMethodSweeper::possibly_sweep();
782 }
783
784 JavaThread* WhiteBox::create_sweeper_thread(TRAPS) {
1184 {CC"stressVirtualSpaceResize",CC"(JJJ)I", (void*)&WB_StressVirtualSpaceResize},
1185 #if INCLUDE_ALL_GCS
1186 {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
1187 {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
1188 {CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
1189 {CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
1190 {CC"g1StartConcMarkCycle", CC"()Z", (void*)&WB_G1StartMarkCycle },
1191 #endif // INCLUDE_ALL_GCS
1192 #if INCLUDE_NMT
1193 {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc },
1194 {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack},
1195 {CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree },
1196 {CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory },
1197 {CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory },
1198 {CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
1199 {CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
1200 {CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported},
1201 {CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel},
1202 {CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize },
1203 #endif // INCLUDE_NMT
1204 {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
1205 {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
1206 (void*)&WB_DeoptimizeMethod },
1207 {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;Z)Z",
1208 (void*)&WB_IsMethodCompiled },
1209 {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;IZ)Z",
1210 (void*)&WB_IsMethodCompilable},
1211 {CC"isMethodQueuedForCompilation",
1212 CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation},
1213 {CC"makeMethodNotCompilable",
1214 CC"(Ljava/lang/reflect/Executable;IZ)V", (void*)&WB_MakeMethodNotCompilable},
1215 {CC"testSetDontInlineMethod",
1216 CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod},
1217 {CC"getMethodCompilationLevel",
1218 CC"(Ljava/lang/reflect/Executable;Z)I", (void*)&WB_GetMethodCompilationLevel},
1219 {CC"getMethodEntryBci",
1220 CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci},
1221 {CC"getCompileQueueSize",
1222 CC"(I)I", (void*)&WB_GetCompileQueueSize},
1223 {CC"testSetForceInlineMethod",
|
52 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
53 #include "gc_implementation/g1/concurrentMark.hpp"
54 #include "gc_implementation/g1/concurrentMarkThread.hpp"
55 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
56 #include "gc_implementation/g1/heapRegionRemSet.hpp"
57 #endif // INCLUDE_ALL_GCS
58 #if INCLUDE_NMT
59 #include "services/mallocSiteTable.hpp"
60 #include "services/memTracker.hpp"
61 #include "utilities/nativeCallStack.hpp"
62 #endif // INCLUDE_NMT
63
64
65 PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
66
67 #define SIZE_T_MAX_VALUE ((size_t) -1)
68
69 bool WhiteBox::_used = false;
70 volatile bool WhiteBox::compilation_locked = false;
71
72 class VM_WhiteBoxOperation : public VM_Operation {
73 public:
74 VM_WhiteBoxOperation() { }
75 VMOp_Type type() const { return VMOp_WhiteBoxOperation; }
76 bool allow_nested_vm_operations() const { return true; }
77 };
78
79
80 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
81 return (jlong)(void*)JNIHandles::resolve(obj);
82 WB_END
83
84 WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
85 return heapOopSize;
86 WB_END
87
88 WB_ENTRY(jint, WB_GetVMPageSize(JNIEnv* env, jobject o))
89 return os::vm_page_size();
90 WB_END
91
92 class WBIsKlassAliveClosure : public KlassClosure {
93 Symbol* _name;
94 bool _found;
95 public:
96 WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {}
97
98 void do_klass(Klass* k) {
99 if (_found) return;
395 // Really can never go up to detail, verify that the code would never do this.
396 MemTracker::transition_to(NMT_detail);
397 assert(MemTracker::tracking_level() == NMT_minimal, "Should still be minimal now");
398 return MemTracker::tracking_level() == NMT_minimal;
399 }
400 WB_END
401
402 WB_ENTRY(jint, WB_NMTGetHashSize(JNIEnv* env, jobject o))
403 int hash_size = MallocSiteTable::hash_buckets();
404 assert(hash_size > 0, "NMT hash_size should be > 0");
405 return (jint)hash_size;
406 WB_END
407 #endif // INCLUDE_NMT
408
409 static jmethodID reflected_method_to_jmid(JavaThread* thread, JNIEnv* env, jobject method) {
410 assert(method != NULL, "method should not be null");
411 ThreadToNativeFromVM ttn(thread);
412 return env->FromReflectedMethod(method);
413 }
414
415 // Deoptimizes all compiled frames and makes nmethods not entrant if it's requested
416 class VM_WhiteBoxDeoptimizeFrames : public VM_WhiteBoxOperation {
417 private:
418 int _result;
419 const bool _make_not_entrant;
420 public:
421 VM_WhiteBoxDeoptimizeFrames(bool make_not_entrant) :
422 _result(0), _make_not_entrant(make_not_entrant) { }
423 int result() const { return _result; }
424
425 void doit() {
426 for (JavaThread* t = Threads::first(); t != NULL; t = t->next()) {
427 if (t->has_last_Java_frame()) {
428 for (StackFrameStream fst(t, UseBiasedLocking); !fst.is_done(); fst.next()) {
429 frame* f = fst.current();
430 if (f->can_be_deoptimized() && !f->is_deoptimized_frame()) {
431 RegisterMap* reg_map = fst.register_map();
432 Deoptimization::deoptimize(t, *f, reg_map);
433 if (_make_not_entrant) {
434 nmethod* nm = CodeCache::find_nmethod(f->pc());
435 assert(nm != NULL, "sanity check");
436 nm->make_not_entrant();
437 }
438 ++_result;
439 }
440 }
441 }
442 }
443 }
444 };
445
446 WB_ENTRY(jint, WB_DeoptimizeFrames(JNIEnv* env, jobject o, jboolean make_not_entrant))
447 VM_WhiteBoxDeoptimizeFrames op(make_not_entrant);
448 VMThread::execute(&op);
449 return op.result();
450 WB_END
451
452 WB_ENTRY(void, WB_DeoptimizeAll(JNIEnv* env, jobject o))
453 MutexLockerEx mu(Compile_lock);
454 CodeCache::mark_all_nmethods_for_deoptimization();
455 VM_Deoptimize op;
456 VMThread::execute(&op);
457 WB_END
458
459 WB_ENTRY(jint, WB_DeoptimizeMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
460 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
461 int result = 0;
462 CHECK_JNI_EXCEPTION_(env, result);
463 MutexLockerEx mu(Compile_lock);
464 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
465 if (is_osr) {
466 result += mh->mark_osr_nmethods();
467 } else if (mh->code() != NULL) {
468 mh->code()->mark_for_deoptimization();
469 ++result;
470 }
471 result += CodeCache::mark_for_deoptimization(mh());
554 WB_END
555
556 WB_ENTRY(jboolean, WB_TestSetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
557 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
558 CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
559 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
560 bool result = mh->force_inline();
561 mh->set_force_inline(value == JNI_TRUE);
562 return result;
563 WB_END
564
565 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci))
566 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
567 CHECK_JNI_EXCEPTION_(env, JNI_FALSE);
568 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
569 nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
570 MutexLockerEx mu(Compile_lock);
571 return (mh->queued_for_compilation() || nm != NULL);
572 WB_END
573
574 class AlwaysFalseClosure : public BoolObjectClosure {
575 public:
576 bool do_object_b(oop p) { return false; }
577 };
578
579 static AlwaysFalseClosure always_false;
580
581 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
582 jmethodID jmid = reflected_method_to_jmid(thread, env, method);
583 CHECK_JNI_EXCEPTION(env);
584 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
585 MutexLockerEx mu(Compile_lock);
586 MethodData* mdo = mh->method_data();
587 MethodCounters* mcs = mh->method_counters();
588
589 if (mdo != NULL) {
590 mdo->init();
591 ResourceMark rm;
592 int arg_count = mdo->method()->size_of_parameters();
593 for (int i = 0; i < arg_count; i++) {
782 SetVMFlag <double> (thread, env, name, &result, &CommandLineFlags::doubleAtPut);
783 WB_END
784
785 WB_ENTRY(void, WB_SetStringVMFlag(JNIEnv* env, jobject o, jstring name, jstring value))
786 ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
787 const char* ccstrValue = (value == NULL) ? NULL : env->GetStringUTFChars(value, NULL);
788 ccstr ccstrResult = ccstrValue;
789 bool needFree;
790 {
791 ThreadInVMfromNative ttvfn(thread); // back to VM
792 needFree = SetVMFlag <ccstr> (thread, env, name, &ccstrResult, &CommandLineFlags::ccstrAtPut);
793 }
794 if (value != NULL) {
795 env->ReleaseStringUTFChars(value, ccstrValue);
796 }
797 if (needFree) {
798 FREE_C_HEAP_ARRAY(char, ccstrResult);
799 }
800 WB_END
801
802 WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
803 WhiteBox::compilation_locked = true;
804 WB_END
805
806 WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
807 MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
808 WhiteBox::compilation_locked = false;
809 mo.notify_all();
810 WB_END
811
812 void WhiteBox::sweeper_thread_entry(JavaThread* thread, TRAPS) {
813 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
814 {
815 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
816 NMethodSweeper::_should_sweep = true;
817 }
818 NMethodSweeper::possibly_sweep();
819 }
820
821 JavaThread* WhiteBox::create_sweeper_thread(TRAPS) {
1221 {CC"stressVirtualSpaceResize",CC"(JJJ)I", (void*)&WB_StressVirtualSpaceResize},
1222 #if INCLUDE_ALL_GCS
1223 {CC"g1InConcurrentMark", CC"()Z", (void*)&WB_G1InConcurrentMark},
1224 {CC"g1IsHumongous", CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous },
1225 {CC"g1NumFreeRegions", CC"()J", (void*)&WB_G1NumFreeRegions },
1226 {CC"g1RegionSize", CC"()I", (void*)&WB_G1RegionSize },
1227 {CC"g1StartConcMarkCycle", CC"()Z", (void*)&WB_G1StartMarkCycle },
1228 #endif // INCLUDE_ALL_GCS
1229 #if INCLUDE_NMT
1230 {CC"NMTMalloc", CC"(J)J", (void*)&WB_NMTMalloc },
1231 {CC"NMTMallocWithPseudoStack", CC"(JI)J", (void*)&WB_NMTMallocWithPseudoStack},
1232 {CC"NMTFree", CC"(J)V", (void*)&WB_NMTFree },
1233 {CC"NMTReserveMemory", CC"(J)J", (void*)&WB_NMTReserveMemory },
1234 {CC"NMTCommitMemory", CC"(JJ)V", (void*)&WB_NMTCommitMemory },
1235 {CC"NMTUncommitMemory", CC"(JJ)V", (void*)&WB_NMTUncommitMemory },
1236 {CC"NMTReleaseMemory", CC"(JJ)V", (void*)&WB_NMTReleaseMemory },
1237 {CC"NMTIsDetailSupported",CC"()Z", (void*)&WB_NMTIsDetailSupported},
1238 {CC"NMTChangeTrackingLevel", CC"()Z", (void*)&WB_NMTChangeTrackingLevel},
1239 {CC"NMTGetHashSize", CC"()I", (void*)&WB_NMTGetHashSize },
1240 #endif // INCLUDE_NMT
1241 {CC"deoptimizeFrames", CC"(Z)I", (void*)&WB_DeoptimizeFrames },
1242 {CC"deoptimizeAll", CC"()V", (void*)&WB_DeoptimizeAll },
1243 {CC"deoptimizeMethod", CC"(Ljava/lang/reflect/Executable;Z)I",
1244 (void*)&WB_DeoptimizeMethod },
1245 {CC"isMethodCompiled", CC"(Ljava/lang/reflect/Executable;Z)Z",
1246 (void*)&WB_IsMethodCompiled },
1247 {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Executable;IZ)Z",
1248 (void*)&WB_IsMethodCompilable},
1249 {CC"isMethodQueuedForCompilation",
1250 CC"(Ljava/lang/reflect/Executable;)Z", (void*)&WB_IsMethodQueuedForCompilation},
1251 {CC"makeMethodNotCompilable",
1252 CC"(Ljava/lang/reflect/Executable;IZ)V", (void*)&WB_MakeMethodNotCompilable},
1253 {CC"testSetDontInlineMethod",
1254 CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetDontInlineMethod},
1255 {CC"getMethodCompilationLevel",
1256 CC"(Ljava/lang/reflect/Executable;Z)I", (void*)&WB_GetMethodCompilationLevel},
1257 {CC"getMethodEntryBci",
1258 CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci},
1259 {CC"getCompileQueueSize",
1260 CC"(I)I", (void*)&WB_GetCompileQueueSize},
1261 {CC"testSetForceInlineMethod",
|