< prev index next >

src/share/vm/prims/jvm.cpp

Print this page




 570 
 571 
 572 JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle))
 573   JVMWrapper("JVM_MonitorNotify");
 574   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
 575   ObjectSynchronizer::notify(obj, CHECK);
 576 JVM_END
 577 
 578 
 579 JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle))
 580   JVMWrapper("JVM_MonitorNotifyAll");
 581   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
 582   ObjectSynchronizer::notifyall(obj, CHECK);
 583 JVM_END
 584 
 585 
 586 static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) {
 587   // If G1 is enabled then we need to register a non-null referent
 588   // with the SATB barrier.
 589 #if INCLUDE_ALL_GCS
 590   if (UseG1GC) {
 591     oop referent = java_lang_ref_Reference::referent(clone);
 592     if (referent != NULL) {
 593       G1SATBCardTableModRefBS::enqueue(referent);
 594     }
 595   }
 596 #endif // INCLUDE_ALL_GCS
 597   if ((java_lang_ref_Reference::next(clone) != NULL) ||
 598       (java_lang_ref_Reference::queue(clone) == java_lang_ref_ReferenceQueue::ENQUEUED_queue())) {
 599     // If the source has been enqueued or is being enqueued, don't
 600     // register the clone with a queue.
 601     java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue());
 602   }
 603   // discovered and next are list links; the clone is not in those lists.
 604   java_lang_ref_Reference::set_discovered(clone, NULL);
 605   java_lang_ref_Reference::set_next(clone, NULL);
 606 }
 607 
 608 JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
 609   JVMWrapper("JVM_Clone");
 610   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
 611   const KlassHandle klass (THREAD, obj->klass());
 612   JvmtiVMObjectAllocEventCollector oam;
 613 
 614 #ifdef ASSERT
 615   // Just checking that the cloneable flag is set correct
 616   if (obj->is_array()) {
 617     guarantee(klass->is_cloneable(), "all arrays are cloneable");
 618   } else {


 637     const int length = ((arrayOop)obj())->length();
 638     new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
 639   } else {
 640     ref_type = InstanceKlass::cast(klass())->reference_type();
 641     assert((ref_type == REF_NONE) ==
 642            !klass->is_subclass_of(SystemDictionary::Reference_klass()),
 643            "invariant");
 644     new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
 645   }
 646 
 647   // 4839641 (4840070): We must do an oop-atomic copy, because if another thread
 648   // is modifying a reference field in the clonee, a non-oop-atomic copy might
 649   // be suspended in the middle of copying the pointer and end up with parts
 650   // of two different pointers in the field.  Subsequent dereferences will crash.
 651   // 4846409: an oop-copy of objects with long or double fields or arrays of same
 652   // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead
 653   // of oops.  We know objects are aligned on a minimum of an jlong boundary.
 654   // The same is true of StubRoutines::object_copy and the various oop_copy
 655   // variants, and of the code generated by the inline_native_clone intrinsic.
 656   assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");
 657   Copy::conjoint_jlongs_atomic((jlong*)obj(), (jlong*)new_obj_oop,
 658                                (size_t)align_object_size(size) / HeapWordsPerLong);
 659   // Clear the header
 660   new_obj_oop->init_mark();
 661 
 662   // Store check (mark entire object and let gc sort it out)
 663   BarrierSet* bs = Universe::heap()->barrier_set();
 664   assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
 665   bs->write_region(MemRegion((HeapWord*)new_obj_oop, size));
 666 
 667   // If cloning a Reference, set Reference fields to a safe state.
 668   // Fixup must be completed before any safepoint.
 669   if (ref_type != REF_NONE) {
 670     fixup_cloned_reference(ref_type, obj(), new_obj_oop);
 671   }
 672 
 673   Handle new_obj(THREAD, new_obj_oop);
 674   // Special handling for MemberNames.  Since they contain Method* metadata, they
 675   // must be registered so that RedefineClasses can fix metadata contained in them.
 676   if (java_lang_invoke_MemberName::is_instance(new_obj()) &&
 677       java_lang_invoke_MemberName::is_method(new_obj())) {


1491   oop previous_protection_domain = NULL;
1492   Handle privileged_context(thread, NULL);
1493   bool is_privileged = false;
1494   oop protection_domain = NULL;
1495 
1496   for(; !vfst.at_end(); vfst.next()) {
1497     // get method of frame
1498     Method* method = vfst.method();
1499     intptr_t* frame_id   = vfst.frame_id();
1500 
1501     // check the privileged frames to see if we have a match
1502     if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) {
1503       // this frame is privileged
1504       is_privileged = true;
1505       privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context());
1506       protection_domain  = thread->privileged_stack_top()->protection_domain();
1507     } else {
1508       protection_domain = method->method_holder()->protection_domain();
1509     }
1510 
1511     if ((previous_protection_domain != protection_domain) && (protection_domain != NULL)) {
1512       local_array->push(protection_domain);
1513       previous_protection_domain = protection_domain;
1514     }
1515 
1516     if (is_privileged) break;
1517   }
1518 
1519 
1520   // either all the domains on the stack were system domains, or
1521   // we had a privileged system domain
1522   if (local_array->is_empty()) {
1523     if (is_privileged && privileged_context.is_null()) return NULL;
1524 
1525     oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);
1526     return JNIHandles::make_local(env, result);
1527   }
1528 
1529   // the resource area must be registered in case of a gc
1530   RegisterArrayForGC ragc(thread, local_array);
1531   objArrayOop context = oopFactory::new_objArray(SystemDictionary::ProtectionDomain_klass(),


3095 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints
3096 // before the quasi-asynchronous exception is delivered.  This is a little obtrusive,
3097 // but is thought to be reliable and simple. In the case, where the receiver is the
3098 // same thread as the sender, no safepoint is needed.
3099 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))
3100   JVMWrapper("JVM_StopThread");
3101 
3102   oop java_throwable = JNIHandles::resolve(throwable);
3103   if (java_throwable == NULL) {
3104     THROW(vmSymbols::java_lang_NullPointerException());
3105   }
3106   oop java_thread = JNIHandles::resolve_non_null(jthread);
3107   JavaThread* receiver = java_lang_Thread::thread(java_thread);
3108   Events::log_exception(JavaThread::current(),
3109                         "JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]",
3110                         p2i(receiver), p2i((address)java_thread), p2i(throwable));
3111   // First check if thread is alive
3112   if (receiver != NULL) {
3113     // Check if exception is getting thrown at self (use oop equality, since the
3114     // target object might exit)
3115     if (java_thread == thread->threadObj()) {
3116       THROW_OOP(java_throwable);
3117     } else {
3118       // Enques a VM_Operation to stop all threads and then deliver the exception...
3119       Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));
3120     }
3121   }
3122   else {
3123     // Either:
3124     // - target thread has not been started before being stopped, or
3125     // - target thread already terminated
3126     // We could read the threadStatus to determine which case it is
3127     // but that is overkill as it doesn't matter. We must set the
3128     // stillborn flag for the first case, and if the thread has already
3129     // exited setting this flag has no affect
3130     java_lang_Thread::set_stillborn(java_thread);
3131   }
3132 JVM_END
3133 
3134 
3135 JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread))


3297 #endif /* USDT2 */
3298 JVM_END
3299 
3300 JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
3301   JVMWrapper("JVM_CurrentThread");
3302   oop jthread = thread->threadObj();
3303   assert (thread != NULL, "no current thread!");
3304   return JNIHandles::make_local(env, jthread);
3305 JVM_END
3306 
3307 
3308 JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
3309   JVMWrapper("JVM_CountStackFrames");
3310 
3311   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
3312   oop java_thread = JNIHandles::resolve_non_null(jthread);
3313   bool throw_illegal_thread_state = false;
3314   int count = 0;
3315 
3316   {
3317     MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
3318     // We need to re-resolve the java_thread, since a GC might have happened during the
3319     // acquire of the lock
3320     JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
3321 
3322     if (thr == NULL) {
3323       // do nothing
3324     } else if(! thr->is_external_suspend() || ! thr->frame_anchor()->walkable()) {
3325       // Check whether this java thread has been suspended already. If not, throws
3326       // IllegalThreadStateException. We defer to throw that exception until
3327       // Threads_lock is released since loading exception class has to leave VM.
3328       // The correct way to test a thread is actually suspended is
3329       // wait_for_ext_suspend_completion(), but we can't call that while holding
3330       // the Threads_lock. The above tests are sufficient for our purposes
3331       // provided the walkability of the stack is stable - which it isn't
3332       // 100% but close enough for most practical purposes.
3333       throw_illegal_thread_state = true;
3334     } else {
3335       // Count all java activation, i.e., number of vframes
3336       for(vframeStream vfst(thr); !vfst.at_end(); vfst.next()) {
3337         // Native frames are not counted


3346   }
3347   return count;
3348 JVM_END
3349 
3350 // Consider: A better way to implement JVM_Interrupt() is to acquire
3351 // Threads_lock to resolve the jthread into a Thread pointer, fetch
3352 // Thread->platformevent, Thread->native_thr, Thread->parker, etc.,
3353 // drop Threads_lock, and the perform the unpark() and thr_kill() operations
3354 // outside the critical section.  Threads_lock is hot so we want to minimize
3355 // the hold-time.  A cleaner interface would be to decompose interrupt into
3356 // two steps.  The 1st phase, performed under Threads_lock, would return
3357 // a closure that'd be invoked after Threads_lock was dropped.
3358 // This tactic is safe as PlatformEvent and Parkers are type-stable (TSM) and
3359 // admit spurious wakeups.
3360 
3361 JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
3362   JVMWrapper("JVM_Interrupt");
3363 
3364   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
3365   oop java_thread = JNIHandles::resolve_non_null(jthread);
3366   MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
3367   // We need to re-resolve the java_thread, since a GC might have happened during the
3368   // acquire of the lock
3369   JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
3370   if (thr != NULL) {
3371     Thread::interrupt(thr);
3372   }
3373 JVM_END
3374 
3375 
3376 JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))
3377   JVMWrapper("JVM_IsInterrupted");
3378 
3379   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
3380   oop java_thread = JNIHandles::resolve_non_null(jthread);
3381   MutexLockerEx ml(thread->threadObj() == java_thread ? NULL : Threads_lock);
3382   // We need to re-resolve the java_thread, since a GC might have happened during the
3383   // acquire of the lock
3384   JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
3385   if (thr == NULL) {
3386     return JNI_FALSE;
3387   } else {
3388     return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0);
3389   }
3390 JVM_END
3391 
3392 
3393 // Return true iff the current thread has locked the object passed in
3394 
3395 JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))
3396   JVMWrapper("JVM_HoldsLock");
3397   assert(THREAD->is_Java_thread(), "sanity check");
3398   if (obj == NULL) {
3399     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
3400   }
3401   Handle h_obj(THREAD, JNIHandles::resolve(obj));




 570 
 571 
 572 JVM_ENTRY(void, JVM_MonitorNotify(JNIEnv* env, jobject handle))
 573   JVMWrapper("JVM_MonitorNotify");
 574   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
 575   ObjectSynchronizer::notify(obj, CHECK);
 576 JVM_END
 577 
 578 
 579 JVM_ENTRY(void, JVM_MonitorNotifyAll(JNIEnv* env, jobject handle))
 580   JVMWrapper("JVM_MonitorNotifyAll");
 581   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
 582   ObjectSynchronizer::notifyall(obj, CHECK);
 583 JVM_END
 584 
 585 
 586 static void fixup_cloned_reference(ReferenceType ref_type, oop src, oop clone) {
 587   // If G1 is enabled then we need to register a non-null referent
 588   // with the SATB barrier.
 589 #if INCLUDE_ALL_GCS
 590   if (UseG1GC || UseShenandoahGC) {
 591     oop referent = java_lang_ref_Reference::referent(clone);
 592     if (referent != NULL) {
 593       G1SATBCardTableModRefBS::enqueue(referent);
 594     }
 595   }
 596 #endif // INCLUDE_ALL_GCS
 597   if ((java_lang_ref_Reference::next(clone) != NULL) ||
 598       (oopDesc::equals(java_lang_ref_Reference::queue(clone), java_lang_ref_ReferenceQueue::ENQUEUED_queue()))) {
 599     // If the source has been enqueued or is being enqueued, don't
 600     // register the clone with a queue.
 601     java_lang_ref_Reference::set_queue(clone, java_lang_ref_ReferenceQueue::NULL_queue());
 602   }
 603   // discovered and next are list links; the clone is not in those lists.
 604   java_lang_ref_Reference::set_discovered(clone, NULL);
 605   java_lang_ref_Reference::set_next(clone, NULL);
 606 }
 607 
 608 JVM_ENTRY(jobject, JVM_Clone(JNIEnv* env, jobject handle))
 609   JVMWrapper("JVM_Clone");
 610   Handle obj(THREAD, JNIHandles::resolve_non_null(handle));
 611   const KlassHandle klass (THREAD, obj->klass());
 612   JvmtiVMObjectAllocEventCollector oam;
 613 
 614 #ifdef ASSERT
 615   // Just checking that the cloneable flag is set correct
 616   if (obj->is_array()) {
 617     guarantee(klass->is_cloneable(), "all arrays are cloneable");
 618   } else {


 637     const int length = ((arrayOop)obj())->length();
 638     new_obj_oop = CollectedHeap::array_allocate(klass, size, length, CHECK_NULL);
 639   } else {
 640     ref_type = InstanceKlass::cast(klass())->reference_type();
 641     assert((ref_type == REF_NONE) ==
 642            !klass->is_subclass_of(SystemDictionary::Reference_klass()),
 643            "invariant");
 644     new_obj_oop = CollectedHeap::obj_allocate(klass, size, CHECK_NULL);
 645   }
 646 
 647   // 4839641 (4840070): We must do an oop-atomic copy, because if another thread
 648   // is modifying a reference field in the clonee, a non-oop-atomic copy might
 649   // be suspended in the middle of copying the pointer and end up with parts
 650   // of two different pointers in the field.  Subsequent dereferences will crash.
 651   // 4846409: an oop-copy of objects with long or double fields or arrays of same
 652   // won't copy the longs/doubles atomically in 32-bit vm's, so we copy jlongs instead
 653   // of oops.  We know objects are aligned on a minimum of an jlong boundary.
 654   // The same is true of StubRoutines::object_copy and the various oop_copy
 655   // variants, and of the code generated by the inline_native_clone intrinsic.
 656   assert(MinObjAlignmentInBytes >= BytesPerLong, "objects misaligned");
 657   Copy::conjoint_jlongs_atomic((jlong*) oopDesc::bs()->read_barrier(obj()), (jlong*)new_obj_oop,
 658                                (size_t)align_object_size(size) / HeapWordsPerLong);
 659   // Clear the header
 660   new_obj_oop->init_mark();
 661 
 662   // Store check (mark entire object and let gc sort it out)
 663   BarrierSet* bs = Universe::heap()->barrier_set();
 664   assert(bs->has_write_region_opt(), "Barrier set does not have write_region");
 665   bs->write_region(MemRegion((HeapWord*)new_obj_oop, size));
 666 
 667   // If cloning a Reference, set Reference fields to a safe state.
 668   // Fixup must be completed before any safepoint.
 669   if (ref_type != REF_NONE) {
 670     fixup_cloned_reference(ref_type, obj(), new_obj_oop);
 671   }
 672 
 673   Handle new_obj(THREAD, new_obj_oop);
 674   // Special handling for MemberNames.  Since they contain Method* metadata, they
 675   // must be registered so that RedefineClasses can fix metadata contained in them.
 676   if (java_lang_invoke_MemberName::is_instance(new_obj()) &&
 677       java_lang_invoke_MemberName::is_method(new_obj())) {


1491   oop previous_protection_domain = NULL;
1492   Handle privileged_context(thread, NULL);
1493   bool is_privileged = false;
1494   oop protection_domain = NULL;
1495 
1496   for(; !vfst.at_end(); vfst.next()) {
1497     // get method of frame
1498     Method* method = vfst.method();
1499     intptr_t* frame_id   = vfst.frame_id();
1500 
1501     // check the privileged frames to see if we have a match
1502     if (thread->privileged_stack_top() && thread->privileged_stack_top()->frame_id() == frame_id) {
1503       // this frame is privileged
1504       is_privileged = true;
1505       privileged_context = Handle(thread, thread->privileged_stack_top()->privileged_context());
1506       protection_domain  = thread->privileged_stack_top()->protection_domain();
1507     } else {
1508       protection_domain = method->method_holder()->protection_domain();
1509     }
1510 
1511     if ((! oopDesc::equals(previous_protection_domain, protection_domain)) && protection_domain != NULL) {
1512       local_array->push(protection_domain);
1513       previous_protection_domain = protection_domain;
1514     }
1515 
1516     if (is_privileged) break;
1517   }
1518 
1519 
1520   // either all the domains on the stack were system domains, or
1521   // we had a privileged system domain
1522   if (local_array->is_empty()) {
1523     if (is_privileged && privileged_context.is_null()) return NULL;
1524 
1525     oop result = java_security_AccessControlContext::create(objArrayHandle(), is_privileged, privileged_context, CHECK_NULL);
1526     return JNIHandles::make_local(env, result);
1527   }
1528 
1529   // the resource area must be registered in case of a gc
1530   RegisterArrayForGC ragc(thread, local_array);
1531   objArrayOop context = oopFactory::new_objArray(SystemDictionary::ProtectionDomain_klass(),


3095 // JVM_Stop is implemented using a VM_Operation, so threads are forced to safepoints
3096 // before the quasi-asynchronous exception is delivered.  This is a little obtrusive,
3097 // but is thought to be reliable and simple. In the case, where the receiver is the
3098 // same thread as the sender, no safepoint is needed.
3099 JVM_ENTRY(void, JVM_StopThread(JNIEnv* env, jobject jthread, jobject throwable))
3100   JVMWrapper("JVM_StopThread");
3101 
3102   oop java_throwable = JNIHandles::resolve(throwable);
3103   if (java_throwable == NULL) {
3104     THROW(vmSymbols::java_lang_NullPointerException());
3105   }
3106   oop java_thread = JNIHandles::resolve_non_null(jthread);
3107   JavaThread* receiver = java_lang_Thread::thread(java_thread);
3108   Events::log_exception(JavaThread::current(),
3109                         "JVM_StopThread thread JavaThread " INTPTR_FORMAT " as oop " INTPTR_FORMAT " [exception " INTPTR_FORMAT "]",
3110                         p2i(receiver), p2i((address)java_thread), p2i(throwable));
3111   // First check if thread is alive
3112   if (receiver != NULL) {
3113     // Check if exception is getting thrown at self (use oop equality, since the
3114     // target object might exit)
3115     if (oopDesc::equals(java_thread, thread->threadObj())) {
3116       THROW_OOP(java_throwable);
3117     } else {
3118       // Enques a VM_Operation to stop all threads and then deliver the exception...
3119       Thread::send_async_exception(java_thread, JNIHandles::resolve(throwable));
3120     }
3121   }
3122   else {
3123     // Either:
3124     // - target thread has not been started before being stopped, or
3125     // - target thread already terminated
3126     // We could read the threadStatus to determine which case it is
3127     // but that is overkill as it doesn't matter. We must set the
3128     // stillborn flag for the first case, and if the thread has already
3129     // exited setting this flag has no affect
3130     java_lang_Thread::set_stillborn(java_thread);
3131   }
3132 JVM_END
3133 
3134 
3135 JVM_ENTRY(jboolean, JVM_IsThreadAlive(JNIEnv* env, jobject jthread))


3297 #endif /* USDT2 */
3298 JVM_END
3299 
3300 JVM_ENTRY(jobject, JVM_CurrentThread(JNIEnv* env, jclass threadClass))
3301   JVMWrapper("JVM_CurrentThread");
3302   oop jthread = thread->threadObj();
3303   assert (thread != NULL, "no current thread!");
3304   return JNIHandles::make_local(env, jthread);
3305 JVM_END
3306 
3307 
3308 JVM_ENTRY(jint, JVM_CountStackFrames(JNIEnv* env, jobject jthread))
3309   JVMWrapper("JVM_CountStackFrames");
3310 
3311   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
3312   oop java_thread = JNIHandles::resolve_non_null(jthread);
3313   bool throw_illegal_thread_state = false;
3314   int count = 0;
3315 
3316   {
3317     MutexLockerEx ml(oopDesc::equals(thread->threadObj(), java_thread) ? NULL : Threads_lock);
3318     // We need to re-resolve the java_thread, since a GC might have happened during the
3319     // acquire of the lock
3320     JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
3321 
3322     if (thr == NULL) {
3323       // do nothing
3324     } else if(! thr->is_external_suspend() || ! thr->frame_anchor()->walkable()) {
3325       // Check whether this java thread has been suspended already. If not, throws
3326       // IllegalThreadStateException. We defer to throw that exception until
3327       // Threads_lock is released since loading exception class has to leave VM.
3328       // The correct way to test a thread is actually suspended is
3329       // wait_for_ext_suspend_completion(), but we can't call that while holding
3330       // the Threads_lock. The above tests are sufficient for our purposes
3331       // provided the walkability of the stack is stable - which it isn't
3332       // 100% but close enough for most practical purposes.
3333       throw_illegal_thread_state = true;
3334     } else {
3335       // Count all java activation, i.e., number of vframes
3336       for(vframeStream vfst(thr); !vfst.at_end(); vfst.next()) {
3337         // Native frames are not counted


3346   }
3347   return count;
3348 JVM_END
3349 
3350 // Consider: A better way to implement JVM_Interrupt() is to acquire
3351 // Threads_lock to resolve the jthread into a Thread pointer, fetch
3352 // Thread->platformevent, Thread->native_thr, Thread->parker, etc.,
3353 // drop Threads_lock, and the perform the unpark() and thr_kill() operations
3354 // outside the critical section.  Threads_lock is hot so we want to minimize
3355 // the hold-time.  A cleaner interface would be to decompose interrupt into
3356 // two steps.  The 1st phase, performed under Threads_lock, would return
3357 // a closure that'd be invoked after Threads_lock was dropped.
3358 // This tactic is safe as PlatformEvent and Parkers are type-stable (TSM) and
3359 // admit spurious wakeups.
3360 
3361 JVM_ENTRY(void, JVM_Interrupt(JNIEnv* env, jobject jthread))
3362   JVMWrapper("JVM_Interrupt");
3363 
3364   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
3365   oop java_thread = JNIHandles::resolve_non_null(jthread);
3366   MutexLockerEx ml(oopDesc::equals(thread->threadObj(), java_thread) ? NULL : Threads_lock);
3367   // We need to re-resolve the java_thread, since a GC might have happened during the
3368   // acquire of the lock
3369   JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
3370   if (thr != NULL) {
3371     Thread::interrupt(thr);
3372   }
3373 JVM_END
3374 
3375 
3376 JVM_QUICK_ENTRY(jboolean, JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrupted))
3377   JVMWrapper("JVM_IsInterrupted");
3378 
3379   // Ensure that the C++ Thread and OSThread structures aren't freed before we operate
3380   oop java_thread = JNIHandles::resolve_non_null(jthread);
3381   MutexLockerEx ml(oopDesc::equals(thread->threadObj(), java_thread) ? NULL : Threads_lock);
3382   // We need to re-resolve the java_thread, since a GC might have happened during the
3383   // acquire of the lock
3384   JavaThread* thr = java_lang_Thread::thread(JNIHandles::resolve_non_null(jthread));
3385   if (thr == NULL) {
3386     return JNI_FALSE;
3387   } else {
3388     return (jboolean) Thread::is_interrupted(thr, clear_interrupted != 0);
3389   }
3390 JVM_END
3391 
3392 
3393 // Return true iff the current thread has locked the object passed in
3394 
3395 JVM_ENTRY(jboolean, JVM_HoldsLock(JNIEnv* env, jclass threadClass, jobject obj))
3396   JVMWrapper("JVM_HoldsLock");
3397   assert(THREAD->is_Java_thread(), "sanity check");
3398   if (obj == NULL) {
3399     THROW_(vmSymbols::java_lang_NullPointerException(), JNI_FALSE);
3400   }
3401   Handle h_obj(THREAD, JNIHandles::resolve(obj));


< prev index next >