src/share/vm/prims/whitebox.cpp

changeset 9931
fd44df5e3bc3
parent 9703
2fdf635bcf28
parent 9881
8a0aca5caca0
     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",

mercurial