1.1 --- a/src/share/vm/prims/whitebox.cpp Wed Oct 14 16:43:13 2020 +0800 1.2 +++ b/src/share/vm/prims/whitebox.cpp Wed Oct 14 17:44:48 2020 +0800 1.3 @@ -40,6 +40,7 @@ 1.4 #include "runtime/interfaceSupport.hpp" 1.5 #include "runtime/os.hpp" 1.6 #include "utilities/array.hpp" 1.7 +#include "utilities/align.hpp" 1.8 #include "utilities/debug.hpp" 1.9 #include "utilities/macros.hpp" 1.10 #include "utilities/exceptions.hpp" 1.11 @@ -568,13 +569,53 @@ 1.12 return result; 1.13 WB_END 1.14 1.15 +bool WhiteBox::compile_method(Method* method, int comp_level, int bci, Thread* THREAD) { 1.16 + // Screen for unavailable/bad comp level or null method 1.17 + AbstractCompiler* comp = CompileBroker::compiler(comp_level); 1.18 + if (method == NULL) { 1.19 + tty->print_cr("WB error: request to compile NULL method"); 1.20 + return false; 1.21 + } 1.22 + if (comp_level > MIN2((CompLevel) TieredStopAtLevel, CompLevel_highest_tier)) { 1.23 + tty->print_cr("WB error: invalid compilation level %d", comp_level); 1.24 + return false; 1.25 + } 1.26 + if (comp == NULL) { 1.27 + tty->print_cr("WB error: no compiler for requested compilation level %d", comp_level); 1.28 + return false; 1.29 + } 1.30 + 1.31 + methodHandle mh(THREAD, method); 1.32 + 1.33 + // Compile method and check result 1.34 + nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "Whitebox", THREAD); 1.35 + MutexLocker mu(Compile_lock); 1.36 + bool is_queued = mh->queued_for_compilation(); 1.37 + if (is_queued || nm != NULL) { 1.38 + return true; 1.39 + } 1.40 + tty->print("WB error: failed to compile at level %d method ", comp_level); 1.41 + mh->print_short_name(tty); 1.42 + tty->cr(); 1.43 + if (is_queued) { 1.44 + tty->print_cr("WB error: blocking compilation is still in queue!"); 1.45 + } 1.46 + return false; 1.47 +} 1.48 + 1.49 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level, jint bci)) 1.50 jmethodID jmid = reflected_method_to_jmid(thread, env, method); 1.51 CHECK_JNI_EXCEPTION_(env, JNI_FALSE); 1.52 - methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid)); 1.53 - nmethod* nm = CompileBroker::compile_method(mh, bci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD); 1.54 - MutexLockerEx mu(Compile_lock); 1.55 - return (mh->queued_for_compilation() || nm != NULL); 1.56 + return WhiteBox::compile_method(Method::checked_resolve_jmethod_id(jmid), comp_level, bci, THREAD); 1.57 +WB_END 1.58 + 1.59 +WB_ENTRY(jboolean, WB_EnqueueInitializerForCompilation(JNIEnv* env, jobject o, jclass klass, jint comp_level)) 1.60 + InstanceKlass* ik = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve(klass))); 1.61 + Method* clinit = ik->class_initializer(); 1.62 + if (clinit == NULL) { 1.63 + return false; 1.64 + } 1.65 + return WhiteBox::compile_method(clinit, comp_level, InvocationEntryBci, THREAD); 1.66 WB_END 1.67 1.68 class VM_WhiteBoxOperation : public VM_Operation { 1.69 @@ -653,13 +694,13 @@ 1.70 WB_END 1.71 1.72 template <typename T> 1.73 -static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*)) { 1.74 +static bool GetVMFlag(JavaThread* thread, JNIEnv* env, jstring name, T* value, bool (*TAt)(const char*, T*, bool, bool)) { 1.75 if (name == NULL) { 1.76 return false; 1.77 } 1.78 ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI 1.79 const char* flag_name = env->GetStringUTFChars(name, NULL); 1.80 - bool result = (*TAt)(flag_name, value); 1.81 + bool result = (*TAt)(flag_name, value, true, true); 1.82 env->ReleaseStringUTFChars(name, flag_name); 1.83 return result; 1.84 } 1.85 @@ -804,7 +845,6 @@ 1.86 } 1.87 WB_END 1.88 1.89 - 1.90 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString)) 1.91 ResourceMark rm(THREAD); 1.92 int len; 1.93 @@ -851,6 +891,47 @@ 1.94 return features_string; 1.95 WB_END 1.96 1.97 +int WhiteBox::get_blob_type(const CodeBlob* code) { 1.98 + guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled"); 1.99 + return CodeBlobType::All;; 1.100 +} 1.101 + 1.102 +struct CodeBlobStub { 1.103 + CodeBlobStub(const CodeBlob* blob) : 1.104 + name(os::strdup(blob->name())), 1.105 + size(blob->size()), 1.106 + blob_type(WhiteBox::get_blob_type(blob)), 1.107 + address((jlong) blob) { } 1.108 + ~CodeBlobStub() { os::free((void*) name); } 1.109 + const char* const name; 1.110 + const jint size; 1.111 + const jint blob_type; 1.112 + const jlong address; 1.113 +}; 1.114 + 1.115 +static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) { 1.116 + jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string()); 1.117 + CHECK_JNI_EXCEPTION_(env, NULL); 1.118 + jobjectArray result = env->NewObjectArray(4, clazz, NULL); 1.119 + 1.120 + jstring name = env->NewStringUTF(cb->name); 1.121 + CHECK_JNI_EXCEPTION_(env, NULL); 1.122 + env->SetObjectArrayElement(result, 0, name); 1.123 + 1.124 + jobject obj = integerBox(thread, env, cb->size); 1.125 + CHECK_JNI_EXCEPTION_(env, NULL); 1.126 + env->SetObjectArrayElement(result, 1, obj); 1.127 + 1.128 + obj = integerBox(thread, env, cb->blob_type); 1.129 + CHECK_JNI_EXCEPTION_(env, NULL); 1.130 + env->SetObjectArrayElement(result, 2, obj); 1.131 + 1.132 + obj = longBox(thread, env, cb->address); 1.133 + CHECK_JNI_EXCEPTION_(env, NULL); 1.134 + env->SetObjectArrayElement(result, 3, obj); 1.135 + 1.136 + return result; 1.137 +} 1.138 1.139 WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr)) 1.140 ResourceMark rm(THREAD); 1.141 @@ -888,6 +969,47 @@ 1.142 return result; 1.143 WB_END 1.144 1.145 +CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) { 1.146 + guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to be enabled"); 1.147 + BufferBlob* blob; 1.148 + int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob)); 1.149 + if (full_size < size) { 1.150 + full_size += align_up(size - full_size, oopSize); 1.151 + } 1.152 + { 1.153 + MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); 1.154 + blob = (BufferBlob*) CodeCache::allocate(full_size); 1.155 + ::new (blob) BufferBlob("WB::DummyBlob", full_size); 1.156 + } 1.157 + // Track memory usage statistic after releasing CodeCache_lock 1.158 + MemoryService::track_code_cache_memory_usage(); 1.159 + return blob; 1.160 +} 1.161 + 1.162 +WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type)) 1.163 + if (size < 0) { 1.164 + THROW_MSG_0(vmSymbols::java_lang_IllegalArgumentException(), 1.165 + err_msg("WB_AllocateCodeBlob: size is negative: " INT32_FORMAT, size)); 1.166 + } 1.167 + return (jlong) WhiteBox::allocate_code_blob(size, blob_type); 1.168 +WB_END 1.169 + 1.170 +WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr)) 1.171 + if (addr == 0) { 1.172 + return; 1.173 + } 1.174 + BufferBlob::free((BufferBlob*) addr); 1.175 +WB_END 1.176 + 1.177 +WB_ENTRY(jobjectArray, WB_GetCodeBlob(JNIEnv* env, jobject o, jlong addr)) 1.178 + if (addr == 0) { 1.179 + THROW_MSG_NULL(vmSymbols::java_lang_NullPointerException(), 1.180 + "WB_GetCodeBlob: addr is null"); 1.181 + } 1.182 + ThreadToNativeFromVM ttn(thread); 1.183 + CodeBlobStub stub((CodeBlob*) addr); 1.184 + return codeBlob2objectArray(thread, env, &stub); 1.185 +WB_END 1.186 1.187 int WhiteBox::array_bytes_to_length(size_t bytes) { 1.188 return Array<u1>::bytes_to_length(bytes); 1.189 @@ -959,6 +1081,11 @@ 1.190 VMThread::execute(&force_safepoint_op); 1.191 WB_END 1.192 1.193 +WB_ENTRY(jlong, WB_GetHeapAlignment(JNIEnv* env, jobject o)) 1.194 + size_t alignment = Universe::heap()->collector_policy()->heap_alignment(); 1.195 + return (jlong)alignment; 1.196 +WB_END 1.197 + 1.198 //Some convenience methods to deal with objects from java 1.199 int WhiteBox::offset_for_field(const char* field_name, oop object, 1.200 Symbol* signature_symbol) { 1.201 @@ -1073,6 +1200,7 @@ 1.202 {CC"getHeapOopSize", CC"()I", (void*)&WB_GetHeapOopSize }, 1.203 {CC"getVMPageSize", CC"()I", (void*)&WB_GetVMPageSize }, 1.204 {CC"getVMLargePageSize", CC"()J", (void*)&WB_GetVMLargePageSize}, 1.205 + {CC"getHeapAlignment", CC"()J", (void*)&WB_GetHeapAlignment }, 1.206 {CC"isClassAlive0", CC"(Ljava/lang/String;)Z", (void*)&WB_IsClassAlive }, 1.207 {CC"classKnownToNotExist", 1.208 CC"(Ljava/lang/ClassLoader;Ljava/lang/String;)Z",(void*)&WB_ClassKnownToNotExist}, 1.209 @@ -1138,8 +1266,10 @@ 1.210 CC"(I)I", (void*)&WB_GetCompileQueueSize}, 1.211 {CC"testSetForceInlineMethod", 1.212 CC"(Ljava/lang/reflect/Executable;Z)Z", (void*)&WB_TestSetForceInlineMethod}, 1.213 - {CC"enqueueMethodForCompilation", 1.214 + {CC"enqueueMethodForCompilation0", 1.215 CC"(Ljava/lang/reflect/Executable;II)Z", (void*)&WB_EnqueueMethodForCompilation}, 1.216 + {CC"enqueueInitializerForCompilation0", 1.217 + CC"(Ljava/lang/Class;I)Z", (void*)&WB_EnqueueInitializerForCompilation}, 1.218 {CC"clearMethodState", 1.219 CC"(Ljava/lang/reflect/Executable;)V", (void*)&WB_ClearMethodState}, 1.220 {CC"markMethodProfiled", 1.221 @@ -1167,6 +1297,9 @@ 1.222 {CC"fullGC", CC"()V", (void*)&WB_FullGC }, 1.223 {CC"youngGC", CC"()V", (void*)&WB_YoungGC }, 1.224 {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory }, 1.225 + {CC"allocateCodeBlob", CC"(II)J", (void*)&WB_AllocateCodeBlob }, 1.226 + {CC"freeCodeBlob", CC"(J)V", (void*)&WB_FreeCodeBlob }, 1.227 + {CC"getCodeBlob", CC"(J)[Ljava/lang/Object;",(void*)&WB_GetCodeBlob }, 1.228 {CC"allocateMetaspace", 1.229 CC"(Ljava/lang/ClassLoader;J)J", (void*)&WB_AllocateMetaspace }, 1.230 {CC"freeMetaspace",