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
00043
00044
00045
00046
00047
00048 #include "hprof.h"
00049
00050
00051 #define JNI_FUNC_PTR(env,f) (*((*(env))->f))
00052
00053
00054 #define JVM_FUNC_PTR(env,f) (*((*(env))->f))
00055
00056
00057 #define JVMTI_FUNC_PTR(env,f) (*((*(env))->f))
00058
00059
00060
00061
00062 JNIEnv *
00063 getEnv(void)
00064 {
00065 JNIEnv *env;
00066 jint res;
00067
00068 res = JVM_FUNC_PTR(gdata->jvm,GetEnv)
00069 (gdata->jvm, (void **)&env, JNI_VERSION_1_2);
00070 if (res != JNI_OK) {
00071 char buf[256];
00072
00073 (void)md_snprintf(buf, sizeof(buf),
00074 "Unable to access JNI Version 1.2 (0x%x),"
00075 " is your JDK a 5.0 or newer version?"
00076 " JNIEnv's GetEnv() returned %d",
00077 JNI_VERSION_1_2, res);
00078 buf[sizeof(buf)-1] = 0;
00079 HPROF_ERROR(JNI_FALSE, buf);
00080 error_exit_process(1);
00081 }
00082 return env;
00083 }
00084
00085
00086
00087
00088 void *
00089 jvmtiAllocate(int size)
00090 {
00091 jvmtiError error;
00092 unsigned char *ptr;
00093
00094 HPROF_ASSERT(size>=0);
00095 ptr = NULL;
00096 if ( size == 0 ) {
00097 return ptr;
00098 }
00099 error = JVMTI_FUNC_PTR(gdata->jvmti,Allocate)
00100 (gdata->jvmti, (jlong)size, &ptr);
00101 if ( error != JVMTI_ERROR_NONE || ptr == NULL ) {
00102 HPROF_JVMTI_ERROR(error, "Cannot allocate jvmti memory");
00103 }
00104 return (void*)ptr;
00105 }
00106
00107 void
00108 jvmtiDeallocate(void *ptr)
00109 {
00110 if ( ptr != NULL ) {
00111 jvmtiError error;
00112
00113 error = JVMTI_FUNC_PTR(gdata->jvmti,Deallocate)
00114 (gdata->jvmti, (unsigned char*)ptr);
00115 if ( error != JVMTI_ERROR_NONE ) {
00116 HPROF_JVMTI_ERROR(error, "Cannot deallocate jvmti memory");
00117 }
00118 }
00119 }
00120
00121 #ifdef DEBUG
00122
00123 void *
00124 hprof_debug_malloc(int size, char *file, int line)
00125 {
00126 void *ptr;
00127
00128 HPROF_ASSERT(size>0);
00129
00130 rawMonitorEnter(gdata->debug_malloc_lock); {
00131 ptr = debug_malloc(size, file, line);
00132 } rawMonitorExit(gdata->debug_malloc_lock);
00133
00134 if ( ptr == NULL ) {
00135 HPROF_ERROR(JNI_TRUE, "Cannot allocate malloc memory");
00136 }
00137 return ptr;
00138 }
00139
00140 void
00141 hprof_debug_free(void *ptr, char *file, int line)
00142 {
00143 HPROF_ASSERT(ptr!=NULL);
00144
00145 rawMonitorEnter(gdata->debug_malloc_lock); {
00146 (void)debug_free(ptr, file, line);
00147 } rawMonitorExit(gdata->debug_malloc_lock);
00148 }
00149
00150 #endif
00151
00152 void *
00153 hprof_malloc(int size)
00154 {
00155 void *ptr;
00156
00157 HPROF_ASSERT(size>0);
00158 ptr = malloc(size);
00159 if ( ptr == NULL ) {
00160 HPROF_ERROR(JNI_TRUE, "Cannot allocate malloc memory");
00161 }
00162 return ptr;
00163 }
00164
00165 void
00166 hprof_free(void *ptr)
00167 {
00168 HPROF_ASSERT(ptr!=NULL);
00169 (void)free(ptr);
00170 }
00171
00172
00173
00174
00175 jint
00176 jvmtiVersion(void)
00177 {
00178 if (gdata->cachedJvmtiVersion == 0) {
00179 jvmtiError error;
00180
00181 error = JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)
00182 (gdata->jvmti, &(gdata->cachedJvmtiVersion));
00183 if (error != JVMTI_ERROR_NONE) {
00184 HPROF_JVMTI_ERROR(error, "Cannot get jvmti version number");
00185 }
00186 }
00187 return gdata->cachedJvmtiVersion;
00188 }
00189
00190 static jint
00191 jvmtiMajorVersion(void)
00192 {
00193 return (jvmtiVersion() & JVMTI_VERSION_MASK_MAJOR)
00194 >> JVMTI_VERSION_SHIFT_MAJOR;
00195 }
00196
00197 static jint
00198 jvmtiMinorVersion(void)
00199 {
00200 return (jvmtiVersion() & JVMTI_VERSION_MASK_MINOR)
00201 >> JVMTI_VERSION_SHIFT_MINOR;
00202 }
00203
00204 static jint
00205 jvmtiMicroVersion(void)
00206 {
00207 return (jvmtiVersion() & JVMTI_VERSION_MASK_MICRO)
00208 >> JVMTI_VERSION_SHIFT_MICRO;
00209 }
00210
00211
00212 static jboolean
00213 compatible_versions(jint major_runtime, jint minor_runtime,
00214 jint major_compiletime, jint minor_compiletime)
00215 {
00216
00217 if ( major_runtime != major_compiletime ) {
00218 return JNI_FALSE;
00219 }
00220
00221 if ( minor_runtime < minor_compiletime ) {
00222 return JNI_FALSE;
00223 }
00224
00225 return JNI_TRUE;
00226 }
00227
00228
00229
00230
00231 jrawMonitorID
00232 createRawMonitor(const char *str)
00233 {
00234 jvmtiError error;
00235 jrawMonitorID m;
00236
00237 m = NULL;
00238 error = JVMTI_FUNC_PTR(gdata->jvmti,CreateRawMonitor)
00239 (gdata->jvmti, str, &m);
00240 if ( error != JVMTI_ERROR_NONE ) {
00241 HPROF_JVMTI_ERROR(error, "Cannot create raw monitor");
00242 }
00243 return m;
00244 }
00245
00246 void
00247 rawMonitorEnter(jrawMonitorID m)
00248 {
00249 jvmtiError error;
00250
00251 error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorEnter)
00252 (gdata->jvmti, m);
00253 if ( error == JVMTI_ERROR_WRONG_PHASE ) {
00254
00255 error = JVMTI_ERROR_NONE;
00256 }
00257 if ( error != JVMTI_ERROR_NONE ) {
00258 HPROF_JVMTI_ERROR(error, "Cannot enter with raw monitor");
00259 }
00260 }
00261
00262 void
00263 rawMonitorWait(jrawMonitorID m, jlong pause_time)
00264 {
00265 jvmtiError error;
00266
00267 error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorWait)
00268 (gdata->jvmti, m, pause_time);
00269 if ( error != JVMTI_ERROR_NONE ) {
00270 HPROF_JVMTI_ERROR(error, "Cannot wait with raw monitor");
00271 }
00272 }
00273
00274 void
00275 rawMonitorNotifyAll(jrawMonitorID m)
00276 {
00277 jvmtiError error;
00278
00279 error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll)
00280 (gdata->jvmti, m);
00281 if ( error != JVMTI_ERROR_NONE ) {
00282 HPROF_JVMTI_ERROR(error, "Cannot notify all with raw monitor");
00283 }
00284 }
00285
00286 void
00287 rawMonitorExit(jrawMonitorID m)
00288 {
00289 jvmtiError error;
00290
00291 error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorExit)
00292 (gdata->jvmti, m);
00293 if ( error == JVMTI_ERROR_WRONG_PHASE ) {
00294
00295 error = JVMTI_ERROR_NONE;
00296 }
00297 if ( error != JVMTI_ERROR_NONE ) {
00298 HPROF_JVMTI_ERROR(error, "Cannot exit with raw monitor");
00299 }
00300 }
00301
00302 void
00303 destroyRawMonitor(jrawMonitorID m)
00304 {
00305 jvmtiError error;
00306
00307 error = JVMTI_FUNC_PTR(gdata->jvmti,DestroyRawMonitor)
00308 (gdata->jvmti, m);
00309 if ( error == JVMTI_ERROR_WRONG_PHASE ) {
00310
00311 error = JVMTI_ERROR_NONE;
00312 }
00313 if ( error != JVMTI_ERROR_NONE ) {
00314 HPROF_JVMTI_ERROR(error, "Cannot destroy raw monitor");
00315 }
00316 }
00317
00318
00319
00320
00321 void
00322 setEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event, jthread thread)
00323 {
00324 jvmtiError error;
00325
00326 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode)
00327 (gdata->jvmti, mode, event, thread);
00328 if ( error != JVMTI_ERROR_NONE ) {
00329 HPROF_JVMTI_ERROR(error, "Cannot set event notification");
00330 }
00331 }
00332
00333
00334
00335
00336 jobject
00337 exceptionOccurred(JNIEnv *env)
00338 {
00339 return JNI_FUNC_PTR(env,ExceptionOccurred)(env);
00340 }
00341
00342 void
00343 exceptionDescribe(JNIEnv *env)
00344 {
00345 JNI_FUNC_PTR(env,ExceptionDescribe)(env);
00346 }
00347
00348 void
00349 exceptionClear(JNIEnv *env)
00350 {
00351 JNI_FUNC_PTR(env,ExceptionClear)(env);
00352 }
00353
00354 jobject
00355 newGlobalReference(JNIEnv *env, jobject object)
00356 {
00357 jobject gref;
00358
00359 HPROF_ASSERT(env!=NULL);
00360 HPROF_ASSERT(object!=NULL);
00361 gref = JNI_FUNC_PTR(env,NewGlobalRef)(env, object);
00362 HPROF_ASSERT(gref!=NULL);
00363 return gref;
00364 }
00365
00366 jobject
00367 newWeakGlobalReference(JNIEnv *env, jobject object)
00368 {
00369 jobject gref;
00370
00371 HPROF_ASSERT(env!=NULL);
00372 HPROF_ASSERT(object!=NULL);
00373 gref = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, object);
00374 HPROF_ASSERT(gref!=NULL);
00375 return gref;
00376 }
00377
00378 void
00379 deleteGlobalReference(JNIEnv *env, jobject object)
00380 {
00381 HPROF_ASSERT(env!=NULL);
00382 HPROF_ASSERT(object!=NULL);
00383 JNI_FUNC_PTR(env,DeleteGlobalRef)(env, object);
00384 }
00385
00386 jobject
00387 newLocalReference(JNIEnv *env, jobject object)
00388 {
00389 jobject lref;
00390
00391 HPROF_ASSERT(env!=NULL);
00392 HPROF_ASSERT(object!=NULL);
00393 lref = JNI_FUNC_PTR(env,NewLocalRef)(env, object);
00394
00395 return lref;
00396 }
00397
00398 void
00399 deleteLocalReference(JNIEnv *env, jobject object)
00400 {
00401 HPROF_ASSERT(env!=NULL);
00402 HPROF_ASSERT(object!=NULL);
00403 JNI_FUNC_PTR(env,DeleteLocalRef)(env, object);
00404 }
00405
00406 void
00407 deleteWeakGlobalReference(JNIEnv *env, jobject object)
00408 {
00409 HPROF_ASSERT(env!=NULL);
00410 HPROF_ASSERT(object!=NULL);
00411 JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, object);
00412 }
00413
00414 jclass
00415 getObjectClass(JNIEnv *env, jobject object)
00416
00417 {
00418 jclass clazz;
00419
00420 HPROF_ASSERT(env!=NULL);
00421 HPROF_ASSERT(object!=NULL);
00422 clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
00423 HPROF_ASSERT(clazz!=NULL);
00424 return clazz;
00425 }
00426
00427 jclass
00428 getSuperclass(JNIEnv *env, jclass klass)
00429
00430 {
00431 jclass super_klass;
00432
00433 HPROF_ASSERT(env!=NULL);
00434 HPROF_ASSERT(klass!=NULL);
00435 super_klass = JNI_FUNC_PTR(env,GetSuperclass)(env, klass);
00436 return super_klass;
00437 }
00438
00439 jmethodID
00440 getStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
00441 {
00442 jmethodID method;
00443
00444 HPROF_ASSERT(env!=NULL);
00445 HPROF_ASSERT(clazz!=NULL);
00446 HPROF_ASSERT(name!=NULL);
00447 HPROF_ASSERT(sig!=NULL);
00448 CHECK_EXCEPTIONS(env) {
00449 method = JNI_FUNC_PTR(env,GetStaticMethodID)(env, clazz, name, sig);
00450 } END_CHECK_EXCEPTIONS;
00451 HPROF_ASSERT(method!=NULL);
00452 return method;
00453 }
00454
00455 jmethodID
00456 getMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
00457 {
00458 jmethodID method;
00459 jobject exception;
00460
00461 HPROF_ASSERT(env!=NULL);
00462 HPROF_ASSERT(clazz!=NULL);
00463 HPROF_ASSERT(name!=NULL);
00464 HPROF_ASSERT(sig!=NULL);
00465 method = JNI_FUNC_PTR(env,GetMethodID)(env, clazz, name, sig);
00466
00467 exception = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
00468 if ( exception != NULL ) {
00469 JNI_FUNC_PTR(env,ExceptionClear)(env);
00470 method = getStaticMethodID(env, clazz, name, sig);
00471 }
00472 HPROF_ASSERT(method!=NULL);
00473 return method;
00474 }
00475
00476 jclass
00477 findClass(JNIEnv *env, const char *name)
00478
00479 {
00480 jclass clazz;
00481
00482 HPROF_ASSERT(env!=NULL);
00483 HPROF_ASSERT(name!=NULL);
00484 LOG2("FindClass", name);
00485 CHECK_EXCEPTIONS(env) {
00486 clazz = JNI_FUNC_PTR(env,FindClass)(env, name);
00487 } END_CHECK_EXCEPTIONS;
00488 HPROF_ASSERT(clazz!=NULL);
00489 return clazz;
00490 }
00491
00492 jfieldID
00493 getStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
00494 {
00495 jfieldID field;
00496
00497 HPROF_ASSERT(env!=NULL);
00498 HPROF_ASSERT(clazz!=NULL);
00499 HPROF_ASSERT(name!=NULL);
00500 HPROF_ASSERT(sig!=NULL);
00501 CHECK_EXCEPTIONS(env) {
00502 field = JNI_FUNC_PTR(env,GetStaticFieldID)(env, clazz, name, sig);
00503 } END_CHECK_EXCEPTIONS;
00504 return field;
00505 }
00506
00507 void
00508 setStaticIntField(JNIEnv *env, jclass clazz, jfieldID field, jint value)
00509 {
00510 HPROF_ASSERT(env!=NULL);
00511 HPROF_ASSERT(clazz!=NULL);
00512 HPROF_ASSERT(field!=NULL);
00513 CHECK_EXCEPTIONS(env) {
00514 JNI_FUNC_PTR(env,SetStaticIntField)(env, clazz, field, value);
00515 } END_CHECK_EXCEPTIONS;
00516 }
00517
00518 static jobject
00519 callStaticObjectMethod(JNIEnv *env, jclass klass, jmethodID method)
00520 {
00521 jobject x;
00522
00523 HPROF_ASSERT(env!=NULL);
00524 HPROF_ASSERT(klass!=NULL);
00525 HPROF_ASSERT(method!=NULL);
00526 CHECK_EXCEPTIONS(env) {
00527 x = JNI_FUNC_PTR(env,CallStaticObjectMethod)(env, klass, method);
00528 } END_CHECK_EXCEPTIONS;
00529 return x;
00530 }
00531
00532 static jlong
00533 callLongMethod(JNIEnv *env, jobject object, jmethodID method)
00534 {
00535 jlong x;
00536
00537 HPROF_ASSERT(env!=NULL);
00538 HPROF_ASSERT(object!=NULL);
00539 HPROF_ASSERT(method!=NULL);
00540 CHECK_EXCEPTIONS(env) {
00541 x = JNI_FUNC_PTR(env,CallLongMethod)(env, object, method);
00542 } END_CHECK_EXCEPTIONS;
00543 return x;
00544 }
00545
00546 static void
00547 callVoidMethod(JNIEnv *env, jobject object, jmethodID method, jboolean arg)
00548 {
00549 HPROF_ASSERT(env!=NULL);
00550 HPROF_ASSERT(object!=NULL);
00551 HPROF_ASSERT(method!=NULL);
00552 CHECK_EXCEPTIONS(env) {
00553 JNI_FUNC_PTR(env,CallVoidMethod)(env, object, method, arg);
00554 } END_CHECK_EXCEPTIONS;
00555 }
00556
00557 static jstring
00558 newStringUTF(JNIEnv *env, const char *name)
00559
00560 {
00561 jstring string;
00562
00563 HPROF_ASSERT(env!=NULL);
00564 HPROF_ASSERT(name!=NULL);
00565 CHECK_EXCEPTIONS(env) {
00566 string = JNI_FUNC_PTR(env,NewStringUTF)(env, name);
00567 } END_CHECK_EXCEPTIONS;
00568 HPROF_ASSERT(string!=NULL);
00569 return string;
00570 }
00571
00572 static jobject
00573 newThreadObject(JNIEnv *env, jclass clazz, jmethodID method,
00574 jthreadGroup group, jstring name)
00575
00576 {
00577 jthread thread;
00578
00579 HPROF_ASSERT(env!=NULL);
00580 HPROF_ASSERT(clazz!=NULL);
00581 HPROF_ASSERT(method!=NULL);
00582 CHECK_EXCEPTIONS(env) {
00583 thread = JNI_FUNC_PTR(env,NewObject)(env, clazz, method, group, name);
00584 } END_CHECK_EXCEPTIONS;
00585 HPROF_ASSERT(thread!=NULL);
00586 return thread;
00587 }
00588
00589 jboolean
00590 isSameObject(JNIEnv *env, jobject o1, jobject o2)
00591 {
00592 HPROF_ASSERT(env!=NULL);
00593 if ( o1 == o2 || JNI_FUNC_PTR(env,IsSameObject)(env, o1, o2) ) {
00594 return JNI_TRUE;
00595 }
00596 return JNI_FALSE;
00597 }
00598
00599 void
00600 pushLocalFrame(JNIEnv *env, jint capacity)
00601 {
00602 HPROF_ASSERT(env!=NULL);
00603 CHECK_EXCEPTIONS(env) {
00604 jint ret;
00605
00606 ret = JNI_FUNC_PTR(env,PushLocalFrame)(env, capacity);
00607 if ( ret != 0 ) {
00608 HPROF_ERROR(JNI_TRUE, "JNI PushLocalFrame returned non-zero");
00609 }
00610 } END_CHECK_EXCEPTIONS;
00611 }
00612
00613 void
00614 popLocalFrame(JNIEnv *env, jobject result)
00615 {
00616 jobject ret;
00617
00618 HPROF_ASSERT(env!=NULL);
00619 ret = JNI_FUNC_PTR(env,PopLocalFrame)(env, result);
00620 if ( (result != NULL && ret == NULL) || (result == NULL && ret != NULL) ) {
00621 HPROF_ERROR(JNI_TRUE, "JNI PopLocalFrame returned wrong object");
00622 }
00623 }
00624
00625 void
00626 registerNatives(JNIEnv *env, jclass clazz,
00627 JNINativeMethod *methods, jint count)
00628 {
00629 jint ret;
00630
00631 HPROF_ASSERT(env!=NULL);
00632 HPROF_ASSERT(clazz!=NULL);
00633 HPROF_ASSERT(methods!=NULL);
00634 HPROF_ASSERT(count>0);
00635 ret = JNI_FUNC_PTR(env,RegisterNatives)(env, clazz, methods, count);
00636 if ( ret != 0 ) {
00637 HPROF_ERROR(JNI_TRUE, "JNI RegisterNatives returned non-zero");
00638 }
00639 }
00640
00641
00642
00643
00644 char *
00645 getErrorName(jvmtiError error_number)
00646 {
00647 char *error_name;
00648
00649 error_name = NULL;
00650 (void)JVMTI_FUNC_PTR(gdata->jvmti,GetErrorName)
00651 (gdata->jvmti, error_number, &error_name);
00652 return error_name;
00653 }
00654
00655 jvmtiPhase
00656 getPhase(void)
00657 {
00658 jvmtiPhase phase;
00659
00660 phase = 0;
00661 (void)JVMTI_FUNC_PTR(gdata->jvmti,GetPhase)(gdata->jvmti, &phase);
00662 return phase;
00663 }
00664
00665 char *
00666 phaseString(jvmtiPhase phase)
00667 {
00668 switch ( phase ) {
00669 case JVMTI_PHASE_ONLOAD:
00670 return "onload";
00671 case JVMTI_PHASE_PRIMORDIAL:
00672 return "primordial";
00673 case JVMTI_PHASE_START:
00674 return "start";
00675 case JVMTI_PHASE_LIVE:
00676 return "live";
00677 case JVMTI_PHASE_DEAD:
00678 return "dead";
00679 }
00680 return "unknown";
00681 }
00682
00683 void
00684 disposeEnvironment(void)
00685 {
00686 (void)JVMTI_FUNC_PTR(gdata->jvmti,DisposeEnvironment)
00687 (gdata->jvmti);
00688 }
00689
00690 jlong
00691 getObjectSize(jobject object)
00692 {
00693 jlong size;
00694 jvmtiError error;
00695
00696 HPROF_ASSERT(object!=NULL);
00697 size = 0;
00698 error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectSize)
00699 (gdata->jvmti, object, &size);
00700 if ( error != JVMTI_ERROR_NONE ) {
00701 HPROF_JVMTI_ERROR(error, "Cannot get object size");
00702 }
00703 return size;
00704 }
00705
00706 static jboolean
00707 isInterface(jclass klass)
00708 {
00709 jvmtiError error;
00710 jboolean answer;
00711
00712 HPROF_ASSERT(klass!=NULL);
00713 answer = JNI_FALSE;
00714 error = JVMTI_FUNC_PTR(gdata->jvmti,IsInterface)
00715 (gdata->jvmti, klass, &answer);
00716 if ( error != JVMTI_ERROR_NONE ) {
00717 HPROF_JVMTI_ERROR(error, "Cannot call IsInterface");
00718 }
00719 return answer;
00720 }
00721
00722 jint
00723 getClassStatus(jclass klass)
00724 {
00725 jvmtiError error;
00726 jint status;
00727
00728 HPROF_ASSERT(klass!=NULL);
00729 status = 0;
00730 error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassStatus)
00731 (gdata->jvmti, klass, &status);
00732 if ( error == JVMTI_ERROR_WRONG_PHASE ) {
00733
00734 error = JVMTI_ERROR_NONE;
00735 status = 0;
00736 }
00737 if ( error != JVMTI_ERROR_NONE ) {
00738 HPROF_JVMTI_ERROR(error, "Cannot get class status");
00739 }
00740 return status;
00741 }
00742
00743 jobject
00744 getClassLoader(jclass klass)
00745
00746 {
00747 jvmtiError error;
00748 jobject loader;
00749
00750 HPROF_ASSERT(klass!=NULL);
00751 loader = NULL;
00752 error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoader)
00753 (gdata->jvmti, klass, &loader);
00754 if ( error != JVMTI_ERROR_NONE ) {
00755 HPROF_JVMTI_ERROR(error, "Cannot get class loader");
00756 }
00757 return loader;
00758 }
00759
00760 jlong
00761 getTag(jobject object)
00762 {
00763 jlong tag;
00764 jvmtiError error;
00765
00766 HPROF_ASSERT(object!=NULL);
00767 tag = 0;
00768 error = JVMTI_FUNC_PTR(gdata->jvmti,GetTag)
00769 (gdata->jvmti, object, &tag);
00770 if ( error != JVMTI_ERROR_NONE ) {
00771 HPROF_JVMTI_ERROR(error, "Cannot get object tag");
00772 }
00773 return tag;
00774 }
00775
00776 void
00777 setTag(jobject object, jlong tag)
00778 {
00779 jvmtiError error;
00780
00781 HPROF_ASSERT(object!=NULL);
00782 error = JVMTI_FUNC_PTR(gdata->jvmti,SetTag)
00783 (gdata->jvmti, object, tag);
00784 if ( error != JVMTI_ERROR_NONE ) {
00785 HPROF_JVMTI_ERROR(error, "Cannot set object tag");
00786 }
00787 }
00788
00789 void
00790 getObjectMonitorUsage(jobject object, jvmtiMonitorUsage *uinfo)
00791 {
00792 jvmtiError error;
00793
00794 HPROF_ASSERT(object!=NULL);
00795 error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectMonitorUsage)
00796 (gdata->jvmti, object, uinfo);
00797 if ( error != JVMTI_ERROR_NONE ) {
00798 HPROF_JVMTI_ERROR(error, "Cannot get monitor usage info");
00799 }
00800 }
00801
00802 void
00803 getOwnedMonitorInfo(jthread thread, jobject **ppobjects, jint *pcount)
00804
00805 {
00806 jvmtiError error;
00807
00808 HPROF_ASSERT(thread!=NULL);
00809 HPROF_ASSERT(ppobjects!=NULL);
00810 HPROF_ASSERT(pcount!=NULL);
00811 *pcount = 0;
00812 *ppobjects = NULL;
00813 error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorInfo)
00814 (gdata->jvmti, thread, pcount, ppobjects);
00815 if ( error == JVMTI_ERROR_THREAD_NOT_ALIVE ) {
00816 *pcount = 0;
00817 error = JVMTI_ERROR_NONE;
00818 }
00819 if ( error != JVMTI_ERROR_NONE ) {
00820 HPROF_JVMTI_ERROR(error, "Cannot get thread owned monitor info");
00821 }
00822 }
00823
00824 void
00825 getSystemProperty(const char *name, char **value)
00826 {
00827 jvmtiError error;
00828
00829 HPROF_ASSERT(name!=NULL);
00830 *value = NULL;
00831 error = JVMTI_FUNC_PTR(gdata->jvmti,GetSystemProperty)
00832 (gdata->jvmti, name, value);
00833 if ( error != JVMTI_ERROR_NONE ) {
00834 HPROF_JVMTI_ERROR(error, "Cannot get system property");
00835 }
00836 }
00837
00838 void
00839 getClassSignature(jclass klass, char** psignature, char **pgeneric_signature)
00840 {
00841 jvmtiError error;
00842 char *generic_signature;
00843
00844 HPROF_ASSERT(klass!=NULL);
00845 *psignature = NULL;
00846 error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassSignature)
00847 (gdata->jvmti, klass, psignature, &generic_signature);
00848 if ( error != JVMTI_ERROR_NONE ) {
00849 HPROF_JVMTI_ERROR(error, "Cannot get class signature");
00850 }
00851 if ( pgeneric_signature != NULL ) {
00852 *pgeneric_signature = generic_signature;
00853 } else {
00854 jvmtiDeallocate(generic_signature);
00855 }
00856 }
00857
00858 void
00859 getSourceFileName(jclass klass, char** pname)
00860 {
00861 jvmtiError error;
00862
00863 HPROF_ASSERT(klass!=NULL);
00864 *pname = NULL;
00865 error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName)
00866 (gdata->jvmti, klass, pname);
00867 if ( error == JVMTI_ERROR_ABSENT_INFORMATION ) {
00868 error = JVMTI_ERROR_NONE;
00869 *pname = NULL;
00870 }
00871 if ( error != JVMTI_ERROR_NONE ) {
00872 HPROF_JVMTI_ERROR(error, "Cannot get source file name");
00873 }
00874 }
00875
00876 static void
00877 getClassFields(jclass klass, jint* pn_fields, jfieldID** pfields)
00878 {
00879 jvmtiError error;
00880 jint status;
00881
00882 HPROF_ASSERT(klass!=NULL);
00883 *pn_fields = 0;
00884 *pfields = NULL;
00885
00886
00887 status = getClassStatus(klass);
00888
00889
00890 if ( status & JVMTI_CLASS_STATUS_ARRAY ) {
00891 return;
00892 }
00893
00894
00895 if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {
00896 return;
00897 }
00898
00899
00900 if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {
00901 HPROF_ERROR(JNI_FALSE, "Class not prepared when needing fields");
00902 return;
00903 }
00904
00905
00906 error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassFields)
00907 (gdata->jvmti, klass, pn_fields, pfields);
00908 if ( error != JVMTI_ERROR_NONE ) {
00909 HPROF_JVMTI_ERROR(error, "Cannot get class field list");
00910 }
00911 }
00912
00913 static jint
00914 getFieldModifiers(jclass klass, jfieldID field)
00915 {
00916 jvmtiError error;
00917 jint modifiers;
00918
00919 HPROF_ASSERT(klass!=NULL);
00920 HPROF_ASSERT(field!=NULL);
00921 modifiers = 0;
00922 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldModifiers)
00923 (gdata->jvmti, klass, field, &modifiers);
00924 if ( error != JVMTI_ERROR_NONE ) {
00925 HPROF_JVMTI_ERROR(error, "Cannot get field modifiers");
00926 }
00927 return modifiers;
00928 }
00929
00930 static void
00931 getFieldName(jclass klass, jfieldID field, char** pname, char** psignature,
00932 char **pgeneric_signature)
00933 {
00934 jvmtiError error;
00935 char *generic_signature;
00936
00937 generic_signature = NULL;
00938 *pname = NULL;
00939 *psignature = NULL;
00940 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldName)
00941 (gdata->jvmti, klass, field, pname, psignature, &generic_signature);
00942 if ( error != JVMTI_ERROR_NONE ) {
00943 HPROF_JVMTI_ERROR(error, "Cannot get field name");
00944 }
00945 if ( pgeneric_signature != NULL ) {
00946 *pgeneric_signature = generic_signature;
00947 } else {
00948 jvmtiDeallocate(generic_signature);
00949 }
00950 }
00951
00952 static void
00953 getImplementedInterfaces(jclass klass, jint* pn_interfaces,
00954 jclass** pinterfaces)
00955
00956 {
00957 jvmtiError error;
00958
00959 *pn_interfaces = 0;
00960 *pinterfaces = NULL;
00961 error = JVMTI_FUNC_PTR(gdata->jvmti,GetImplementedInterfaces)
00962 (gdata->jvmti, klass, pn_interfaces, pinterfaces);
00963 if ( error != JVMTI_ERROR_NONE ) {
00964 HPROF_JVMTI_ERROR(error, "Cannot get class interface list");
00965 }
00966 }
00967
00968 static ClassIndex
00969 get_cnum(JNIEnv *env, jclass klass)
00970
00971 {
00972 ClassIndex cnum;
00973 LoaderIndex loader_index;
00974 char *sig;
00975 jobject loader;
00976
00977 loader = getClassLoader(klass);
00978 loader_index = loader_find_or_create(env, loader);
00979 getClassSignature(klass, &sig, NULL);
00980 cnum = class_find_or_create(sig, loader_index);
00981 jvmtiDeallocate(sig);
00982 (void)class_new_classref(env, cnum, klass);
00983 return cnum;
00984 }
00985
00986
00987 char
00988 primTypeToSigChar(jvmtiPrimitiveType primType)
00989 {
00990 char sig_ch;
00991
00992 sig_ch = 0;
00993 switch ( primType ) {
00994 case JVMTI_PRIMITIVE_TYPE_BYTE:
00995 sig_ch = JVM_SIGNATURE_BYTE;
00996 break;
00997 case JVMTI_PRIMITIVE_TYPE_CHAR:
00998 sig_ch = JVM_SIGNATURE_CHAR;
00999 break;
01000 case JVMTI_PRIMITIVE_TYPE_FLOAT:
01001 sig_ch = JVM_SIGNATURE_FLOAT;
01002 break;
01003 case JVMTI_PRIMITIVE_TYPE_DOUBLE:
01004 sig_ch = JVM_SIGNATURE_DOUBLE;
01005 break;
01006 case JVMTI_PRIMITIVE_TYPE_INT:
01007 sig_ch = JVM_SIGNATURE_INT;
01008 break;
01009 case JVMTI_PRIMITIVE_TYPE_LONG:
01010 sig_ch = JVM_SIGNATURE_LONG;
01011 break;
01012 case JVMTI_PRIMITIVE_TYPE_SHORT:
01013 sig_ch = JVM_SIGNATURE_SHORT;
01014 break;
01015 case JVMTI_PRIMITIVE_TYPE_BOOLEAN:
01016 sig_ch = JVM_SIGNATURE_BOOLEAN;
01017 break;
01018 default:
01019 sig_ch = 0;
01020 break;
01021 }
01022 return sig_ch;
01023 }
01024
01025
01026 jvmtiPrimitiveType
01027 sigToPrimType(char *sig)
01028 {
01029 jvmtiPrimitiveType primType;
01030
01031 primType = 0;
01032 if ( sig == NULL || sig[0] == 0 ) {
01033 return primType;
01034 }
01035 switch ( sig[0] ) {
01036 case JVM_SIGNATURE_BYTE:
01037 primType = JVMTI_PRIMITIVE_TYPE_BYTE;
01038 break;
01039 case JVM_SIGNATURE_CHAR:
01040 primType = JVMTI_PRIMITIVE_TYPE_CHAR;
01041 break;
01042 case JVM_SIGNATURE_FLOAT:
01043 primType = JVMTI_PRIMITIVE_TYPE_FLOAT;
01044 break;
01045 case JVM_SIGNATURE_DOUBLE:
01046 primType = JVMTI_PRIMITIVE_TYPE_DOUBLE;
01047 break;
01048 case JVM_SIGNATURE_INT:
01049 primType = JVMTI_PRIMITIVE_TYPE_INT;
01050 break;
01051 case JVM_SIGNATURE_LONG:
01052 primType = JVMTI_PRIMITIVE_TYPE_LONG;
01053 break;
01054 case JVM_SIGNATURE_SHORT:
01055 primType = JVMTI_PRIMITIVE_TYPE_SHORT;
01056 break;
01057 case JVM_SIGNATURE_BOOLEAN:
01058 primType = JVMTI_PRIMITIVE_TYPE_BOOLEAN;
01059 break;
01060 }
01061 return primType;
01062 }
01063
01064
01065 int
01066 sigToPrimSize(char *sig)
01067 {
01068 unsigned size;
01069
01070 size = 0;
01071 if ( sig == NULL || sig[0] == 0 ) {
01072 return size;
01073 }
01074 switch ( sig[0] ) {
01075 case JVM_SIGNATURE_BYTE:
01076 case JVM_SIGNATURE_BOOLEAN:
01077 size = 1;
01078 break;
01079 case JVM_SIGNATURE_CHAR:
01080 case JVM_SIGNATURE_SHORT:
01081 size = 2;
01082 break;
01083 case JVM_SIGNATURE_FLOAT:
01084 case JVM_SIGNATURE_INT:
01085 size = 4;
01086 break;
01087 case JVM_SIGNATURE_DOUBLE:
01088 case JVM_SIGNATURE_LONG:
01089 size = 8;
01090 break;
01091 }
01092 return size;
01093 }
01094
01095 static void
01096 add_class_fields(JNIEnv *env, ClassIndex top_cnum, ClassIndex cnum,
01097 jclass klass, Stack *field_list, Stack *class_list)
01098
01099 {
01100 jclass *interfaces;
01101 jint n_interfaces;
01102 jfieldID *idlist;
01103 jint n_fields;
01104 int i;
01105 int depth;
01106 int skip_static_field_names;
01107 jint status;
01108
01109 HPROF_ASSERT(env!=NULL);
01110 HPROF_ASSERT(klass!=NULL);
01111 HPROF_ASSERT(field_list!=NULL);
01112 HPROF_ASSERT(class_list!=NULL);
01113
01114
01115 skip_static_field_names = (cnum != top_cnum);
01116
01117
01118 status = getClassStatus(klass);
01119
01120
01121 if ( status & JVMTI_CLASS_STATUS_ARRAY ) {
01122 return;
01123 }
01124
01125
01126 if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {
01127 return;
01128 }
01129
01130
01131 if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {
01132 char *sig;
01133
01134 getClassSignature(klass, &sig, NULL);
01135 debug_message("Class signature is: %s\n", sig);
01136 HPROF_ERROR(JNI_FALSE, "Class not prepared when needing all fields");
01137 jvmtiDeallocate(sig);
01138 return;
01139 }
01140
01141
01142 depth = stack_depth(class_list);
01143 for ( i = depth-1 ; i >= 0 ; i-- ) {
01144 if ( isSameObject(env, klass, *(jclass*)stack_element(class_list, i)) ) {
01145 return;
01146 }
01147 }
01148
01149
01150 getImplementedInterfaces(klass, &n_interfaces, &interfaces);
01151 for ( i = 0 ; i < n_interfaces ; i++ ) {
01152 add_class_fields(env, top_cnum,
01153 get_cnum(env, interfaces[i]), interfaces[i],
01154 field_list, class_list);
01155 }
01156 jvmtiDeallocate(interfaces);
01157
01158
01159 if ( !isInterface(klass) ) {
01160 jclass super_klass;
01161
01162 super_klass = getSuperclass(env, klass);
01163 if ( super_klass != NULL ) {
01164 add_class_fields(env, top_cnum,
01165 get_cnum(env, super_klass), super_klass,
01166 field_list, class_list);
01167 }
01168 }
01169
01170
01171
01172 stack_push(class_list, &klass);
01173
01174
01175 getClassFields(klass, &n_fields, &idlist);
01176 for ( i = 0 ; i < n_fields ; i++ ) {
01177 FieldInfo finfo;
01178 static FieldInfo empty_finfo;
01179
01180 finfo = empty_finfo;
01181 finfo.cnum = cnum;
01182 finfo.modifiers = getFieldModifiers(klass, idlist[i]);
01183 if ( ( finfo.modifiers & JVM_ACC_STATIC ) == 0 ||
01184 !skip_static_field_names ) {
01185 char *field_name;
01186 char *field_sig;
01187
01188 getFieldName(klass, idlist[i], &field_name, &field_sig, NULL);
01189 finfo.name_index = string_find_or_create(field_name);
01190 finfo.sig_index = string_find_or_create(field_sig);
01191 finfo.primType = sigToPrimType(field_sig);
01192 finfo.primSize = sigToPrimSize(field_sig);
01193 jvmtiDeallocate(field_name);
01194 jvmtiDeallocate(field_sig);
01195 }
01196 stack_push(field_list, &finfo);
01197 }
01198 jvmtiDeallocate(idlist);
01199 }
01200
01201 void
01202 getAllClassFieldInfo(JNIEnv *env, jclass klass,
01203 jint* pn_fields, FieldInfo** pfields)
01204 {
01205 ClassIndex cnum;
01206
01207 *pfields = NULL;
01208 *pn_fields = 0;
01209
01210 WITH_LOCAL_REFS(env, 1) {
01211 Stack *class_list;
01212 Stack *field_list;
01213 int nbytes;
01214
01215 cnum = get_cnum(env, klass);
01216 class_list = stack_init( 16, 16, (int)sizeof(jclass));
01217 field_list = stack_init(128, 128, (int)sizeof(FieldInfo));
01218 add_class_fields(env, cnum, cnum, klass, field_list, class_list);
01219 *pn_fields = stack_depth(field_list);
01220 if ( (*pn_fields) > 0 ) {
01221 nbytes = (*pn_fields) * (int)sizeof(FieldInfo);
01222 *pfields = (FieldInfo*)HPROF_MALLOC(nbytes);
01223 (void)memcpy(*pfields, stack_element(field_list, 0), nbytes);
01224 }
01225 stack_term(field_list);
01226 stack_term(class_list);
01227 } END_WITH_LOCAL_REFS;
01228 }
01229
01230 void
01231 getMethodClass(jmethodID method, jclass *pclazz)
01232
01233 {
01234 jvmtiError error;
01235
01236 HPROF_ASSERT(method!=NULL);
01237 *pclazz = NULL;
01238 error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
01239 (gdata->jvmti, method, pclazz);
01240 if ( error != JVMTI_ERROR_NONE ) {
01241 HPROF_JVMTI_ERROR(error, "Cannot get method class");
01242 }
01243 }
01244
01245 jboolean
01246 isMethodNative(jmethodID method)
01247 {
01248 jvmtiError error;
01249 jboolean isNative;
01250
01251 HPROF_ASSERT(method!=NULL);
01252 error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodNative)
01253 (gdata->jvmti, method, &isNative);
01254 if ( error != JVMTI_ERROR_NONE ) {
01255 HPROF_JVMTI_ERROR(error, "Cannot check is method native");
01256 }
01257 return isNative;
01258 }
01259
01260 void
01261 getMethodName(jmethodID method, char** pname, char** psignature)
01262 {
01263 jvmtiError error;
01264 char *generic_signature;
01265
01266 HPROF_ASSERT(method!=NULL);
01267 generic_signature = NULL;
01268 *pname = NULL;
01269 *psignature = NULL;
01270 error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodName)
01271 (gdata->jvmti, method, pname, psignature, &generic_signature);
01272 if ( error != JVMTI_ERROR_NONE ) {
01273 HPROF_JVMTI_ERROR(error, "Cannot get method name");
01274 }
01275 jvmtiDeallocate(generic_signature);
01276 }
01277
01278 void
01279 getPotentialCapabilities(jvmtiCapabilities *pcapabilities)
01280 {
01281 jvmtiError error;
01282
01283 (void)memset(pcapabilities,0,sizeof(jvmtiCapabilities));
01284 error = JVMTI_FUNC_PTR(gdata->jvmti,GetPotentialCapabilities)
01285 (gdata->jvmti, pcapabilities);
01286 if (error != JVMTI_ERROR_NONE) {
01287 HPROF_ERROR(JNI_FALSE, "Unable to get potential JVMTI capabilities.");
01288 error_exit_process(1);
01289 }
01290 }
01291
01292 void
01293 addCapabilities(jvmtiCapabilities *pcapabilities)
01294 {
01295 jvmtiError error;
01296
01297 error = JVMTI_FUNC_PTR(gdata->jvmti,AddCapabilities)
01298 (gdata->jvmti, pcapabilities);
01299 if (error != JVMTI_ERROR_NONE) {
01300 HPROF_ERROR(JNI_FALSE, "Unable to get necessary JVMTI capabilities.");
01301 error_exit_process(1);
01302 }
01303 }
01304
01305 void
01306 setEventCallbacks(jvmtiEventCallbacks *pcallbacks)
01307 {
01308 jvmtiError error;
01309
01310 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
01311 (gdata->jvmti, pcallbacks, (int)sizeof(jvmtiEventCallbacks));
01312 if (error != JVMTI_ERROR_NONE) {
01313 HPROF_JVMTI_ERROR(error, "Cannot set jvmti callbacks");
01314 }
01315
01316 }
01317
01318 void *
01319 getThreadLocalStorage(jthread thread)
01320 {
01321 jvmtiError error;
01322 void *ptr;
01323
01324 HPROF_ASSERT(thread!=NULL);
01325 ptr = NULL;
01326 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadLocalStorage)
01327 (gdata->jvmti, thread, &ptr);
01328 if ( error == JVMTI_ERROR_WRONG_PHASE ) {
01329
01330 error = JVMTI_ERROR_NONE;
01331 ptr = NULL;
01332 }
01333 if ( error != JVMTI_ERROR_NONE ) {
01334 HPROF_JVMTI_ERROR(error, "Cannot get thread local storage");
01335 }
01336 return ptr;
01337 }
01338
01339 void
01340 setThreadLocalStorage(jthread thread, void *ptr)
01341 {
01342 jvmtiError error;
01343
01344 HPROF_ASSERT(thread!=NULL);
01345 error = JVMTI_FUNC_PTR(gdata->jvmti,SetThreadLocalStorage)
01346 (gdata->jvmti, thread, (const void *)ptr);
01347 if ( error == JVMTI_ERROR_WRONG_PHASE ) {
01348
01349 error = JVMTI_ERROR_NONE;
01350 }
01351 if ( error != JVMTI_ERROR_NONE ) {
01352 HPROF_JVMTI_ERROR(error, "Cannot set thread local storage");
01353 }
01354 }
01355
01356 void
01357 getThreadState(jthread thread, jint *threadState)
01358 {
01359 jvmtiError error;
01360
01361 HPROF_ASSERT(thread!=NULL);
01362 HPROF_ASSERT(threadState!=NULL);
01363 *threadState = 0;
01364 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadState)
01365 (gdata->jvmti, thread, threadState);
01366 if ( error != JVMTI_ERROR_NONE ) {
01367 HPROF_JVMTI_ERROR(error, "Cannot get thread state");
01368 }
01369 }
01370
01371 void
01372 getThreadInfo(jthread thread, jvmtiThreadInfo *info)
01373
01374 {
01375 jvmtiError error;
01376
01377 HPROF_ASSERT(thread!=NULL);
01378 HPROF_ASSERT(info!=NULL);
01379 (void)memset((void*)info, 0, sizeof(jvmtiThreadInfo));
01380 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
01381 (gdata->jvmti, thread, info);
01382 if ( error != JVMTI_ERROR_NONE ) {
01383 HPROF_JVMTI_ERROR(error, "Cannot get thread info");
01384 }
01385 }
01386
01387 void
01388 getThreadGroupInfo(jthreadGroup thread_group, jvmtiThreadGroupInfo *info)
01389
01390 {
01391 jvmtiError error;
01392
01393 HPROF_ASSERT(info!=NULL);
01394 (void)memset((void*)info, 0, sizeof(jvmtiThreadGroupInfo));
01395 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadGroupInfo)
01396 (gdata->jvmti, thread_group, info);
01397 if ( error != JVMTI_ERROR_NONE ) {
01398 HPROF_JVMTI_ERROR(error, "Cannot get thread group info");
01399 }
01400 }
01401
01402 void
01403 getLoadedClasses(jclass **ppclasses, jint *pcount)
01404
01405 {
01406 jvmtiError error;
01407
01408 *ppclasses = NULL;
01409 *pcount = 0;
01410 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLoadedClasses)
01411 (gdata->jvmti, pcount, ppclasses);
01412 if ( error != JVMTI_ERROR_NONE ) {
01413 HPROF_JVMTI_ERROR(error, "Cannot get all loaded class list");
01414 }
01415 }
01416
01417 static void
01418 getLineNumberTable(jmethodID method, jvmtiLineNumberEntry **ppentries,
01419 jint *pcount)
01420 {
01421 jvmtiError error;
01422
01423 HPROF_ASSERT(method!=NULL);
01424 *ppentries = NULL;
01425 *pcount = 0;
01426 error = JVMTI_FUNC_PTR(gdata->jvmti,GetLineNumberTable)
01427 (gdata->jvmti, method, pcount, ppentries);
01428 if ( error == JVMTI_ERROR_ABSENT_INFORMATION ) {
01429 error = JVMTI_ERROR_NONE;
01430 *ppentries = NULL;
01431 *pcount = 0;
01432 }
01433 if ( error != JVMTI_ERROR_NONE ) {
01434 HPROF_JVMTI_ERROR(error, "Cannot get source line numbers");
01435 }
01436 }
01437
01438 static jint
01439 map_loc2line(jlocation location, jvmtiLineNumberEntry *table, jint count)
01440 {
01441 jint line_number;
01442 int i;
01443 int start;
01444 int half;
01445
01446 HPROF_ASSERT(location>=0);
01447 HPROF_ASSERT(count>=0);
01448
01449 line_number = -1;
01450 if ( count == 0 ) {
01451 return line_number;
01452 }
01453
01454
01455 half = count >> 1;
01456 start = 0;
01457 while ( half > 0 ) {
01458 jlocation start_location;
01459
01460 start_location = table[start + half].start_location;
01461 if ( location > start_location ) {
01462 start = start + half;
01463 } else if ( location == start_location ) {
01464 start = start + half;
01465 break;
01466 }
01467 half = half >> 1;
01468 }
01469
01470 HPROF_ASSERT(start < count);
01471
01472
01473 for ( i = start ; i < count ; i++ ) {
01474 if ( location < table[i].start_location ) {
01475 HPROF_ASSERT( ((int)location) < ((int)table[i].start_location) );
01476 break;
01477 }
01478 line_number = table[i].line_number;
01479 }
01480 HPROF_ASSERT(line_number > 0);
01481 return line_number;
01482 }
01483
01484 jint
01485 getLineNumber(jmethodID method, jlocation location)
01486 {
01487 jvmtiLineNumberEntry *line_table;
01488 jint line_count;
01489 jint lineno;
01490
01491 HPROF_ASSERT(method!=NULL);
01492 if ( location < 0 ) {
01493 HPROF_ASSERT(location > -4);
01494 return (jint)location;
01495 }
01496 lineno = -1;
01497
01498 getLineNumberTable(method, &line_table, &line_count);
01499 lineno = map_loc2line(location, line_table, line_count);
01500 jvmtiDeallocate(line_table);
01501
01502 return lineno;
01503 }
01504
01505 jlong
01506 getMaxMemory(JNIEnv *env)
01507 {
01508 jlong max;
01509
01510 HPROF_ASSERT(env!=NULL);
01511
01512 max = (jlong)0;
01513 WITH_LOCAL_REFS(env, 1) {
01514 jclass clazz;
01515 jmethodID getRuntime;
01516 jobject runtime;
01517 jmethodID maxMemory;
01518
01519 clazz = findClass(env, "java/lang/Runtime");
01520 getRuntime = getStaticMethodID(env, clazz, "getRuntime",
01521 "()Ljava/lang/Runtime;");
01522 runtime = callStaticObjectMethod(env, clazz, getRuntime);
01523 maxMemory = getMethodID(env, clazz, "maxMemory", "()J");
01524 max = callLongMethod(env, runtime, maxMemory);
01525 } END_WITH_LOCAL_REFS;
01526 return max;
01527 }
01528
01529 void
01530 createAgentThread(JNIEnv *env, const char *name, jvmtiStartFunction func)
01531 {
01532 jvmtiError error;
01533
01534 HPROF_ASSERT(name!=NULL);
01535 HPROF_ASSERT(func!=NULL);
01536
01537 WITH_LOCAL_REFS(env, 1) {
01538 jclass clazz;
01539 jmethodID threadConstructor;
01540 jmethodID threadSetDaemon;
01541 jthread thread;
01542 jstring nameString;
01543 jthreadGroup systemThreadGroup;
01544 jthreadGroup * groups;
01545 jint groupCount;
01546
01547 thread = NULL;
01548 systemThreadGroup = NULL;
01549 groups = NULL;
01550 clazz = class_get_class(env, gdata->thread_cnum);
01551 HPROF_ASSERT(clazz!=NULL);
01552 threadConstructor = getMethodID(env, clazz, "<init>",
01553 "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
01554 threadSetDaemon = getMethodID(env, clazz, "setDaemon",
01555 "(Z)V");
01556
01557 error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
01558 (gdata->jvmti, &groupCount, &groups);
01559 if ( error == JVMTI_ERROR_NONE ) {
01560 if ( groupCount > 0 ) {
01561 systemThreadGroup = groups[0];
01562 }
01563 jvmtiDeallocate(groups);
01564
01565 nameString = newStringUTF(env, name);
01566 HPROF_ASSERT(nameString!=NULL);
01567 thread = newThreadObject(env, clazz, threadConstructor,
01568 systemThreadGroup, nameString);
01569 HPROF_ASSERT(thread!=NULL);
01570 callVoidMethod(env, thread, threadSetDaemon, JNI_TRUE);
01571
01572 error = JVMTI_FUNC_PTR(gdata->jvmti,RunAgentThread)
01573 (gdata->jvmti, thread, func, NULL, JVMTI_THREAD_MAX_PRIORITY);
01574
01575
01576
01577
01578 tls_agent_thread(env, thread);
01579 }
01580 } END_WITH_LOCAL_REFS;
01581
01582 if ( error != JVMTI_ERROR_NONE ) {
01583 HPROF_JVMTI_ERROR(error, "Cannot create agent thread");
01584 }
01585 }
01586
01587 jlong
01588 getThreadCpuTime(jthread thread)
01589 {
01590 jvmtiError error;
01591 jlong cpuTime;
01592
01593 HPROF_ASSERT(thread!=NULL);
01594 cpuTime = -1;
01595 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadCpuTime)
01596 (gdata->jvmti, thread, &cpuTime);
01597 if ( error != JVMTI_ERROR_NONE ) {
01598 HPROF_JVMTI_ERROR(error, "Cannot get cpu time");
01599 }
01600 return cpuTime;
01601 }
01602
01603
01604 void
01605 getFrameCount(jthread thread, jint *pcount)
01606 {
01607 jvmtiError error;
01608
01609 HPROF_ASSERT(thread!=NULL);
01610 HPROF_ASSERT(pcount!=NULL);
01611 *pcount = 0;
01612 error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
01613 (gdata->jvmti, thread, pcount);
01614 if ( error != JVMTI_ERROR_NONE ) {
01615 *pcount = 0;
01616 }
01617 }
01618
01619
01620 void
01621 getStackTrace(jthread thread, jvmtiFrameInfo *pframes, jint depth, jint *pcount)
01622 {
01623 jvmtiError error;
01624
01625 HPROF_ASSERT(thread!=NULL);
01626 HPROF_ASSERT(pframes!=NULL);
01627 HPROF_ASSERT(depth >= 0);
01628 HPROF_ASSERT(pcount!=NULL);
01629 *pcount = 0;
01630 error = JVMTI_FUNC_PTR(gdata->jvmti,GetStackTrace)
01631 (gdata->jvmti, thread, 0, depth, pframes, pcount);
01632 if ( error != JVMTI_ERROR_NONE ) {
01633 *pcount = 0;
01634 }
01635 }
01636
01637 void
01638 getThreadListStackTraces(jint count, jthread *threads,
01639 jint depth, jvmtiStackInfo **stack_info)
01640 {
01641 jvmtiError error;
01642
01643 HPROF_ASSERT(threads!=NULL);
01644 HPROF_ASSERT(stack_info!=NULL);
01645 HPROF_ASSERT(depth >= 0);
01646 HPROF_ASSERT(count > 0);
01647 *stack_info = NULL;
01648 error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadListStackTraces)
01649 (gdata->jvmti, count, threads, depth, stack_info);
01650 if ( error != JVMTI_ERROR_NONE ) {
01651 HPROF_JVMTI_ERROR(error, "Cannot get thread list stack info");
01652 }
01653 }
01654
01655 void
01656 followReferences(jvmtiHeapCallbacks *pHeapCallbacks, void *user_data)
01657 {
01658 jvmtiError error;
01659
01660 error = JVMTI_FUNC_PTR(gdata->jvmti,FollowReferences)
01661 (gdata->jvmti, 0, NULL, NULL, pHeapCallbacks, user_data);
01662 if ( error != JVMTI_ERROR_NONE ) {
01663 HPROF_JVMTI_ERROR(error, "Cannot follow references");
01664 }
01665 }
01666
01667
01668 void
01669 runGC(void)
01670 {
01671 jvmtiError error;
01672 error = JVMTI_FUNC_PTR(gdata->jvmti,ForceGarbageCollection)
01673 (gdata->jvmti);
01674 if ( error != JVMTI_ERROR_NONE ) {
01675 HPROF_JVMTI_ERROR(error, "Cannot force garbage collection");
01676 }
01677 }
01678
01679
01680
01681
01682 void
01683 getJvmti(void)
01684 {
01685 jvmtiEnv *jvmti = NULL;
01686 jint res;
01687 jint jvmtiCompileTimeMajorVersion;
01688 jint jvmtiCompileTimeMinorVersion;
01689 jint jvmtiCompileTimeMicroVersion;
01690
01691 res = JVM_FUNC_PTR(gdata->jvm,GetEnv)
01692 (gdata->jvm, (void **)&jvmti, JVMTI_VERSION_1);
01693 if (res != JNI_OK) {
01694 char buf[256];
01695
01696 (void)md_snprintf(buf, sizeof(buf),
01697 "Unable to access JVMTI Version 1 (0x%x),"
01698 " is your JDK a 5.0 or newer version?"
01699 " JNIEnv's GetEnv() returned %d",
01700 JVMTI_VERSION_1, res);
01701 buf[sizeof(buf)-1] = 0;
01702 HPROF_ERROR(JNI_FALSE, buf);
01703 error_exit_process(1);
01704 }
01705 gdata->jvmti = jvmti;
01706
01707
01708
01709
01710 jvmtiCompileTimeMajorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MAJOR )
01711 >> JVMTI_VERSION_SHIFT_MAJOR;
01712 jvmtiCompileTimeMinorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MINOR )
01713 >> JVMTI_VERSION_SHIFT_MINOR;
01714 jvmtiCompileTimeMicroVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MICRO )
01715 >> JVMTI_VERSION_SHIFT_MICRO;
01716 if ( !compatible_versions(jvmtiMajorVersion(), jvmtiMinorVersion(),
01717 jvmtiCompileTimeMajorVersion, jvmtiCompileTimeMinorVersion) ) {
01718 char buf[256];
01719
01720 (void)md_snprintf(buf, sizeof(buf),
01721 "This " AGENTNAME " native library will not work with this VM's "
01722 "version of JVMTI (%d.%d.%d), it needs JVMTI %d.%d[.%d]."
01723 ,
01724 jvmtiMajorVersion(),
01725 jvmtiMinorVersion(),
01726 jvmtiMicroVersion(),
01727 jvmtiCompileTimeMajorVersion,
01728 jvmtiCompileTimeMinorVersion,
01729 jvmtiCompileTimeMicroVersion);
01730 buf[sizeof(buf)-1] = 0;
01731 HPROF_ERROR(JNI_FALSE, buf);
01732 error_exit_process(1);
01733 }
01734 }
01735