27 #include <new>
28
29 #include "code/codeCache.hpp"
30 #include "memory/metadataFactory.hpp"
31 #include "memory/universe.hpp"
32 #include "oops/oop.inline.hpp"
33
34 #include "classfile/stringTable.hpp"
35 #include "classfile/classLoaderData.hpp"
36
37 #include "prims/whitebox.hpp"
38 #include "prims/wbtestmethods/parserTests.hpp"
39
40 #include "runtime/thread.hpp"
41 #include "runtime/arguments.hpp"
42 #include "runtime/deoptimization.hpp"
43 #include "runtime/interfaceSupport.hpp"
44 #include "runtime/os.hpp"
45 #include "runtime/vm_version.hpp"
46 #include "runtime/sweeper.hpp"
47
48 #include "utilities/array.hpp"
49 #include "utilities/debug.hpp"
50 #include "utilities/macros.hpp"
51 #include "utilities/exceptions.hpp"
52
53 #if INCLUDE_ALL_GCS
54 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
55 #include "gc_implementation/g1/concurrentMark.hpp"
56 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
57 #include "gc_implementation/g1/heapRegionRemSet.hpp"
58 #endif // INCLUDE_ALL_GCS
59
60 #if INCLUDE_NMT
61 #include "services/mallocSiteTable.hpp"
62 #include "services/memTracker.hpp"
63 #include "utilities/nativeCallStack.hpp"
64 #endif // INCLUDE_NMT
65
66 #include "compiler/compileBroker.hpp"
725 }
726 if (value != NULL) {
727 env->ReleaseStringUTFChars(value, ccstrValue);
728 }
729 if (needFree) {
730 FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal);
731 }
732 WB_END
733
734
735 WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
736 WhiteBox::compilation_locked = true;
737 WB_END
738
739 WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
740 MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
741 WhiteBox::compilation_locked = false;
742 mo.notify_all();
743 WB_END
744
745 void WhiteBox::force_sweep() {
746 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
747 {
748 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
749 NMethodSweeper::_should_sweep = true;
750 }
751 NMethodSweeper::possibly_sweep();
752 }
753
754 WB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
755 WhiteBox::force_sweep();
756 WB_END
757
758 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
759 ResourceMark rm(THREAD);
760 int len;
761 jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false);
762 return (StringTable::lookup(name, len) != NULL);
763 WB_END
764
765 WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
766 Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
767 Universe::heap()->collect(GCCause::_last_ditch_collection);
768 #if INCLUDE_ALL_GCS
769 if (UseG1GC) {
770 // Needs to be cleared explicitly for G1
771 Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false);
772 }
773 #endif // INCLUDE_ALL_GCS
774 WB_END
775
785
786 p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
787 if (p == NULL) {
788 THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
789 }
790
791 c = *p;
792 WB_END
793
794 WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o))
795 const char* cpu_features = VM_Version::cpu_features();
796 ThreadToNativeFromVM ttn(thread);
797 jstring features_string = env->NewStringUTF(cpu_features);
798
799 CHECK_JNI_EXCEPTION_(env, NULL);
800
801 return features_string;
802 WB_END
803
804 int WhiteBox::get_blob_type(const CodeBlob* code) {
805 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
806 return CodeCache::get_code_heap(code)->code_blob_type();
807 }
808
809 CodeHeap* WhiteBox::get_code_heap(int blob_type) {
810 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
811 return CodeCache::get_code_heap(blob_type);
812 }
813
814 struct CodeBlobStub {
815 CodeBlobStub(const CodeBlob* blob) :
816 name(os::strdup(blob->name())),
817 size(blob->size()),
818 blob_type(WhiteBox::get_blob_type(blob)) { }
819 ~CodeBlobStub() { os::free((void*) name); }
820 const char* const name;
821 const int size;
822 const int blob_type;
823 };
824
825 static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) {
826 jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
827 CHECK_JNI_EXCEPTION_(env, NULL);
828 jobjectArray result = env->NewObjectArray(3, clazz, NULL);
829
830 jstring name = env->NewStringUTF(cb->name);
866 jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub);
867 env->SetObjectArrayElement(result, 0, codeBlob);
868
869 jobject level = integerBox(thread, env, code->comp_level());
870 CHECK_JNI_EXCEPTION_(env, NULL);
871 env->SetObjectArrayElement(result, 1, level);
872
873 jbyteArray insts = env->NewByteArray(insts_size);
874 CHECK_JNI_EXCEPTION_(env, NULL);
875 env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin());
876 env->SetObjectArrayElement(result, 2, insts);
877
878 jobject id = integerBox(thread, env, code->compile_id());
879 CHECK_JNI_EXCEPTION_(env, NULL);
880 env->SetObjectArrayElement(result, 3, id);
881
882 return result;
883 WB_END
884
885 CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) {
886 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
887 BufferBlob* blob;
888 int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob));
889 if (full_size < size) {
890 full_size += round_to(size - full_size, oopSize);
891 }
892 {
893 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
894 blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type);
895 }
896 // Track memory usage statistic after releasing CodeCache_lock
897 MemoryService::track_code_cache_memory_usage();
898 ::new (blob) BufferBlob("WB::DummyBlob", full_size);
899 return blob;
900 }
901
902 WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type))
903 return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
904 WB_END
905
906 WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr))
907 BufferBlob::free((BufferBlob*) addr);
908 WB_END
909
910 WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type))
911 ResourceMark rm;
912 GrowableArray<CodeBlobStub*> blobs;
913 {
914 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
915 CodeHeap* heap = WhiteBox::get_code_heap(blob_type);
916 if (heap == NULL) {
917 return NULL;
918 }
1183 (void*)&WB_GetUint64VMFlag},
1184 {CC"getSizeTVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
1185 (void*)&WB_GetSizeTVMFlag},
1186 {CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;",
1187 (void*)&WB_GetDoubleVMFlag},
1188 {CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;",
1189 (void*)&WB_GetStringVMFlag},
1190 {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
1191 {CC"fullGC", CC"()V", (void*)&WB_FullGC },
1192 {CC"youngGC", CC"()V", (void*)&WB_YoungGC },
1193 {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
1194 {CC"allocateMetaspace",
1195 CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace },
1196 {CC"freeMetaspace",
1197 CC"(Ljava/lang/ClassLoader;JJ)V", (void*)&WB_FreeMetaspace },
1198 {CC"incMetaspaceCapacityUntilGC", CC"(J)J", (void*)&WB_IncMetaspaceCapacityUntilGC },
1199 {CC"metaspaceCapacityUntilGC", CC"()J", (void*)&WB_MetaspaceCapacityUntilGC },
1200 {CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures },
1201 {CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
1202 (void*)&WB_GetNMethod },
1203 {CC"forceNMethodSweep", CC"()V", (void*)&WB_ForceNMethodSweep },
1204 {CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob },
1205 {CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob },
1206 {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
1207 {CC"getCompilationActivityMode",
1208 CC"()I", (void*)&WB_GetCompilationActivityMode},
1209 {CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob },
1210 {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize },
1211 {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize },
1212 };
1213
1214 #undef CC
1215
1216 JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
1217 {
1218 if (WhiteBoxAPI) {
1219 // Make sure that wbclass is loaded by the null classloader
1220 instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
1221 Handle loader(ikh->class_loader());
1222 if (loader.is_null()) {
1223 WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0]));
|
27 #include <new>
28
29 #include "code/codeCache.hpp"
30 #include "memory/metadataFactory.hpp"
31 #include "memory/universe.hpp"
32 #include "oops/oop.inline.hpp"
33
34 #include "classfile/stringTable.hpp"
35 #include "classfile/classLoaderData.hpp"
36
37 #include "prims/whitebox.hpp"
38 #include "prims/wbtestmethods/parserTests.hpp"
39
40 #include "runtime/thread.hpp"
41 #include "runtime/arguments.hpp"
42 #include "runtime/deoptimization.hpp"
43 #include "runtime/interfaceSupport.hpp"
44 #include "runtime/os.hpp"
45 #include "runtime/vm_version.hpp"
46 #include "runtime/sweeper.hpp"
47 #include "runtime/javaCalls.hpp"
48
49 #include "utilities/array.hpp"
50 #include "utilities/debug.hpp"
51 #include "utilities/macros.hpp"
52 #include "utilities/exceptions.hpp"
53
54 #if INCLUDE_ALL_GCS
55 #include "gc_implementation/parallelScavenge/parallelScavengeHeap.inline.hpp"
56 #include "gc_implementation/g1/concurrentMark.hpp"
57 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
58 #include "gc_implementation/g1/heapRegionRemSet.hpp"
59 #endif // INCLUDE_ALL_GCS
60
61 #if INCLUDE_NMT
62 #include "services/mallocSiteTable.hpp"
63 #include "services/memTracker.hpp"
64 #include "utilities/nativeCallStack.hpp"
65 #endif // INCLUDE_NMT
66
67 #include "compiler/compileBroker.hpp"
726 }
727 if (value != NULL) {
728 env->ReleaseStringUTFChars(value, ccstrValue);
729 }
730 if (needFree) {
731 FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal);
732 }
733 WB_END
734
735
736 WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
737 WhiteBox::compilation_locked = true;
738 WB_END
739
740 WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
741 MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
742 WhiteBox::compilation_locked = false;
743 mo.notify_all();
744 WB_END
745
746 void WhiteBox::sweeper_thread_entry(JavaThread* thread, TRAPS) {
747 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
748 {
749 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
750 NMethodSweeper::_should_sweep = true;
751 }
752 NMethodSweeper::possibly_sweep();
753 }
754
755 JavaThread* WhiteBox::create_sweeper_thread(TRAPS) {
756 // create sweeper thread w/ custom entry -- one iteration instead of loop
757 CodeCacheSweeperThread* sweeper_thread = new CodeCacheSweeperThread();
758 sweeper_thread->set_entry_point(&WhiteBox::sweeper_thread_entry);
759
760 // create j.l.Thread object and associate it w/ sweeper thread
761 {
762 // inherit deamon property from current thread
763 bool is_daemon = java_lang_Thread::is_daemon(JavaThread::current()->threadObj());
764
765 HandleMark hm(THREAD);
766 Handle thread_group(THREAD, Universe::system_thread_group());
767 const char* name = "WB Sweeper thread";
768 sweeper_thread->allocate_threadObj(thread_group, name, is_daemon, THREAD);
769 }
770
771 {
772 MutexLocker mu(Threads_lock, THREAD);
773 Threads::add(sweeper_thread);
774 }
775 return sweeper_thread;
776 }
777
778 WB_ENTRY(jobject, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
779 JavaThread* sweeper_thread = WhiteBox::create_sweeper_thread(Thread::current());
780 if (sweeper_thread == NULL) {
781 return NULL;
782 }
783 jobject result = JNIHandles::make_local(env, sweeper_thread->threadObj());
784 Thread::start(sweeper_thread);
785 return result;
786 WB_END
787
788 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
789 ResourceMark rm(THREAD);
790 int len;
791 jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false);
792 return (StringTable::lookup(name, len) != NULL);
793 WB_END
794
795 WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
796 Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(true);
797 Universe::heap()->collect(GCCause::_last_ditch_collection);
798 #if INCLUDE_ALL_GCS
799 if (UseG1GC) {
800 // Needs to be cleared explicitly for G1
801 Universe::heap()->collector_policy()->set_should_clear_all_soft_refs(false);
802 }
803 #endif // INCLUDE_ALL_GCS
804 WB_END
805
815
816 p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
817 if (p == NULL) {
818 THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
819 }
820
821 c = *p;
822 WB_END
823
824 WB_ENTRY(jstring, WB_GetCPUFeatures(JNIEnv* env, jobject o))
825 const char* cpu_features = VM_Version::cpu_features();
826 ThreadToNativeFromVM ttn(thread);
827 jstring features_string = env->NewStringUTF(cpu_features);
828
829 CHECK_JNI_EXCEPTION_(env, NULL);
830
831 return features_string;
832 WB_END
833
834 int WhiteBox::get_blob_type(const CodeBlob* code) {
835 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
836 return CodeCache::get_code_heap(code)->code_blob_type();
837 }
838
839 CodeHeap* WhiteBox::get_code_heap(int blob_type) {
840 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
841 return CodeCache::get_code_heap(blob_type);
842 }
843
844 struct CodeBlobStub {
845 CodeBlobStub(const CodeBlob* blob) :
846 name(os::strdup(blob->name())),
847 size(blob->size()),
848 blob_type(WhiteBox::get_blob_type(blob)) { }
849 ~CodeBlobStub() { os::free((void*) name); }
850 const char* const name;
851 const int size;
852 const int blob_type;
853 };
854
855 static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) {
856 jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
857 CHECK_JNI_EXCEPTION_(env, NULL);
858 jobjectArray result = env->NewObjectArray(3, clazz, NULL);
859
860 jstring name = env->NewStringUTF(cb->name);
896 jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub);
897 env->SetObjectArrayElement(result, 0, codeBlob);
898
899 jobject level = integerBox(thread, env, code->comp_level());
900 CHECK_JNI_EXCEPTION_(env, NULL);
901 env->SetObjectArrayElement(result, 1, level);
902
903 jbyteArray insts = env->NewByteArray(insts_size);
904 CHECK_JNI_EXCEPTION_(env, NULL);
905 env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin());
906 env->SetObjectArrayElement(result, 2, insts);
907
908 jobject id = integerBox(thread, env, code->compile_id());
909 CHECK_JNI_EXCEPTION_(env, NULL);
910 env->SetObjectArrayElement(result, 3, id);
911
912 return result;
913 WB_END
914
915 CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) {
916 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled");
917 BufferBlob* blob;
918 int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob));
919 if (full_size < size) {
920 full_size += round_to(size - full_size, oopSize);
921 }
922 {
923 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
924 blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type);
925 ::new (blob) BufferBlob("WB::DummyBlob", full_size);
926 }
927 // Track memory usage statistic after releasing CodeCache_lock
928 MemoryService::track_code_cache_memory_usage();
929 return blob;
930 }
931
932 WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type))
933 return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
934 WB_END
935
936 WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr))
937 BufferBlob::free((BufferBlob*) addr);
938 WB_END
939
940 WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type))
941 ResourceMark rm;
942 GrowableArray<CodeBlobStub*> blobs;
943 {
944 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
945 CodeHeap* heap = WhiteBox::get_code_heap(blob_type);
946 if (heap == NULL) {
947 return NULL;
948 }
1213 (void*)&WB_GetUint64VMFlag},
1214 {CC"getSizeTVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Long;",
1215 (void*)&WB_GetSizeTVMFlag},
1216 {CC"getDoubleVMFlag", CC"(Ljava/lang/String;)Ljava/lang/Double;",
1217 (void*)&WB_GetDoubleVMFlag},
1218 {CC"getStringVMFlag", CC"(Ljava/lang/String;)Ljava/lang/String;",
1219 (void*)&WB_GetStringVMFlag},
1220 {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
1221 {CC"fullGC", CC"()V", (void*)&WB_FullGC },
1222 {CC"youngGC", CC"()V", (void*)&WB_YoungGC },
1223 {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
1224 {CC"allocateMetaspace",
1225 CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace },
1226 {CC"freeMetaspace",
1227 CC"(Ljava/lang/ClassLoader;JJ)V", (void*)&WB_FreeMetaspace },
1228 {CC"incMetaspaceCapacityUntilGC", CC"(J)J", (void*)&WB_IncMetaspaceCapacityUntilGC },
1229 {CC"metaspaceCapacityUntilGC", CC"()J", (void*)&WB_MetaspaceCapacityUntilGC },
1230 {CC"getCPUFeatures", CC"()Ljava/lang/String;", (void*)&WB_GetCPUFeatures },
1231 {CC"getNMethod", CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
1232 (void*)&WB_GetNMethod },
1233 {CC"forceNMethodSweep0", CC"()Ljava/lang/Thread;", (void*)&WB_ForceNMethodSweep },
1234 {CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob },
1235 {CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob },
1236 {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
1237 {CC"getCompilationActivityMode",
1238 CC"()I", (void*)&WB_GetCompilationActivityMode},
1239 {CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob },
1240 {CC"getThreadStackSize", CC"()J", (void*)&WB_GetThreadStackSize },
1241 {CC"getThreadRemainingStackSize", CC"()J", (void*)&WB_GetThreadRemainingStackSize },
1242 };
1243
1244 #undef CC
1245
1246 JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
1247 {
1248 if (WhiteBoxAPI) {
1249 // Make sure that wbclass is loaded by the null classloader
1250 instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
1251 Handle loader(ikh->class_loader());
1252 if (loader.is_null()) {
1253 WhiteBox::register_methods(env, wbclass, thread, methods, sizeof(methods) / sizeof(methods[0]));
|