diff truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/CoverageTracker.java @ 22266:0d36601f233e

Merge revised Instrumentation framework into the Polyglot API - Required language implementation support now in TruffleLanguage - Instrumentation services provided by the new Instrumenter class - Reduced public API exposure; communication with other components via Accessor - Several methods removed from the Node class - Many test rewritten or using a new "test mode" because of limited access to Engine services Merge with c66f520ad8562b906a878e9b3293aaf54270db90
author Michael Van De Vanter <michael.van.de.vanter@oracle.com>
date Wed, 30 Sep 2015 16:33:56 -0700
parents 1348cc2e084e
children
line wrap: on
line diff
--- a/truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/CoverageTracker.java	Tue Sep 29 18:04:11 2015 +0200
+++ b/truffle/com.oracle.truffle.tools/src/com/oracle/truffle/tools/CoverageTracker.java	Wed Sep 30 16:33:56 2015 -0700
@@ -24,9 +24,18 @@
  */
 package com.oracle.truffle.tools;
 
-import com.oracle.truffle.api.instrument.Instrument;
-import com.oracle.truffle.api.instrument.InstrumentationTool;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeSet;
+
+import com.oracle.truffle.api.instrument.Instrumenter;
 import com.oracle.truffle.api.instrument.Probe;
+import com.oracle.truffle.api.instrument.ProbeInstrument;
 import com.oracle.truffle.api.instrument.ProbeListener;
 import com.oracle.truffle.api.instrument.SimpleInstrumentListener;
 import com.oracle.truffle.api.instrument.StandardSyntaxTag;
@@ -37,33 +46,26 @@
 import com.oracle.truffle.api.source.LineLocation;
 import com.oracle.truffle.api.source.Source;
 import com.oracle.truffle.api.source.SourceSection;
-import java.io.PrintStream;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeSet;
 
 /**
- * An {@link InstrumentationTool} that counts interpreter <em>execution calls</em> to AST nodes that
- * hold a specified {@linkplain SyntaxTag syntax tag}, tabulated by source and line number
- * associated with each node. Syntax tags are presumed to be applied external to the tool. If no tag
- * is specified, {@linkplain StandardSyntaxTag#STATEMENT STATEMENT} is used, corresponding to
- * conventional behavior for code coverage tools.
+ * An {@linkplain Instrumenter.Tool Instrumentation Tool} that counts interpreter
+ * <em>execution calls</em> to AST nodes that hold a specified {@linkplain SyntaxTag syntax tag},
+ * tabulated by source and line number associated with each node. Syntax tags are presumed to be
+ * applied external to the tool. If no tag is specified, {@linkplain StandardSyntaxTag#STATEMENT
+ * STATEMENT} is used, corresponding to conventional behavior for code coverage tools.
  * <p>
  * <b>Tool Life Cycle</b>
  * <p>
- * See {@link InstrumentationTool} for the life cycle common to all such tools.
+ * See {@linkplain Instrumenter.Tool Instrumentation Tool} for the life cycle common to all such
+ * tools.
  * <p>
  * <b>Execution Counts</b>
  * <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 SimpleInstrumentListener#enter(Probe)};</li>
- * <li>Execution calls are tabulated only at <em>instrumented</em> nodes, i.e. those for which
- * {@linkplain Node#isInstrumentable() isInstrumentable() == true};</li>
+ * to produce the event {@link SimpleInstrumentListener#onEnter(Probe)};</li>
+ * <li>Execution calls are tabulated only at nodes where the guest languages supports
+ * {@linkplain Instrumenter#probe(Node) probing}.</li>
  * <li>Execution calls are tabulated only at nodes present in the AST when originally created;
  * dynamically added nodes will not be instrumented.</li>
  * </ul>
@@ -78,16 +80,16 @@
  * any time in a simple textual format, with no other effect on the state of the tool.
  * </p>
  *
- * @see Instrument
+ * @see ProbeInstrument
  * @see SyntaxTag
  */
-public final class CoverageTracker extends InstrumentationTool {
+public final class CoverageTracker extends Instrumenter.Tool {
 
     /** Counting data. */
     private final Map<LineLocation, CoverageRecord> coverageMap = new HashMap<>();
 
     /** Needed for disposal. */
-    private final List<Instrument> instruments = new ArrayList<>();
+    private final List<ProbeInstrument> instruments = new ArrayList<>();
 
     /**
      * Coverage counting is restricted to nodes holding this tag.
@@ -115,7 +117,11 @@
 
     @Override
     protected boolean internalInstall() {
-        Probe.addProbeListener(probeListener);
+        final Instrumenter instrumenter = getInstrumenter();
+        for (Probe probe : instrumenter.findProbesTaggedAs(countingTag)) {
+            addCoverageCounter(probe);
+        }
+        instrumenter.addProbeListener(probeListener);
         return true;
     }
 
@@ -126,8 +132,8 @@
 
     @Override
     protected void internalDispose() {
-        Probe.removeProbeListener(probeListener);
-        for (Instrument instrument : instruments) {
+        getInstrumenter().removeProbeListener(probeListener);
+        for (ProbeInstrument instrument : instruments) {
             instrument.dispose();
         }
     }
@@ -242,7 +248,7 @@
     private final class CoverageRecord extends DefaultSimpleInstrumentListener {
 
         private final SourceSection srcSection; // The text of the code being counted
-        private Instrument instrument;  // The attached Instrument, in case need to remove.
+        private ProbeInstrument instrument;  // The attached Instrument, in case need to remove.
         private long count = 0;
 
         CoverageRecord(SourceSection srcSection) {
@@ -250,7 +256,7 @@
         }
 
         @Override
-        public void enter(Probe probe) {
+        public void onEnter(Probe probe) {
             if (isEnabled()) {
                 count++;
             }
@@ -273,34 +279,35 @@
         @Override
         public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) {
             if (countingTag == tag) {
-
-                final SourceSection srcSection = probe.getProbedSourceSection();
-                if (srcSection == null) {
-                    // TODO (mlvdv) report this?
-                    return;
-                }
-                // Get the source line where the
-                final LineLocation lineLocation = srcSection.getLineLocation();
-                CoverageRecord record = coverageMap.get(lineLocation);
-                if (record != null) {
-                    // Another node starts on same line; count only the first (textually)
-                    if (srcSection.getCharIndex() > record.srcSection.getCharIndex()) {
-                        // Existing record, corresponds to code earlier on line
-                        return;
-                    } else {
-                        // Existing record, corresponds to code at a later position; replace it
-                        record.instrument.dispose();
-                    }
-                }
-
-                final CoverageRecord coverage = new CoverageRecord(srcSection);
-                final Instrument instrument = Instrument.create(coverage, CoverageTracker.class.getSimpleName());
-                coverage.instrument = instrument;
-                instruments.add(instrument);
-                probe.attach(instrument);
-                coverageMap.put(lineLocation, coverage);
+                addCoverageCounter(probe);
             }
         }
     }
 
+    private void addCoverageCounter(Probe probe) {
+        final SourceSection srcSection = probe.getProbedSourceSection();
+        if (srcSection == null) {
+            // TODO (mlvdv) report this?
+            return;
+        }
+        // Get the source line where the
+        final LineLocation lineLocation = srcSection.getLineLocation();
+        CoverageRecord record = coverageMap.get(lineLocation);
+        if (record != null) {
+            // Another node starts on same line; count only the first (textually)
+            if (srcSection.getCharIndex() > record.srcSection.getCharIndex()) {
+                // Existing record, corresponds to code earlier on line
+                return;
+            } else {
+                // Existing record, corresponds to code at a later position; replace it
+                record.instrument.dispose();
+            }
+        }
+
+        final CoverageRecord coverageRecord = new CoverageRecord(srcSection);
+        final ProbeInstrument instrument = getInstrumenter().attach(probe, coverageRecord, CoverageTracker.class.getSimpleName());
+        coverageRecord.instrument = instrument;
+        instruments.add(instrument);
+        coverageMap.put(lineLocation, coverageRecord);
+    }
 }