Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members  

prof_jvm.cpp

00001 /*
00002  *                         Sun Public License Notice
00003  *
00004  * The contents of this file are subject to the Sun Public License
00005  * Version 1.0 (the "License"); you may not use this file except
00006  * in compliance with the License. A copy of the License is available
00007  * at http://www.sun.com/
00008  *
00009  * The Original Code is the Java Profiler module.  The Initial Developers
00010  * of the Original Code are Jan Stola, Pavel Vacha, Michal Pise, Petr Luner,
00011  * Lukas Petru and Marek Przeczek.
00012  *
00013  * Portions created by Jan Stola are Copyright (C) 2000-2001.
00014  * All Rights Reserved.
00015  *
00016  * Portions created by Pavel Vacha are Copyright (C) 2000-2001.
00017  * All Rights Reserved.
00018  *
00019  * Portions created by Michal Pise are Copyright (C) 2000-2001.
00020  * All Rights Reserved.
00021  *
00022  * Portions created by Petr Luner are Copyright (C) 2000-2001.
00023  * All Rights Reserved.
00024  *
00025  * Portions created by Lukas Petru are Copyright (C) 2000-2001.
00026  * All Rights Reserved.
00027  *
00028  * Portions created by Marek Przeczek are Copyright (C) 2000-2001.
00029  * All Rights Reserved.
00030  *
00031  * Contributors: Jan Stola, Pavel Vacha, Michal Pise, Petr Luner,
00032  *               Lukas Petru and Marek Przeczek.
00033  */
00034 
00035 #include "../prof/prof.h"
00036 #include "../delay/delay.h"
00037 
00038 #ifdef _DEBUG
00039 
00040 #include "../shared/classField.h"
00041 #include "../shared/groupThread.h"
00042 #include "../alloc/allocArena.h"
00043 #include "../alloc/allocObject.h"
00044 #include "../alloc/allocTrace.h"
00045 #include "../shared/traceFrame.h"
00046 #include "../alloc/allocInstance.h"
00047 #include "../gc/gc.h"
00048 #include "../alloc/allocGlobalRef.h"
00049 #include "../alloc/allocObjectMethod.h"
00050 #include "../alloc/allocThreadObject.h"
00051 #include "../alloc/allocThreadObjectMethod.h"
00052 #include "../alloc/allocThreadMethod.h"
00053 #include "../cpu/cpuThreadMethod.h"
00054 #include "../mon/monThreadMethod.h"
00055 
00056 static int printMethod( Method* m, void**) {
00057         
00058         cout << m->methodName << " SIGN = " << m->methodSignature << endl;
00059         return 0;
00060 }
00061 
00062 static int printField( ClassField* f, void**) {
00063         
00064         cout << f->fieldName << " SIGN = " << f->fieldSignature << endl;
00065         return 0;
00066 }
00067 
00068 static int printClass( Class* c, void**) {
00069         
00070         cout << "CLASS = " << c->className << endl << endl;
00071         
00072         cout << "METHODS:" << endl;
00073         c->methods.forEach( printMethod, NULL);
00074         cout << endl;
00075         
00076         cout << "INSTANCE FIELDS:" << endl;
00077         c->instances.forEach( printField, NULL);
00078         cout << endl;
00079 
00080         cout << "STATIC FIELDS:" << endl;
00081         c->statics.forEach( printField, NULL);
00082         cout << endl;
00083 
00084         return 0;
00085 }
00086 
00087 static int printThread( Thread* t, void**) {
00088         
00089         cout << t->threadName << " : " << (long)(t->threadEnvId) << endl;
00090         return 0;
00091 }
00092 
00093 static int printGroup( GroupThread* g, void**) {
00094         
00095         cout << "GROUP = " << g->groupName << endl;
00096         g->threads.forEach( printThread, NULL);
00097         cout << endl;
00098 
00099         return 0;
00100 }
00101 
00102 static int printArena( AllocArena* a, void**) {
00103         
00104         cout << "ARENA = " << a->arenaName << endl << endl;
00105         return 0;
00106 }
00107 
00108 static int printObject( AllocObject* o, void**) {
00109         
00110         cout << "OBJECT TYPE:" << endl;
00111         if( o->clss) cout << "CLASS = " << o->clss->className << endl;
00112 
00113         String s;
00114         switch( o->isArray) {
00115         case JVMPI_NORMAL_OBJECT:
00116                 s = "JVMPI_NORMAL_OBJECT";
00117                 break;
00118         case JVMPI_CLASS:
00119                 s = "JVMPI_CLASS";
00120                 break;
00121         case JVMPI_BOOLEAN:
00122                 s = "JVMPI_BOOLEAN";
00123                 break;
00124         case JVMPI_BYTE:
00125                 s = "JVMPI_BYTE";
00126                 break;
00127         case JVMPI_CHAR:
00128                 s = "JVMPI_CHAR";
00129                 break;
00130         case JVMPI_SHORT:
00131                 s = "JVMPI_SHORT";
00132                 break;
00133         case JVMPI_INT:
00134                 s = "JVMPI_INT";
00135                 break;
00136         case JVMPI_LONG:
00137                 s = "JVMPI_LONG";
00138                 break;
00139         case JVMPI_FLOAT:
00140                 s = "JVMPI_FLOAT";
00141                 break;
00142         case JVMPI_DOUBLE:
00143                 s = "JVMPI_DOUBLE";
00144                 break;
00145         }
00146         
00147         cout << "IS_ARRAY = " << s << endl;
00148         cout << endl;
00149 
00150         return 0;
00151 }
00152 
00153 static int printAllocTrace( AllocTrace* at, void**) {
00154         
00155         cout << "ALLOC_TRACE:" << endl;
00156         for( int i = 0; i < at->numFrames; i++) {
00157 
00158                 cout << "method:       " << at->frames[i].method->methodName << endl;
00159                 cout << "method sign:  " << at->frames[i].method->methodSignature << endl;
00160                 cout << "method class: " << at->frames[i].method->clss->className << endl;
00161                 cout << "lineno: " << at->frames[i].lineno << endl << endl;
00162         }
00163 
00164         return 0;
00165 }
00166 
00167 static int printInstance( AllocInstance* ins, void**) {
00168         
00169         cout << "INSTANCE:" << endl;
00170         cout << "id:   " << ins->objId << endl;
00171         cout << "size: " << ins->size << endl;
00172         cout << endl;
00173 
00174         return 0;
00175 }
00176 
00177 static int printGC( GC* gc, void**) {
00178         
00179         cout << "GC:" << endl;
00180         cout << "start: " << ctime( &gc->startTime) << endl;
00181         cout << "end:   " << ctime( &gc->endTime) << endl;
00182         cout << endl;
00183 
00184         return 0;
00185 }
00186 
00187 static int printGlobalRefs( AllocGlobalRef* r, void**) {
00188 
00189         cout << "JNI (WEAK) GLOBALREF:" << endl;
00190         printInstance( r->instance, NULL);
00191         cout << "reference id: " << r->refId << endl;
00192         cout << endl;
00193 
00194         return 0;
00195 }
00196 
00197 static void printHashStatistics() {
00198 
00199         Prof* _prof = &Prof::prof();
00200 
00201         cout << "HASH TABLE STATISTICS:" << endl;
00202         cout << endl;
00203 
00204         cout << "activeClasses:" << endl;
00205         _prof->activeClasses.printStatistics(); 
00206         cout << endl;
00207 
00208         cout << "activeMethods:" << endl;
00209         _prof->activeMethods.printStatistics(); 
00210         cout << endl;
00211 
00212         cout << "activeCpuThreadMethods:" << endl;
00213         _prof->activeCpuThreadMethods.printStatistics(); 
00214         cout << endl;
00215 
00216         cout << "activeCpuTraces:" << endl;
00217         _prof->activeCpuTraces.printStatistics(); 
00218         cout << endl;
00219 
00220         cout << "activeCpuThreadTraces:" << endl;
00221         _prof->activeCpuThreadTraces.printStatistics(); 
00222         cout << endl;
00223 
00224         cout << "instances:" << endl;
00225         _prof->instances.printStatistics(); 
00226         cout << endl;
00227 }
00228 
00229 static void printTotals() {
00230 
00231         Prof* _prof = &Prof::prof();
00232 
00233         long totalClasses = 0;
00234         long totalMethods = 0;
00235         long totalAllocTraces = 0;
00236         long totalAllocObjects = 0;
00237         long totalAllocObjectMethods = 0;
00238         long totalAllocObjectTraces = 0;
00239         long totalThreads = 0;
00240         long totalAllocThreadObjects = 0;
00241         long totalAllocThreadObjectMethods = 0;
00242         long totalAllocThreadObjectTraces = 0;
00243         long totalAllocThreadMethods = 0;
00244         long totalAllocThreadTraces = 0;
00245         long totalCpuTraces = 0;
00246         long totalCpuThreadMethods = 0;
00247         long totalCpuThreadTraces = 0;
00248         long totalMonTraces = 0;
00249         long totalMonThreadMethods = 0;
00250         long totalMonThreadTraces = 0;
00251 
00252         Class* c = _prof->classes.first();
00253         while (c) {
00254 
00255                 Method* m = c->methods.first();
00256                 while (m) {
00257 
00258                         AllocTrace* at = m->allocTraces.first();
00259                         while (at) {
00260 
00261                                 totalAllocTraces++;
00262                                 at = m->allocTraces.next(at);
00263                         }
00264 
00265                         CpuTrace* ct = m->cpuTraces.first();
00266                         while (ct) {
00267 
00268                                 totalCpuTraces++;
00269                                 ct = m->cpuTraces.next(ct);
00270                         }
00271 
00272                         MonTrace* mt = m->monTraces.first();
00273                         while (mt) {
00274 
00275                                 totalMonTraces++;
00276                                 mt = m->monTraces.next(mt);
00277                         }
00278 
00279                         totalMethods++;
00280                         m = c->methods.next(m);
00281                 }
00282 
00283                 totalClasses++;
00284                 c = _prof->classes.next(c);
00285         }
00286 
00287         AllocObject* ao = _prof->allocObjects.first();
00288         while (ao) {
00289 
00290                 AllocObjectMethod *aom = ao->objectMethods.first();
00291                 while (aom) {
00292 
00293                         AllocObjectTrace* aot = aom->objectTraces.first();
00294                         while (aot) {
00295 
00296                                 totalAllocObjectTraces++;
00297                                 aot = aom->objectTraces.next(aot);
00298                         }
00299 
00300                         totalAllocObjectMethods++;
00301                         aom = ao->objectMethods.next(aom);
00302                 }
00303 
00304                 totalAllocObjects++;
00305                 ao = _prof->allocObjects.next(ao);
00306         }
00307 
00308         Thread* t = _prof->threads.first();
00309         while (t) {
00310 
00311                 AllocThreadObject* ato = t->allocThreadObjects.first();
00312                 while (ato) {
00313 
00314                         AllocThreadObjectMethod* atom = ato->threadObjectMethods.first();
00315                         while (atom) {
00316 
00317                                 AllocThreadObjectTrace* atot = atom->threadObjectTraces.first();
00318                                 while (atot) {
00319 
00320                                         totalAllocThreadObjectTraces++;
00321                                         atot = atom->threadObjectTraces.next(atot);
00322                                 }
00323 
00324                                 totalAllocThreadObjectMethods++;
00325                                 atom = ato->threadObjectMethods.next(atom);
00326                         }
00327 
00328                         totalAllocThreadObjects++;
00329                         ato = t->allocThreadObjects.next(ato);
00330                 }
00331 
00332                 AllocThreadMethod* atm = t->allocThreadMethods.first();
00333                 while (atm) {
00334 
00335                         AllocThreadTrace* att = atm->threadTraces.first();
00336                         while (att) {
00337 
00338                                 totalAllocThreadTraces++;
00339                                 att = atm->threadTraces.next(att);
00340                         }
00341 
00342                         totalAllocThreadMethods++;
00343                         atm = t->allocThreadMethods.next(atm);
00344                 }
00345 
00346                 CpuThreadMethod* ctm = t->cpuThreadMethods.first();
00347                 while (ctm) {
00348 
00349                         CpuThreadTrace* ctt = ctm->threadTraces.first();
00350                         while (ctt) {
00351 
00352                                 totalCpuThreadTraces++;
00353                                 ctt = ctm->threadTraces.next(ctt);
00354                         }
00355 
00356                         totalCpuThreadMethods++;
00357                         ctm = t->cpuThreadMethods.next(ctm);
00358                 }
00359 
00360                 MonThreadMethod* mtm = t->monThreadMethods.first();
00361                 while (mtm) {
00362 
00363                         MonThreadTrace* mtt = mtm->threadTraces.first();
00364                         while (mtt) {
00365 
00366                                 totalMonThreadTraces++;
00367                                 mtt = mtm->threadTraces.next(mtt);
00368                         }
00369 
00370                         totalMonThreadMethods++;
00371                         mtm = t->monThreadMethods.next(mtm);
00372                 }
00373 
00374                 totalThreads++;
00375                 t = _prof->threads.next(t);
00376         }
00377 
00378         cout << "TOTALS:" << endl;
00379         cout << endl;
00380 
00381         cout << "Classes: " << totalClasses << endl;
00382         cout << "Methods: " << totalMethods << endl;
00383         cout << "Threads: " << totalThreads << endl;
00384         cout << endl;
00385 
00386         cout << "AllocObject: " << totalAllocObjects << endl;
00387         cout << "AllocThreadObject: " << totalAllocThreadObjects << endl;
00388         cout << endl;
00389 
00390         cout << "AllocObjectMethod: " << totalAllocObjectMethods << endl;
00391         cout << "AllocThreadMethod: " << totalAllocThreadMethods << endl;
00392         cout << "AllocThreadObjectMethod: " << totalAllocThreadObjectMethods << endl;
00393         cout << endl;
00394         
00395         cout << "AllocTrace: " << totalAllocTraces << endl;
00396         cout << "AllocObjectTrace: " << totalAllocObjectTraces << endl;
00397         cout << "AllocThreadTrace: " << totalAllocThreadTraces << endl;
00398         cout << "AllocThreadObjectTrace: " << totalAllocThreadObjectTraces << endl;
00399         cout << endl;
00400 
00401         cout << "CpuThreadMethod: " << totalCpuThreadMethods << endl;
00402         cout << endl;
00403 
00404         cout << "CpuTrace: " << totalCpuTraces << endl;
00405         cout << "CpuThreadTrace: " << totalCpuThreadTraces << endl;
00406         cout << endl;
00407 
00408         cout << "MonThreadMethod: " << totalMonThreadMethods << endl;
00409         cout << endl;
00410 
00411         cout << "MonTrace: " << totalMonTraces << endl;
00412         cout << "MonThreadTrace: " << totalMonThreadTraces << endl;
00413         cout << endl;
00414 }
00415 
00416 static void printSampling() {
00417 
00418         unsigned long start = Prof::prof().sampling.start;
00419         unsigned long finish = Prof::prof().sampling.finish;
00420         unsigned long samples = Prof::prof().sampling.samples;
00421 
00422         cout << "SAMPLING:" << endl << endl;
00423         cout << "start: " << start << " ms" << endl;  
00424         cout << "finish: " << finish << " ms" << endl;  
00425         cout << "samples: " << samples << endl;  
00426 
00427         if ((samples > 0) && (finish > start)) 
00428                 cout << "period: " << (double)(finish - start) / (double)samples << " ms" << endl;  
00429 
00430         cout << endl;
00431 }
00432 #endif // _DEBUG
00433 
00434 void Prof::event_jvmInitDone( JVMPI_Event* event) {
00435 
00436         // enable some curious events ;-)
00437 
00438         jvmpiInterface->EnableEvent( JVMPI_EVENT_THREAD_START, NULL);
00439         jvmpiInterface->EnableEvent( JVMPI_EVENT_CLASS_LOAD,   NULL);
00440 
00441         if( setup.alloc.turnedOn) jvmpiInterface->EnableEvent( JVMPI_EVENT_ARENA_NEW, NULL);
00442 
00443         jvmpiInterface->EnableEvent ( JVMPI_EVENT_JVM_SHUT_DOWN, NULL);
00444         jvmpiInterface->DisableEvent( JVMPI_EVENT_JVM_INIT_DONE, NULL);
00445 
00446         if( setup.cpu.turnedOn && setup.cpu.sampling) sampling.startThread( 1);
00447 
00448         jvmpiInterface->CreateSystemThread( (char*)COMMUN_THREAD,
00449                 JVMPI_NORMAL_PRIORITY,
00450                 Prof::communThreadRoutine);
00451 }
00452 
00453 void Prof::event_jvmShutDown( JVMPI_Event* event) {
00454 
00455         if( isConnectionEstablished()) {
00456 
00457                 communLock.wait();
00458                 dataLock.wait();
00459         }
00460 
00461         if( setup.cpu.turnedOn && setup.cpu.sampling) sampling.terminateThread();
00462         shuttingDown = 1;
00463 
00464         if( isConnectionEstablished()) {
00465 
00466                 communLock.release();
00467                 shutdownLock.wait();
00468                 communLock.wait();
00469         }
00470         else communThreadEnd = 1;
00471 
00472 #ifdef _DEBUG
00473         classes.forEach( printClass, NULL);
00474         groupsOfThreads.forEach( printGroup, NULL);
00475         allocObjects.forEach( printObject, NULL);
00476         arenas.forEach( printArena, NULL);
00477         instances.forEach( printInstance, NULL);
00478         gcStat.forEach( printGC, NULL);
00479         jniGlobalRefs.forEach( printGlobalRefs, NULL);
00480         jniWeakGlobalRefs.forEach( printGlobalRefs, NULL);
00481         printHashStatistics();
00482         printTotals();
00483         printSampling();
00484 #endif
00485 
00486         // that's amazing ! must be called in reverse order ;-)
00487 
00488         jvmpiInterface->DisableEvent( JVMPI_EVENT_CLASS_UNLOAD, NULL);
00489         jvmpiInterface->DisableEvent( JVMPI_EVENT_CLASS_LOAD,   NULL);
00490 
00491         jvmpiInterface->DisableEvent( JVMPI_EVENT_METHOD_EXIT,  NULL);
00492         jvmpiInterface->DisableEvent( JVMPI_EVENT_METHOD_ENTRY, NULL);
00493 
00494         jvmpiInterface->DisableEvent( JVMPI_EVENT_THREAD_END,   NULL);
00495         jvmpiInterface->DisableEvent( JVMPI_EVENT_THREAD_START, NULL);
00496 
00497         jvmpiInterface->DisableEvent( JVMPI_EVENT_GC_FINISH, NULL);
00498         jvmpiInterface->DisableEvent( JVMPI_EVENT_GC_START,  NULL);
00499 
00500         jvmpiInterface->DisableEvent( JVMPI_EVENT_ARENA_DELETE, NULL);
00501         jvmpiInterface->DisableEvent( JVMPI_EVENT_ARENA_NEW,    NULL);
00502 
00503         jvmpiInterface->DisableEvent( JVMPI_EVENT_OBJECT_FREE,  NULL);
00504         jvmpiInterface->DisableEvent( JVMPI_EVENT_OBJECT_MOVE,  NULL);
00505         jvmpiInterface->DisableEvent( JVMPI_EVENT_OBJECT_ALLOC, NULL);
00506 
00507         jvmpiInterface->DisableEvent( JVMPI_EVENT_JNI_GLOBALREF_FREE,  NULL);
00508         jvmpiInterface->DisableEvent( JVMPI_EVENT_JNI_GLOBALREF_ALLOC, NULL);
00509 
00510         jvmpiInterface->DisableEvent( JVMPI_EVENT_JNI_WEAK_GLOBALREF_FREE,  NULL);
00511         jvmpiInterface->DisableEvent( JVMPI_EVENT_JNI_WEAK_GLOBALREF_ALLOC, NULL);
00512 
00513         jvmpiInterface->DisableEvent( JVMPI_EVENT_MONITOR_WAITED,            NULL);
00514         jvmpiInterface->DisableEvent( JVMPI_EVENT_MONITOR_CONTENDED_ENTERED, NULL);
00515         jvmpiInterface->DisableEvent( JVMPI_EVENT_MONITOR_CONTENDED_ENTER,   NULL);
00516 
00517         jvmpiInterface->DisableEvent( JVMPI_EVENT_JVM_SHUT_DOWN, NULL);
00518 
00519         dataLock.release();
00520 
00521         while( !sampling.isTerminated()) Delay::delay( 10);
00522         Delay::delay( 1000);
00523 
00524         dataLock.wait();
00525 
00526         Prof::destroy();
00527         exit( 0); // for sure
00528 }

Generated on Mon Jan 28 14:53:27 2002 for Java Profiler Dynamic Library by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001