History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/tools/example/debug/tty/ThreadInfo.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/example/debug/tty/ThreadInfo.java+287−0
@@ -0,0 +1,287 @@
1+/*
2+ * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
3+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+ *
5+ * This code is free software; you can redistribute it and/or modify it
6+ * under the terms of the GNU General Public License version 2 only, as
7+ * published by the Free Software Foundation. Oracle designates this
8+ * particular file as subject to the "Classpath" exception as provided
9+ * by Oracle in the LICENSE file that accompanied this code.
10+ *
11+ * This code is distributed in the hope that it will be useful, but WITHOUT
12+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+ * version 2 for more details (a copy is included in the LICENSE file that
15+ * accompanied this code).
16+ *
17+ * You should have received a copy of the GNU General Public License version
18+ * 2 along with this work; if not, write to the Free Software Foundation,
19+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+ *
21+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+ * or visit www.oracle.com if you need additional information or have any
23+ * questions.
24+ */
25+
26+package com.sun.tools.example.debug.tty;
27+
28+import com.sun.jdi.ThreadReference;
29+import com.sun.jdi.ThreadGroupReference;
30+import com.sun.jdi.IncompatibleThreadStateException;
31+import com.sun.jdi.StackFrame;
32+import java.util.List;
33+import java.util.ArrayList;
34+import java.util.Collections;
35+
36+class ThreadInfo {
37+ // This is a list of all known ThreadInfo objects. It survives
38+ // ThreadInfo.invalidateAll, unlike the other static fields below.
39+ private static List<ThreadInfo> threads = Collections.synchronizedList(new ArrayList<ThreadInfo>());
40+ private static boolean gotInitialThreads = false;
41+
42+ private static ThreadInfo current = null;
43+ private static ThreadGroupReference group = null;
44+
45+ private final ThreadReference thread;
46+ private int currentFrameIndex = 0;
47+
48+ private ThreadInfo(ThreadReference thread) {
49+ this.thread = thread;
50+ if (thread == null) {
51+ MessageOutput.fatalError("Internal error: null ThreadInfo created");
52+ }
53+ }
54+
55+ private static void initThreads() {
56+ if (!gotInitialThreads) {
57+ for (ThreadReference thread : Env.vm().allThreads()) {
58+ threads.add(new ThreadInfo(thread));
59+ }
60+ gotInitialThreads = true;
61+ }
62+ }
63+
64+ static void addThread(ThreadReference thread) {
65+ synchronized (threads) {
66+ initThreads();
67+ ThreadInfo ti = new ThreadInfo(thread);
68+ // Guard against duplicates. Duplicates can happen during
69+ // initialization when a particular thread might be added both
70+ // by a thread start event and by the initial call to threads()
71+ if (getThreadInfo(thread) == null) {
72+ threads.add(ti);
73+ }
74+ }
75+ }
76+
77+ static void removeThread(ThreadReference thread) {
78+ if (thread.equals(ThreadInfo.current)) {
79+ // Current thread has died.
80+
81+ // Be careful getting the thread name. If its death happens
82+ // as part of VM termination, it may be too late to get the
83+ // information, and an exception will be thrown.
84+ String currentThreadName;
85+ try {
86+ currentThreadName = "\"" + thread.name() + "\"";
87+ } catch (Exception e) {
88+ currentThreadName = "";
89+ }
90+
91+ setCurrentThread(null);
92+
93+ MessageOutput.println();
94+ MessageOutput.println("Current thread died. Execution continuing...",
95+ currentThreadName);
96+ }
97+ threads.remove(getThreadInfo(thread));
98+ }
99+
100+ static List<ThreadInfo> threads() {
101+ synchronized(threads) {
102+ initThreads();
103+ // Make a copy to allow iteration without synchronization
104+ return new ArrayList<ThreadInfo>(threads);
105+ }
106+ }
107+
108+ static void invalidateAll() {
109+ current = null;
110+ group = null;
111+ synchronized (threads) {
112+ for (ThreadInfo ti : threads()) {
113+ ti.invalidate();
114+ }
115+ }
116+ }
117+
118+ static void setThreadGroup(ThreadGroupReference tg) {
119+ group = tg;
120+ }
121+
122+ static void setCurrentThread(ThreadReference tr) {
123+ if (tr == null) {
124+ setCurrentThreadInfo(null);
125+ } else {
126+ ThreadInfo tinfo = getThreadInfo(tr);
127+ setCurrentThreadInfo(tinfo);
128+ }
129+ }
130+
131+ static void setCurrentThreadInfo(ThreadInfo tinfo) {
132+ current = tinfo;
133+ if (current != null) {
134+ current.invalidate();
135+ }
136+ }
137+
138+ /**
139+ * Get the current ThreadInfo object.
140+ *
141+ * @return the ThreadInfo for the current thread.
142+ */
143+ static ThreadInfo getCurrentThreadInfo() {
144+ return current;
145+ }
146+
147+ /**
148+ * Get the thread from this ThreadInfo object.
149+ *
150+ * @return the Thread wrapped by this ThreadInfo.
151+ */
152+ ThreadReference getThread() {
153+ return thread;
154+ }
155+
156+ static ThreadGroupReference group() {
157+ if (group == null) {
158+ // Current thread group defaults to the first top level
159+ // thread group.
160+ setThreadGroup(Env.vm().topLevelThreadGroups().get(0));
161+ }
162+ return group;
163+ }
164+
165+ static ThreadInfo getThreadInfo(long id) {
166+ ThreadInfo retInfo = null;
167+
168+ synchronized (threads) {
169+ for (ThreadInfo ti : threads()) {
170+ if (ti.thread.uniqueID() == id) {
171+ retInfo = ti;
172+ break;
173+ }
174+ }
175+ }
176+ return retInfo;
177+ }
178+
179+ static ThreadInfo getThreadInfo(ThreadReference tr) {
180+ return getThreadInfo(tr.uniqueID());
181+ }
182+
183+ static ThreadInfo getThreadInfo(String idToken) {
184+ ThreadInfo tinfo = null;
185+ if (idToken.startsWith("t@")) {
186+ idToken = idToken.substring(2);
187+ }
188+ try {
189+ long threadId = Long.decode(idToken).longValue();
190+ tinfo = getThreadInfo(threadId);
191+ } catch (NumberFormatException e) {
192+ tinfo = null;
193+ }
194+ return tinfo;
195+ }
196+
197+ /**
198+ * Get the thread stack frames.
199+ *
200+ * @return a <code>List</code> of the stack frames.
201+ */
202+ List<StackFrame> getStack() throws IncompatibleThreadStateException {
203+ return thread.frames();
204+ }
205+
206+ /**
207+ * Get the current stackframe.
208+ *
209+ * @return the current stackframe.
210+ */
211+ StackFrame getCurrentFrame() throws IncompatibleThreadStateException {
212+ if (thread.frameCount() == 0) {
213+ return null;
214+ }
215+ return thread.frame(currentFrameIndex);
216+ }
217+
218+ /**
219+ * Invalidate the current stackframe index.
220+ */
221+ void invalidate() {
222+ currentFrameIndex = 0;
223+ }
224+
225+ /* Throw IncompatibleThreadStateException if not suspended */
226+ private void assureSuspended() throws IncompatibleThreadStateException {
227+ if (!thread.isSuspended()) {
228+ throw new IncompatibleThreadStateException();
229+ }
230+ }
231+
232+ /**
233+ * Get the current stackframe index.
234+ *
235+ * @return the number of the current stackframe. Frame zero is the
236+ * closest to the current program counter
237+ */
238+ int getCurrentFrameIndex() {
239+ return currentFrameIndex;
240+ }
241+
242+ /**
243+ * Set the current stackframe to a specific frame.
244+ *
245+ * @param nFrame the number of the desired stackframe. Frame zero is the
246+ * closest to the current program counter
247+ * @exception IllegalAccessError when the thread isn't
248+ * suspended or waiting at a breakpoint
249+ * @exception ArrayIndexOutOfBoundsException when the
250+ * requested frame is beyond the stack boundary
251+ */
252+ void setCurrentFrameIndex(int nFrame) throws IncompatibleThreadStateException {
253+ assureSuspended();
254+ if ((nFrame < 0) || (nFrame >= thread.frameCount())) {
255+ throw new ArrayIndexOutOfBoundsException();
256+ }
257+ currentFrameIndex = nFrame;
258+ }
259+
260+ /**
261+ * Change the current stackframe to be one or more frames higher
262+ * (as in, away from the current program counter).
263+ *
264+ * @param nFrames the number of stackframes
265+ * @exception IllegalAccessError when the thread isn't
266+ * suspended or waiting at a breakpoint
267+ * @exception ArrayIndexOutOfBoundsException when the
268+ * requested frame is beyond the stack boundary
269+ */
270+ void up(int nFrames) throws IncompatibleThreadStateException {
271+ setCurrentFrameIndex(currentFrameIndex + nFrames);
272+ }
273+
274+ /**
275+ * Change the current stackframe to be one or more frames lower
276+ * (as in, toward the current program counter). *
277+ * @param nFrames the number of stackframes
278+ * @exception IllegalAccessError when the thread isn't
279+ * suspended or waiting at a breakpoint
280+ * @exception ArrayIndexOutOfBoundsException when the
281+ * requested frame is beyond the stack boundary
282+ */
283+ void down(int nFrames) throws IncompatibleThreadStateException {
284+ setCurrentFrameIndex(currentFrameIndex - nFrames);
285+ }
286+
287+}