2362N/A * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 409N/A * Some objects can only be created while a thread is suspended and are valid 409N/A * only while the thread remains suspended. Examples are StackFrameImpl 409N/A * and MonitorInfoImpl. When the thread resumes, these objects have to be 409N/A * marked as invalid so that their methods can throw 409N/A * InvalidStackFrameException if they are called. To do this, such objects 409N/A * register themselves as listeners of the associated thread. When the 409N/A * thread is resumed, its listeners are notified and mark themselves 409N/A * Also, note that ThreadReferenceImpl itself caches some info that 409N/A * is valid only as long as the thread is suspended. When the thread 409N/A * is resumed, that cache must be purged. 409N/A * Lastly, note that ThreadReferenceImpl and its super, ObjectReferenceImpl 409N/A * cache some info that is only valid as long as the entire VM is suspended. 409N/A * If _any_ thread is resumed, this cache must be purged. To handle this, 409N/A * both ThreadReferenceImpl and ObjectReferenceImpl register themselves as 409N/A * VMListeners so that they get notified when all threads are suspended and 409N/A * when any thread is resumed. 409N/A // This is cached for the life of the thread 409N/A // This is cached only while this one thread is suspended. Each time 650N/A // the thread is resumed, we abandon the current cache object and 650N/A // create a new intialized one. 650N/A * The localCache instance var is set by resetLocalCache to an initialized 650N/A * object as shown above. This occurs when the ThreadReference 650N/A * object is created, and when the mirrored thread is resumed. 650N/A * The fields are then filled in by the relevant methods as they 650N/A * are called. A problem can occur if resetLocalCache is called 650N/A * (ie, a resume() is executed) at certain points in the execution 650N/A * of some of these methods - see 6751643. To avoid this, each 650N/A * method that wants to use this cache must make a local copy of 650N/A * this variable and use that. This means that each invocation of 650N/A * these methods will use a copy of the cache object that was in 650N/A * effect at the point that the copy was made; if a racy resume 650N/A * occurs, it won't affect the method's local copy. This means that 650N/A * the values returned by these calls may not match the state of 650N/A * the debuggee at the time the caller gets the values. EG, 650N/A * frameCount() is called and comes up with 5 frames. But before 650N/A * it returns this, a resume of the debuggee thread is executed in a 650N/A * different debugger thread. The thread is resumed and running at 650N/A * the time that the value 5 is returned. Or even worse, the thread 650N/A * could be suspended again and have a different number of frames, eg, 24, 650N/A * but this call will still return 5. 409N/A // This is cached only while all threads in the VM are suspended 409N/A // Yes, someone could change the name of a thread while it is suspended. 0N/A // Listeners - synchronized on vm.state() 0N/A * VMListener implementation 409N/A // all threads are being resumed 409N/A * Othewise, only one thread is being resumed: 409N/A * we have already done our processThreadAction to notify our 409N/A * listeners when we processed the resume. 409N/A * we don't want to notify our listeners 409N/A * because we are not being resumed. 650N/A * Note that we only cache the name string while the entire VM is suspended 650N/A * because the name can change via Thread.setName arbitrarily while this 0N/A * Sends a command to the back end which is defined to do an 0N/A * implicit vm-wide resume. 0N/A // Don't consider the thread suspended yet. On reply, notifySuspend() 0N/A * If it's a zombie, we can just update internal state without 0N/A * going to back end. 0N/A * If it's a zombie, we maintain the count in the front end. 0N/A // Verify that the given object is a Throwable instance 409N/A // thread is suspended, we can cache the status. 0N/A * TO DO: This fails to take filters into account. 0N/A return false;
// no frames on stack => not at breakpoint 0N/A // Per the javadoc, not suspended => return false 409N/A * Thread group can't change, so it's cached once and for all. 0N/A * Is the requested subrange within what has been retrieved? 409N/A * local is known to be non-null. Should only be called from 0N/A "length must be greater than or equal to zero");
0N/A * Private version of frames() allows "-1" to specify all 409N/A // Lock must be held while creating stack frames so if that two threads 409N/A // do this at the same time, one won't clobber the subset created by the other. 409N/A // Add to the frame list 409N/A " temporarily caching owned monitors"+
409N/A " temporarily caching contended monitor"+
409N/A " temporarily caching owned monitors"+
0N/A // Note that interface-wise this functionality belongs 0N/A // here in ThreadReference, but implementation-wise it 0N/A // belongs in StackFrame, so we just forward it. 0N/A "target does not support popping frames");
0N/A "target does not support the forcing of a method to return early");
0N/A "Thread not suspended");
0N/A "Thread has not started or has finished");
0N/A "No more frames on the stack");
0N/A * Propagate the the thread state change information 0N/A * to registered listeners. 0N/A * Must be entered while synchronized on vm.state() 0N/A // Listener is unreachable; clean up 409N/A // Discard our local cache