Mercurial > hg > truffle
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/ProbeNode.java @ 19869:1d6a7ea5de59
Truffle/Instrumentation: remove support for "probe-lite", an optimization for a particular use case that no longer seems worth the complexity.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Mon, 16 Mar 2015 15:59:57 -0700 |
parents | 907128d02b31 |
children | d7c48ee7ed4b |
comparison
equal
deleted
inserted
replaced
19858:1cbbdc29ab45 | 19869:1d6a7ea5de59 |
---|---|
31 import com.oracle.truffle.api.instrument.InstrumentationNode.TruffleEvents; | 31 import com.oracle.truffle.api.instrument.InstrumentationNode.TruffleEvents; |
32 import com.oracle.truffle.api.nodes.*; | 32 import com.oracle.truffle.api.nodes.*; |
33 import com.oracle.truffle.api.source.*; | 33 import com.oracle.truffle.api.source.*; |
34 | 34 |
35 /** | 35 /** |
36 * Implementation interfaces and classes for attaching {@link Probe}s to {@link WrapperNode}s. | 36 * Implementation class & interface for enabling the attachment of {@linkplain Probe Probes} to |
37 * Truffle ASTs. | |
38 * <p> | |
39 * A {@link ProbeNode} is the head of a chain of nodes acting on behalf of {@linkplain Instrument | |
40 * instruments}. It is attached to an AST as a child of a guest-language-specific | |
41 * {@link WrapperNode} node. | |
42 * <p> | |
43 * When Truffle clones an AST, the chain, including all attached {@linkplain Instrument instruments} | |
44 * will be cloned along with the {@link WrapperNode} to which it is attached. An instance of | |
45 * {@link Probe} represents abstractly the instrumentation at a particular location in a GL AST, | |
46 * tracks the clones of the chain, and keeps the instrumentation attached to the clones consistent. | |
37 */ | 47 */ |
38 public abstract class ProbeNode extends Node implements TruffleEvents, InstrumentationNode { | 48 @NodeInfo(cost = NodeCost.NONE) |
49 public final class ProbeNode extends Node implements TruffleEvents, InstrumentationNode { | |
39 | 50 |
40 /** | 51 /** |
41 * A node that can be inserted into a Truffle AST, and which enables {@linkplain Instrument | 52 * A node that can be inserted into a Truffle AST, and which enables {@linkplain Instrument |
42 * instrumentation} at a particular Guest Language (GL) node. Implementations must extend | 53 * instrumentation} at a particular Guest Language (GL) node. Implementations must extend |
43 * {@link Node} and should override {@link Node#isInstrumentable()} to return {@code false}. | 54 * {@link Node} and should override {@link Node#isInstrumentable()} to return {@code false}. |
89 * the Instrumentation Framework. | 100 * the Instrumentation Framework. |
90 */ | 101 */ |
91 Node getChild(); | 102 Node getChild(); |
92 | 103 |
93 /** | 104 /** |
94 * Gets the {@link Probe} responsible for installing this wrapper; none if the wrapper | 105 * Gets the {@link Probe} responsible for installing this wrapper. |
95 * installed via {@linkplain Node#probeLite(ASTInstrumentListener) "lite-Probing"}. | |
96 */ | 106 */ |
97 Probe getProbe(); | 107 Probe getProbe(); |
98 | 108 |
99 /** | 109 /** |
100 * Implementation support for completing a newly created wrapper node. | 110 * Implementation support for completing a newly created wrapper node. |
101 */ | 111 */ |
102 void insertProbe(ProbeNode probeNode); | 112 void insertProbe(ProbeNode probeNode); |
103 | |
104 } | 113 } |
105 | 114 |
106 /** | 115 /** |
107 * Create a new {@link Probe} associated with, and attached to, a Guest Language specific | 116 * Create a new {@link Probe} associated with, and attached to, a Guest Language specific |
108 * instance of {@link WrapperNode}. | 117 * instance of {@link WrapperNode}. |
109 */ | 118 */ |
110 public static Probe insertProbe(WrapperNode wrapper) { | 119 public static Probe insertProbe(WrapperNode wrapper) { |
111 final SourceSection sourceSection = wrapper.getChild().getSourceSection(); | 120 final SourceSection sourceSection = wrapper.getChild().getSourceSection(); |
112 final ProbeFullNode probeFullNode = new ProbeFullNode(); // private constructor | 121 final ProbeNode probeNode = new ProbeNode(); // private constructor |
113 final Probe probe = new Probe(probeFullNode, sourceSection); // package private access | 122 probeNode.probe = new Probe(probeNode, sourceSection); // package private access |
114 probeFullNode.setProbe(probe); | 123 wrapper.insertProbe(probeNode); |
115 wrapper.insertProbe(probeFullNode); | 124 return probeNode.probe; |
116 return probe; | 125 } |
117 } | 126 |
118 | 127 // Never changed once set. |
119 /** | 128 @CompilationFinal Probe probe = null; |
120 * Creates a new {@link ProbeLiteNode} associated with, and attached to, a Guest Language | 129 /** |
121 * specific instance of {@link WrapperNode}. | 130 * First {@link AbstractInstrumentNode} node in chain; {@code null} of no instruments in chain. |
122 */ | 131 */ |
123 public static void insertProbeLite(WrapperNode wrapper, ASTInstrumentListener instrumentListener) { | 132 @Child protected AbstractInstrumentNode firstInstrument; |
124 final ProbeLiteNode probeLiteNode = new ProbeLiteNode(instrumentListener); | |
125 wrapper.insertProbe(probeLiteNode); | |
126 } | |
127 | 133 |
128 @Override | 134 @Override |
129 public boolean isInstrumentable() { | 135 public boolean isInstrumentable() { |
130 return false; | 136 return false; |
131 } | 137 } |
132 | 138 |
139 @Override | |
140 public Node copy() { | |
141 Node node = super.copy(); | |
142 probe.registerProbeNodeClone((ProbeNode) node); | |
143 return node; | |
144 } | |
145 | |
133 /** | 146 /** |
134 * @return the {@link Probe} permanently associated with this {@link ProbeNode}. | 147 * @return the {@link Probe} permanently associated with this {@link ProbeNode}. |
135 * | 148 */ |
136 * @throws IllegalStateException if this location was "lite-Probed" | 149 public Probe getProbe() { |
137 */ | 150 return probe; |
138 public abstract Probe getProbe() throws IllegalStateException; | 151 } |
152 | |
153 public void enter(Node node, VirtualFrame vFrame) { | |
154 this.probe.checkProbeUnchanged(); | |
155 final SyntaxTagTrap trap = probe.getTrap(); | |
156 if (trap != null) { | |
157 trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); | |
158 } | |
159 if (firstInstrument != null) { | |
160 firstInstrument.enter(node, vFrame); | |
161 } | |
162 } | |
163 | |
164 public void returnVoid(Node node, VirtualFrame vFrame) { | |
165 this.probe.checkProbeUnchanged(); | |
166 if (firstInstrument != null) { | |
167 firstInstrument.returnVoid(node, vFrame); | |
168 } | |
169 } | |
170 | |
171 public void returnValue(Node node, VirtualFrame vFrame, Object result) { | |
172 this.probe.checkProbeUnchanged(); | |
173 if (firstInstrument != null) { | |
174 firstInstrument.returnValue(node, vFrame, result); | |
175 } | |
176 } | |
177 | |
178 public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { | |
179 this.probe.checkProbeUnchanged(); | |
180 if (firstInstrument != null) { | |
181 firstInstrument.returnExceptional(node, vFrame, exception); | |
182 } | |
183 } | |
184 | |
185 public String instrumentationInfo() { | |
186 return "Standard probe"; | |
187 } | |
139 | 188 |
140 /** | 189 /** |
141 * Adds an {@link AbstractInstrumentNode} to this chain. | 190 * Adds an {@link AbstractInstrumentNode} to this chain. |
142 * | 191 */ |
143 * @throws IllegalStateException if at a "lite-Probed" location. | 192 @TruffleBoundary |
144 */ | 193 void addInstrument(Instrument instrument) { |
145 abstract void addInstrument(Instrument instrument); | 194 assert instrument.getProbe() == probe; |
195 // The existing chain of nodes may be empty | |
196 // Attach the modified chain. | |
197 firstInstrument = insert(instrument.addToChain(firstInstrument)); | |
198 } | |
146 | 199 |
147 /** | 200 /** |
148 * Removes an instrument from this chain of instruments. | 201 * Removes an instrument from this chain of instruments. |
149 * | 202 * |
150 * @throws IllegalStateException if at a "lite-Probed" location. | |
151 * @throws RuntimeException if no matching instrument is found, | 203 * @throws RuntimeException if no matching instrument is found, |
152 */ | 204 */ |
153 abstract void removeInstrument(Instrument instrument); | 205 @TruffleBoundary |
154 | 206 void removeInstrument(Instrument instrument) { |
155 /** | 207 assert instrument.getProbe() == probe; |
156 * Implementation class & interfaces for enabling the attachment of {@linkplain Probe Probes} to | 208 final AbstractInstrumentNode modifiedChain = instrument.removeFromChain(firstInstrument); |
157 * Truffle ASTs. | 209 if (modifiedChain == null) { |
158 * <p> | 210 firstInstrument = null; |
159 * Head of a chain of nodes acting on behalf of {@linkplain Instrument instruments}, attached to | 211 } else { |
160 * a Guest Language (GL) AST as a child of a GL-specific {@link WrapperNode} node. | 212 firstInstrument = insert(modifiedChain); |
161 * <p> | 213 } |
162 * When Truffle clones an AST, the chain, including all attached {@linkplain Instrument | 214 } |
163 * instruments} will be cloned along with the {@link WrapperNode} to which it is attached. An | 215 |
164 * instance of {@link Probe} represents abstractly the instrumentation at a particular location | |
165 * in a GL AST, tracks the clones of the chain, and keeps the instrumentation attached to the | |
166 * clones consistent. | |
167 */ | |
168 @NodeInfo(cost = NodeCost.NONE) | |
169 private static final class ProbeFullNode extends ProbeNode { | |
170 | |
171 /** | |
172 * First {@link AbstractInstrumentNode} node in chain; {@code null} of no instruments in | |
173 * chain. | |
174 */ | |
175 @Child protected AbstractInstrumentNode firstInstrument; | |
176 | |
177 // Never changed once set. | |
178 @CompilationFinal private Probe probe = null; | |
179 | |
180 private ProbeFullNode() { | |
181 this.firstInstrument = null; | |
182 } | |
183 | |
184 @Override | |
185 public Probe getProbe() throws IllegalStateException { | |
186 return probe; | |
187 } | |
188 | |
189 @Override | |
190 public Node copy() { | |
191 Node node = super.copy(); | |
192 probe.registerProbeNodeClone((ProbeNode) node); | |
193 return node; | |
194 } | |
195 | |
196 private void setProbe(Probe probe) { | |
197 this.probe = probe; | |
198 } | |
199 | |
200 @Override | |
201 @TruffleBoundary | |
202 void addInstrument(Instrument instrument) { | |
203 assert instrument.getProbe() == probe; | |
204 // The existing chain of nodes may be empty | |
205 // Attach the modified chain. | |
206 firstInstrument = insert(instrument.addToChain(firstInstrument)); | |
207 } | |
208 | |
209 @Override | |
210 @TruffleBoundary | |
211 void removeInstrument(Instrument instrument) { | |
212 assert instrument.getProbe() == probe; | |
213 final AbstractInstrumentNode modifiedChain = instrument.removeFromChain(firstInstrument); | |
214 if (modifiedChain == null) { | |
215 firstInstrument = null; | |
216 } else { | |
217 firstInstrument = insert(modifiedChain); | |
218 } | |
219 } | |
220 | |
221 public void enter(Node node, VirtualFrame vFrame) { | |
222 this.probe.checkProbeUnchanged(); | |
223 final SyntaxTagTrap trap = probe.getTrap(); | |
224 if (trap != null) { | |
225 trap.tagTrappedAt(((WrapperNode) this.getParent()).getChild(), vFrame.materialize()); | |
226 } | |
227 if (firstInstrument != null) { | |
228 firstInstrument.enter(node, vFrame); | |
229 } | |
230 } | |
231 | |
232 public void returnVoid(Node node, VirtualFrame vFrame) { | |
233 this.probe.checkProbeUnchanged(); | |
234 if (firstInstrument != null) { | |
235 firstInstrument.returnVoid(node, vFrame); | |
236 } | |
237 } | |
238 | |
239 public void returnValue(Node node, VirtualFrame vFrame, Object result) { | |
240 this.probe.checkProbeUnchanged(); | |
241 if (firstInstrument != null) { | |
242 firstInstrument.returnValue(node, vFrame, result); | |
243 } | |
244 } | |
245 | |
246 public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { | |
247 this.probe.checkProbeUnchanged(); | |
248 if (firstInstrument != null) { | |
249 firstInstrument.returnExceptional(node, vFrame, exception); | |
250 } | |
251 } | |
252 | |
253 public String instrumentationInfo() { | |
254 return "Standard probe"; | |
255 } | |
256 } | |
257 | |
258 /** | |
259 * Implementation of a probe that only ever has a single "instrument" associated with it. No | |
260 * {@link Instrument} is ever created; instead this method simply delegates the various enter | |
261 * and return events to a {@link TruffleEvents} passed in during construction. | |
262 */ | |
263 @NodeInfo(cost = NodeCost.NONE) | |
264 private static final class ProbeLiteNode extends ProbeNode { | |
265 | |
266 private final ASTInstrumentListener instrumentListener; | |
267 | |
268 private ProbeLiteNode(ASTInstrumentListener eventListener) { | |
269 this.instrumentListener = eventListener; | |
270 } | |
271 | |
272 @Override | |
273 public Probe getProbe() throws IllegalStateException { | |
274 throw new IllegalStateException("\"lite-Probed\" nodes have no explicit Probe"); | |
275 } | |
276 | |
277 @Override | |
278 @TruffleBoundary | |
279 void addInstrument(Instrument instrument) { | |
280 throw new IllegalStateException("Instruments may not be added at a \"lite-probed\" location"); | |
281 } | |
282 | |
283 @Override | |
284 @TruffleBoundary | |
285 void removeInstrument(Instrument instrument) { | |
286 throw new IllegalStateException("Instruments may not be removed at a \"lite-probed\" location"); | |
287 } | |
288 | |
289 public void enter(Node node, VirtualFrame vFrame) { | |
290 instrumentListener.enter(getProbe(), node, vFrame); | |
291 } | |
292 | |
293 public void returnVoid(Node node, VirtualFrame vFrame) { | |
294 instrumentListener.returnVoid(getProbe(), node, vFrame); | |
295 } | |
296 | |
297 public void returnValue(Node node, VirtualFrame vFrame, Object result) { | |
298 instrumentListener.returnValue(getProbe(), node, vFrame, result); | |
299 } | |
300 | |
301 public void returnExceptional(Node node, VirtualFrame vFrame, Exception exception) { | |
302 instrumentListener.returnExceptional(getProbe(), node, vFrame, exception); | |
303 } | |
304 | |
305 public String instrumentationInfo() { | |
306 return "\"Lite\" probe"; | |
307 } | |
308 | |
309 } | |
310 } | 216 } |