4848import com .sun .btrace .org .objectweb .asm .Opcodes ;
4949import com .sun .btrace .runtime .ClassFilter ;
5050import com .sun .btrace .runtime .ClassRenamer ;
51- import com .sun .btrace .runtime .ClinitInjector ;
5251import com .sun .btrace .runtime .Instrumentor ;
5352import com .sun .btrace .runtime .InstrumentUtils ;
5453import com .sun .btrace .runtime .Location ;
6564import java .lang .instrument .ClassFileTransformer ;
6665import java .lang .instrument .IllegalClassFormatException ;
6766import java .lang .instrument .Instrumentation ;
67+ import java .lang .instrument .UnmodifiableClassException ;
68+ import java .lang .reflect .Field ;
6869import java .util .ArrayList ;
6970import java .util .Collection ;
71+ import java .util .HashSet ;
72+ import java .util .Iterator ;
7073import java .util .Map ;
74+ import java .util .Set ;
75+ import java .util .Vector ;
76+ import java .util .concurrent .Executors ;
77+ import java .util .concurrent .ScheduledExecutorService ;
78+ import java .util .concurrent .ThreadFactory ;
79+ import java .util .concurrent .TimeUnit ;
7180import sun .reflect .annotation .AnnotationParser ;
7281import sun .reflect .annotation .AnnotationType ;
7382
8089abstract class Client implements ClassFileTransformer , CommandListener {
8190 protected final Instrumentation inst ;
8291 private volatile BTraceRuntime runtime ;
92+ private volatile boolean isClassRenamed = false ;
8393 private volatile String className ;
8494 private volatile Class btraceClazz ;
8595 private volatile byte [] btraceCode ;
@@ -106,36 +116,6 @@ abstract class Client implements ClassFileTransformer, CommandListener {
106116 BTraceRuntime .init (createPerfReaderImpl (), new RunnableGeneratorImpl ());
107117 }
108118
109- final private ClassFileTransformer clInitTransformer = new ClassFileTransformer () {
110-
111- @ Override
112- public byte [] transform (ClassLoader loader , final String cname , Class <?> classBeingRedefined , ProtectionDomain protectionDomain , byte [] classfileBuffer ) throws IllegalClassFormatException {
113- if (!hasSubclassChecks || classBeingRedefined != null || isBTraceClass (cname ) || isSensitiveClass (cname )) return null ;
114-
115- if (!skipRetransforms ) {
116- if (isDebug ()) {
117- Client .this .debugPrint ("injecting <clinit> for " + cname ); // NOI18N
118- }
119- ClassReader cr = new ClassReader (classfileBuffer );
120- ClassWriter cw = new ClassWriter (cr , ClassWriter .COMPUTE_MAXS );
121- ClinitInjector injector = new ClinitInjector (cw , className , cname );
122- InstrumentUtils .accept (cr , injector );
123- if (injector .isTransformed ()) {
124- byte [] instrumentedCode = cw .toByteArray ();
125- if (settings .isDumpClasses ()) {
126- debug .dumpClass (className , cname + "_clinit" , instrumentedCode ); // NOI18N
127- }
128- return instrumentedCode ;
129- }
130- } else {
131- if (isDebug ()) {
132- Client .this .debugPrint ("client " + className + ": skipping transform for " + cname ); // NOI18N
133- }
134- }
135- return null ;
136- }
137- };
138-
139119 private static PerfReader createPerfReaderImpl () {
140120 // see if we can access any jvmstat class
141121 try {
@@ -178,21 +158,19 @@ public byte[] transform(
178158 if (classBeingRedefined != null ) {
179159 // class already defined; retransforming
180160 if (!skipRetransforms && filter .isCandidate (classBeingRedefined )) {
181- return doTransform (classBeingRedefined , cname , classfileBuffer );
161+ return doTransform (loader , classBeingRedefined , cname , classfileBuffer );
182162 } else {
183163 if (isDebug ()) {
184- debugPrint ("client " + className + ": skipping transform for " + cname ); // NOi18N
164+ debugPrint ("client " + className + "[" + skipRetransforms + "] : skipping transform for " + cname ); // NOi18N
185165 }
186166 }
187167 } else {
188168 // class not yet defined
189- if (!hasSubclassChecks ) {
190- if (filter .isCandidate (classfileBuffer )) {
191- return doTransform (classBeingRedefined , cname , classfileBuffer );
192- } else {
193- if (isDebug ()) {
194- debugPrint ("client " + className + ": skipping transform for " + cname ); // NOI18N
195- }
169+ if (filter .isCandidate (loader , classfileBuffer , hasSubclassChecks )) {
170+ return doTransform (loader , classBeingRedefined , cname , classfileBuffer );
171+ } else {
172+ if (isDebug ()) {
173+ debugPrint ("client " + className + "[" + skipRetransforms + "]: skipping transform for " + cname ); // NOI18N
196174 }
197175 }
198176 }
@@ -220,16 +198,14 @@ protected final void setSettings(Map<String, Object> params) {
220198 }
221199
222200 void registerTransformer () {
223- inst .addTransformer (clInitTransformer , false );
224201 inst .addTransformer (this , true );
225202 }
226203
227204 void unregisterTransformer () {
228205 inst .removeTransformer (this );
229- inst .removeTransformer (clInitTransformer );
230206 }
231207
232- private byte [] doTransform (Class <?> classBeingRedefined , String cname , byte [] classfileBuffer ) {
208+ private byte [] doTransform (ClassLoader loader , Class <?> classBeingRedefined , String cname , byte [] classfileBuffer ) {
233209 if (isDebug ()) {
234210 debugPrint ("client " + className + ": instrumenting " + cname );
235211 }
@@ -240,7 +216,7 @@ private byte[] doTransform(Class<?> classBeingRedefined, String cname, byte[] cl
240216 debugPrint (e );
241217 }
242218 }
243- return instrument (classBeingRedefined , cname , classfileBuffer );
219+ return instrument (loader , classBeingRedefined , cname , classfileBuffer );
244220 }
245221
246222 protected synchronized void onExit (int exitCode ) {
@@ -277,8 +253,7 @@ protected Class loadClass(InstrumentCommand instr) throws IOException {
277253 ClassWriter writer = InstrumentUtils .newClassWriter (btraceCode );
278254 ClassReader reader = new ClassReader (btraceCode );
279255 ClassVisitor visitor = new Preprocessor (writer );
280- if (BTraceRuntime .classNameExists (className )) {
281- className += "$" + getCount ();
256+ if (isClassRenamed ) {
282257 if (isDebug ()) {
283258 debugPrint ("class renamed to " + className );
284259 }
@@ -465,10 +440,10 @@ private static boolean isSensitiveClass(String name) {
465440 name .equals ("java/lang/VerifyError" ); // NOI18N
466441 }
467442
468- private byte [] instrument (Class clazz , String cname , byte [] target ) {
443+ private byte [] instrument (ClassLoader loader , Class clazz , String cname , byte [] target ) {
469444 byte [] instrumentedCode ;
470445 try {
471- ClassWriter writer = InstrumentUtils .newClassWriter (target );
446+ ClassWriter writer = InstrumentUtils .newClassWriter (loader , target );
472447 ClassReader reader = new ClassReader (target );
473448 Instrumentor i = new Instrumentor (clazz , className , btraceCode , onMethods , writer );
474449 InstrumentUtils .accept (reader , i );
@@ -492,6 +467,7 @@ private void verify(byte[] buf) {
492467 debugPrint ("verifying BTrace class" );
493468 InstrumentUtils .accept (reader , verifier );
494469 className = verifier .getClassName ().replace ('/' , '.' );
470+ isClassRenamed = verifier .isClassRenamed ();
495471 if (isDebug ()) {
496472 debugPrint ("verified '" + className + "' successfully" );
497473 }
@@ -505,7 +481,6 @@ private void verify(byte[] buf) {
505481 verifySpecialParameters (om );
506482 if (om .getClazz ().startsWith ("+" )) {
507483 hasSubclassChecks = true ;
508- break ;
509484 }
510485 }
511486 }
@@ -609,9 +584,4 @@ private List<OnMethod> mapOnProbes(List<OnProbe> onProbes) {
609584 }
610585 return res ;
611586 }
612-
613- private static long count = 0L ;
614- private static long getCount () {
615- return count ++;
616- }
617587}
0 commit comments