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
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "hprof.h"
00043
00044
00045
00046
00047 static TraceIndex
00048 get_current(TlsIndex tls_index, JNIEnv *env, jboolean skip_init)
00049 {
00050 TraceIndex trace_index;
00051
00052 trace_index = tls_get_trace(tls_index, env, gdata->max_trace_depth, skip_init);
00053 return trace_index;
00054 }
00055
00056
00057 static ClassIndex
00058 find_cnum(JNIEnv *env, jclass klass, jobject loader)
00059 {
00060 LoaderIndex loader_index;
00061 ClassIndex cnum;
00062 char * signature;
00063
00064 HPROF_ASSERT(klass!=NULL);
00065
00066
00067 loader_index = loader_find_or_create(env, loader);
00068
00069
00070 getClassSignature(klass, &signature, NULL);
00071
00072
00073 cnum = class_find_or_create(signature, loader_index);
00074
00075
00076 jvmtiDeallocate(signature);
00077
00078
00079 HPROF_ASSERT(cnum!=0);
00080 (void)class_new_classref(env, cnum, klass);
00081 return cnum;
00082 }
00083
00084
00085 static ClassIndex
00086 get_super(JNIEnv *env, jclass klass)
00087 {
00088 ClassIndex super_cnum;
00089
00090 super_cnum = 0;
00091 WITH_LOCAL_REFS(env, 1) {
00092 jclass super_klass;
00093
00094 super_klass = getSuperclass(env, klass);
00095 if ( super_klass != NULL ) {
00096 super_cnum = find_cnum(env, super_klass,
00097 getClassLoader(super_klass));
00098 }
00099 } END_WITH_LOCAL_REFS;
00100 return super_cnum;
00101 }
00102
00103
00104 static void
00105 any_allocation(JNIEnv *env, SerialNumber thread_serial_num,
00106 TraceIndex trace_index, jobject object)
00107 {
00108 SiteIndex site_index;
00109 ClassIndex cnum;
00110 jint size;
00111 jclass klass;
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 klass = getObjectClass(env, object);
00122 cnum = find_cnum(env, klass, getClassLoader(klass));
00123 site_index = site_find_or_create(cnum, trace_index);
00124 tag_class(env, klass, cnum, thread_serial_num, site_index);
00125
00126
00127 size = (jint)getObjectSize(object);
00128 tag_new_object(object, OBJECT_NORMAL, thread_serial_num, size, site_index);
00129 }
00130
00131
00132 void
00133 event_object_init(JNIEnv *env, jthread thread, jobject object)
00134 {
00135
00136
00137
00138
00139 jint *pstatus;
00140 TraceIndex trace_index;
00141 SerialNumber thread_serial_num;
00142
00143 HPROF_ASSERT(env!=NULL);
00144 HPROF_ASSERT(thread!=NULL);
00145 HPROF_ASSERT(object!=NULL);
00146
00147
00148 if ( tls_get_tracker_status(env, thread, JNI_TRUE,
00149 &pstatus, NULL, &thread_serial_num, &trace_index) == 0 ) {
00150 (*pstatus) = 1;
00151 any_allocation(env, thread_serial_num, trace_index, object);
00152 (*pstatus) = 0;
00153 }
00154 }
00155
00156
00157 void
00158 event_newarray(JNIEnv *env, jthread thread, jobject object)
00159 {
00160
00161
00162
00163
00164 jint *pstatus;
00165 TraceIndex trace_index;
00166 SerialNumber thread_serial_num;
00167
00168 HPROF_ASSERT(env!=NULL);
00169 HPROF_ASSERT(thread!=NULL);
00170 HPROF_ASSERT(object!=NULL);
00171
00172
00173 if ( tls_get_tracker_status(env, thread, JNI_FALSE,
00174 &pstatus, NULL, &thread_serial_num, &trace_index) == 0 ) {
00175 (*pstatus) = 1;
00176 any_allocation(env, thread_serial_num, trace_index, object);
00177 (*pstatus) = 0;
00178 }
00179 }
00180
00181
00182 void
00183 event_call(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum)
00184 {
00185
00186
00187
00188
00189 TlsIndex tls_index;
00190 jint *pstatus;
00191
00192 HPROF_ASSERT(env!=NULL);
00193 HPROF_ASSERT(thread!=NULL);
00194 HPROF_ASSERT(cnum!=0 && cnum!=gdata->tracker_cnum);
00195
00196
00197 if ( tls_get_tracker_status(env, thread, JNI_FALSE,
00198 &pstatus, &tls_index, NULL, NULL) == 0 ) {
00199 jmethodID method;
00200
00201 (*pstatus) = 1;
00202 method = class_get_methodID(env, cnum, mnum);
00203 HPROF_ASSERT(method!=NULL);
00204 tls_push_method(tls_index, method);
00205 (*pstatus) = 0;
00206 }
00207 }
00208
00209
00210 void
00211 event_exception_catch(JNIEnv *env, jthread thread, jmethodID method,
00212 jlocation location, jobject exception)
00213 {
00214
00215
00216
00217
00218 TlsIndex tls_index;
00219 jint *pstatus;
00220
00221 HPROF_ASSERT(env!=NULL);
00222 HPROF_ASSERT(thread!=NULL);
00223 HPROF_ASSERT(method!=NULL);
00224
00225
00226 if ( tls_get_tracker_status(env, thread, JNI_FALSE,
00227 &pstatus, &tls_index, NULL, NULL) == 0 ) {
00228 (*pstatus) = 1;
00229 tls_pop_exception_catch(tls_index, thread, method);
00230 (*pstatus) = 0;
00231 }
00232 }
00233
00234
00235 void
00236 event_return(JNIEnv *env, jthread thread, ClassIndex cnum, MethodIndex mnum)
00237 {
00238
00239
00240
00241
00242 TlsIndex tls_index;
00243 jint *pstatus;
00244
00245 HPROF_ASSERT(env!=NULL);
00246 HPROF_ASSERT(thread!=NULL);
00247 HPROF_ASSERT(cnum!=0 && cnum!=gdata->tracker_cnum);
00248
00249
00250 if ( tls_get_tracker_status(env, thread, JNI_FALSE,
00251 &pstatus, &tls_index, NULL, NULL) == 0 ) {
00252 jmethodID method;
00253
00254 (*pstatus) = 1;
00255 method = class_get_methodID(env, cnum, mnum);
00256 HPROF_ASSERT(method!=NULL);
00257 tls_pop_method(tls_index, thread, method);
00258 (*pstatus) = 0;
00259 }
00260 }
00261
00262
00263 void
00264 event_class_prepare(JNIEnv *env, jthread thread, jclass klass, jobject loader)
00265 {
00266
00267
00268 ClassIndex cnum;
00269
00270 HPROF_ASSERT(env!=NULL);
00271 HPROF_ASSERT(thread!=NULL);
00272 HPROF_ASSERT(klass!=NULL);
00273
00274
00275 cnum = find_cnum(env, klass, loader);
00276 class_add_status(cnum, CLASS_PREPARED);
00277
00278 }
00279
00280
00281 void
00282 event_class_load(JNIEnv *env, jthread thread, jclass klass, jobject loader)
00283 {
00284
00285
00286 ClassIndex cnum;
00287
00288 HPROF_ASSERT(env!=NULL);
00289 HPROF_ASSERT(klass!=NULL);
00290
00291
00292 cnum = find_cnum(env, klass, loader);
00293
00294
00295 class_add_status(cnum, CLASS_IN_LOAD_LIST);
00296
00297
00298 if ( ! ( class_get_status(cnum) & CLASS_LOADED ) ) {
00299 TraceIndex trace_index;
00300 SiteIndex site_index;
00301 ClassIndex super;
00302 SerialNumber class_serial_num;
00303 SerialNumber trace_serial_num;
00304 SerialNumber thread_serial_num;
00305 ObjectIndex class_object_index;
00306 char *signature;
00307
00308
00309 if ( thread == NULL ) {
00310
00311
00312
00313
00314
00315
00316 trace_index = gdata->system_trace_index;
00317 thread_serial_num = gdata->unknown_thread_serial_num;
00318 } else {
00319 TlsIndex tls_index;
00320
00321 tls_index = tls_find_or_create(env, thread);
00322 trace_index = get_current(tls_index, env, JNI_FALSE);
00323 thread_serial_num = tls_get_thread_serial_number(tls_index);
00324 }
00325
00326
00327
00328 site_index = site_find_or_create(cnum, trace_index);
00329
00330
00331 tag_class(env, klass, cnum, thread_serial_num, site_index);
00332
00333 class_add_status(cnum, CLASS_LOADED);
00334
00335 class_serial_num = class_get_serial_number(cnum);
00336 class_object_index = class_get_object_index(cnum);
00337 trace_serial_num = trace_get_serial_number(trace_index);
00338 signature = string_get(class_get_signature(cnum));
00339
00340 rawMonitorEnter(gdata->data_access_lock); {
00341 io_write_class_load(class_serial_num, class_object_index,
00342 trace_serial_num, signature);
00343 } rawMonitorExit(gdata->data_access_lock);
00344
00345 super = get_super(env, klass);
00346 class_set_super(cnum, super);
00347 }
00348
00349 }
00350
00351
00352 void
00353 event_thread_start(JNIEnv *env, jthread thread)
00354 {
00355
00356
00357 TlsIndex tls_index;
00358 ObjectIndex object_index;
00359 TraceIndex trace_index;
00360 jlong tag;
00361 SerialNumber thread_serial_num;
00362
00363 HPROF_ASSERT(env!=NULL);
00364 HPROF_ASSERT(thread!=NULL);
00365
00366 tls_index = tls_find_or_create(env, thread);
00367 thread_serial_num = tls_get_thread_serial_number(tls_index);
00368 trace_index = get_current(tls_index, env, JNI_FALSE);
00369
00370 tag = getTag(thread);
00371 if ( tag == (jlong)0 ) {
00372 SiteIndex site_index;
00373 jint size;
00374
00375 size = (jint)getObjectSize(thread);
00376 site_index = site_find_or_create(gdata->thread_cnum, trace_index);
00377
00378 object_index = object_new(site_index, size, OBJECT_NORMAL,
00379 thread_serial_num);
00380 } else {
00381 object_index = tag_extract(tag);
00382
00383
00384
00385
00386 object_set_thread_serial_number(object_index, thread_serial_num);
00387 }
00388 tls_set_thread_object_index(tls_index, object_index);
00389
00390 WITH_LOCAL_REFS(env, 1) {
00391 jvmtiThreadInfo threadInfo;
00392 jvmtiThreadGroupInfo threadGroupInfo;
00393 jvmtiThreadGroupInfo parentGroupInfo;
00394
00395 getThreadInfo(thread, &threadInfo);
00396 getThreadGroupInfo(threadInfo.thread_group, &threadGroupInfo);
00397 if ( threadGroupInfo.parent != NULL ) {
00398 getThreadGroupInfo(threadGroupInfo.parent, &parentGroupInfo);
00399 } else {
00400 (void)memset(&parentGroupInfo, 0, sizeof(parentGroupInfo));
00401 }
00402
00403 rawMonitorEnter(gdata->data_access_lock); {
00404 io_write_thread_start(thread_serial_num,
00405 object_index, trace_get_serial_number(trace_index),
00406 threadInfo.name, threadGroupInfo.name, parentGroupInfo.name);
00407 } rawMonitorExit(gdata->data_access_lock);
00408
00409 jvmtiDeallocate(threadInfo.name);
00410 jvmtiDeallocate(threadGroupInfo.name);
00411 jvmtiDeallocate(parentGroupInfo.name);
00412
00413 } END_WITH_LOCAL_REFS;
00414 }
00415
00416 void
00417 event_thread_end(JNIEnv *env, jthread thread)
00418 {
00419
00420 TlsIndex tls_index;
00421
00422 HPROF_ASSERT(env!=NULL);
00423 HPROF_ASSERT(thread!=NULL);
00424
00425 tls_index = tls_find_or_create(env, thread);
00426 rawMonitorEnter(gdata->data_access_lock); {
00427 io_write_thread_end(tls_get_thread_serial_number(tls_index));
00428 } rawMonitorExit(gdata->data_access_lock);
00429 tls_thread_ended(env, tls_index);
00430 setThreadLocalStorage(thread, (void*)NULL);
00431 }
00432