Mercurial > hg > truffle
diff graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/NodeExecCounter.java @ 19248:a2ff253c458f
Truffle/Instrumentation: code cleanups in tools CoverageTracker and NodeExecCounter, especially for tutorial value
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Tue, 10 Feb 2015 16:44:19 -0800 |
parents | c5b20395a8bf |
children | b5467bb34b24 |
line wrap: on
line diff
--- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/NodeExecCounter.java Tue Feb 10 16:44:11 2015 -0800 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/tools/NodeExecCounter.java Tue Feb 10 16:44:19 2015 -0800 @@ -49,7 +49,7 @@ * <p> * <ul> * <li>"Execution call" on a node is is defined as invocation of a node method that is instrumented - * to produce the event {@link TruffleEventReceiver#enter(Node, VirtualFrame)};</li> + * to produce the event {@link TruffleEventListener#enter(Node, VirtualFrame)};</li> * <li>Execution calls are tabulated only at <em>instrumented</em> nodes, i.e. those for which * {@linkplain Node#isInstrumentable() isInstrumentable() == true};</li> * <li>Execution calls are tabulated only at nodes present in the AST when originally created; @@ -92,26 +92,38 @@ } /** - * Receiver for events at instrumented nodes. Counts are maintained in a shared table, so the - * receiver is stateless and can be shared by every {@link Instrument}. + * Listener for events at instrumented nodes. Counts are maintained in a shared table, so the + * listener is stateless and can be shared by every {@link Instrument}. */ - private final TruffleEventReceiver eventReceiver = new DefaultEventReceiver() { + private final TruffleEventListener eventListener = new DefaultEventListener() { @Override public void enter(Node node, VirtualFrame frame) { - internalReceive(node); + if (isEnabled()) { + final Class<?> nodeClass = node.getClass(); + /* + * Everything up to here is inlined by Truffle compilation. Delegate the next part + * to a method behind an inlining boundary. + * + * Note that it is not permitted to pass a {@link VirtualFrame} across an inlining + * boundary; they are truly virtual in inlined code. + */ + AtomicLong nodeCounter = getCounter(nodeClass); + nodeCounter.getAndIncrement(); + } } + /** + * Mark this method as a boundary that will stop Truffle inlining, which should not be + * allowed to inline the hash table method or any other complex library code. + */ @TruffleBoundary - private void internalReceive(Node node) { - if (isEnabled()) { - final Class<?> nodeClass = node.getClass(); - AtomicLong nodeCounter = counters.get(nodeClass); - if (nodeCounter == null) { - nodeCounter = new AtomicLong(); - counters.put(nodeClass, nodeCounter); - } - nodeCounter.getAndIncrement(); + private AtomicLong getCounter(Class<?> nodeClass) { + AtomicLong nodeCounter = counters.get(nodeClass); + if (nodeCounter == null) { + nodeCounter = new AtomicLong(); + counters.put(nodeClass, nodeCounter); } + return nodeCounter; } }; @@ -268,7 +280,7 @@ if (node.isInstrumentable()) { try { - final Instrument instrument = Instrument.create(eventReceiver, "NodeExecCounter"); + final Instrument instrument = Instrument.create(eventListener, "NodeExecCounter"); instruments.add(instrument); node.probe().attach(instrument); } catch (ProbeException ex) { @@ -292,7 +304,7 @@ @Override public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { if (countingTag == tag) { - final Instrument instrument = Instrument.create(eventReceiver, NodeExecCounter.class.getSimpleName()); + final Instrument instrument = Instrument.create(eventListener, NodeExecCounter.class.getSimpleName()); instruments.add(instrument); probe.attach(instrument); }