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/instrument/TransformerManager.java (1 of 18352 files). Show all

Unified · Split

java/pkg/sun/instrument/TransformerManager.java+253−0
@@ -0,0 +1,253 @@
1+/*
2+ * Copyright (c) 2003, 2005, 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.instrument;
27+
28+
29+import java.lang.instrument.Instrumentation;
30+import java.lang.instrument.ClassFileTransformer;
31+import java.security.ProtectionDomain;
32+
33+/*
34+ * Copyright 2003 Wily Technology, Inc.
35+ */
36+
37+/**
38+ * Support class for the InstrumentationImpl. Manages the list of registered transformers.
39+ * Keeps everything in the right order, deals with sync of the list,
40+ * and actually does the calling of the transformers.
41+ */
42+public class TransformerManager
43+{
44+ private class TransformerInfo {
45+ final ClassFileTransformer mTransformer;
46+ String mPrefix;
47+
48+ TransformerInfo(ClassFileTransformer transformer) {
49+ mTransformer = transformer;
50+ mPrefix = null;
51+ }
52+
53+ ClassFileTransformer transformer() {
54+ return mTransformer;
55+ }
56+
57+ String getPrefix() {
58+ return mPrefix;
59+ }
60+
61+ void setPrefix(String prefix) {
62+ mPrefix = prefix;
63+ }
64+ }
65+
66+ /**
67+ * a given instance of this list is treated as immutable to simplify sync;
68+ * we pay copying overhead whenever the list is changed rather than every time
69+ * the list is referenced.
70+ * The array is kept in the order the transformers are added via addTransformer
71+ * (first added is 0, last added is length-1)
72+ * Use an array, not a List or other Collection. This keeps the set of classes
73+ * used by this code to a minimum. We want as few dependencies as possible in this
74+ * code, since it is used inside the class definition system. Any class referenced here
75+ * cannot be transformed by Java code.
76+ */
77+ private TransformerInfo[] mTransformerList;
78+
79+ /***
80+ * Is this TransformerManager for transformers capable of retransformation?
81+ */
82+ private boolean mIsRetransformable;
83+
84+ TransformerManager(boolean isRetransformable) {
85+ mTransformerList = new TransformerInfo[0];
86+ mIsRetransformable = isRetransformable;
87+ }
88+
89+ boolean isRetransformable() {
90+ return mIsRetransformable;
91+ }
92+
93+ public synchronized void
94+ addTransformer( ClassFileTransformer transformer) {
95+ TransformerInfo[] oldList = mTransformerList;
96+ TransformerInfo[] newList = new TransformerInfo[oldList.length + 1];
97+ System.arraycopy( oldList,
98+ 0,
99+ newList,
100+ 0,
101+ oldList.length);
102+ newList[oldList.length] = new TransformerInfo(transformer);
103+ mTransformerList = newList;
104+ }
105+
106+ public synchronized boolean
107+ removeTransformer(ClassFileTransformer transformer) {
108+ boolean found = false;
109+ TransformerInfo[] oldList = mTransformerList;
110+ int oldLength = oldList.length;
111+ int newLength = oldLength - 1;
112+
113+ // look for it in the list, starting at the last added, and remember
114+ // where it was if we found it
115+ int matchingIndex = 0;
116+ for ( int x = oldLength - 1; x >= 0; x-- ) {
117+ if ( oldList[x].transformer() == transformer ) {
118+ found = true;
119+ matchingIndex = x;
120+ break;
121+ }
122+ }
123+
124+ // make a copy of the array without the matching element
125+ if ( found ) {
126+ TransformerInfo[] newList = new TransformerInfo[newLength];
127+
128+ // copy up to but not including the match
129+ if ( matchingIndex > 0 ) {
130+ System.arraycopy( oldList,
131+ 0,
132+ newList,
133+ 0,
134+ matchingIndex);
135+ }
136+
137+ // if there is anything after the match, copy it as well
138+ if ( matchingIndex < (newLength) ) {
139+ System.arraycopy( oldList,
140+ matchingIndex + 1,
141+ newList,
142+ matchingIndex,
143+ (newLength) - matchingIndex);
144+ }
145+ mTransformerList = newList;
146+ }
147+ return found;
148+ }
149+
150+ synchronized boolean
151+ includesTransformer(ClassFileTransformer transformer) {
152+ for (TransformerInfo info : mTransformerList) {
153+ if ( info.transformer() == transformer ) {
154+ return true;
155+ }
156+ }
157+ return false;
158+ }
159+
160+ // This function doesn't actually snapshot anything, but should be
161+ // used to set a local variable, which will snapshot the transformer
162+ // list because of the copying semantics of mTransformerList (see
163+ // the comment for mTransformerList).
164+ private TransformerInfo[]
165+ getSnapshotTransformerList() {
166+ return mTransformerList;
167+ }
168+
169+ public byte[]
170+ transform( ClassLoader loader,
171+ String classname,
172+ Class classBeingRedefined,
173+ ProtectionDomain protectionDomain,
174+ byte[] classfileBuffer) {
175+ boolean someoneTouchedTheBytecode = false;
176+
177+ TransformerInfo[] transformerList = getSnapshotTransformerList();
178+
179+ byte[] bufferToUse = classfileBuffer;
180+
181+ // order matters, gotta run 'em in the order they were added
182+ for ( int x = 0; x < transformerList.length; x++ ) {
183+ TransformerInfo transformerInfo = transformerList[x];
184+ ClassFileTransformer transformer = transformerInfo.transformer();
185+ byte[] transformedBytes = null;
186+
187+ try {
188+ transformedBytes = transformer.transform( loader,
189+ classname,
190+ classBeingRedefined,
191+ protectionDomain,
192+ bufferToUse);
193+ }
194+ catch (Throwable t) {
195+ // don't let any one transformer mess it up for the others.
196+ // This is where we need to put some logging. What should go here? FIXME
197+ }
198+
199+ if ( transformedBytes != null ) {
200+ someoneTouchedTheBytecode = true;
201+ bufferToUse = transformedBytes;
202+ }
203+ }
204+
205+ // if someone modified it, return the modified buffer.
206+ // otherwise return null to mean "no transforms occurred"
207+ byte [] result;
208+ if ( someoneTouchedTheBytecode ) {
209+ result = bufferToUse;
210+ }
211+ else {
212+ result = null;
213+ }
214+
215+ return result;
216+ }
217+
218+
219+ int
220+ getTransformerCount() {
221+ TransformerInfo[] transformerList = getSnapshotTransformerList();
222+ return transformerList.length;
223+ }
224+
225+ boolean
226+ setNativeMethodPrefix(ClassFileTransformer transformer, String prefix) {
227+ TransformerInfo[] transformerList = getSnapshotTransformerList();
228+
229+ for ( int x = 0; x < transformerList.length; x++ ) {
230+ TransformerInfo transformerInfo = transformerList[x];
231+ ClassFileTransformer aTransformer = transformerInfo.transformer();
232+
233+ if ( aTransformer == transformer ) {
234+ transformerInfo.setPrefix(prefix);
235+ return true;
236+ }
237+ }
238+ return false;
239+ }
240+
241+
242+ String[]
243+ getNativeMethodPrefixes() {
244+ TransformerInfo[] transformerList = getSnapshotTransformerList();
245+ String[] prefixes = new String[transformerList.length];
246+
247+ for ( int x = 0; x < transformerList.length; x++ ) {
248+ TransformerInfo transformerInfo = transformerList[x];
249+ prefixes[x] = transformerInfo.getPrefix();
250+ }
251+ return prefixes;
252+ }
253+}