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+
26+package sun.tracing.dtrace;
27+
28+import java.lang.reflect.Method;
29+import java.lang.reflect.InvocationTargetException;
30+import java.lang.reflect.Modifier;
31+import java.lang.reflect.Constructor;
32+import java.lang.reflect.InvocationHandler;
33+import java.lang.reflect.InvocationTargetException;
34+import java.lang.annotation.Annotation;
35+import java.util.HashMap;
36+
37+import sun.tracing.ProviderSkeleton;
38+import sun.tracing.ProbeSkeleton;
39+import com.sun.tracing.Provider;
40+import com.sun.tracing.ProviderName;
41+import com.sun.tracing.ProbeName;
42+import com.sun.tracing.dtrace.Attributes;
43+import com.sun.tracing.dtrace.ModuleName;
44+import com.sun.tracing.dtrace.FunctionName;
45+import com.sun.tracing.dtrace.StabilityLevel;
46+import com.sun.tracing.dtrace.DependencyClass;
47+
48+import sun.misc.ProxyGenerator;
49+
50+class 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+}