History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/sun/tracing/dtrace/DTraceProvider.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/tracing/dtrace/DTraceProvider.java+230−0
@@ -0,0 +1,230 @@
1/*
2 * Copyright (c) 2008, 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
26package sun.tracing.dtrace;
27
28import java.lang.reflect.Method;
29import java.lang.reflect.InvocationTargetException;
30import java.lang.reflect.Modifier;
31import java.lang.reflect.Constructor;
32import java.lang.reflect.InvocationHandler;
33import java.lang.reflect.InvocationTargetException;
34import java.lang.annotation.Annotation;
35import java.util.HashMap;
36
37import sun.tracing.ProviderSkeleton;
38import sun.tracing.ProbeSkeleton;
39import com.sun.tracing.Provider;
40import com.sun.tracing.ProviderName;
41import com.sun.tracing.ProbeName;
42import com.sun.tracing.dtrace.Attributes;
43import com.sun.tracing.dtrace.ModuleName;
44import com.sun.tracing.dtrace.FunctionName;
45import com.sun.tracing.dtrace.StabilityLevel;
46import com.sun.tracing.dtrace.DependencyClass;
47
48import sun.misc.ProxyGenerator;
49
50class DTraceProvider extends ProviderSkeleton {
51
52 private Activation activation;
53 private Object proxy;
54
55 // For proxy generation
56 private final static Class[] constructorParams = { InvocationHandler.class };
57 private final String proxyClassNamePrefix = "$DTraceTracingProxy";
58
59 static final String DEFAULT_MODULE = "java_tracing";
60 static final String DEFAULT_FUNCTION = "unspecified";
61
62 private static long nextUniqueNumber = 0;
63 private static synchronized long getUniqueNumber() {
64 return nextUniqueNumber++;
65 }
66
67 protected ProbeSkeleton createProbe(Method m) {
68 return new DTraceProbe(proxy, m);
69 }
70
71 DTraceProvider(Class<? extends Provider> type) {
72 super(type);
73 }
74
75 void setProxy(Object p) {
76 proxy = p;
77 }
78
79 void setActivation(Activation a) {
80 this.activation = a;
81 }
82
83 public void dispose() {
84 if (activation != null) {
85 activation.disposeProvider(this);
86 activation = null;
87 }
88 super.dispose();
89 }
90
91 /**
92 * Magic routine which creates an implementation of the user's interface.
93 *
94 * This method uses the ProxyGenerator directly to bypass the
95 * java.lang.reflect.proxy cache so that we get a unique class each
96 * time it's called and can't accidently reuse a $Proxy class.
97 *
98 * @return an implementation of the user's interface
99 */
100 @SuppressWarnings("unchecked")
101 public <T extends Provider> T newProxyInstance() {
102 /*
103 * Choose a name for the proxy class to generate.
104 */
105 long num = getUniqueNumber();
106
107 String proxyPkg = "";
108 if (!Modifier.isPublic(providerType.getModifiers())) {
109 String name = providerType.getName();
110 int n = name.lastIndexOf('.');
111 proxyPkg = ((n == -1) ? "" : name.substring(0, n + 1));
112 }
113
114 String proxyName = proxyPkg + proxyClassNamePrefix + num;
115
116 /*
117 * Generate the specified proxy class.
118 */
119 Class<?> proxyClass = null;
120 byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
121 proxyName, new Class<?>[] { providerType });
122 try {
123 proxyClass = JVM.defineClass(
124 providerType.getClassLoader(), proxyName,
125 proxyClassFile, 0, proxyClassFile.length);
126 } catch (ClassFormatError e) {
127 /*
128 * A ClassFormatError here means that (barring bugs in the
129 * proxy class generation code) there was some other
130 * invalid aspect of the arguments supplied to the proxy
131 * class creation (such as virtual machine limitations
132 * exceeded).
133 */
134 throw new IllegalArgumentException(e.toString());
135 }
136
137 /*
138 * Invoke its constructor with the designated invocation handler.
139 */
140 try {
141 Constructor cons = proxyClass.getConstructor(constructorParams);
142 return (T)cons.newInstance(new Object[] { this });
143 } catch (NoSuchMethodException e) {
144 throw new InternalError(e.toString());
145 } catch (IllegalAccessException e) {
146 throw new InternalError(e.toString());
147 } catch (InstantiationException e) {
148 throw new InternalError(e.toString());
149 } catch (InvocationTargetException e) {
150 throw new InternalError(e.toString());
151 }
152 }
153
154 // In the normal case, the proxy object's method implementations will call
155 // this method (it usually calls the ProviderSkeleton's version). That
156 // method uses the passed 'method' object to lookup the associated
157 // 'ProbeSkeleton' and calls uncheckedTrigger() on that probe to cause the
158 // probe to fire. DTrace probes are different in that the proxy class's
159 // methods are immediately overridden with native code to fire the probe
160 // directly. So this method should never get invoked. We also wire up the
161 // DTraceProbe.uncheckedTrigger() method to call the proxy method instead
162 // of doing the work itself.
163 public Object invoke(Object proxy, Method method, Object[] args) {
164 if (method.getDeclaringClass() != providerType) {
165 try {
166 return method.invoke(this, args);
167 } catch (IllegalAccessException e) {
168 assert false;
169 } catch (InvocationTargetException e) {
170 assert false;
171 }
172 } else if (active) {
173 assert false : "This method should have been overridden by the JVM";
174 }
175 return null;
176 }
177
178 public String getProviderName() {
179 return super.getProviderName();
180 }
181
182 String getModuleName() {
183 return getAnnotationString(
184 providerType, ModuleName.class, DEFAULT_MODULE);
185 }
186
187 static String getProbeName(Method method) {
188 return getAnnotationString(
189 method, ProbeName.class, method.getName());
190 }
191
192 static String getFunctionName(Method method) {
193 return getAnnotationString(
194 method, FunctionName.class, DEFAULT_FUNCTION);
195 }
196
197 DTraceProbe[] getProbes() {
198 return probes.values().toArray(new DTraceProbe[0]);
199 }
200
201 StabilityLevel getNameStabilityFor(Class<? extends Annotation> type) {
202 Attributes attrs = (Attributes)getAnnotationValue(
203 providerType, type, "value", null);
204 if (attrs == null) {
205 return StabilityLevel.PRIVATE;
206 } else {
207 return attrs.name();
208 }
209 }
210
211 StabilityLevel getDataStabilityFor(Class<? extends Annotation> type) {
212 Attributes attrs = (Attributes)getAnnotationValue(
213 providerType, type, "value", null);
214 if (attrs == null) {
215 return StabilityLevel.PRIVATE;
216 } else {
217 return attrs.data();
218 }
219 }
220
221 DependencyClass getDependencyClassFor(Class<? extends Annotation> type) {
222 Attributes attrs = (Attributes)getAnnotationValue(
223 providerType, type, "value", null);
224 if (attrs == null) {
225 return DependencyClass.UNKNOWN;
226 } else {
227 return attrs.dependency();
228 }
229 }
230}