< prev index next >

src/jdk.jdi/share/classes/com/sun/tools/jdi/ThreadReferenceImpl.java

Print this page

 59     /*
 60      * Some objects can only be created while a thread is suspended and are valid
 61      * only while the thread remains suspended.  Examples are StackFrameImpl
 62      * and MonitorInfoImpl.  When the thread resumes, these objects have to be
 63      * marked as invalid so that their methods can throw
 64      * InvalidStackFrameException if they are called.  To do this, such objects
 65      * register themselves as listeners of the associated thread.  When the
 66      * thread is resumed, its listeners are notified and mark themselves
 67      * invalid.
 68      * Also, note that ThreadReferenceImpl itself caches some info that
 69      * is valid only as long as the thread is suspended.  When the thread
 70      * is resumed, that cache must be purged.
 71      * Lastly, note that ThreadReferenceImpl and its super, ObjectReferenceImpl
 72      * cache some info that is only valid as long as the entire VM is suspended.
 73      * If _any_ thread is resumed, this cache must be purged.  To handle this,
 74      * both ThreadReferenceImpl and ObjectReferenceImpl register themselves as
 75      * VMListeners so that they get notified when all threads are suspended and
 76      * when any thread is resumed.
 77      */
 78 
 79     // This is cached for the life of the thread
 80     private ThreadGroupReference threadGroup;
 81 




 82     // This is cached only while this one thread is suspended.  Each time
 83     // the thread is resumed, we abandon the current cache object and
 84     // create a new initialized one.
 85     private static class LocalCache {
 86         JDWP.ThreadReference.Status status = null;
 87         List<StackFrame> frames = null;
 88         int framesStart = -1;
 89         int framesLength = 0;
 90         int frameCount = -1;
 91         List<ObjectReference> ownedMonitors = null;
 92         List<MonitorInfo> ownedMonitorsInfo = null;
 93         ObjectReference contendedMonitor = null;
 94         boolean triedCurrentContended = false;
 95     }
 96 
 97     /*
 98      * The localCache instance var is set by resetLocalCache to an initialized
 99      * object as shown above.  This occurs when the ThreadReference
100      * object is created, and when the mirrored thread is resumed.
101      * The fields are then filled in by the relevant methods as they

580             JDWP.ThreadReference.ForceEarlyReturn.process(vm, this, convertedValue);
581         } catch (JDWPException exc) {
582             switch (exc.errorCode()) {
583             case JDWP.Error.OPAQUE_FRAME:
584                 throw new NativeMethodException();
585             case JDWP.Error.THREAD_NOT_SUSPENDED:
586                 throw new IncompatibleThreadStateException(
587                          "Thread not suspended");
588             case JDWP.Error.THREAD_NOT_ALIVE:
589                 throw new IncompatibleThreadStateException(
590                                      "Thread has not started or has finished");
591             case JDWP.Error.NO_MORE_FRAMES:
592                 throw new InvalidStackFrameException(
593                          "No more frames on the stack");
594             default:
595                 throw exc.toJDIException();
596             }
597         }
598     }
599 

















600     public String toString() {
601         return "instance of " + referenceType().name() +
602                "(name='" + name() + "', " + "id=" + uniqueID() + ")";
603     }
604 
605     byte typeValueKey() {
606         return JDWP.Tag.THREAD;
607     }
608 
609     void addListener(ThreadListener listener) {
610         synchronized (vm.state()) {
611             listeners.add(new WeakReference<>(listener));
612         }
613     }
614 
615     void removeListener(ThreadListener listener) {
616         synchronized (vm.state()) {
617             Iterator<WeakReference<ThreadListener>> iter = listeners.iterator();
618             while (iter.hasNext()) {
619                 WeakReference<ThreadListener> ref = iter.next();

 59     /*
 60      * Some objects can only be created while a thread is suspended and are valid
 61      * only while the thread remains suspended.  Examples are StackFrameImpl
 62      * and MonitorInfoImpl.  When the thread resumes, these objects have to be
 63      * marked as invalid so that their methods can throw
 64      * InvalidStackFrameException if they are called.  To do this, such objects
 65      * register themselves as listeners of the associated thread.  When the
 66      * thread is resumed, its listeners are notified and mark themselves
 67      * invalid.
 68      * Also, note that ThreadReferenceImpl itself caches some info that
 69      * is valid only as long as the thread is suspended.  When the thread
 70      * is resumed, that cache must be purged.
 71      * Lastly, note that ThreadReferenceImpl and its super, ObjectReferenceImpl
 72      * cache some info that is only valid as long as the entire VM is suspended.
 73      * If _any_ thread is resumed, this cache must be purged.  To handle this,
 74      * both ThreadReferenceImpl and ObjectReferenceImpl register themselves as
 75      * VMListeners so that they get notified when all threads are suspended and
 76      * when any thread is resumed.
 77      */
 78 
 79     // The ThreadGroup is cached for the life of the thread
 80     private ThreadGroupReference threadGroup;
 81 
 82     // Whether a thread is a virtual thread or not is cached
 83     private volatile boolean isVirtual;
 84     private volatile boolean isVirtualCached;
 85 
 86     // This is cached only while this one thread is suspended.  Each time
 87     // the thread is resumed, we abandon the current cache object and
 88     // create a new initialized one.
 89     private static class LocalCache {
 90         JDWP.ThreadReference.Status status = null;
 91         List<StackFrame> frames = null;
 92         int framesStart = -1;
 93         int framesLength = 0;
 94         int frameCount = -1;
 95         List<ObjectReference> ownedMonitors = null;
 96         List<MonitorInfo> ownedMonitorsInfo = null;
 97         ObjectReference contendedMonitor = null;
 98         boolean triedCurrentContended = false;
 99     }
100 
101     /*
102      * The localCache instance var is set by resetLocalCache to an initialized
103      * object as shown above.  This occurs when the ThreadReference
104      * object is created, and when the mirrored thread is resumed.
105      * The fields are then filled in by the relevant methods as they

584             JDWP.ThreadReference.ForceEarlyReturn.process(vm, this, convertedValue);
585         } catch (JDWPException exc) {
586             switch (exc.errorCode()) {
587             case JDWP.Error.OPAQUE_FRAME:
588                 throw new NativeMethodException();
589             case JDWP.Error.THREAD_NOT_SUSPENDED:
590                 throw new IncompatibleThreadStateException(
591                          "Thread not suspended");
592             case JDWP.Error.THREAD_NOT_ALIVE:
593                 throw new IncompatibleThreadStateException(
594                                      "Thread has not started or has finished");
595             case JDWP.Error.NO_MORE_FRAMES:
596                 throw new InvalidStackFrameException(
597                          "No more frames on the stack");
598             default:
599                 throw exc.toJDIException();
600             }
601         }
602     }
603 
604     @Override
605     public boolean isVirtual() {
606         if (isVirtualCached) {
607             return isVirtual;
608         } else {
609             boolean result;
610             try {
611                 result = JDWP.ThreadReference.IsVirtual.process(vm, this).isVirtual;
612             } catch (JDWPException exc) {
613                 throw exc.toJDIException();
614             }
615             isVirtual = result;
616             isVirtualCached = true;
617             return result;
618         }
619     }
620 
621     public String toString() {
622         return "instance of " + referenceType().name() +
623                "(name='" + name() + "', " + "id=" + uniqueID() + ")";
624     }
625 
626     byte typeValueKey() {
627         return JDWP.Tag.THREAD;
628     }
629 
630     void addListener(ThreadListener listener) {
631         synchronized (vm.state()) {
632             listeners.add(new WeakReference<>(listener));
633         }
634     }
635 
636     void removeListener(ThreadListener listener) {
637         synchronized (vm.state()) {
638             Iterator<WeakReference<ThreadListener>> iter = listeners.iterator();
639             while (iter.hasNext()) {
640                 WeakReference<ThreadListener> ref = iter.next();
< prev index next >