hotspot/src/share/vm/prims/whitebox.cpp
changeset 27642 8c9eff693145
parent 27480 51e6396f8a98
child 27701 c6b49b72dc61
child 27672 d24adedd3655
child 27685 26a697375de3
--- a/hotspot/src/share/vm/prims/whitebox.cpp	Sat Nov 08 16:00:28 2014 +0300
+++ b/hotspot/src/share/vm/prims/whitebox.cpp	Mon Nov 10 19:04:38 2014 +0300
@@ -24,6 +24,8 @@
 
 #include "precompiled.hpp"
 
+#include <new>
+
 #include "code/codeCache.hpp"
 #include "memory/metadataFactory.hpp"
 #include "memory/universe.hpp"
@@ -37,9 +39,11 @@
 
 #include "runtime/thread.hpp"
 #include "runtime/arguments.hpp"
+#include "runtime/deoptimization.hpp"
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/os.hpp"
 #include "runtime/vm_version.hpp"
+#include "runtime/sweeper.hpp"
 
 #include "utilities/array.hpp"
 #include "utilities/debug.hpp"
@@ -67,6 +71,7 @@
 #define SIZE_T_MAX_VALUE ((size_t) -1)
 
 bool WhiteBox::_used = false;
+volatile bool WhiteBox::compilation_locked = false;
 
 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
   return (jlong)(void*)JNIHandles::resolve(obj);
@@ -302,13 +307,12 @@
 WB_ENTRY(jlong, WB_NMTReserveMemory(JNIEnv* env, jobject o, jlong size))
   jlong addr = 0;
 
-    addr = (jlong)(uintptr_t)os::reserve_memory(size);
-    MemTracker::record_virtual_memory_type((address)addr, mtTest);
+  addr = (jlong)(uintptr_t)os::reserve_memory(size);
+  MemTracker::record_virtual_memory_type((address)addr, mtTest);
 
   return addr;
 WB_END
 
-
 WB_ENTRY(void, WB_NMTCommitMemory(JNIEnv* env, jobject o, jlong addr, jlong size))
   os::commit_memory((char *)(uintptr_t)addr, size, !ExecMem);
   MemTracker::record_virtual_memory_type((address)(uintptr_t)addr, mtTest);
@@ -728,6 +732,29 @@
 WB_END
 
 
+WB_ENTRY(void, WB_LockCompilation(JNIEnv* env, jobject o, jlong timeout))
+  WhiteBox::compilation_locked = true;
+WB_END
+
+WB_ENTRY(void, WB_UnlockCompilation(JNIEnv* env, jobject o))
+  MonitorLockerEx mo(Compilation_lock, Mutex::_no_safepoint_check_flag);
+  WhiteBox::compilation_locked = false;
+  mo.notify_all();
+WB_END
+
+void WhiteBox::force_sweep() {
+  guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+  {
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    NMethodSweeper::_should_sweep = true;
+  }
+  NMethodSweeper::possibly_sweep();
+}
+
+WB_ENTRY(void, WB_ForceNMethodSweep(JNIEnv* env, jobject o))
+  WhiteBox::force_sweep();
+WB_END
+
 WB_ENTRY(jboolean, WB_IsInStringTable(JNIEnv* env, jobject o, jstring javaString))
   ResourceMark rm(THREAD);
   int len;
@@ -774,6 +801,46 @@
   return features_string;
 WB_END
 
+int WhiteBox::get_blob_type(const CodeBlob* code) {
+  guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+  return CodeCache::get_code_heap(code)->code_blob_type();
+}
+
+CodeHeap* WhiteBox::get_code_heap(int blob_type) {
+  guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+  return CodeCache::get_code_heap(blob_type);
+}
+
+struct CodeBlobStub {
+  CodeBlobStub(const CodeBlob* blob) :
+      name(os::strdup(blob->name())),
+      size(blob->size()),
+      blob_type(WhiteBox::get_blob_type(blob)) { }
+  ~CodeBlobStub() { os::free((void*) name); }
+  const char* const name;
+  const int         size;
+  const int         blob_type;
+};
+
+static jobjectArray codeBlob2objectArray(JavaThread* thread, JNIEnv* env, CodeBlobStub* cb) {
+  jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
+  CHECK_JNI_EXCEPTION_(env, NULL);
+  jobjectArray result = env->NewObjectArray(3, clazz, NULL);
+
+  jstring name = env->NewStringUTF(cb->name);
+  CHECK_JNI_EXCEPTION_(env, NULL);
+  env->SetObjectArrayElement(result, 0, name);
+
+  jobject obj = integerBox(thread, env, cb->size);
+  CHECK_JNI_EXCEPTION_(env, NULL);
+  env->SetObjectArrayElement(result, 1, obj);
+
+  obj = integerBox(thread, env, cb->blob_type);
+  CHECK_JNI_EXCEPTION_(env, NULL);
+  env->SetObjectArrayElement(result, 2, obj);
+
+  return result;
+}
 
 WB_ENTRY(jobjectArray, WB_GetNMethod(JNIEnv* env, jobject o, jobject method, jboolean is_osr))
   ResourceMark rm(THREAD);
@@ -790,24 +857,90 @@
   ThreadToNativeFromVM ttn(thread);
   jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
   CHECK_JNI_EXCEPTION_(env, NULL);
-  result = env->NewObjectArray(3, clazz, NULL);
+  result = env->NewObjectArray(4, clazz, NULL);
   if (result == NULL) {
     return result;
   }
 
+  CodeBlobStub stub(code);
+  jobjectArray codeBlob = codeBlob2objectArray(thread, env, &stub);
+  env->SetObjectArrayElement(result, 0, codeBlob);
+
   jobject level = integerBox(thread, env, code->comp_level());
   CHECK_JNI_EXCEPTION_(env, NULL);
-  env->SetObjectArrayElement(result, 0, level);
+  env->SetObjectArrayElement(result, 1, level);
 
   jbyteArray insts = env->NewByteArray(insts_size);
   CHECK_JNI_EXCEPTION_(env, NULL);
   env->SetByteArrayRegion(insts, 0, insts_size, (jbyte*) code->insts_begin());
-  env->SetObjectArrayElement(result, 1, insts);
+  env->SetObjectArrayElement(result, 2, insts);
 
   jobject id = integerBox(thread, env, code->compile_id());
   CHECK_JNI_EXCEPTION_(env, NULL);
-  env->SetObjectArrayElement(result, 2, id);
+  env->SetObjectArrayElement(result, 3, id);
+
+  return result;
+WB_END
+
+CodeBlob* WhiteBox::allocate_code_blob(int size, int blob_type) {
+  guarantee(WhiteBoxAPI, "internal testing API :: WhiteBox has to enabled");
+  BufferBlob* blob;
+  int full_size = CodeBlob::align_code_offset(sizeof(BufferBlob));
+  if (full_size < size) {
+    full_size += round_to(size - full_size, oopSize);
+  }
+  {
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    blob = (BufferBlob*) CodeCache::allocate(full_size, blob_type);
+  }
+  // Track memory usage statistic after releasing CodeCache_lock
+  MemoryService::track_code_cache_memory_usage();
+  ::new (blob) BufferBlob("WB::DummyBlob", full_size);
+  return blob;
+}
+
+WB_ENTRY(jlong, WB_AllocateCodeBlob(JNIEnv* env, jobject o, jint size, jint blob_type))
+    return (jlong) WhiteBox::allocate_code_blob(size, blob_type);
+WB_END
+
+WB_ENTRY(void, WB_FreeCodeBlob(JNIEnv* env, jobject o, jlong addr))
+    BufferBlob::free((BufferBlob*) addr);
+WB_END
 
+WB_ENTRY(jobjectArray, WB_GetCodeHeapEntries(JNIEnv* env, jobject o, jint blob_type))
+  ResourceMark rm;
+  GrowableArray<CodeBlobStub*> blobs;
+  {
+    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+    CodeHeap* heap = WhiteBox::get_code_heap(blob_type);
+    if (heap == NULL) {
+      return NULL;
+    }
+    for (CodeBlob* cb = (CodeBlob*) heap->first();
+         cb != NULL; cb = (CodeBlob*) heap->next(cb)) {
+      CodeBlobStub* stub = NEW_RESOURCE_OBJ(CodeBlobStub);
+      new (stub) CodeBlobStub(cb);
+      blobs.append(stub);
+    }
+  }
+  if (blobs.length() == 0) {
+    return NULL;
+  }
+  ThreadToNativeFromVM ttn(thread);
+  jobjectArray result = NULL;
+  jclass clazz = env->FindClass(vmSymbols::java_lang_Object()->as_C_string());
+  CHECK_JNI_EXCEPTION_(env, NULL);
+  result = env->NewObjectArray(blobs.length(), clazz, NULL);
+  if (result == NULL) {
+    return result;
+  }
+  int i = 0;
+  for (GrowableArrayIterator<CodeBlobStub*> it = blobs.begin();
+       it != blobs.end(); ++it) {
+    jobjectArray obj = codeBlob2objectArray(thread, env, *it);
+    env->SetObjectArrayElement(result, i, obj);
+    ++i;
+  }
   return result;
 WB_END
 
@@ -1018,6 +1151,8 @@
       CC"(Ljava/lang/reflect/Executable;II)Z",        (void*)&WB_EnqueueMethodForCompilation},
   {CC"clearMethodState",
       CC"(Ljava/lang/reflect/Executable;)V",          (void*)&WB_ClearMethodState},
+  {CC"lockCompilation",    CC"()V",                   (void*)&WB_LockCompilation},
+  {CC"unlockCompilation",  CC"()V",                   (void*)&WB_UnlockCompilation},
   {CC"isConstantVMFlag",   CC"(Ljava/lang/String;)Z", (void*)&WB_IsConstantVMFlag},
   {CC"isLockedVMFlag",     CC"(Ljava/lang/String;)Z", (void*)&WB_IsLockedVMFlag},
   {CC"setBooleanVMFlag",   CC"(Ljava/lang/String;Z)V",(void*)&WB_SetBooleanVMFlag},
@@ -1055,6 +1190,10 @@
   {CC"getCPUFeatures",     CC"()Ljava/lang/String;",  (void*)&WB_GetCPUFeatures     },
   {CC"getNMethod",         CC"(Ljava/lang/reflect/Executable;Z)[Ljava/lang/Object;",
                                                       (void*)&WB_GetNMethod         },
+  {CC"forceNMethodSweep",  CC"()V",                   (void*)&WB_ForceNMethodSweep  },
+  {CC"allocateCodeBlob",   CC"(II)J",                 (void*)&WB_AllocateCodeBlob   },
+  {CC"freeCodeBlob",       CC"(J)V",                  (void*)&WB_FreeCodeBlob       },
+  {CC"getCodeHeapEntries", CC"(I)[Ljava/lang/Object;",(void*)&WB_GetCodeHeapEntries },
   {CC"getThreadStackSize", CC"()J",                   (void*)&WB_GetThreadStackSize },
   {CC"getThreadRemainingStackSize", CC"()J",          (void*)&WB_GetThreadRemainingStackSize },
 };