src/share/vm/prims/whitebox.cpp

Print this page




  32 
  33 #include "prims/whitebox.hpp"
  34 #include "prims/wbtestmethods/parserTests.hpp"
  35 
  36 #include "runtime/interfaceSupport.hpp"
  37 #include "runtime/os.hpp"
  38 #include "utilities/debug.hpp"
  39 #include "utilities/macros.hpp"
  40 
  41 #if INCLUDE_ALL_GCS
  42 #include "gc_implementation/g1/concurrentMark.hpp"
  43 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  44 #include "gc_implementation/g1/heapRegionRemSet.hpp"
  45 #endif // INCLUDE_ALL_GCS
  46 
  47 #ifdef INCLUDE_NMT
  48 #include "services/memTracker.hpp"
  49 #endif // INCLUDE_NMT
  50 
  51 #include "compiler/compileBroker.hpp"

  52 
  53 bool WhiteBox::_used = false;
  54 
  55 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
  56   return (jlong)(void*)JNIHandles::resolve(obj);
  57 WB_END
  58 
  59 WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
  60   return heapOopSize;
  61 WB_END
  62 
  63 
  64 class WBIsKlassAliveClosure : public KlassClosure {
  65     Symbol* _name;
  66     bool _found;
  67 public:
  68     WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {}
  69 
  70     void do_klass(Klass* k) {
  71       if (_found) return;


 196   }
 197   result += CodeCache::mark_for_deoptimization(mh());
 198   if (result > 0) {
 199     VM_Deoptimize op;
 200     VMThread::execute(&op);
 201   }
 202   return result;
 203 WB_END
 204 
 205 WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method))
 206   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 207   MutexLockerEx mu(Compile_lock);
 208   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 209   nmethod* code = mh->code();
 210   if (code == NULL) {
 211     return JNI_FALSE;
 212   }
 213   return (code->is_alive() && !code->is_marked_for_deoptimization());
 214 WB_END
 215 
 216 WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method))
 217   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 218   MutexLockerEx mu(Compile_lock);
 219   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 220   return !mh->is_not_compilable();
 221 WB_END
 222 
 223 WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
 224   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 225   MutexLockerEx mu(Compile_lock);
 226   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 227   return mh->queued_for_compilation();
 228 WB_END
 229 
 230 WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method))
 231   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 232   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 233   nmethod* code = mh->code();
 234   return (code != NULL ? code->comp_level() : CompLevel_none);
 235 WB_END
 236 
 237 
 238 WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method))
 239   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 240   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 241   mh->set_not_compilable();
 242 WB_END
 243 
 244 WB_ENTRY(jboolean, WB_SetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
 245   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 246   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 247   bool result = mh->dont_inline();
 248   mh->set_dont_inline(value == JNI_TRUE);
 249   return result;
 250 WB_END
 251 
 252 WB_ENTRY(jint, WB_GetCompileQueuesSize(JNIEnv* env, jobject o))
 253   return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
 254          CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
 255 WB_END
 256 















































 257 //Some convenience methods to deal with objects from java
 258 int WhiteBox::offset_for_field(const char* field_name, oop object,
 259     Symbol* signature_symbol) {
 260   assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid");
 261   Thread* THREAD = Thread::current();
 262 
 263   //Get the class of our object
 264   Klass* arg_klass = object->klass();
 265   //Turn it into an instance-klass
 266   InstanceKlass* ik = InstanceKlass::cast(arg_klass);
 267 
 268   //Create symbols to look for in the class
 269   TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name),
 270       THREAD);
 271 
 272   //To be filled in with an offset of the field we're looking for
 273   fieldDescriptor fd;
 274 
 275   Klass* res = ik->find_field(name_symbol, signature_symbol, &fd);
 276   if (res == NULL) {


 314   {CC"parseCommandLine",
 315       CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
 316       (void*) &WB_ParseCommandLine
 317   },
 318 #if INCLUDE_ALL_GCS
 319   {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
 320   {CC"g1IsHumongous",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
 321   {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
 322   {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
 323 #endif // INCLUDE_ALL_GCS
 324 #ifdef INCLUDE_NMT
 325   {CC"NMTAllocTest",       CC"()Z",                   (void*)&WB_NMTAllocTest      },
 326   {CC"NMTFreeTestMemory",  CC"()Z",                   (void*)&WB_NMTFreeTestMemory },
 327   {CC"NMTWaitForDataMerge",CC"()Z",                   (void*)&WB_NMTWaitForDataMerge},
 328 #endif // INCLUDE_NMT
 329   {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
 330   {CC"deoptimizeMethod",   CC"(Ljava/lang/reflect/Method;)I",
 331                                                       (void*)&WB_DeoptimizeMethod  },
 332   {CC"isMethodCompiled",   CC"(Ljava/lang/reflect/Method;)Z",
 333                                                       (void*)&WB_IsMethodCompiled  },
 334   {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Method;)Z",
 335                                                       (void*)&WB_IsMethodCompilable},
 336   {CC"isMethodQueuedForCompilation",
 337       CC"(Ljava/lang/reflect/Method;)Z",              (void*)&WB_IsMethodQueuedForCompilation},
 338   {CC"makeMethodNotCompilable",
 339       CC"(Ljava/lang/reflect/Method;)V",              (void*)&WB_MakeMethodNotCompilable},
 340   {CC"setDontInlineMethod",
 341       CC"(Ljava/lang/reflect/Method;Z)Z",             (void*)&WB_SetDontInlineMethod},
 342   {CC"getMethodCompilationLevel",
 343       CC"(Ljava/lang/reflect/Method;)I",              (void*)&WB_GetMethodCompilationLevel},
 344   {CC"getCompileQueuesSize",
 345       CC"()I",                                        (void*)&WB_GetCompileQueuesSize},






 346 };
 347 
 348 #undef CC
 349 
 350 JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
 351   {
 352     if (WhiteBoxAPI) {
 353       // Make sure that wbclass is loaded by the null classloader
 354       instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
 355       Handle loader(ikh->class_loader());
 356       if (loader.is_null()) {
 357         ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
 358         jint result = env->RegisterNatives(wbclass, methods, sizeof(methods)/sizeof(methods[0]));
 359         if (result == 0) {
 360           WhiteBox::set_used();
 361         }
 362       }
 363     }
 364   }
 365 JVM_END


  32 
  33 #include "prims/whitebox.hpp"
  34 #include "prims/wbtestmethods/parserTests.hpp"
  35 
  36 #include "runtime/interfaceSupport.hpp"
  37 #include "runtime/os.hpp"
  38 #include "utilities/debug.hpp"
  39 #include "utilities/macros.hpp"
  40 
  41 #if INCLUDE_ALL_GCS
  42 #include "gc_implementation/g1/concurrentMark.hpp"
  43 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
  44 #include "gc_implementation/g1/heapRegionRemSet.hpp"
  45 #endif // INCLUDE_ALL_GCS
  46 
  47 #ifdef INCLUDE_NMT
  48 #include "services/memTracker.hpp"
  49 #endif // INCLUDE_NMT
  50 
  51 #include "compiler/compileBroker.hpp"
  52 #include "runtime/compilationPolicy.hpp"
  53 
  54 bool WhiteBox::_used = false;
  55 
  56 WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
  57   return (jlong)(void*)JNIHandles::resolve(obj);
  58 WB_END
  59 
  60 WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
  61   return heapOopSize;
  62 WB_END
  63 
  64 
  65 class WBIsKlassAliveClosure : public KlassClosure {
  66     Symbol* _name;
  67     bool _found;
  68 public:
  69     WBIsKlassAliveClosure(Symbol* name) : _name(name), _found(false) {}
  70 
  71     void do_klass(Klass* k) {
  72       if (_found) return;


 197   }
 198   result += CodeCache::mark_for_deoptimization(mh());
 199   if (result > 0) {
 200     VM_Deoptimize op;
 201     VMThread::execute(&op);
 202   }
 203   return result;
 204 WB_END
 205 
 206 WB_ENTRY(jboolean, WB_IsMethodCompiled(JNIEnv* env, jobject o, jobject method))
 207   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 208   MutexLockerEx mu(Compile_lock);
 209   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 210   nmethod* code = mh->code();
 211   if (code == NULL) {
 212     return JNI_FALSE;
 213   }
 214   return (code->is_alive() && !code->is_marked_for_deoptimization());
 215 WB_END
 216 
 217 WB_ENTRY(jboolean, WB_IsMethodCompilable(JNIEnv* env, jobject o, jobject method, jint comp_level))
 218   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 219   MutexLockerEx mu(Compile_lock);
 220   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 221   return CompilationPolicy::can_be_compiled(mh, comp_level);
 222 WB_END
 223 
 224 WB_ENTRY(jboolean, WB_IsMethodQueuedForCompilation(JNIEnv* env, jobject o, jobject method))
 225   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 226   MutexLockerEx mu(Compile_lock);
 227   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 228   return mh->queued_for_compilation();
 229 WB_END
 230 
 231 WB_ENTRY(jint, WB_GetMethodCompilationLevel(JNIEnv* env, jobject o, jobject method))
 232   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 233   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 234   nmethod* code = mh->code();
 235   return (code != NULL ? code->comp_level() : CompLevel_none);
 236 WB_END
 237 
 238 
 239 WB_ENTRY(void, WB_MakeMethodNotCompilable(JNIEnv* env, jobject o, jobject method))
 240   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 241   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 242   mh->set_not_compilable();
 243 WB_END
 244 
 245 WB_ENTRY(jboolean, WB_SetDontInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
 246   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 247   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 248   bool result = mh->dont_inline();
 249   mh->set_dont_inline(value == JNI_TRUE);
 250   return result;
 251 WB_END
 252 
 253 WB_ENTRY(jint, WB_GetCompileQueuesSize(JNIEnv* env, jobject o))
 254   return CompileBroker::queue_size(CompLevel_full_optimization) /* C2 */ +
 255          CompileBroker::queue_size(CompLevel_full_profile) /* C1 */;
 256 WB_END
 257 
 258 WB_ENTRY(jboolean, WB_SetForceInlineMethod(JNIEnv* env, jobject o, jobject method, jboolean value))
 259   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 260   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 261   bool result = mh->force_inline();
 262   mh->set_force_inline(value == JNI_TRUE);
 263   return result;
 264 WB_END
 265 
 266 WB_ENTRY(jboolean, WB_EnqueueMethodForCompilation(JNIEnv* env, jobject o, jobject method, jint comp_level))
 267   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 268   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 269   nmethod* nm = CompileBroker::compile_method(mh, InvocationEntryBci, comp_level, mh, mh->invocation_count(), "WhiteBox", THREAD);
 270   MutexLockerEx mu(Compile_lock);
 271   return (mh->queued_for_compilation() || nm != NULL);
 272 WB_END
 273 
 274 WB_ENTRY(void, WB_ClearMethodState(JNIEnv* env, jobject o, jobject method))
 275   jmethodID jmid = reflected_method_to_jmid(thread, env, method);
 276   methodHandle mh(THREAD, Method::checked_resolve_jmethod_id(jmid));
 277   MutexLockerEx mu(Compile_lock);
 278   MethodData* mdo = mh->method_data();
 279 
 280   if (mdo != NULL) {
 281     mdo->init();
 282     ResourceMark rm;
 283     int arg_count = mdo->method()->size_of_parameters();
 284     for (int i = 0; i < arg_count; i++) {
 285       mdo->set_arg_modified(i, 0);
 286     }
 287   }
 288 
 289   mh->backedge_counter()->init();
 290   mh->invocation_counter()->init();
 291   mh->set_interpreter_invocation_count(0);
 292   mh->set_interpreter_throwout_count(0);
 293   mh->clear_not_c1_compilable();
 294   mh->clear_not_c2_compilable();
 295   mh->clear_not_c2_osr_compilable();
 296   NOT_PRODUCT(mh->set_compiled_invocation_count(0));
 297 
 298 #ifdef TIERED
 299   mh->set_rate(0.0F);
 300   mh->set_prev_event_count(0);
 301   mh->set_prev_time(0);
 302 #endif
 303 WB_END
 304 
 305 //Some convenience methods to deal with objects from java
 306 int WhiteBox::offset_for_field(const char* field_name, oop object,
 307     Symbol* signature_symbol) {
 308   assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid");
 309   Thread* THREAD = Thread::current();
 310 
 311   //Get the class of our object
 312   Klass* arg_klass = object->klass();
 313   //Turn it into an instance-klass
 314   InstanceKlass* ik = InstanceKlass::cast(arg_klass);
 315 
 316   //Create symbols to look for in the class
 317   TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name),
 318       THREAD);
 319 
 320   //To be filled in with an offset of the field we're looking for
 321   fieldDescriptor fd;
 322 
 323   Klass* res = ik->find_field(name_symbol, signature_symbol, &fd);
 324   if (res == NULL) {


 362   {CC"parseCommandLine",
 363       CC"(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
 364       (void*) &WB_ParseCommandLine
 365   },
 366 #if INCLUDE_ALL_GCS
 367   {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
 368   {CC"g1IsHumongous",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
 369   {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
 370   {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
 371 #endif // INCLUDE_ALL_GCS
 372 #ifdef INCLUDE_NMT
 373   {CC"NMTAllocTest",       CC"()Z",                   (void*)&WB_NMTAllocTest      },
 374   {CC"NMTFreeTestMemory",  CC"()Z",                   (void*)&WB_NMTFreeTestMemory },
 375   {CC"NMTWaitForDataMerge",CC"()Z",                   (void*)&WB_NMTWaitForDataMerge},
 376 #endif // INCLUDE_NMT
 377   {CC"deoptimizeAll",      CC"()V",                   (void*)&WB_DeoptimizeAll     },
 378   {CC"deoptimizeMethod",   CC"(Ljava/lang/reflect/Method;)I",
 379                                                       (void*)&WB_DeoptimizeMethod  },
 380   {CC"isMethodCompiled",   CC"(Ljava/lang/reflect/Method;)Z",
 381                                                       (void*)&WB_IsMethodCompiled  },
 382   {CC"isMethodCompilable", CC"(Ljava/lang/reflect/Method;I)Z",
 383                                                       (void*)&WB_IsMethodCompilable},
 384   {CC"isMethodQueuedForCompilation",
 385       CC"(Ljava/lang/reflect/Method;)Z",              (void*)&WB_IsMethodQueuedForCompilation},
 386   {CC"makeMethodNotCompilable",
 387       CC"(Ljava/lang/reflect/Method;)V",              (void*)&WB_MakeMethodNotCompilable},
 388   {CC"setDontInlineMethod",
 389       CC"(Ljava/lang/reflect/Method;Z)Z",             (void*)&WB_SetDontInlineMethod},
 390   {CC"getMethodCompilationLevel",
 391       CC"(Ljava/lang/reflect/Method;)I",              (void*)&WB_GetMethodCompilationLevel},
 392   {CC"getCompileQueuesSize",
 393       CC"()I",                                        (void*)&WB_GetCompileQueuesSize},
 394   {CC"setForceInlineMethod",
 395       CC"(Ljava/lang/reflect/Method;Z)Z",             (void*)&WB_SetForceInlineMethod},
 396   {CC"enqueueMethodForCompilation",
 397       CC"(Ljava/lang/reflect/Method;I)Z",             (void*)&WB_EnqueueMethodForCompilation},
 398   {CC"clearMethodState",
 399       CC"(Ljava/lang/reflect/Method;)V",              (void*)&WB_ClearMethodState},
 400 };
 401 
 402 #undef CC
 403 
 404 JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
 405   {
 406     if (WhiteBoxAPI) {
 407       // Make sure that wbclass is loaded by the null classloader
 408       instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
 409       Handle loader(ikh->class_loader());
 410       if (loader.is_null()) {
 411         ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
 412         jint result = env->RegisterNatives(wbclass, methods, sizeof(methods)/sizeof(methods[0]));
 413         if (result == 0) {
 414           WhiteBox::set_used();
 415         }
 416       }
 417     }
 418   }
 419 JVM_END