38 |
38 |
39 #include "runtime/arguments.hpp" |
39 #include "runtime/arguments.hpp" |
40 #include "runtime/interfaceSupport.hpp" |
40 #include "runtime/interfaceSupport.hpp" |
41 #include "runtime/os.hpp" |
41 #include "runtime/os.hpp" |
42 #include "utilities/array.hpp" |
42 #include "utilities/array.hpp" |
|
43 #include "utilities/align.hpp" |
43 #include "utilities/debug.hpp" |
44 #include "utilities/debug.hpp" |
44 #include "utilities/macros.hpp" |
45 #include "utilities/macros.hpp" |
45 #include "utilities/exceptions.hpp" |
46 #include "utilities/exceptions.hpp" |
46 |
47 |
47 #if INCLUDE_ALL_GCS |
48 #if INCLUDE_ALL_GCS |
566 bool result = mh->force_inline(); |
567 bool result = mh->force_inline(); |
567 mh->set_force_inline(value == JNI_TRUE); |
568 mh->set_force_inline(value == JNI_TRUE); |
568 return result; |
569 return result; |
569 WB_END |
570 WB_END |
570 |
571 |
|
572 bool WhiteBox::compile_method(Method* method, int comp_level, int bci, Thread* THREAD) { |
|
573 // Screen for unavailable/bad comp level or null method |
|
574 AbstractCompiler* comp = CompileBroker::compiler(comp_level); |
|
575 if (method == NULL) { |
|
576 tty->print_cr("WB error: request to compile NULL method"); |
|
577 return false; |
|
578 } |
|
579 if (comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) { |
|
580 tty->print_cr("WB error: invalid compilation level %d", comp_level); |
|
581 return false; |
|
582 } |
|
583 if (comp == NULL) { |
|
584 tty->print_cr("WB error: no compiler for requested compilation level %d", comp_level); |
|
585 return false; |
|
586 } |
|
587 |
|
588 methodHandle mh(THREAD, method); |
|
589 |
|
590 // Compile method and check result |
|
591 nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "Whitebox", THREAD); |
|
592 MutexLocker mu(Compile_lock); |
|
593 bool is_queued = mh->queued_for_compilation(); |
|
594 if (is_queued || nm != NULL) { |
|
595 return true; |
|
596 } |
|
597 tty->print("WB error: failed to compile at level %d method ", comp_level); |
|
598 mh->print_short_name(tty); |
|
599 tty->cr(); |
|
600 if (is_queued) { |
|
601 tty->print_cr("WB error: blocking compilation is still in queue!"); |
|
602 } |
|
603 return false; |
|
604 } |
|
605 |
571 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci)) |
606 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci)) |
572 jmethodID jmid = reflected_method_to_jmid(thread, env, method); |
607 jmethodID jmid = reflected_method_to_jmid(thread, env, method); |
573 CHECK_JNI_EXCEPTION_(env, JNI_FALSE); |
608 CHECK_JNI_EXCEPTION_(env, JNI_FALSE); |
574 methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); |
609 return WhiteBox::compile_method(Method::checked_resolve_jmethod_id(jmid), comp_level, bci, THREAD); |
575 nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD); |
610 WB_END |
576 MutexLockerEx mu(Compile_lock); |
611 |
577 return (mh->queued_for_compilation() || nm != NULL); |
612 WB_ENTRY(jboolean, WB_EnqueueInitializerForCompilation(JNIEnv* env, jobject o, jclass klass, jint comp_level)) |
|
613 InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); |
|
614 Method* clinit = ik->class_initializer(); |
|
615 if (clinit == NULL) { |
|
616 return false; |
|
617 } |
|
618 return WhiteBox::compile_method(clinit, comp_level, InvocationEntryBci, THREAD); |
578 WB_END |
619 WB_END |
579 |
620 |
580 class VM_WhiteBoxOperation : public VM_Operation { |
621 class VM_WhiteBoxOperation : public VM_Operation { |
581 public: |
622 public: |
582 VM_WhiteBoxOperation() { } |
623 VM_WhiteBoxOperation() { } |
651 icnt->set(InvocationCounter::wait_for_compile, Tier4MinInvocationThreshold + 1); |
692 icnt->set(InvocationCounter::wait_for_compile, Tier4MinInvocationThreshold + 1); |
652 bcnt->set(InvocationCounter::wait_for_compile, Tier4CompileThreshold + 1); |
693 bcnt->set(InvocationCounter::wait_for_compile, Tier4CompileThreshold + 1); |
653 WB_END |
694 WB_END |
654 |
695 |
655 template <typename T> |
696 template <typename T> |
656 static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) { |
697 static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*, bool, bool)) { |
657 if (name == NULL) { |
698 if (name == NULL) { |
658 return false; |
699 return false; |
659 } |
700 } |
660 ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI |
701 ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI |
661 const char* flag_name = env->GetStringUTFChars(name, NULL); |
702 const char* flag_name = env->GetStringUTFChars(name, NULL); |
662 bool result = (*TAt)(flag_name, value); |
703 bool result = (*TAt)(flag_name, value, true, true); |
663 env->ReleaseStringUTFChars(name, flag_name); |
704 env->ReleaseStringUTFChars(name, flag_name); |
664 return result; |
705 return result; |
665 } |
706 } |
666 |
707 |
667 template <typename T> |
708 template <typename T> |
802 if (needFree) { |
843 if (needFree) { |
803 FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal); |
844 FREE_C_HEAP_ARRAY(char, ccstrResult, mtInternal); |
804 } |
845 } |
805 WB_END |
846 WB_END |
806 |
847 |
807 |
|
808 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) |
848 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) |
809 ResourceMark rm(THREAD); |
849 ResourceMark rm(THREAD); |
810 int len; |
850 int len; |
811 jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false); |
851 jchar* name = java_lang_String::as_unicode_string(JNIHandles::resolve(javaString), len, CHECK_false); |
812 return (StringTable::lookup(name, len) != NULL); |
852 return (StringTable::lookup(name, len) != NULL); |
849 CHECK_JNI_EXCEPTION_(env, NULL); |
889 CHECK_JNI_EXCEPTION_(env, NULL); |
850 |
890 |
851 return features_string; |
891 return features_string; |
852 WB_END |
892 WB_END |
853 |
893 |
|
894 int WhiteBox::get_blob_type(const CodeBlob* code) { |
|
895 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled"); |
|
896 return CodeBlobType::All;; |
|
897 } |
|
898 |
|
899 struct CodeBlobStub { |
|
900 CodeBlobStub(const CodeBlob* blob) : |
|
901 name(os::strdup(blob->name())), |
|
902 size(blob->size()), |
|
903 blob_type(WhiteBox::get_blob_type(blob)), |
|
904 address((jlong) blob) { } |
|
905 ~CodeBlobStub() { os::free((void*) name); } |
|
906 const char* const name; |
|
907 const jint size; |
|
908 const jint blob_type; |
|
909 const jlong address; |
|
910 }; |
|
911 |
|
912 static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) { |
|
913 jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); |
|
914 CHECK_JNI_EXCEPTION_(env, NULL); |
|
915 jobjectArray result = env->NewObjectArray(4, clazz, NULL); |
|
916 |
|
917 jstring name = env->NewStringUTF(cb->name); |
|
918 CHECK_JNI_EXCEPTION_(env, NULL); |
|
919 env->SetObjectArrayElement(result, 0, name); |
|
920 |
|
921 jobject obj = integerBox(thread, env, cb->size); |
|
922 CHECK_JNI_EXCEPTION_(env, NULL); |
|
923 env->SetObjectArrayElement(result, 1, obj); |
|
924 |
|
925 obj = integerBox(thread, env, cb->blob_type); |
|
926 CHECK_JNI_EXCEPTION_(env, NULL); |
|
927 env->SetObjectArrayElement(result, 2, obj); |
|
928 |
|
929 obj = longBox(thread, env, cb->address); |
|
930 CHECK_JNI_EXCEPTION_(env, NULL); |
|
931 env->SetObjectArrayElement(result, 3, obj); |
|
932 |
|
933 return result; |
|
934 } |
854 |
935 |
855 WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) |
936 WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) |
856 ResourceMark rm(THREAD); |
937 ResourceMark rm(THREAD); |
857 jmethodID jmid = reflected_method_to_jmid(thread, env, method); |
938 jmethodID jmid = reflected_method_to_jmid(thread, env, method); |
858 CHECK_JNI_EXCEPTION_(env, NULL); |
939 CHECK_JNI_EXCEPTION_(env, NULL); |
886 env->SetObjectArrayElement(result, 2, insts); |
967 env->SetObjectArrayElement(result, 2, insts); |
887 |
968 |
888 return result; |
969 return result; |
889 WB_END |
970 WB_END |
890 |
971 |
|
972 CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) { |
|
973 guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled"); |
|
974 BufferBlob* blob; |
|
975 int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob)); |
|
976 if (full_size < size) { |
|
977 full_size += align_up(size - full_size, oopSize); |
|
978 } |
|
979 { |
|
980 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
|
981 blob = (BufferBlob*) CodeCache::allocate(full_size); |
|
982 ::new (blob) BufferBlob("WB::DummyBlob", full_size); |
|
983 } |
|
984 // Track memory usage statistic after releasing CodeCache_lock |
|
985 MemoryService::track_code_cache_memory_usage(); |
|
986 return blob; |
|
987 } |
|
988 |
|
989 WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type)) |
|
990 if (size < 0) { |
|
991 THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), |
|
992 err_msg("WB_AllocateCodeBlob: size is negative: " INT32_FORMAT, size)); |
|
993 } |
|
994 return (jlong) WhiteBox::allocate_code_blob(size, blob_type); |
|
995 WB_END |
|
996 |
|
997 WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr)) |
|
998 if (addr == 0) { |
|
999 return; |
|
1000 } |
|
1001 BufferBlob::free((BufferBlob*) addr); |
|
1002 WB_END |
|
1003 |
|
1004 WB_ENTRY(jobjectArray, WB_GetCodeBlob(JNIEnv* env, jobject o, jlong addr)) |
|
1005 if (addr == 0) { |
|
1006 THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), |
|
1007 "WB_GetCodeBlob: addr is null"); |
|
1008 } |
|
1009 ThreadToNativeFromVM ttn(thread); |
|
1010 CodeBlobStub stub((CodeBlob*) addr); |
|
1011 return codeBlob2objectArray(thread, env, &stub); |
|
1012 WB_END |
891 |
1013 |
892 int WhiteBox::array_bytes_to_length(size_t bytes) { |
1014 int WhiteBox::array_bytes_to_length(size_t bytes) { |
893 return Array<u1>::bytes_to_length(bytes); |
1015 return Array<u1>::bytes_to_length(bytes); |
894 } |
1016 } |
895 |
1017 |
955 WB_END |
1077 WB_END |
956 |
1078 |
957 WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb)) |
1079 WB_ENTRY(void, WB_ForceSafepoint(JNIEnv* env, jobject wb)) |
958 VM_ForceSafepoint force_safepoint_op; |
1080 VM_ForceSafepoint force_safepoint_op; |
959 VMThread::execute(&force_safepoint_op); |
1081 VMThread::execute(&force_safepoint_op); |
|
1082 WB_END |
|
1083 |
|
1084 WB_ENTRY(jlong, WB_GetHeapAlignment(JNIEnv* env, jobject o)) |
|
1085 size_t alignment = Universe::heap()->collector_policy()->heap_alignment(); |
|
1086 return (jlong)alignment; |
960 WB_END |
1087 WB_END |
961 |
1088 |
962 //Some convenience methods to deal with objects from java |
1089 //Some convenience methods to deal with objects from java |
963 int WhiteBox::offset_for_field(const char* field_name, oop object, |
1090 int WhiteBox::offset_for_field(const char* field_name, oop object, |
964 Symbol* signature_symbol) { |
1091 Symbol* signature_symbol) { |
1071 {CC"getObjectSize", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize }, |
1198 {CC"getObjectSize", CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectSize }, |
1072 {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen }, |
1199 {CC"isObjectInOldGen", CC"(Ljava/lang/Object;)Z", (void*)&WB_isObjectInOldGen }, |
1073 {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize }, |
1200 {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize }, |
1074 {CC"getVMPageSize", CC"()I", (void*)&WB_GetVMPageSize }, |
1201 {CC"getVMPageSize", CC"()I", (void*)&WB_GetVMPageSize }, |
1075 {CC"getVMLargePageSize", CC"()J", (void*)&WB_GetVMLargePageSize}, |
1202 {CC"getVMLargePageSize", CC"()J", (void*)&WB_GetVMLargePageSize}, |
|
1203 {CC"getHeapAlignment", CC"()J", (void*)&WB_GetHeapAlignment }, |
1076 {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, |
1204 {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, |
1077 {CC"classKnownToNotExist", |
1205 {CC"classKnownToNotExist", |
1078 CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)Z",(void*)&WB_ClassKnownToNotExist}, |
1206 CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)Z",(void*)&WB_ClassKnownToNotExist}, |
1079 {CC"getLookupCacheURLs", CC"(Ljava/lang/ClassLoader;)[Ljava/net/URL;", (void*)&WB_GetLookupCacheURLs}, |
1207 {CC"getLookupCacheURLs", CC"(Ljava/lang/ClassLoader;)[Ljava/net/URL;", (void*)&WB_GetLookupCacheURLs}, |
1080 {CC"getLookupCacheMatches", CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)[I", |
1208 {CC"getLookupCacheMatches", CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)[I", |
1136 CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci}, |
1264 CC"(Ljava/lang/reflect/Executable;)I", (void*)&WB_GetMethodEntryBci}, |
1137 {CC"getCompileQueueSize", |
1265 {CC"getCompileQueueSize", |
1138 CC"(I)I", (void*)&WB_GetCompileQueueSize}, |
1266 CC"(I)I", (void*)&WB_GetCompileQueueSize}, |
1139 {CC"testSetForceInlineMethod", |
1267 {CC"testSetForceInlineMethod", |
1140 CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod}, |
1268 CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod}, |
1141 {CC"enqueueMethodForCompilation", |
1269 {CC"enqueueMethodForCompilation0", |
1142 CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, |
1270 CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, |
|
1271 {CC"enqueueInitializerForCompilation0", |
|
1272 CC"(Ljava/lang/Class;I)Z", (void*)&WB_EnqueueInitializerForCompilation}, |
1143 {CC"clearMethodState", |
1273 {CC"clearMethodState", |
1144 CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, |
1274 CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, |
1145 {CC"markMethodProfiled", |
1275 {CC"markMethodProfiled", |
1146 CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_MarkMethodProfiled}, |
1276 CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_MarkMethodProfiled}, |
1147 {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, |
1277 {CC"setBooleanVMFlag", CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag}, |
1165 (void*)&WB_GetStringVMFlag}, |
1295 (void*)&WB_GetStringVMFlag}, |
1166 {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, |
1296 {CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable }, |
1167 {CC"fullGC", CC"()V", (void*)&WB_FullGC }, |
1297 {CC"fullGC", CC"()V", (void*)&WB_FullGC }, |
1168 {CC"youngGC", CC"()V", (void*)&WB_YoungGC }, |
1298 {CC"youngGC", CC"()V", (void*)&WB_YoungGC }, |
1169 {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory }, |
1299 {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory }, |
|
1300 {CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob }, |
|
1301 {CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob }, |
|
1302 {CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob }, |
1170 {CC"allocateMetaspace", |
1303 {CC"allocateMetaspace", |
1171 CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace }, |
1304 CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace }, |
1172 {CC"freeMetaspace", |
1305 {CC"freeMetaspace", |
1173 CC"(Ljava/lang/ClassLoader;JJ)V", (void*)&WB_FreeMetaspace }, |
1306 CC"(Ljava/lang/ClassLoader;JJ)V", (void*)&WB_FreeMetaspace }, |
1174 {CC"incMetaspaceCapacityUntilGC", CC"(J)J", (void*)&WB_IncMetaspaceCapacityUntilGC }, |
1307 {CC"incMetaspaceCapacityUntilGC", CC"(J)J", (void*)&WB_IncMetaspaceCapacityUntilGC }, |