Mercurial > hg > truffle
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/LineToProbesMap.java @ 18485:e3c95cbbb50c
Truffle Instrumentation: major API revision, based around the Probe and Instrument classes; add Instrumentable API for language implementors, with most details automated; reimplemented to handle AST splitting automatically; more JUnit tests.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Sun, 23 Nov 2014 16:07:23 -0800 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
18484:e97e1f07a3d6 | 18485:e3c95cbbb50c |
---|---|
1 /* | |
2 * Copyright (c) 2014, 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.api.instrument.impl; | |
26 | |
27 import java.io.*; | |
28 import java.util.*; | |
29 | |
30 import com.oracle.truffle.api.instrument.*; | |
31 import com.oracle.truffle.api.instrument.Probe.ProbeListener; | |
32 import com.oracle.truffle.api.source.*; | |
33 | |
34 /** | |
35 * A mapping from {@link LineLocation} (a line number in a specific piece of {@link Source} code) to | |
36 * a collection of {@link Probe}s whose associated {@link SourceSection} starts on that line. | |
37 */ | |
38 public class LineToProbesMap implements ProbeListener { | |
39 | |
40 private static final boolean TRACE = false; | |
41 private static final PrintStream OUT = System.out; | |
42 | |
43 private static void trace(String msg) { | |
44 OUT.println("LineToProbesMap: " + msg); | |
45 } | |
46 | |
47 /** | |
48 * Map: Source line ==> probes associated with source sections starting on the line. | |
49 */ | |
50 private final Map<LineLocation, Collection<Probe>> lineToProbesMap = new HashMap<>(); | |
51 | |
52 public LineToProbesMap() { | |
53 } | |
54 | |
55 public void startASTProbing(Source source) { | |
56 } | |
57 | |
58 public void newProbeInserted(Probe probe) { | |
59 final SourceSection sourceSection = probe.getProbedSourceSection(); | |
60 if (sourceSection != null && !(sourceSection instanceof NullSourceSection)) { | |
61 final LineLocation lineLocation = sourceSection.getLineLocation(); | |
62 if (TRACE) { | |
63 trace("ADD " + lineLocation.getShortDescription() + " ==> " + probe.getShortDescription()); | |
64 } | |
65 this.addProbeToLine(lineLocation, probe); | |
66 } | |
67 } | |
68 | |
69 public void probeTaggedAs(Probe probe, SyntaxTag tag, Object tagValue) { | |
70 // This map ignores tags | |
71 } | |
72 | |
73 public void endASTProbing(Source source) { | |
74 } | |
75 | |
76 /** | |
77 * Returns the {@link Probe}, if any, associated with source that starts on a specified line; if | |
78 * there are more than one, return the one with the first starting character location. | |
79 */ | |
80 public Probe findLineProbe(LineLocation lineLocation) { | |
81 Probe probe = null; | |
82 final Collection<Probe> probes = getProbesAtLine(lineLocation); | |
83 for (Probe probesOnLine : probes) { | |
84 if (probe == null) { | |
85 probe = probesOnLine; | |
86 } else if (probesOnLine.getProbedSourceSection().getCharIndex() < probe.getProbedSourceSection().getCharIndex()) { | |
87 probe = probesOnLine; | |
88 } | |
89 } | |
90 return probe; | |
91 } | |
92 | |
93 /** | |
94 * Records creation of a probe whose associated source starts on the given line. | |
95 * <p> | |
96 * If the line already exists in the internal {@link #lineToProbesMap}, this probe will be added | |
97 * to the existing collection. If no line already exists in the internal map, then a new key is | |
98 * added along with a new collection containing the probe. | |
99 * <p> | |
100 * This class requires that each added line/probe pair hasn't been previously added. However, | |
101 * attaching the same probe to a new line location is allowed. | |
102 * | |
103 * @param line The {@link LineLocation} to attach the probe to. | |
104 * @param probe The {@link Probe} to attach for that line location. | |
105 */ | |
106 protected void addProbeToLine(LineLocation line, Probe probe) { | |
107 | |
108 if (!lineToProbesMap.containsKey(line)) { | |
109 // Key does not exist, add new probe list | |
110 final ArrayList<Probe> newProbeList = new ArrayList<>(2); | |
111 newProbeList.add(probe); | |
112 lineToProbesMap.put(line, newProbeList); | |
113 } else { | |
114 // Probe list exists, add to existing | |
115 final Collection<Probe> existingProbeList = lineToProbesMap.get(line); | |
116 assert !existingProbeList.contains(probe); | |
117 existingProbeList.add(probe); | |
118 } | |
119 } | |
120 | |
121 /** | |
122 * | |
123 * Returns a collection of {@link Probe}s whose associated source begins at the given | |
124 * {@link LineLocation}, an empty list if none. | |
125 * | |
126 * @param line The line to check. | |
127 * @return A collection of probes at the given line. | |
128 */ | |
129 public Collection<Probe> getProbesAtLine(LineLocation line) { | |
130 Collection<Probe> probesList = lineToProbesMap.get(line); | |
131 | |
132 if (probesList == null) { | |
133 return Collections.emptyList(); | |
134 } | |
135 return probesList; | |
136 } | |
137 | |
138 /** | |
139 * Convenience method to get probes according to a int line number. Returns a collection of | |
140 * {@link Probe}s at the given line number, an empty list if none. | |
141 * | |
142 * @param lineNumber The line number to check. | |
143 * @return A collection of probes at the given line. | |
144 */ | |
145 public Collection<Probe> getProbesAtLineNumber(int lineNumber) { | |
146 | |
147 final Set<LineLocation> keySet = lineToProbesMap.keySet(); | |
148 if (keySet.size() == 0) { | |
149 return Collections.emptyList(); | |
150 } | |
151 | |
152 ArrayList<Probe> probes = new ArrayList<>(); | |
153 for (LineLocation line : keySet) { | |
154 if (line.getLineNumber() == lineNumber) { | |
155 probes.addAll(lineToProbesMap.get(line)); | |
156 } | |
157 } | |
158 | |
159 return probes; | |
160 } | |
161 | |
162 public void forget(Source source) { | |
163 final Set<LineLocation> mappedLines = lineToProbesMap.keySet(); | |
164 if (mappedLines.size() > 0) { | |
165 List<LineLocation> forgetLines = new ArrayList<>(); | |
166 for (LineLocation line : mappedLines) { | |
167 if (line.getSource().equals(source)) { | |
168 forgetLines.add(line); | |
169 } | |
170 } | |
171 for (LineLocation line : forgetLines) { | |
172 lineToProbesMap.remove(line); | |
173 } | |
174 } | |
175 } | |
176 } |