|
From: Petr L. <lu...@us...> - 2001-08-24 17:54:08
|
Update of /cvsroot/javaprofiler/library/src/prof
In directory usw-pr-cvs1:/tmp/cvs-serv4667/prof
Modified Files:
Makefile.rules dir.info prof.cpp prof.h prof_get.cpp
prof_jvm.cpp
Added Files:
prof_monitor.cpp
Log Message:
Monitor profiling
--- NEW FILE: prof_monitor.cpp ---
#include "../main/includes.h"
void Prof::event_monitorContendedEnter( JVMPI_Event* event) {
Synchronized sync(dataLock);
// cerr << "MONITOR CONTENDED ENTER: " << (long)(event->env_id) << endl;
Thread* t;
if (!(t = getThread(event->env_id))) {
PROF_ERROR("MONITOR CONTENDED ENTER", "Thread not found");
return;
}
t->monitorEnter = 1;
t->monitorEnterObject = event->u.monitor.object;
t->monitorEnterTime = getMilliticks();
}
void Prof::event_monitorContendedEntered( JVMPI_Event* event) {
Synchronized sync(dataLock);
// cerr << "MONITOR CONTENDED ENTERED: " << (long)(event->env_id) << endl;
Thread* t;
if (!(t = getThread(event->env_id))) {
PROF_ERROR("MONITOR CONTENDED ENTERED", "Thread not found");
return;
}
if ((!(t->monitorEnter)) || (t->monitorEnterObject != event->u.monitor.object)) {
PROF_ERROR("MONITOR CONTENDED ENTERED", "No corresponding MONITOR CONTENDED ENTER");
t->monitorEnter = 0;
return;
}
t->monitorEnter = 0;
unsigned long curTime = getMilliticks();
if (curTime < t->monitorEnterTime) return;
int numFrames = 1;
if (setup.mon.level == Setup::LEVEL_TRACE) numFrames = setup.mon.traceDepth;
JVMPI_CallTrace callTrace;
JVMPI_CallFrame callFrames[MAX_TRACE];
callTrace.env_id = event->env_id;
callTrace.num_frames = (jint)numFrames;
callTrace.frames = callFrames;
jvmpiInterface->GetCallTrace(&callTrace, (jint)numFrames);
numFrames = callTrace.num_frames;
if (numFrames == 0) {
PROF_ERROR("MONITOR CONTENDED ENTERED", "GetCallTrace failed");
return;
}
MonStatData* stat;
if (setup.mon.threadsEnabled) {
if (setup.mon.level == Setup::LEVEL_METHOD) {
if (!(stat = getMonThreadMethod(event->env_id, callFrames[0].method_id))) {
PROF_ERROR("MONITOR CONTENDED ENTERED", "Cannot get MonThreadMethod");
return;
}
}
else {
if (!(stat = getMonThreadTrace(event->env_id, numFrames, callFrames))) {
PROF_ERROR("MONITOR CONTENDED ENTERED", "Cannot get MonThreadTrace");
return;
}
}
}
else {
if (setup.mon.level == Setup::LEVEL_METHOD) {
if (!(stat = getMethod(callFrames[0].method_id))) {
PROF_ERROR("MONITOR CONTENDED ENTERED", "Method not found");
return;
}
}
else {
if (!(stat = getMonTrace(numFrames, callFrames))) {
PROF_ERROR("MONITOR CONTENDED ENTERED", "Cannot get MonTrace");
return;
}
}
}
int hits = (stat->wait) ? 0 : 1;
stat->addMonStat(hits, curTime - t->monitorEnterTime);
}
void Prof::event_monitorWaited( JVMPI_Event* event) {
Synchronized sync(dataLock);
// cerr << "MONITOR WAITED: " << (long)(event->env_id) << endl;
Thread* t;
if (!(t = getThread(event->env_id))) {
PROF_ERROR("MONITOR WAITED", "Thread not found");
return;
}
int numFrames = 1;
if (setup.mon.level == Setup::LEVEL_TRACE) numFrames = setup.mon.traceDepth;
JVMPI_CallTrace callTrace;
JVMPI_CallFrame callFrames[MAX_TRACE];
callTrace.env_id = event->env_id;
callTrace.num_frames = (jint)numFrames;
callTrace.frames = callFrames;
jvmpiInterface->GetCallTrace(&callTrace, (jint)numFrames);
numFrames = callTrace.num_frames;
if (numFrames == 0) {
PROF_ERROR("MONITOR WAITED", "GetCallTrace failed");
return;
}
MonStatData* stat;
if (setup.mon.threadsEnabled) {
if (setup.mon.level == Setup::LEVEL_METHOD) {
if (!(stat = getMonThreadMethod(event->env_id, callFrames[0].method_id))) {
PROF_ERROR("MONITOR WAITED", "Cannot get MonThreadMethod");
return;
}
}
else {
if (!(stat = getMonThreadTrace(event->env_id, numFrames, callFrames))) {
PROF_ERROR("MONITOR WAITED", "Cannot get MonThreadTrace");
return;
}
}
}
else {
if (setup.mon.level == Setup::LEVEL_METHOD) {
if (!(stat = getMethod(callFrames[0].method_id))) {
PROF_ERROR("MONITOR WAITED", "Method not found");
return;
}
}
else {
if (!(stat = getMonTrace(numFrames, callFrames))) {
PROF_ERROR("MONITOR WAITED", "Cannot get MonTrace");
return;
}
}
}
stat->wait = 1;
stat->addMonStat(1, event->u.monitor_wait.timeout);
}
Index: Makefile.rules
===================================================================
RCS file: /cvsroot/javaprofiler/library/src/prof/Makefile.rules,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -r1.2 -r1.3
*** Makefile.rules 2001/07/22 23:37:58 1.2
--- Makefile.rules 2001/08/24 17:54:04 1.3
***************
*** 38,39 ****
--- 38,43 ----
prof_method.obj: prof_method.cpp ../main/includes.h
$(CCC) $(CPPFLAGS) prof_method.cpp
+
+ prof_monitor.o \
+ prof_monitor.obj: prof_monitor.cpp ../main/includes.h
+ $(CCC) $(CPPFLAGS) prof_monitor.cpp
Index: dir.info
===================================================================
RCS file: /cvsroot/javaprofiler/library/src/prof/dir.info,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** dir.info 2001/07/28 04:11:17 1.4
--- dir.info 2001/08/24 17:54:04 1.5
***************
*** 1,4 ****
FILES = prof prof_arena prof_class prof_gc prof_get prof_jniref prof_jvm \
! prof_method prof_object prof_thread
CLEAN_FILES = *.pdb *.obj *.o
--- 1,4 ----
FILES = prof prof_arena prof_class prof_gc prof_get prof_jniref prof_jvm \
! prof_method prof_monitor prof_object prof_thread
CLEAN_FILES = *.pdb *.obj *.o
Index: prof.cpp
===================================================================
RCS file: /cvsroot/javaprofiler/library/src/prof/prof.cpp,v
retrieving revision 1.21
retrieving revision 1.22
diff -C2 -r1.21 -r1.22
*** prof.cpp 2001/08/23 23:57:31 1.21
--- prof.cpp 2001/08/24 17:54:04 1.22
***************
*** 36,45 ****
tF( 19, JVMPI_EVENT_METHOD_ENTRY2, NULL);
tF( 20, JVMPI_EVENT_METHOD_EXIT, &Prof::event_methodExit);
! tF( 21, JVMPI_EVENT_MONITOR_CONTENDED_ENTER, NULL);
! tF( 22, JVMPI_EVENT_MONITOR_CONTENDED_ENTERED, NULL);
tF( 23, JVMPI_EVENT_MONITOR_CONTENDED_EXIT, NULL);
tF( 24, JVMPI_EVENT_MONITOR_DUMP, NULL);
tF( 25, JVMPI_EVENT_MONITOR_WAIT, NULL);
! tF( 26, JVMPI_EVENT_MONITOR_WAITED, NULL);
tF( 27, JVMPI_EVENT_OBJECT_ALLOC, &Prof::event_objectAlloc);
tF( 28, JVMPI_EVENT_OBJECT_DUMP, NULL);
--- 36,45 ----
tF( 19, JVMPI_EVENT_METHOD_ENTRY2, NULL);
tF( 20, JVMPI_EVENT_METHOD_EXIT, &Prof::event_methodExit);
! tF( 21, JVMPI_EVENT_MONITOR_CONTENDED_ENTER, &Prof::event_monitorContendedEnter);
! tF( 22, JVMPI_EVENT_MONITOR_CONTENDED_ENTERED, &Prof::event_monitorContendedEntered);
tF( 23, JVMPI_EVENT_MONITOR_CONTENDED_EXIT, NULL);
tF( 24, JVMPI_EVENT_MONITOR_DUMP, NULL);
tF( 25, JVMPI_EVENT_MONITOR_WAIT, NULL);
! tF( 26, JVMPI_EVENT_MONITOR_WAITED, &Prof::event_monitorWaited);
tF( 27, JVMPI_EVENT_OBJECT_ALLOC, &Prof::event_objectAlloc);
tF( 28, JVMPI_EVENT_OBJECT_DUMP, NULL);
***************
*** 78,81 ****
--- 78,97 ----
prof().shutdownLock.wait();
while( !communThreadEnd) prof().run();
+ }
+
+ unsigned long Prof::getMilliticks() {
+
+ #ifdef WIN32
+
+ return timeGetTime();
+
+ #else
+
+ struct timeval tv;
+
+ gettimeofday(&tv, NULL);
+ return (((unsigned long)tv.tv_sec * (unsigned long)1000) + ((unsigned long)tv.tv_usec / (unsigned long)1000));
+
+ #endif
}
Index: prof.h
===================================================================
RCS file: /cvsroot/javaprofiler/library/src/prof/prof.h,v
retrieving revision 1.31
retrieving revision 1.32
diff -C2 -r1.31 -r1.32
*** prof.h 2001/08/23 23:57:31 1.31
--- prof.h 2001/08/24 17:54:04 1.32
***************
*** 138,141 ****
--- 138,150 ----
Hash<CpuThreadTrace,CpuThreadTraceKey,LI1> activeCpuThreadTraces;
+ /// hash table of active MonTraces
+ Hash<MonTrace,TraceKey,LI1> activeMonTraces;
+
+ /// hash table of active MonThreadMethods
+ Hash<MonThreadMethod,MonThreadMethodKey,LI1> activeMonThreadMethods;
+
+ /// hash table of active MonThreadTraces
+ Hash<MonThreadTrace,MonThreadTraceKey,LI1> activeMonThreadTraces;
+
public:
***************
*** 366,369 ****
--- 375,418 ----
CpuThreadTrace* getCpuThreadTrace(JNIEnv* envId, int numFrames, JVMPI_CallFrame* frames, int create = 1);
+ /** Returns corresponding MonTrace object.
+ ** If none exists and the 'create' flag is set to 1
+ ** the function attempts to construct one.
+ ** If unsuccessful in either case the NULL is returned.
+ **
+ ** @param numFrames number of call frames
+ ** @param frames array of call frames
+ ** @param create creation flag
+ **
+ ** @return pointer to MonTrace object or NULL */
+
+ MonTrace* getMonTrace(int numFrames, JVMPI_CallFrame* frames, int create = 1);
+
+ /** Returns corresponding MonThreadMethod object.
+ ** If none exists and the 'create' flag is set to 1
+ ** the function attempts to construct one.
+ ** If unsuccessful in either case the NULL is returned.
+ **
+ ** @param envId thread ID
+ ** @param methodId method ID
+ ** @param create creation flag
+ **
+ ** @return pointer to MonThreadMethod object or NULL */
+
+ MonThreadMethod* getMonThreadMethod(JNIEnv* envId, jmethodID methodId, int create = 1);
+
+ /** Returns corresponding MonThreadTrace object.
+ ** If none exists and the 'create' flag is set to 1
+ ** the function attempts to construct one.
+ ** If unsuccessful in either case the NULL is returned.
+ **
+ ** @param envId thread ID
+ ** @param numFrames number of call frames
+ ** @param frames array of call frames
+ ** @param create creation flag
+ **
+ ** @return pointer to MonThreadTrace object or NULL */
+
+ MonThreadTrace* getMonThreadTrace(JNIEnv* envId, int numFrames, JVMPI_CallFrame* frames, int create = 1);
+
private:
***************
*** 532,535 ****
--- 581,632 ----
void event_methodExit ( JVMPI_Event* event);
+ /** Monitor contended enter.
+ ** This method is a JVMPI_EVENT_MONITOR_CONTENDED_ENTER
+ ** event handler. This event is sent when a thread is
+ ** attemping to enter a Java monitor already acquired
+ ** by another thread.
+ ** It is issued with GC disabled. GC is re-enabled after
+ ** this method returns.
+ ** Here only the current time before the thread starts
+ ** waiting on the monitor is recorded.
+ **
+ ** @param event JVMPI_Event structure describing the event
+ **
+ ** @see runEvent(), JVMPI specification */
+
+ void event_monitorContendedEnter( JVMPI_Event* event);
+
+ /** Monitor contended entered.
+ ** This method is a JVMPI_EVENT_MONITOR_CONTENDED_ENTERED
+ ** event handler. This event is sent when a thread enters
+ ** a Java monitor after waiting for it to be released by
+ ** another thread.
+ ** It is issued with GC disabled. GC is re-enabled after
+ ** this method returns.
+ ** Here the total time the thread spent by waiting
+ ** on the monitor is determined and recorded to
+ ** appriate structures.
+ **
+ ** @param event JVMPI_Event structure describing the event
+ **
+ ** @see runEvent(), JVMPI specification */
+
+ void event_monitorContendedEntered( JVMPI_Event* event);
+
+ /** Monitor waited.
+ ** This method is a JVMPI_EVENT_MONITOR_WAITED
+ ** event handler. This event is sent when a thread
+ ** finishes waiting on an object.
+ ** It is issued with GC disabled. GC is re-enabled after
+ ** this method returns.
+ ** Here the total time the thread has waited is recored
+ ** to appropriate structures.
+ **
+ ** @param event JVMPI_Event structure describing the event
+ **
+ ** @see runEvent(), JVMPI specification */
+
+ void event_monitorWaited( JVMPI_Event* event);
+
/** Object alloc. This method is a JVMPI_EVENT_OBJECT_ALLOC
** event handler. This event is sent when an object is allocated.
***************
*** 819,822 ****
--- 916,925 ----
public:
+
+ /** Gets current milliticks.
+ **
+ ** @return ticks in milliseconds */
+
+ unsigned long getMilliticks();
/** Dumps error.
Index: prof_get.cpp
===================================================================
RCS file: /cvsroot/javaprofiler/library/src/prof/prof_get.cpp,v
retrieving revision 1.5
retrieving revision 1.6
diff -C2 -r1.5 -r1.6
*** prof_get.cpp 2001/08/04 13:53:37 1.5
--- prof_get.cpp 2001/08/24 17:54:04 1.6
***************
*** 397,399 ****
--- 397,492 ----
}
+ MonTrace* Prof::getMonTrace(int numFrames, JVMPI_CallFrame* frames, int create) {
+
+ TraceKey key;
+ MonTrace* trace;
+
+ key.numFrames = numFrames;
+ key.frames = frames;
+
+ if (trace = activeMonTraces.get(key)) return trace;
+ if (!create) return NULL;
+
+ TraceFrame* traceFrames = TraceFrame::newArray(numFrames);
+ Method *method;
+
+ for (int i = 0; i < numFrames; i++) {
+ if (!(method = getMethod(frames[i].method_id))) {
+ TraceFrame::deleteArray(traceFrames, numFrames);
+ return NULL;
+ }
+ traceFrames[i].method = method;
+ traceFrames[i].lineno = frames[i].lineno;
+ }
+
+ trace = new MonTrace;
+
+ trace->method = traceFrames[0].method;
+ trace->numFrames = numFrames;
+ trace->frames = traceFrames;
+
+ activeMonTraces.add(trace);
+ trace->method->monTraces.add(trace);
+
+ return trace;
+ }
+
+ MonThreadMethod* Prof::getMonThreadMethod(JNIEnv* envId, jmethodID methodId, int create) {
+
+ MonThreadMethodKey key;
+ MonThreadMethod* threadMethod;
+
+ key.envId = envId;
+ key.methodId = methodId;
+
+ if (threadMethod = activeMonThreadMethods.get(key)) return threadMethod;
+ if (!create) return NULL;
+
+ Method* method;
+ Thread* thread;
+
+ if (!(method = getMethod(methodId))) return NULL;
+ if (!(thread = getThread(envId))) return NULL;
+
+ threadMethod = new MonThreadMethod;
+
+ threadMethod->method = method;
+ threadMethod->thread = thread;
+
+ activeMonThreadMethods.add(threadMethod);
+ method->monThreadMethods.add(threadMethod);
+ thread->monThreadMethods.add(threadMethod);
+
+ return threadMethod;
+ }
+
+ MonThreadTrace* Prof::getMonThreadTrace(JNIEnv* envId, int numFrames, JVMPI_CallFrame* frames, int create) {
+
+ MonThreadTraceKey key;
+ MonThreadTrace* threadTrace;
+
+ key.envId = envId;
+ key.traceKey.numFrames = numFrames;
+ key.traceKey.frames = frames;
+
+ if (threadTrace = activeMonThreadTraces.get(key)) return threadTrace;
+ if (!create) return NULL;
+
+ MonThreadMethod* threadMethod;
+ MonTrace* trace;
+
+ if (!(threadMethod = getMonThreadMethod(envId, frames[0].method_id))) return NULL;
+ if (!(trace = getMonTrace(numFrames, frames))) return NULL;
+
+ threadTrace = new MonThreadTrace;
+
+ threadTrace->threadMethod = threadMethod;
+ threadTrace->trace = trace;
+
+ activeMonThreadTraces.add(threadTrace);
+ threadMethod->threadTraces.add(threadTrace);
+ trace->threadTraces.add(threadTrace);
+
+ return threadTrace;
+ }
Index: prof_jvm.cpp
===================================================================
RCS file: /cvsroot/javaprofiler/library/src/prof/prof_jvm.cpp,v
retrieving revision 1.18
retrieving revision 1.19
diff -C2 -r1.18 -r1.19
*** prof_jvm.cpp 2001/08/23 23:57:31 1.18
--- prof_jvm.cpp 2001/08/24 17:54:04 1.19
***************
*** 198,201 ****
--- 198,204 ----
long totalCpuThreadMethods = 0;
long totalCpuThreadTraces = 0;
+ long totalMonTraces = 0;
+ long totalMonThreadMethods = 0;
+ long totalMonThreadTraces = 0;
Class* c = _prof->classes.first();
***************
*** 219,222 ****
--- 222,232 ----
}
+ MonTrace* mt = m->monTraces.first();
+ while (mt) {
+
+ totalMonTraces++;
+ mt = m->monTraces.next(mt);
+ }
+
totalMethods++;
m = c->methods.next(m);
***************
*** 300,303 ****
--- 310,327 ----
}
+ MonThreadMethod* mtm = t->monThreadMethods.first();
+ while (mtm) {
+
+ MonThreadTrace* mtt = mtm->threadTraces.first();
+ while (mtt) {
+
+ totalMonThreadTraces++;
+ mtt = mtm->threadTraces.next(mtt);
+ }
+
+ totalMonThreadMethods++;
+ mtm = t->monThreadMethods.next(mtm);
+ }
+
totalThreads++;
t = _prof->threads.next(t);
***************
*** 332,335 ****
--- 356,366 ----
cout << "CpuTrace: " << totalCpuTraces << endl;
cout << "CpuThreadTrace: " << totalCpuThreadTraces << endl;
+ cout << endl;
+
+ cout << "MonThreadMethod: " << totalMonThreadMethods << endl;
+ cout << endl;
+
+ cout << "MonTrace: " << totalMonTraces << endl;
+ cout << "MonThreadTrace: " << totalMonThreadTraces << endl;
cout << endl;
}
|