Mercurial > hg > graal-compiler
comparison graal/com.oracle.truffle.api/src/com/oracle/truffle/api/instrument/impl/ProbeManager.java @ 15779:8c34e2cc4add
Truffle/Instrumentation: significant reorganization of the instrumentation framework's implementation and connection to the runtime ExecutionContext, with some new features, including a Tag-based "trap" mechanisms.
author | Michael Van De Vanter <michael.van.de.vanter@oracle.com> |
---|---|
date | Mon, 19 May 2014 17:14:36 -0700 |
parents | |
children | eedf6c293639 |
comparison
equal
deleted
inserted
replaced
15632:dcaf3993ad17 | 15779:8c34e2cc4add |
---|---|
1 /* | |
2 * Copyright (c) 2013, 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.util.*; | |
28 | |
29 import com.oracle.truffle.api.*; | |
30 import com.oracle.truffle.api.instrument.*; | |
31 import com.oracle.truffle.api.instrument.impl.InstrumentationNode.ProbeCallback; | |
32 import com.oracle.truffle.api.instrument.impl.InstrumentationNode.ProbeImpl; | |
33 import com.oracle.truffle.api.source.*; | |
34 | |
35 /** | |
36 * Factory and services for AST {@link Probe}s | |
37 */ | |
38 public final class ProbeManager { | |
39 | |
40 // TODO (mlvdv) use weak references. | |
41 /** | |
42 * Map: SourceSection ==> probe associated with that source section in an AST. | |
43 */ | |
44 private final Map<SourceSection, ProbeImpl> srcToProbe = new HashMap<>(); | |
45 | |
46 // TODO (mlvdv) use weak references. | |
47 /** | |
48 * Map: Source line ==> probes associated with source sections starting on the line. | |
49 */ | |
50 private final Map<SourceLineLocation, Collection<Probe>> lineToProbes = new HashMap<>(); | |
51 | |
52 private final List<ProbeListener> probeListeners = new ArrayList<>(); | |
53 | |
54 private final ProbeCallback probeCallback; | |
55 | |
56 /** | |
57 * When non-null, "enter" events with matching tags will trigger a callback. | |
58 */ | |
59 private PhylumTrap phylumTrap = null; | |
60 | |
61 public ProbeManager() { | |
62 this.probeCallback = new ProbeCallback() { | |
63 /** | |
64 * Receives (from the {@link Probe} implementation) and distributes notification that a | |
65 * {@link Probe} has acquired a new {@linkplain PhylumTag tag}. | |
66 */ | |
67 public void newTagAdded(ProbeImpl probe, PhylumTag tag) { | |
68 for (ProbeListener listener : probeListeners) { | |
69 listener.probeTaggedAs(probe, tag); | |
70 } | |
71 if (phylumTrap != null && tag == phylumTrap.getTag()) { | |
72 probe.setTrap(phylumTrap); | |
73 } | |
74 } | |
75 }; | |
76 } | |
77 | |
78 public void addProbeListener(ProbeListener listener) { | |
79 assert listener != null; | |
80 probeListeners.add(listener); | |
81 } | |
82 | |
83 public Probe getProbe(SourceSection sourceSection) { | |
84 assert sourceSection != null; | |
85 | |
86 ProbeImpl probe = srcToProbe.get(sourceSection); | |
87 | |
88 if (probe != null) { | |
89 return probe; | |
90 } | |
91 probe = InstrumentationNode.createProbe(sourceSection, probeCallback); | |
92 | |
93 // Register new probe by unique SourceSection | |
94 srcToProbe.put(sourceSection, probe); | |
95 | |
96 // Register new probe by source line, there may be more than one | |
97 // Create line location for map key | |
98 final SourceLineLocation lineLocation = new SourceLineLocation(sourceSection.getSource(), sourceSection.getStartLine()); | |
99 | |
100 Collection<Probe> probes = lineToProbes.get(lineLocation); | |
101 if (probes == null) { | |
102 probes = new ArrayList<>(2); | |
103 lineToProbes.put(lineLocation, probes); | |
104 } | |
105 probes.add(probe); | |
106 | |
107 for (ProbeListener listener : probeListeners) { | |
108 listener.newProbeInserted(sourceSection, probe); | |
109 } | |
110 | |
111 return probe; | |
112 } | |
113 | |
114 public Collection<Probe> findProbesTaggedAs(PhylumTag tag) { | |
115 final List<Probe> probes = new ArrayList<>(); | |
116 for (Probe probe : srcToProbe.values()) { | |
117 if (tag == null || probe.isTaggedAs(tag)) { | |
118 probes.add(probe); | |
119 } | |
120 } | |
121 return probes; | |
122 } | |
123 | |
124 public Collection<Probe> findProbesByLine(SourceLineLocation lineLocation) { | |
125 final Collection<Probe> probes = lineToProbes.get(lineLocation); | |
126 if (probes == null) { | |
127 return Collections.emptyList(); | |
128 } | |
129 return new ArrayList<>(probes); | |
130 } | |
131 | |
132 public void setPhylumTrap(PhylumTrap trap) { | |
133 assert trap != null; | |
134 if (this.phylumTrap != null) { | |
135 throw new IllegalStateException("trap already set"); | |
136 } | |
137 this.phylumTrap = trap; | |
138 | |
139 PhylumTag tag = trap.getTag(); | |
140 for (ProbeImpl probe : srcToProbe.values()) { | |
141 if (probe.isTaggedAs(tag)) { | |
142 probe.setTrap(trap); | |
143 } | |
144 } | |
145 } | |
146 | |
147 public void clearPhylumTrap() { | |
148 if (this.phylumTrap == null) { | |
149 throw new IllegalStateException("no trap set"); | |
150 } | |
151 for (ProbeImpl probe : srcToProbe.values()) { | |
152 if (probe.isTaggedAs(phylumTrap.getTag())) { | |
153 probe.setTrap(null); | |
154 } | |
155 } | |
156 phylumTrap = null; | |
157 } | |
158 | |
159 } |