Mercurial > hg > truffle
comparison graal/com.oracle.truffle.tools.debug.engine/src/com/oracle/truffle/tools/debug/engine/Breakpoint.java @ 21568:3b8bbf51d320
Truffle/Debugging: add the Truffle DebugEngine and supporting code, as well as add a crude command-line debugging tool used mainly to test the DebugEngine. Migrate the small tols out of project com.oracle.truffle.api into the new project com.oracle.truffle.tools.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Tue, 26 May 2015 16:38:13 -0700 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
21470:1bbef57f9a38 | 21568:3b8bbf51d320 |
---|---|
1 /* | |
2 * Copyright (c) 2015, 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 package com.oracle.truffle.tools.debug.engine; | |
26 | |
27 import com.oracle.truffle.api.instrument.*; | |
28 import com.oracle.truffle.api.source.*; | |
29 | |
30 public abstract class Breakpoint { | |
31 | |
32 /** | |
33 * A general model of the states occupied by a breakpoint during its lifetime. | |
34 */ | |
35 public enum BreakpointState { | |
36 | |
37 /** | |
38 * Not attached, enabled. | |
39 * <p> | |
40 * Created for a source location but not yet attached: perhaps just created and the source | |
41 * hasn't been loaded yet; perhaps source has been loaded, but the line location isn't | |
42 * probed so a breakpoint cannot be attached. Can be either enabled or disabled. | |
43 */ | |
44 ENABLED_UNRESOLVED("Enabled/Unresolved"), | |
45 | |
46 /** | |
47 * Not attached, disabled. | |
48 * <p> | |
49 * Created for a source location but not yet attached: perhaps just created and the source | |
50 * hasn't been loaded yet; perhaps source has been loaded, but the line location isn't | |
51 * probed so a breakpoint cannot be attached. | |
52 */ | |
53 DISABLED_UNRESOLVED("Disabled/Unresolved"), | |
54 | |
55 /** | |
56 * Attached, instrument enabled. | |
57 * <p> | |
58 * Is currently implemented by some {@link Instrument}, which is attached to a {@link Probe} | |
59 * at a specific node in the AST, and the breakpoint is enabled. | |
60 */ | |
61 ENABLED("Enabled"), | |
62 | |
63 /** | |
64 * Attached, instrument disabled. | |
65 * <p> | |
66 * Is currently implemented by some {@link Instrument}, which is attached to a {@link Probe} | |
67 * at a specific node in the AST, and the breakpoint is disabled. | |
68 */ | |
69 DISABLED("Disabled"), | |
70 | |
71 /** | |
72 * Not attached, instrument is permanently disabled. | |
73 */ | |
74 DISPOSED("Disposed"); | |
75 | |
76 private final String name; | |
77 | |
78 BreakpointState(String name) { | |
79 this.name = name; | |
80 } | |
81 | |
82 public String getName() { | |
83 return name; | |
84 } | |
85 | |
86 @Override | |
87 public String toString() { | |
88 return name; | |
89 } | |
90 | |
91 } | |
92 | |
93 private static int nextBreakpointId = 0; | |
94 | |
95 private final int id; | |
96 private final int groupId; | |
97 private final boolean isOneShot; | |
98 | |
99 private int ignoreCount; | |
100 | |
101 private int hitCount = 0; | |
102 | |
103 private BreakpointState state; | |
104 | |
105 Breakpoint(BreakpointState state, int groupId, int ignoreCount, boolean isOneShot) { | |
106 this.state = state; | |
107 this.id = nextBreakpointId++; | |
108 this.groupId = groupId; | |
109 this.isOneShot = isOneShot; | |
110 this.ignoreCount = ignoreCount; | |
111 } | |
112 | |
113 /** | |
114 * Unique ID. | |
115 */ | |
116 public final int getId() { | |
117 return id; | |
118 } | |
119 | |
120 /** | |
121 * Group ID, set when created. | |
122 */ | |
123 public final int getGroupId() { | |
124 return groupId; | |
125 } | |
126 | |
127 /** | |
128 * Enables or disables this breakpoint's AST instrumentation. The breakpoint is enabled by | |
129 * default. | |
130 * | |
131 * @param enabled <code>true</code> to activate the instrumentation, <code>false</code> to | |
132 * deactivate the instrumentation so that it has no effect. | |
133 */ | |
134 public abstract void setEnabled(boolean enabled); | |
135 | |
136 /** | |
137 * Is this breakpoint active? | |
138 */ | |
139 public abstract boolean isEnabled(); | |
140 | |
141 /** | |
142 * Sets the condition on this breakpoint, {@code null} to make it unconditional. | |
143 * | |
144 * @param expr if non{@code -null}, a boolean expression, expressed in the guest language, to be | |
145 * evaluated in the lexical context at the breakpoint location. | |
146 * @throws DebugException if condition is invalid | |
147 * @throws UnsupportedOperationException if the breakpoint does not support conditions | |
148 */ | |
149 public abstract void setCondition(String expr) throws DebugException; | |
150 | |
151 /** | |
152 * Gets the string, expressed in the Guest Language, that defines the current condition on this | |
153 * breakpoint; {@code null} if this breakpoint is currently unconditional. | |
154 */ | |
155 public String getCondition() { | |
156 return null; | |
157 } | |
158 | |
159 /** | |
160 * Does this breakpoint remove itself after first activation? | |
161 */ | |
162 public final boolean isOneShot() { | |
163 return isOneShot; | |
164 } | |
165 | |
166 /** | |
167 * Gets the number of hits left to be ignored before halting. | |
168 */ | |
169 public final int getIgnoreCount() { | |
170 return ignoreCount; | |
171 } | |
172 | |
173 /** | |
174 * Change the threshold for when this breakpoint should start causing a break. When both an | |
175 * ignore count and a {@linkplain #setCondition(String) condition} are specified, the condition | |
176 * is evaluated first: if {@code false} it is not considered to be a hit. In other words, the | |
177 * ignore count is for successful conditions only. | |
178 */ | |
179 public final void setIgnoreCount(int ignoreCount) { | |
180 this.ignoreCount = ignoreCount; | |
181 } | |
182 | |
183 /** | |
184 * Number of times this breakpoint has reached, with one exception; if the breakpoint has a | |
185 * condition that evaluates to {@code false}, it does not count as a hit. | |
186 */ | |
187 public final int getHitCount() { | |
188 return hitCount; | |
189 } | |
190 | |
191 /** | |
192 * Disables this breakpoint and removes any associated instrumentation; it becomes permanently | |
193 * inert. | |
194 */ | |
195 public abstract void dispose(); | |
196 | |
197 /** | |
198 * Gets a human-sensible description of this breakpoint's location in a {@link Source}. | |
199 */ | |
200 public abstract String getLocationDescription(); | |
201 | |
202 public final BreakpointState getState() { | |
203 return state; | |
204 } | |
205 | |
206 final void assertState(BreakpointState s) { | |
207 assert state == s; | |
208 } | |
209 | |
210 final void setState(BreakpointState state) { | |
211 this.state = state; | |
212 } | |
213 | |
214 /** | |
215 * Assumes that all conditions for causing the break have been satisfied, so increments the | |
216 * <em>hit count</em>. Then checks if the <em>ignore count</em> has been exceeded, and if so | |
217 * returns {@code true}. If not, it still counts as a <em>hit</em> but should be ignored. | |
218 * | |
219 * @return whether to proceed | |
220 */ | |
221 final boolean incrHitCountCheckIgnore() { | |
222 return ++hitCount > ignoreCount; | |
223 } | |
224 | |
225 @Override | |
226 public String toString() { | |
227 final StringBuilder sb = new StringBuilder(getClass().getSimpleName()); | |
228 sb.append(" state="); | |
229 sb.append(getState() == null ? "<none>" : getState().getName()); | |
230 if (isOneShot()) { | |
231 sb.append(", " + "One-Shot"); | |
232 } | |
233 if (getCondition() != null) { | |
234 sb.append(", condition=\"" + getCondition() + "\""); | |
235 } | |
236 return sb.toString(); | |
237 } | |
238 } |