00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "xdprof.h"
00034
00036 MethodMap Methods;
00037
00039 ThreadMap Threads;
00040
00042 ClassMethopMap ClassMethods;
00043
00045 ClassInfoMap Classes;
00046
00048
00049 MethodMap MethodCache;
00050 ClassInfoMap ClassCache;
00051
00052
00054 static set<ThreadID> DeadThreads;
00055
00057
00058
00060 static bool CaughtVM = false;
00061
00062 static unsigned long threadcount = 0;
00063
00067 inline void ThreadStartHandler(ThreadID thread_id, const ThreadInfo & ti)
00068 {
00069 Lock(threads_lock);
00070 ti.setStarted(++threadcount);
00071 Threads[thread_id] = ti;
00072 Unlock(threads_lock);
00073 }
00074
00075 static void DeleteMethods()
00076 {
00077 for (MethodMap::iterator mi = Methods.begin(); mi != Methods.end(); ++mi)
00078 delete mi->second;
00079 }
00080
00084 inline void ThreadEndHandler(JNIEnv *thread_id)
00085 {
00086 Lock(threads_lock);
00088 debug("thread end", thread_id , Threads.size());
00089 int k = Threads.erase(thread_id);
00090 DeadThreads.insert(thread_id);
00091 assert(k == 1);
00092 debug("remove ", thread_id, k);
00093 Unlock(threads_lock);
00094 }
00095
00102 void NotifyEvent(JVMPI_Event *event)
00103 {
00104 switch(event->event_type)
00105 {
00106 case JVMPI_EVENT_CLASS_LOAD:
00107 case JVMPI_EVENT_CLASS_LOAD | JVMPI_REQUESTED_EVENT:
00108 Lock(methods_lock);
00109 ClassLoadEvent(event->env_id,
00110 const_cast<char**>(& event->u.class_load.class_name),
00111 &event->u.class_load.source_name,
00112 event->u.class_load.num_interfaces,
00113 event->u.class_load.num_static_fields,
00114 event->u.class_load.statics,
00115 event->u.class_load.num_instance_fields,
00116 event->u.class_load.instances,
00117 event->u.class_load.num_methods,
00118 event->u.class_load.methods,
00119 event->u.class_load.class_id,
00120 event->event_type);
00121 Unlock(methods_lock);
00122 return;
00123
00124 case JVMPI_EVENT_CLASS_UNLOAD:
00125 ClassUnloadEvent(event->u.class_unload.class_id);
00126 return;
00127
00128 case JVMPI_EVENT_THREAD_START:
00129 case JVMPI_EVENT_THREAD_START | JVMPI_REQUESTED_EVENT:
00130 {
00131 debug("threadstart: ", event->env_id, event->u.thread_start.thread_env_id, (event->u.thread_start.thread_name != null) ? event->u.thread_start.thread_name : "null");
00132 ThreadInfo ti(event->u.thread_start.thread_name,
00133 event->u.thread_start.group_name,
00134 event->u.thread_start.parent_name,
00135 event->u.thread_start.thread_id,
00136 event->u.thread_start.thread_env_id);
00137
00138 ThreadStartHandler(event->u.thread_start.thread_env_id, ti);
00139 }
00140 return;
00141
00142 case JVMPI_EVENT_THREAD_END:
00143
00144 ThreadEndHandler(event->env_id);
00145 return;
00146
00147 case JVMPI_EVENT_OBJECT_ALLOC:
00148 {
00149 if (event->u.obj_alloc.class_id == null)
00150 return;
00151
00152 debug("alloc", event->env_id, event->u.obj_alloc.class_id, event->u.obj_alloc.obj_id);
00153
00154
00155 if (!CaughtVM)
00156 {
00157
00158 Lock(threads_lock);
00159 bool loadThread = (Threads.find(event->env_id) == Threads.end()) &&
00160 (DeadThreads.find(event->env_id) == DeadThreads.end());
00161 Unlock(threads_lock);
00162
00163 if (loadThread)
00164 {
00165 jobjectID o = CALL(GetThreadObject)(event->env_id);
00166 if ((o != null) && (o != event->u.obj_alloc.obj_id))
00167 {
00168 debug("in alloc, about to call RequestEvent JVMPI_EVENT_THREAD_START" , o);
00169 CHECKEDCALL(RequestEvent(JVMPI_EVENT_THREAD_START, o));
00170 debug("back from thread start");
00171 CaughtVM = true;
00172 CHECKEDCALL(DisableEvent(JVMPI_EVENT_OBJECT_ALLOC, NULL));
00173 }
00174 }
00175 }
00176 else
00177 {
00178
00179
00180 }
00181 }
00182 return;
00183
00184 case JVMPI_EVENT_JVM_SHUT_DOWN:
00185 {
00186 ShutdownRequested = true;
00187 CALL(RawMonitorNotifyAll(BackgroundMonitor));
00188
00189
00190
00191
00192 ShutdownCommunications();
00193
00194
00195 ShutdownMonitors();
00196
00197 }
00198 return;
00199
00200 case JVMPI_EVENT_JVM_INIT_DONE:
00201 debug("Init done!!!", event->env_id );
00202 CreateBackgroundThread();
00203 return;
00204
00205
00206 default:
00207 unsafe_debug("Unhandled event", event->event_type);
00208 return;
00209 }
00210 }
00211
00212
00213