< prev index next >

src/hotspot/share/prims/jvmtiEnv.cpp

Print this page

  56 #include "prims/jvmtiUtil.hpp"
  57 #include "runtime/arguments.hpp"
  58 #include "runtime/deoptimization.hpp"
  59 #include "runtime/fieldDescriptor.inline.hpp"
  60 #include "runtime/handles.inline.hpp"
  61 #include "runtime/interfaceSupport.inline.hpp"
  62 #include "runtime/javaCalls.hpp"
  63 #include "runtime/jfieldIDWorkaround.hpp"
  64 #include "runtime/jniHandles.inline.hpp"
  65 #include "runtime/objectMonitor.inline.hpp"
  66 #include "runtime/osThread.hpp"
  67 #include "runtime/reflectionUtils.hpp"
  68 #include "runtime/signature.hpp"
  69 #include "runtime/thread.inline.hpp"
  70 #include "runtime/threadHeapSampler.hpp"
  71 #include "runtime/threadSMR.hpp"
  72 #include "runtime/timerTrace.hpp"
  73 #include "runtime/vframe.inline.hpp"
  74 #include "runtime/vmThread.hpp"
  75 #include "services/threadService.hpp"



  76 #include "utilities/exceptions.hpp"
  77 #include "utilities/preserveException.hpp"
  78 #include "utilities/utf8.hpp"
  79 
  80 
  81 #define FIXLATER 0 // REMOVE this when completed.
  82 
  83  // FIXLATER: hook into JvmtiTrace
  84 #define TraceJVMTICalls false
  85 
  86 JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {
  87 }
  88 
  89 JvmtiEnv::~JvmtiEnv() {
  90 }
  91 
  92 JvmtiEnv*
  93 JvmtiEnv::create_a_jvmti(jint version) {
  94   return new JvmtiEnv(version);
  95 }

3209   if (use_version_1_0_semantics() &&
3210       get_capabilities()->can_redefine_classes == 0) {
3211     // This JvmtiEnv requested version 1.0 semantics and this function
3212     // requires the can_redefine_classes capability in version 1.0 so
3213     // we need to return an error here.
3214     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3215   }
3216 
3217   if (method_oop == NULL || method_oop->is_obsolete()) {
3218     *is_obsolete_ptr = true;
3219   } else {
3220     *is_obsolete_ptr = false;
3221   }
3222   return JVMTI_ERROR_NONE;
3223 } /* end IsMethodObsolete */
3224 
3225   //
3226   // Raw Monitor functions
3227   //
3228 




3229 // name - pre-checked for NULL
3230 // monitor_ptr - pre-checked for NULL
3231 jvmtiError
3232 JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {
3233   JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name);
3234   NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);
3235 
3236   *monitor_ptr = (jrawMonitorID)rmonitor;
3237 


3238   return JVMTI_ERROR_NONE;
3239 } /* end CreateRawMonitor */
3240 
3241 
3242 // rmonitor - pre-checked for validity
3243 jvmtiError
3244 JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
3245   if (Threads::number_of_threads() == 0) {
3246     // Remove this monitor from pending raw monitors list
3247     // if it has entered in onload or start phase.
3248     JvmtiPendingMonitors::destroy(rmonitor);
3249   } else {
3250     Thread* thread  = Thread::current();
3251     if (rmonitor->owner() == thread) {
3252       // The caller owns this monitor which we are about to destroy.
3253       // We exit the underlying synchronization object so that the
3254       // "delete monitor" call below can work without an assertion
3255       // failure on systems that don't like destroying synchronization
3256       // objects that are locked.
3257       int r;
3258       int recursion = rmonitor->recursions();
3259       for (int i = 0; i <= recursion; i++) {

3260         r = rmonitor->raw_exit(thread);
3261         assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
3262         if (r != JvmtiRawMonitor::M_OK) {  // robustness
3263           return JVMTI_ERROR_INTERNAL;
3264         }
3265       }
3266     }
3267     if (rmonitor->owner() != NULL) {
3268       // The caller is trying to destroy a monitor that is locked by
3269       // someone else. While this is not forbidden by the JVMTI
3270       // spec, it will cause an assertion failure on systems that don't
3271       // like destroying synchronization objects that are locked.
3272       // We indicate a problem with the error return (and leak the
3273       // monitor's memory).
3274       return JVMTI_ERROR_NOT_MONITOR_OWNER;
3275     }
3276   }
3277 

3278   delete rmonitor;
3279 
3280   return JVMTI_ERROR_NONE;
3281 } /* end DestroyRawMonitor */
3282 
3283 
3284 // rmonitor - pre-checked for validity
3285 jvmtiError
3286 JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
3287   if (Threads::number_of_threads() == 0) {
3288     // No JavaThreads exist so JvmtiRawMonitor enter cannot be
3289     // used, add this raw monitor to the pending list.
3290     // The pending monitors will be actually entered when
3291     // the VM is setup.
3292     // See transition_pending_raw_monitors in create_vm()
3293     // in thread.cpp.
3294     JvmtiPendingMonitors::enter(rmonitor);
3295   } else {
3296     Thread* thread = Thread::current();
3297     if (thread->is_Java_thread()) {

3301       /* This is really evil. Normally you can't undo _thread_blocked    */
3302       /* transitions like this because it would cause us to miss a       */
3303       /* safepoint but since the thread was already in _thread_in_native */
3304       /* the thread is not leaving a safepoint safe state and it will    */
3305       /* block when it tries to return from native. We can't safepoint   */
3306       /* block in here because we could deadlock the vmthread. Blech.    */
3307 
3308       JavaThreadState state = current_thread->thread_state();
3309       assert(state == _thread_in_native, "Must be _thread_in_native");
3310       // frame should already be walkable since we are in native
3311       assert(!current_thread->has_last_Java_frame() ||
3312              current_thread->frame_anchor()->walkable(), "Must be walkable");
3313       current_thread->set_thread_state(_thread_blocked);
3314 
3315       rmonitor->raw_enter(current_thread);
3316       // restore state, still at a safepoint safe state
3317       current_thread->set_thread_state(state);
3318     } else {
3319       rmonitor->raw_enter(thread);
3320     }

3321   }
3322   return JVMTI_ERROR_NONE;
3323 } /* end RawMonitorEnter */
3324 
3325 
3326 // rmonitor - pre-checked for validity
3327 jvmtiError
3328 JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {
3329   jvmtiError err = JVMTI_ERROR_NONE;
3330 
3331   if (Threads::number_of_threads() == 0) {
3332     // No JavaThreads exist so just remove this monitor from the pending list.
3333     // Bool value from exit is false if rmonitor is not in the list.
3334     if (!JvmtiPendingMonitors::exit(rmonitor)) {
3335       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3336     }
3337   } else {

3338     Thread* thread = Thread::current();
3339     int r = rmonitor->raw_exit(thread);
3340     if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3341       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3342     }
3343   }
3344   return err;
3345 } /* end RawMonitorExit */
3346 
3347 
3348 // rmonitor - pre-checked for validity
3349 jvmtiError
3350 JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {




3351   Thread* thread = Thread::current();


3352   int r = rmonitor->raw_wait(millis, thread);
3353 
3354   switch (r) {
3355   case JvmtiRawMonitor::M_INTERRUPTED:
3356     return JVMTI_ERROR_INTERRUPT;
3357   case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
3358     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3359   default:
3360     return JVMTI_ERROR_NONE;
3361   }
3362 } /* end RawMonitorWait */
3363 
3364 
3365 // rmonitor - pre-checked for validity
3366 jvmtiError
3367 JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
3368   Thread* thread = Thread::current();
3369   int r = rmonitor->raw_notify(thread);
3370 
3371   if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {

  56 #include "prims/jvmtiUtil.hpp"
  57 #include "runtime/arguments.hpp"
  58 #include "runtime/deoptimization.hpp"
  59 #include "runtime/fieldDescriptor.inline.hpp"
  60 #include "runtime/handles.inline.hpp"
  61 #include "runtime/interfaceSupport.inline.hpp"
  62 #include "runtime/javaCalls.hpp"
  63 #include "runtime/jfieldIDWorkaround.hpp"
  64 #include "runtime/jniHandles.inline.hpp"
  65 #include "runtime/objectMonitor.inline.hpp"
  66 #include "runtime/osThread.hpp"
  67 #include "runtime/reflectionUtils.hpp"
  68 #include "runtime/signature.hpp"
  69 #include "runtime/thread.inline.hpp"
  70 #include "runtime/threadHeapSampler.hpp"
  71 #include "runtime/threadSMR.hpp"
  72 #include "runtime/timerTrace.hpp"
  73 #include "runtime/vframe.inline.hpp"
  74 #include "runtime/vmThread.hpp"
  75 #include "services/threadService.hpp"
  76 #if INCLUDE_TSAN
  77 #include "tsan/tsan.hpp"
  78 #endif  // INCLUDE_TSAN
  79 #include "utilities/exceptions.hpp"
  80 #include "utilities/preserveException.hpp"
  81 #include "utilities/utf8.hpp"
  82 
  83 
  84 #define FIXLATER 0 // REMOVE this when completed.
  85 
  86  // FIXLATER: hook into JvmtiTrace
  87 #define TraceJVMTICalls false
  88 
  89 JvmtiEnv::JvmtiEnv(jint version) : JvmtiEnvBase(version) {
  90 }
  91 
  92 JvmtiEnv::~JvmtiEnv() {
  93 }
  94 
  95 JvmtiEnv*
  96 JvmtiEnv::create_a_jvmti(jint version) {
  97   return new JvmtiEnv(version);
  98 }

3212   if (use_version_1_0_semantics() &&
3213       get_capabilities()->can_redefine_classes == 0) {
3214     // This JvmtiEnv requested version 1.0 semantics and this function
3215     // requires the can_redefine_classes capability in version 1.0 so
3216     // we need to return an error here.
3217     return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
3218   }
3219 
3220   if (method_oop == NULL || method_oop->is_obsolete()) {
3221     *is_obsolete_ptr = true;
3222   } else {
3223     *is_obsolete_ptr = false;
3224   }
3225   return JVMTI_ERROR_NONE;
3226 } /* end IsMethodObsolete */
3227 
3228   //
3229   // Raw Monitor functions
3230   //
3231 
3232 // Tsan note: The JVMTI raw monitors are instrumented at JvmtiRawMonitor call
3233 // sites instead of inside the JvmtiRawMonitor implementation. This seems
3234 // cleaner, and mirrors instrumentation of JVM_RawMonitor* functions.
3235 
3236 // name - pre-checked for NULL
3237 // monitor_ptr - pre-checked for NULL
3238 jvmtiError
3239 JvmtiEnv::CreateRawMonitor(const char* name, jrawMonitorID* monitor_ptr) {
3240   JvmtiRawMonitor* rmonitor = new JvmtiRawMonitor(name);
3241   NULL_CHECK(rmonitor, JVMTI_ERROR_OUT_OF_MEMORY);
3242 
3243   *monitor_ptr = (jrawMonitorID)rmonitor;
3244 
3245   TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_CREATE(rmonitor));
3246 
3247   return JVMTI_ERROR_NONE;
3248 } /* end CreateRawMonitor */
3249 
3250 
3251 // rmonitor - pre-checked for validity
3252 jvmtiError
3253 JvmtiEnv::DestroyRawMonitor(JvmtiRawMonitor * rmonitor) {
3254   if (Threads::number_of_threads() == 0) {
3255     // Remove this monitor from pending raw monitors list
3256     // if it has entered in onload or start phase.
3257     JvmtiPendingMonitors::destroy(rmonitor);
3258   } else {
3259     Thread* thread  = Thread::current();
3260     if (rmonitor->owner() == thread) {
3261       // The caller owns this monitor which we are about to destroy.
3262       // We exit the underlying synchronization object so that the
3263       // "delete monitor" call below can work without an assertion
3264       // failure on systems that don't like destroying synchronization
3265       // objects that are locked.
3266       int r;
3267       int recursion = rmonitor->recursions();
3268       for (int i = 0; i <= recursion; i++) {
3269         TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_RELEASED(rmonitor));
3270         r = rmonitor->raw_exit(thread);
3271         assert(r == JvmtiRawMonitor::M_OK, "raw_exit should have worked");
3272         if (r != JvmtiRawMonitor::M_OK) {  // robustness
3273           return JVMTI_ERROR_INTERNAL;
3274         }
3275       }
3276     }
3277     if (rmonitor->owner() != NULL) {
3278       // The caller is trying to destroy a monitor that is locked by
3279       // someone else. While this is not forbidden by the JVMTI
3280       // spec, it will cause an assertion failure on systems that don't
3281       // like destroying synchronization objects that are locked.
3282       // We indicate a problem with the error return (and leak the
3283       // monitor's memory).
3284       return JVMTI_ERROR_NOT_MONITOR_OWNER;
3285     }
3286   }
3287 
3288   TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_DESTROY(rmonitor));
3289   delete rmonitor;
3290 
3291   return JVMTI_ERROR_NONE;
3292 } /* end DestroyRawMonitor */
3293 
3294 
3295 // rmonitor - pre-checked for validity
3296 jvmtiError
3297 JvmtiEnv::RawMonitorEnter(JvmtiRawMonitor * rmonitor) {
3298   if (Threads::number_of_threads() == 0) {
3299     // No JavaThreads exist so JvmtiRawMonitor enter cannot be
3300     // used, add this raw monitor to the pending list.
3301     // The pending monitors will be actually entered when
3302     // the VM is setup.
3303     // See transition_pending_raw_monitors in create_vm()
3304     // in thread.cpp.
3305     JvmtiPendingMonitors::enter(rmonitor);
3306   } else {
3307     Thread* thread = Thread::current();
3308     if (thread->is_Java_thread()) {

3312       /* This is really evil. Normally you can't undo _thread_blocked    */
3313       /* transitions like this because it would cause us to miss a       */
3314       /* safepoint but since the thread was already in _thread_in_native */
3315       /* the thread is not leaving a safepoint safe state and it will    */
3316       /* block when it tries to return from native. We can't safepoint   */
3317       /* block in here because we could deadlock the vmthread. Blech.    */
3318 
3319       JavaThreadState state = current_thread->thread_state();
3320       assert(state == _thread_in_native, "Must be _thread_in_native");
3321       // frame should already be walkable since we are in native
3322       assert(!current_thread->has_last_Java_frame() ||
3323              current_thread->frame_anchor()->walkable(), "Must be walkable");
3324       current_thread->set_thread_state(_thread_blocked);
3325 
3326       rmonitor->raw_enter(current_thread);
3327       // restore state, still at a safepoint safe state
3328       current_thread->set_thread_state(state);
3329     } else {
3330       rmonitor->raw_enter(thread);
3331     }
3332     TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_ACQUIRED(rmonitor));
3333   }
3334   return JVMTI_ERROR_NONE;
3335 } /* end RawMonitorEnter */
3336 
3337 
3338 // rmonitor - pre-checked for validity
3339 jvmtiError
3340 JvmtiEnv::RawMonitorExit(JvmtiRawMonitor * rmonitor) {
3341   jvmtiError err = JVMTI_ERROR_NONE;
3342 
3343   if (Threads::number_of_threads() == 0) {
3344     // No JavaThreads exist so just remove this monitor from the pending list.
3345     // Bool value from exit is false if rmonitor is not in the list.
3346     if (!JvmtiPendingMonitors::exit(rmonitor)) {
3347       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3348     }
3349   } else {
3350     Thread* thread = Thread::current();
3351     TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_RELEASED(rmonitor));
3352     int r = rmonitor->raw_exit(thread);
3353     if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
3354       err = JVMTI_ERROR_NOT_MONITOR_OWNER;
3355     }
3356   }
3357   return err;
3358 } /* end RawMonitorExit */
3359 
3360 
3361 // rmonitor - pre-checked for validity
3362 jvmtiError
3363 JvmtiEnv::RawMonitorWait(JvmtiRawMonitor * rmonitor, jlong millis) {
3364   Thread* thread = Thread::current();
3365 
3366   // A wait is modeled in Tsan as a simple release-acquire pair.
3367   // The matching release annotation is below.
3368   TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_RELEASED(rmonitor));
3369   int r = rmonitor->raw_wait(millis, thread);
3370   // The matching acquire annotation is above.
3371   TSAN_RUNTIME_ONLY(TSAN_RAW_LOCK_ACQUIRED(rmonitor));
3372 
3373   switch (r) {
3374   case JvmtiRawMonitor::M_INTERRUPTED:
3375     return JVMTI_ERROR_INTERRUPT;
3376   case JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE:
3377     return JVMTI_ERROR_NOT_MONITOR_OWNER;
3378   default:
3379     return JVMTI_ERROR_NONE;
3380   }
3381 } /* end RawMonitorWait */
3382 
3383 
3384 // rmonitor - pre-checked for validity
3385 jvmtiError
3386 JvmtiEnv::RawMonitorNotify(JvmtiRawMonitor * rmonitor) {
3387   Thread* thread = Thread::current();
3388   int r = rmonitor->raw_notify(thread);
3389 
3390   if (r == JvmtiRawMonitor::M_ILLEGAL_MONITOR_STATE) {
< prev index next >