RFR(s): 8223313: Use handshakes for CountStackFrames.

Daniel D. Daugherty daniel.daugherty at oracle.com
Mon May 20 19:13:06 UTC 2019


On 5/15/19 7:17 AM, Robbin Ehn wrote:
> Hi all please review.
>
> This change is part of parent issue:
> Utilize handshakes instead of is_thread_fully_suspended
> https://bugs.openjdk.java.net/browse/JDK-8223312
>
> Issue:
> https://bugs.openjdk.java.net/browse/JDK-8223313
> Change-set:
> http://cr.openjdk.java.net/~rehn/8223313/webrev/

src/hotspot/share/prims/jvm.cpp
     old L3019:     if (receiver->is_thread_fully_suspended(true /* wait 
for suspend completion */, &debug_bits)) {
     new L3016:     if (!jt->is_external_suspend()) {
         is_external_suspend() simply checks to see if an external
         suspension has been requested for the thread:

         src/hotspot/share/runtime/thread.hpp
           bool is_external_suspend() const {
             return (_suspend_flags & _external_suspend) != 0;
           }

         It says absolutely nothing about whether the target thread is
         actually suspended (and its stack is safe to walk).

         The "is_thread_fully_suspended(true /* wait for suspend 
completion */"
         call checks to see if the thread has completed the external
         suspension protocol. This is a necessary step for cooperative
         self-suspension.

         However, you've replaced cooperative self-suspension for this
         case with a handshake so the handshake from the target thread
         only happens when that thread's stack can be safely walked.
         This is nice!

         I agree with replacing the "is_thread_fully_suspended(true,"
         call here with is_external_suspend(). A properly coded use of
         Thread suspension followed by a JVM_CountStackFrames() call
         will not be able to detect any difference. If you have a case
         with a racing/rogue Thread resume, your new handshake based
         solution will return the proper (but soon to be stale) answer
         but it won't crash. With "is_thread_fully_suspended(true,"
         there is the possibility of a crash during the stack walk
         when there is a rogue/racing resume (which is one of the
         reasons for deprecation).

So a very long way of saying: Thumbs up!

Dan


A bit more commentary:

https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/lang/Thread.html#countStackFrames()
     countStackFrames() is not only deprecated, but it is deprecated for
     removal. That's the really good news here! However, deprecation does
     not mean that the API cannot be used. It means we recommend that you
     don't use it and if you have issues with the API, then we'll remind
     you that it is deprecated and you should not use it.

And a clarification:
     The reason for the "is_thread_fully_suspended(true," call is
     that a call to SuspendThread() will return to the caller once
     an external suspend is requested. The target thread does not
     have to have completed the self-suspension, but it does have
     to not execute any more bytecode or bytecode equivalents.

     So this sequence:

         SuspendThread(target);
         CountStackFrames(target);

     requires that CountStackFrames() wait for target's stack to
     be safe to walk. In the cooperative self-suspension world,
     that means waiting for the suspend request to be complete.
     Without "is_thread_fully_suspended(true," (in the current
     system), it is possible for CountStackFrames() to crash
     even without a rogue resume.

>
> The only test using this seems to be CountStackFramesAtExit.java which 
> passes fine.
>
> Thanks, Robbin



More information about the hotspot-runtime-dev mailing list