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/jdi/VMState.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/tools/jdi/VMState.java+245−0
@@ -0,0 +1,245 @@
1+/*
2+ * Copyright (c) 1999, 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.jdi;
27+
28+import com.sun.jdi.*;
29+
30+import java.lang.ref.WeakReference;
31+import java.util.*;
32+
33+class VMState {
34+ private final VirtualMachineImpl vm;
35+
36+ // Listeners
37+ private final List<WeakReference> listeners = new ArrayList<WeakReference>(); // synchronized (this)
38+ private boolean notifyingListeners = false; // synchronized (this)
39+
40+ /*
41+ * Certain information can be cached only when the entire VM is
42+ * suspended and there are no pending resumes. The fields below
43+ * are used to track whether there are pending resumes. (There
44+ * is an assumption that JDWP command ids are increasing over time.)
45+ */
46+ private int lastCompletedCommandId = 0; // synchronized (this)
47+ private int lastResumeCommandId = 0; // synchronized (this)
48+
49+ // This is cached only while the VM is suspended
50+ private static class Cache {
51+ List<ThreadGroupReference> groups = null; // cached Top Level ThreadGroups
52+ List<ThreadReference> threads = null; // cached Threads
53+ }
54+
55+ private Cache cache = null; // synchronized (this)
56+ private static final Cache markerCache = new Cache();
57+
58+ private void disableCache() {
59+ synchronized (this) {
60+ cache = null;
61+ }
62+ }
63+
64+ private void enableCache() {
65+ synchronized (this) {
66+ cache = markerCache;
67+ }
68+ }
69+
70+ private Cache getCache() {
71+ synchronized (this) {
72+ if (cache == markerCache) {
73+ cache = new Cache();
74+ }
75+ return cache;
76+ }
77+ }
78+
79+ VMState(VirtualMachineImpl vm) {
80+ this.vm = vm;
81+ }
82+
83+ /**
84+ * Is the VM currently suspended, for the purpose of caching?
85+ * Must be called synchronized on vm.state()
86+ */
87+ boolean isSuspended() {
88+ return cache != null;
89+ }
90+
91+ /*
92+ * A JDWP command has been completed (reply has been received).
93+ * Update data that tracks pending resume commands.
94+ */
95+ synchronized void notifyCommandComplete(int id) {
96+ lastCompletedCommandId = id;
97+ }
98+
99+ synchronized void freeze() {
100+ if (cache == null && (lastCompletedCommandId >= lastResumeCommandId)) {
101+ /*
102+ * No pending resumes to worry about. The VM is suspended
103+ * and additional state can be cached. Notify all
104+ * interested listeners.
105+ */
106+ processVMAction(new VMAction(vm, VMAction.VM_SUSPENDED));
107+ enableCache();
108+ }
109+ }
110+
111+ synchronized PacketStream thawCommand(CommandSender sender) {
112+ PacketStream stream = sender.send();
113+ lastResumeCommandId = stream.id();
114+ thaw();
115+ return stream;
116+ }
117+
118+ /**
119+ * All threads are resuming
120+ */
121+ void thaw() {
122+ thaw(null);
123+ }
124+
125+ /**
126+ * Tell listeners to invalidate suspend-sensitive caches.
127+ * If resumingThread != null, then only that thread is being
128+ * resumed.
129+ */
130+ synchronized void thaw(ThreadReference resumingThread) {
131+ if (cache != null) {
132+ if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
133+ vm.printTrace("Clearing VM suspended cache");
134+ }
135+ disableCache();
136+ }
137+ processVMAction(new VMAction(vm, resumingThread, VMAction.VM_NOT_SUSPENDED));
138+ }
139+
140+ private synchronized void processVMAction(VMAction action) {
141+ if (!notifyingListeners) {
142+ // Prevent recursion
143+ notifyingListeners = true;
144+
145+ Iterator iter = listeners.iterator();
146+ while (iter.hasNext()) {
147+ WeakReference ref = (WeakReference)iter.next();
148+ VMListener listener = (VMListener)ref.get();
149+ if (listener != null) {
150+ boolean keep = true;
151+ switch (action.id()) {
152+ case VMAction.VM_SUSPENDED:
153+ keep = listener.vmSuspended(action);
154+ break;
155+ case VMAction.VM_NOT_SUSPENDED:
156+ keep = listener.vmNotSuspended(action);
157+ break;
158+ }
159+ if (!keep) {
160+ iter.remove();
161+ }
162+ } else {
163+ // Listener is unreachable; clean up
164+ iter.remove();
165+ }
166+ }
167+
168+ notifyingListeners = false;
169+ }
170+ }
171+
172+ synchronized void addListener(VMListener listener) {
173+ listeners.add(new WeakReference<VMListener>(listener));
174+ }
175+
176+ synchronized boolean hasListener(VMListener listener) {
177+ return listeners.contains(listener);
178+ }
179+
180+ synchronized void removeListener(VMListener listener) {
181+ Iterator iter = listeners.iterator();
182+ while (iter.hasNext()) {
183+ WeakReference ref = (WeakReference)iter.next();
184+ if (listener.equals(ref.get())) {
185+ iter.remove();
186+ break;
187+ }
188+ }
189+ }
190+
191+ List<ThreadReference> allThreads() {
192+ List<ThreadReference> threads = null;
193+ try {
194+ Cache local = getCache();
195+
196+ if (local != null) {
197+ // may be stale when returned, but not provably so
198+ threads = local.threads;
199+ }
200+ if (threads == null) {
201+ threads = Arrays.asList((ThreadReference[])JDWP.VirtualMachine.AllThreads.
202+ process(vm).threads);
203+ if (local != null) {
204+ local.threads = threads;
205+ if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
206+ vm.printTrace("Caching all threads (count = " +
207+ threads.size() + ") while VM suspended");
208+ }
209+ }
210+ }
211+ } catch (JDWPException exc) {
212+ throw exc.toJDIException();
213+ }
214+ return threads;
215+ }
216+
217+
218+ List<ThreadGroupReference> topLevelThreadGroups() {
219+ List<ThreadGroupReference> groups = null;
220+ try {
221+ Cache local = getCache();
222+
223+ if (local != null) {
224+ groups = local.groups;
225+ }
226+ if (groups == null) {
227+ groups = Arrays.asList(
228+ (ThreadGroupReference[])JDWP.VirtualMachine.TopLevelThreadGroups.
229+ process(vm).groups);
230+ if (local != null) {
231+ local.groups = groups;
232+ if ((vm.traceFlags & vm.TRACE_OBJREFS) != 0) {
233+ vm.printTrace(
234+ "Caching top level thread groups (count = " +
235+ groups.size() + ") while VM suspended");
236+ }
237+ }
238+ }
239+ } catch (JDWPException exc) {
240+ throw exc.toJDIException();
241+ }
242+ return groups;
243+ }
244+
245+}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t