--- a/jdk/src/jdk.hprof.agent/share/native/libhprof/hprof_util.c Thu Aug 20 11:38:20 2015 -0700
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1738 +0,0 @@
-/*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of Oracle nor the names of its
- * contributors may be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
- * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * This source code is provided to illustrate the usage of a given feature
- * or technique and has been deliberately simplified. Additional steps
- * required for a production-quality application, such as security checks,
- * input validation and proper error handling, might not be present in
- * this sample code.
- */
-
-
-/* General utility functions. */
-
-/*
- * Wrappers over JVM, JNI, and JVMTI functions are placed here.
- *
- * All memory allocation and deallocation goes through jvmtiAllocate()
- * and jvmtiDeallocate().
- *
- */
-
-
-#include "hprof.h"
-
-/* Macro to get JNI function pointer. */
-#define JNI_FUNC_PTR(env,f) (*((*(env))->f))
-
-/* Macro to get JVM function pointer. */
-#define JVM_FUNC_PTR(env,f) (*((*(env))->f))
-
-/* Macro to get JVMTI function pointer. */
-#define JVMTI_FUNC_PTR(env,f) (*((*(env))->f))
-
-/* ------------------------------------------------------------------- */
-/* JVM functions */
-
-JNIEnv *
-getEnv(void)
-{
- JNIEnv *env;
- jint res;
-
- res = JVM_FUNC_PTR(gdata->jvm,GetEnv)
- (gdata->jvm, (void **)&env, JNI_VERSION_1_2);
- if (res != JNI_OK) {
- char buf[256];
-
- (void)md_snprintf(buf, sizeof(buf),
- "Unable to access JNI Version 1.2 (0x%x),"
- " is your JDK a 5.0 or newer version?"
- " JNIEnv's GetEnv() returned %d",
- JNI_VERSION_1_2, res);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_FALSE, buf);
- error_exit_process(1); /* Kill entire process, no core dump */
- }
- return env;
-}
-
-/* ------------------------------------------------------------------- */
-/* Memory Allocation */
-
-void *
-jvmtiAllocate(int size)
-{
- jvmtiError error;
- unsigned char *ptr;
-
- HPROF_ASSERT(size>=0);
- ptr = NULL;
- if ( size == 0 ) {
- return ptr;
- }
- error = JVMTI_FUNC_PTR(gdata->jvmti,Allocate)
- (gdata->jvmti, (jlong)size, &ptr);
- if ( error != JVMTI_ERROR_NONE || ptr == NULL ) {
- HPROF_JVMTI_ERROR(error, "Cannot allocate jvmti memory");
- }
- return (void*)ptr;
-}
-
-void
-jvmtiDeallocate(void *ptr)
-{
- if ( ptr != NULL ) {
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,Deallocate)
- (gdata->jvmti, (unsigned char*)ptr);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot deallocate jvmti memory");
- }
- }
-}
-
-#ifdef DEBUG
-
-void *
-hprof_debug_malloc(int size, char *file, int line)
-{
- void *ptr;
-
- HPROF_ASSERT(size>0);
-
- rawMonitorEnter(gdata->debug_malloc_lock); {
- ptr = debug_malloc(size, file, line);
- } rawMonitorExit(gdata->debug_malloc_lock);
-
- if ( ptr == NULL ) {
- HPROF_ERROR(JNI_TRUE, "Cannot allocate malloc memory");
- }
- return ptr;
-}
-
-void
-hprof_debug_free(void *ptr, char *file, int line)
-{
- HPROF_ASSERT(ptr!=NULL);
-
- rawMonitorEnter(gdata->debug_malloc_lock); {
- (void)debug_free(ptr, file, line);
- } rawMonitorExit(gdata->debug_malloc_lock);
-}
-
-#endif
-
-void *
-hprof_malloc(int size)
-{
- void *ptr;
-
- HPROF_ASSERT(size>0);
- ptr = malloc(size);
- if ( ptr == NULL ) {
- HPROF_ERROR(JNI_TRUE, "Cannot allocate malloc memory");
- }
- return ptr;
-}
-
-void
-hprof_free(void *ptr)
-{
- HPROF_ASSERT(ptr!=NULL);
- (void)free(ptr);
-}
-
-/* ------------------------------------------------------------------- */
-/* JVMTI Version functions */
-
-jint
-jvmtiVersion(void)
-{
- if (gdata->cachedJvmtiVersion == 0) {
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetVersionNumber)
- (gdata->jvmti, &(gdata->cachedJvmtiVersion));
- if (error != JVMTI_ERROR_NONE) {
- HPROF_JVMTI_ERROR(error, "Cannot get jvmti version number");
- }
- }
- return gdata->cachedJvmtiVersion;
-}
-
-static jint
-jvmtiMajorVersion(void)
-{
- return (jvmtiVersion() & JVMTI_VERSION_MASK_MAJOR)
- >> JVMTI_VERSION_SHIFT_MAJOR;
-}
-
-static jint
-jvmtiMinorVersion(void)
-{
- return (jvmtiVersion() & JVMTI_VERSION_MASK_MINOR)
- >> JVMTI_VERSION_SHIFT_MINOR;
-}
-
-static jint
-jvmtiMicroVersion(void)
-{
- return (jvmtiVersion() & JVMTI_VERSION_MASK_MICRO)
- >> JVMTI_VERSION_SHIFT_MICRO;
-}
-
-/* Logic to determine JVMTI version compatibility */
-static jboolean
-compatible_versions(jint major_runtime, jint minor_runtime,
- jint major_compiletime, jint minor_compiletime)
-{
- /* Runtime major version must match. */
- if ( major_runtime != major_compiletime ) {
- return JNI_FALSE;
- }
- /* Runtime minor version must be >= the version compiled with. */
- if ( minor_runtime < minor_compiletime ) {
- return JNI_FALSE;
- }
- /* Assumed compatible */
- return JNI_TRUE;
-}
-
-/* ------------------------------------------------------------------- */
-/* JVMTI Raw Monitor support functions */
-
-jrawMonitorID
-createRawMonitor(const char *str)
-{
- jvmtiError error;
- jrawMonitorID m;
-
- m = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,CreateRawMonitor)
- (gdata->jvmti, str, &m);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot create raw monitor");
- }
- return m;
-}
-
-void
-rawMonitorEnter(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorEnter)
- (gdata->jvmti, m);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok, after agent shutdown CALLBACK code may call this */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot enter with raw monitor");
- }
-}
-
-void
-rawMonitorWait(jrawMonitorID m, jlong pause_time)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorWait)
- (gdata->jvmti, m, pause_time);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot wait with raw monitor");
- }
-}
-
-void
-rawMonitorNotifyAll(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorNotifyAll)
- (gdata->jvmti, m);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot notify all with raw monitor");
- }
-}
-
-void
-rawMonitorExit(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RawMonitorExit)
- (gdata->jvmti, m);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok, after agent shutdown CALLBACK code may call this */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot exit with raw monitor");
- }
-}
-
-void
-destroyRawMonitor(jrawMonitorID m)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,DestroyRawMonitor)
- (gdata->jvmti, m);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot destroy raw monitor");
- }
-}
-
-/* ------------------------------------------------------------------- */
-/* JVMTI Event enabling/disabilin */
-
-void
-setEventNotificationMode(jvmtiEventMode mode, jvmtiEvent event, jthread thread)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode)
- (gdata->jvmti, mode, event, thread);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot set event notification");
- }
-}
-
-/* ---------------------------------------------------------------------- */
-/* JNI Support Functions */
-
-jobject
-exceptionOccurred(JNIEnv *env)
-{
- return JNI_FUNC_PTR(env,ExceptionOccurred)(env);
-}
-
-void
-exceptionDescribe(JNIEnv *env)
-{
- JNI_FUNC_PTR(env,ExceptionDescribe)(env);
-}
-
-void
-exceptionClear(JNIEnv *env)
-{
- JNI_FUNC_PTR(env,ExceptionClear)(env);
-}
-
-jobject
-newGlobalReference(JNIEnv *env, jobject object)
-{
- jobject gref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- gref = JNI_FUNC_PTR(env,NewGlobalRef)(env, object);
- HPROF_ASSERT(gref!=NULL);
- return gref;
-}
-
-jobject
-newWeakGlobalReference(JNIEnv *env, jobject object)
-{
- jobject gref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- gref = JNI_FUNC_PTR(env,NewWeakGlobalRef)(env, object);
- HPROF_ASSERT(gref!=NULL);
- return gref;
-}
-
-void
-deleteGlobalReference(JNIEnv *env, jobject object)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- JNI_FUNC_PTR(env,DeleteGlobalRef)(env, object);
-}
-
-jobject
-newLocalReference(JNIEnv *env, jobject object)
-{
- jobject lref;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- lref = JNI_FUNC_PTR(env,NewLocalRef)(env, object);
- /* Possible for a non-null weak reference to return a NULL localref */
- return lref;
-}
-
-void
-deleteLocalReference(JNIEnv *env, jobject object)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- JNI_FUNC_PTR(env,DeleteLocalRef)(env, object);
-}
-
-void
-deleteWeakGlobalReference(JNIEnv *env, jobject object)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- JNI_FUNC_PTR(env,DeleteWeakGlobalRef)(env, object);
-}
-
-jclass
-getObjectClass(JNIEnv *env, jobject object)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass clazz;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, object);
- HPROF_ASSERT(clazz!=NULL);
- return clazz;
-}
-
-jclass
-getSuperclass(JNIEnv *env, jclass klass)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass super_klass;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(klass!=NULL);
- super_klass = JNI_FUNC_PTR(env,GetSuperclass)(env, klass);
- return super_klass;
-}
-
-jmethodID
-getStaticMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
- jmethodID method;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(sig!=NULL);
- CHECK_EXCEPTIONS(env) {
- method = JNI_FUNC_PTR(env,GetStaticMethodID)(env, clazz, name, sig);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(method!=NULL);
- return method;
-}
-
-jmethodID
-getMethodID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
- jmethodID method;
- jobject exception;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(sig!=NULL);
- method = JNI_FUNC_PTR(env,GetMethodID)(env, clazz, name, sig);
- /* Might be a static method */
- exception = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
- if ( exception != NULL ) {
- JNI_FUNC_PTR(env,ExceptionClear)(env);
- method = getStaticMethodID(env, clazz, name, sig);
- }
- HPROF_ASSERT(method!=NULL);
- return method;
-}
-
-jclass
-findClass(JNIEnv *env, const char *name)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass clazz;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(name!=NULL);
- LOG2("FindClass", name);
- CHECK_EXCEPTIONS(env) {
- clazz = JNI_FUNC_PTR(env,FindClass)(env, name);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(clazz!=NULL);
- return clazz;
-}
-
-jfieldID
-getStaticFieldID(JNIEnv *env, jclass clazz, const char *name, const char *sig)
-{
- jfieldID field;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(sig!=NULL);
- CHECK_EXCEPTIONS(env) {
- field = JNI_FUNC_PTR(env,GetStaticFieldID)(env, clazz, name, sig);
- } END_CHECK_EXCEPTIONS;
- return field;
-}
-
-void
-setStaticIntField(JNIEnv *env, jclass clazz, jfieldID field, jint value)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(field!=NULL);
- CHECK_EXCEPTIONS(env) {
- JNI_FUNC_PTR(env,SetStaticIntField)(env, clazz, field, value);
- } END_CHECK_EXCEPTIONS;
-}
-
-static jobject
-callStaticObjectMethod(JNIEnv *env, jclass klass, jmethodID method)
-{
- jobject x;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(klass!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- x = JNI_FUNC_PTR(env,CallStaticObjectMethod)(env, klass, method);
- } END_CHECK_EXCEPTIONS;
- return x;
-}
-
-static jlong
-callLongMethod(JNIEnv *env, jobject object, jmethodID method)
-{
- jlong x;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- x = JNI_FUNC_PTR(env,CallLongMethod)(env, object, method);
- } END_CHECK_EXCEPTIONS;
- return x;
-}
-
-static void
-callVoidMethod(JNIEnv *env, jobject object, jmethodID method, jboolean arg)
-{
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(object!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- JNI_FUNC_PTR(env,CallVoidMethod)(env, object, method, arg);
- } END_CHECK_EXCEPTIONS;
-}
-
-static jstring
-newStringUTF(JNIEnv *env, const char *name)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jstring string;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(name!=NULL);
- CHECK_EXCEPTIONS(env) {
- string = JNI_FUNC_PTR(env,NewStringUTF)(env, name);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(string!=NULL);
- return string;
-}
-
-static jobject
-newThreadObject(JNIEnv *env, jclass clazz, jmethodID method,
- jthreadGroup group, jstring name)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jthread thread;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(method!=NULL);
- CHECK_EXCEPTIONS(env) {
- thread = JNI_FUNC_PTR(env,NewObject)(env, clazz, method, group, name);
- } END_CHECK_EXCEPTIONS;
- HPROF_ASSERT(thread!=NULL);
- return thread;
-}
-
-jboolean
-isSameObject(JNIEnv *env, jobject o1, jobject o2)
-{
- HPROF_ASSERT(env!=NULL);
- if ( o1 == o2 || JNI_FUNC_PTR(env,IsSameObject)(env, o1, o2) ) {
- return JNI_TRUE;
- }
- return JNI_FALSE;
-}
-
-void
-pushLocalFrame(JNIEnv *env, jint capacity)
-{
- HPROF_ASSERT(env!=NULL);
- CHECK_EXCEPTIONS(env) {
- jint ret;
-
- ret = JNI_FUNC_PTR(env,PushLocalFrame)(env, capacity);
- if ( ret != 0 ) {
- HPROF_ERROR(JNI_TRUE, "JNI PushLocalFrame returned non-zero");
- }
- } END_CHECK_EXCEPTIONS;
-}
-
-void
-popLocalFrame(JNIEnv *env, jobject result)
-{
- jobject ret;
-
- HPROF_ASSERT(env!=NULL);
- ret = JNI_FUNC_PTR(env,PopLocalFrame)(env, result);
- if ( (result != NULL && ret == NULL) || (result == NULL && ret != NULL) ) {
- HPROF_ERROR(JNI_TRUE, "JNI PopLocalFrame returned wrong object");
- }
-}
-
-void
-registerNatives(JNIEnv *env, jclass clazz,
- JNINativeMethod *methods, jint count)
-{
- jint ret;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(clazz!=NULL);
- HPROF_ASSERT(methods!=NULL);
- HPROF_ASSERT(count>0);
- ret = JNI_FUNC_PTR(env,RegisterNatives)(env, clazz, methods, count);
- if ( ret != 0 ) {
- HPROF_ERROR(JNI_TRUE, "JNI RegisterNatives returned non-zero");
- }
-}
-
-/* ---------------------------------------------------------------------- */
-/* JVMTI Support Functions */
-
-char *
-getErrorName(jvmtiError error_number)
-{
- char *error_name;
-
- error_name = NULL;
- (void)JVMTI_FUNC_PTR(gdata->jvmti,GetErrorName)
- (gdata->jvmti, error_number, &error_name);
- return error_name;
-}
-
-jvmtiPhase
-getPhase(void)
-{
- jvmtiPhase phase;
-
- phase = 0;
- (void)JVMTI_FUNC_PTR(gdata->jvmti,GetPhase)(gdata->jvmti, &phase);
- return phase;
-}
-
-char *
-phaseString(jvmtiPhase phase)
-{
- switch ( phase ) {
- case JVMTI_PHASE_ONLOAD:
- return "onload";
- case JVMTI_PHASE_PRIMORDIAL:
- return "primordial";
- case JVMTI_PHASE_START:
- return "start";
- case JVMTI_PHASE_LIVE:
- return "live";
- case JVMTI_PHASE_DEAD:
- return "dead";
- }
- return "unknown";
-}
-
-void
-disposeEnvironment(void)
-{
- (void)JVMTI_FUNC_PTR(gdata->jvmti,DisposeEnvironment)
- (gdata->jvmti);
-}
-
-jlong
-getObjectSize(jobject object)
-{
- jlong size;
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- size = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectSize)
- (gdata->jvmti, object, &size);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get object size");
- }
- return size;
-}
-
-static jboolean
-isInterface(jclass klass)
-{
- jvmtiError error;
- jboolean answer;
-
- HPROF_ASSERT(klass!=NULL);
- answer = JNI_FALSE;
- error = JVMTI_FUNC_PTR(gdata->jvmti,IsInterface)
- (gdata->jvmti, klass, &answer);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot call IsInterface");
- }
- return answer;
-}
-
-jint
-getClassStatus(jclass klass)
-{
- jvmtiError error;
- jint status;
-
- HPROF_ASSERT(klass!=NULL);
- status = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassStatus)
- (gdata->jvmti, klass, &status);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- status = 0;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class status");
- }
- return status;
-}
-
-jobject
-getClassLoader(jclass klass)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
- jobject loader;
-
- HPROF_ASSERT(klass!=NULL);
- loader = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassLoader)
- (gdata->jvmti, klass, &loader);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class loader");
- }
- return loader;
-}
-
-jlong
-getTag(jobject object)
-{
- jlong tag;
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- tag = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetTag)
- (gdata->jvmti, object, &tag);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get object tag");
- }
- return tag;
-}
-
-void
-setTag(jobject object, jlong tag)
-{
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetTag)
- (gdata->jvmti, object, tag);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot set object tag");
- }
-}
-
-void
-getObjectMonitorUsage(jobject object, jvmtiMonitorUsage *uinfo)
-{
- jvmtiError error;
-
- HPROF_ASSERT(object!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetObjectMonitorUsage)
- (gdata->jvmti, object, uinfo);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get monitor usage info");
- }
-}
-
-void
-getOwnedMonitorInfo(jthread thread, jobject **ppobjects, jint *pcount)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(ppobjects!=NULL);
- HPROF_ASSERT(pcount!=NULL);
- *pcount = 0;
- *ppobjects = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetOwnedMonitorInfo)
- (gdata->jvmti, thread, pcount, ppobjects);
- if ( error == JVMTI_ERROR_THREAD_NOT_ALIVE ) {
- *pcount = 0;
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread owned monitor info");
- }
-}
-
-void
-getSystemProperty(const char *name, char **value)
-{
- jvmtiError error;
-
- HPROF_ASSERT(name!=NULL);
- *value = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetSystemProperty)
- (gdata->jvmti, name, value);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get system property");
- }
-}
-
-void
-getClassSignature(jclass klass, char** psignature, char **pgeneric_signature)
-{
- jvmtiError error;
- char *generic_signature;
-
- HPROF_ASSERT(klass!=NULL);
- *psignature = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassSignature)
- (gdata->jvmti, klass, psignature, &generic_signature);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class signature");
- }
- if ( pgeneric_signature != NULL ) {
- *pgeneric_signature = generic_signature;
- } else {
- jvmtiDeallocate(generic_signature);
- }
-}
-
-void
-getSourceFileName(jclass klass, char** pname)
-{
- jvmtiError error;
-
- HPROF_ASSERT(klass!=NULL);
- *pname = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetSourceFileName)
- (gdata->jvmti, klass, pname);
- if ( error == JVMTI_ERROR_ABSENT_INFORMATION ) {
- error = JVMTI_ERROR_NONE;
- *pname = NULL;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get source file name");
- }
-}
-
-static void
-getClassFields(jclass klass, jint* pn_fields, jfieldID** pfields)
-{
- jvmtiError error;
- jint status;
-
- HPROF_ASSERT(klass!=NULL);
- *pn_fields = 0;
- *pfields = NULL;
-
- /* Get class status */
- status = getClassStatus(klass);
-
- /* Arrays have no fields */
- if ( status & JVMTI_CLASS_STATUS_ARRAY ) {
- return;
- }
-
- /* Primitives have no fields */
- if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {
- return;
- }
-
- /* If the class is not prepared, we have a problem? */
- if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {
- HPROF_ERROR(JNI_FALSE, "Class not prepared when needing fields");
- return;
- }
-
- /* Now try and get all the fields */
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetClassFields)
- (gdata->jvmti, klass, pn_fields, pfields);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class field list");
- }
-}
-
-static jint
-getFieldModifiers(jclass klass, jfieldID field)
-{
- jvmtiError error;
- jint modifiers;
-
- HPROF_ASSERT(klass!=NULL);
- HPROF_ASSERT(field!=NULL);
- modifiers = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldModifiers)
- (gdata->jvmti, klass, field, &modifiers);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get field modifiers");
- }
- return modifiers;
-}
-
-static void
-getFieldName(jclass klass, jfieldID field, char** pname, char** psignature,
- char **pgeneric_signature)
-{
- jvmtiError error;
- char *generic_signature;
-
- generic_signature = NULL;
- *pname = NULL;
- *psignature = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetFieldName)
- (gdata->jvmti, klass, field, pname, psignature, &generic_signature);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get field name");
- }
- if ( pgeneric_signature != NULL ) {
- *pgeneric_signature = generic_signature;
- } else {
- jvmtiDeallocate(generic_signature);
- }
-}
-
-static void
-getImplementedInterfaces(jclass klass, jint* pn_interfaces,
- jclass** pinterfaces)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- *pn_interfaces = 0;
- *pinterfaces = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetImplementedInterfaces)
- (gdata->jvmti, klass, pn_interfaces, pinterfaces);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get class interface list");
- }
-}
-
-static ClassIndex
-get_cnum(JNIEnv *env, jclass klass)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- ClassIndex cnum;
- LoaderIndex loader_index;
- char *sig;
- jobject loader;
-
- loader = getClassLoader(klass);
- loader_index = loader_find_or_create(env, loader);
- getClassSignature(klass, &sig, NULL);
- cnum = class_find_or_create(sig, loader_index);
- jvmtiDeallocate(sig);
- (void)class_new_classref(env, cnum, klass);
- return cnum;
-}
-
-/* From primitive type, get signature letter */
-char
-primTypeToSigChar(jvmtiPrimitiveType primType)
-{
- char sig_ch;
-
- sig_ch = 0;
- switch ( primType ) {
- case JVMTI_PRIMITIVE_TYPE_BYTE:
- sig_ch = JVM_SIGNATURE_BYTE;
- break;
- case JVMTI_PRIMITIVE_TYPE_CHAR:
- sig_ch = JVM_SIGNATURE_CHAR;
- break;
- case JVMTI_PRIMITIVE_TYPE_FLOAT:
- sig_ch = JVM_SIGNATURE_FLOAT;
- break;
- case JVMTI_PRIMITIVE_TYPE_DOUBLE:
- sig_ch = JVM_SIGNATURE_DOUBLE;
- break;
- case JVMTI_PRIMITIVE_TYPE_INT:
- sig_ch = JVM_SIGNATURE_INT;
- break;
- case JVMTI_PRIMITIVE_TYPE_LONG:
- sig_ch = JVM_SIGNATURE_LONG;
- break;
- case JVMTI_PRIMITIVE_TYPE_SHORT:
- sig_ch = JVM_SIGNATURE_SHORT;
- break;
- case JVMTI_PRIMITIVE_TYPE_BOOLEAN:
- sig_ch = JVM_SIGNATURE_BOOLEAN;
- break;
- default:
- sig_ch = 0;
- break;
- }
- return sig_ch;
-}
-
-/* From signature, get primitive type */
-jvmtiPrimitiveType
-sigToPrimType(char *sig)
-{
- jvmtiPrimitiveType primType;
-
- primType = 0;
- if ( sig == NULL || sig[0] == 0 ) {
- return primType;
- }
- switch ( sig[0] ) {
- case JVM_SIGNATURE_BYTE:
- primType = JVMTI_PRIMITIVE_TYPE_BYTE;
- break;
- case JVM_SIGNATURE_CHAR:
- primType = JVMTI_PRIMITIVE_TYPE_CHAR;
- break;
- case JVM_SIGNATURE_FLOAT:
- primType = JVMTI_PRIMITIVE_TYPE_FLOAT;
- break;
- case JVM_SIGNATURE_DOUBLE:
- primType = JVMTI_PRIMITIVE_TYPE_DOUBLE;
- break;
- case JVM_SIGNATURE_INT:
- primType = JVMTI_PRIMITIVE_TYPE_INT;
- break;
- case JVM_SIGNATURE_LONG:
- primType = JVMTI_PRIMITIVE_TYPE_LONG;
- break;
- case JVM_SIGNATURE_SHORT:
- primType = JVMTI_PRIMITIVE_TYPE_SHORT;
- break;
- case JVM_SIGNATURE_BOOLEAN:
- primType = JVMTI_PRIMITIVE_TYPE_BOOLEAN;
- break;
- }
- return primType;
-}
-
-/* From signature, get primitive size */
-int
-sigToPrimSize(char *sig)
-{
- unsigned size;
-
- size = 0;
- if ( sig == NULL || sig[0] == 0 ) {
- return size;
- }
- switch ( sig[0] ) {
- case JVM_SIGNATURE_BYTE:
- case JVM_SIGNATURE_BOOLEAN:
- size = 1;
- break;
- case JVM_SIGNATURE_CHAR:
- case JVM_SIGNATURE_SHORT:
- size = 2;
- break;
- case JVM_SIGNATURE_FLOAT:
- case JVM_SIGNATURE_INT:
- size = 4;
- break;
- case JVM_SIGNATURE_DOUBLE:
- case JVM_SIGNATURE_LONG:
- size = 8;
- break;
- }
- return size;
-}
-
-static void
-add_class_fields(JNIEnv *env, ClassIndex top_cnum, ClassIndex cnum,
- jclass klass, Stack *field_list, Stack *class_list)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jclass *interfaces;
- jint n_interfaces;
- jfieldID *idlist;
- jint n_fields;
- int i;
- int depth;
- int skip_static_field_names;
- jint status;
-
- HPROF_ASSERT(env!=NULL);
- HPROF_ASSERT(klass!=NULL);
- HPROF_ASSERT(field_list!=NULL);
- HPROF_ASSERT(class_list!=NULL);
-
- /* If not the initial class, we can skip the static fields (perf issue) */
- skip_static_field_names = (cnum != top_cnum);
-
- /* Get class status */
- status = getClassStatus(klass);
-
- /* Arrays have no fields */
- if ( status & JVMTI_CLASS_STATUS_ARRAY ) {
- return;
- }
-
- /* Primitives have no fields */
- if ( status & JVMTI_CLASS_STATUS_PRIMITIVE ) {
- return;
- }
-
- /* If the class is not prepared, we have a problem? */
- if ( !(status & JVMTI_CLASS_STATUS_PREPARED) ) {
- char *sig;
-
- getClassSignature(klass, &sig, NULL);
- debug_message("Class signature is: %s\n", sig);
- HPROF_ERROR(JNI_FALSE, "Class not prepared when needing all fields");
- jvmtiDeallocate(sig);
- return;
- }
-
- /* See if class already processed */
- depth = stack_depth(class_list);
- for ( i = depth-1 ; i >= 0 ; i-- ) {
- if ( isSameObject(env, klass, *(jclass*)stack_element(class_list, i)) ) {
- return;
- }
- }
-
- /* Class or Interface, do implemented interfaces recursively */
- getImplementedInterfaces(klass, &n_interfaces, &interfaces);
- for ( i = 0 ; i < n_interfaces ; i++ ) {
- add_class_fields(env, top_cnum,
- get_cnum(env, interfaces[i]), interfaces[i],
- field_list, class_list);
- }
- jvmtiDeallocate(interfaces);
-
- /* Begin graph traversal, go up super chain recursively */
- if ( !isInterface(klass) ) {
- jclass super_klass;
-
- super_klass = getSuperclass(env, klass);
- if ( super_klass != NULL ) {
- add_class_fields(env, top_cnum,
- get_cnum(env, super_klass), super_klass,
- field_list, class_list);
- }
- }
-
-
- /* Only now we add klass to list so we don't repeat it later */
- stack_push(class_list, &klass);
-
- /* Now actually add the fields for this klass */
- getClassFields(klass, &n_fields, &idlist);
- for ( i = 0 ; i < n_fields ; i++ ) {
- FieldInfo finfo;
- static FieldInfo empty_finfo;
-
- finfo = empty_finfo;
- finfo.cnum = cnum;
- finfo.modifiers = (unsigned short)getFieldModifiers(klass, idlist[i]);
- if ( ( finfo.modifiers & JVM_ACC_STATIC ) == 0 ||
- !skip_static_field_names ) {
- char *field_name;
- char *field_sig;
-
- getFieldName(klass, idlist[i], &field_name, &field_sig, NULL);
- finfo.name_index = string_find_or_create(field_name);
- finfo.sig_index = string_find_or_create(field_sig);
- finfo.primType = sigToPrimType(field_sig);
- finfo.primSize = sigToPrimSize(field_sig);
- jvmtiDeallocate(field_name);
- jvmtiDeallocate(field_sig);
- }
- stack_push(field_list, &finfo);
- }
- jvmtiDeallocate(idlist);
-}
-
-void
-getAllClassFieldInfo(JNIEnv *env, jclass klass,
- jint* pn_fields, FieldInfo** pfields)
-{
- ClassIndex cnum;
-
- *pfields = NULL;
- *pn_fields = 0;
-
- WITH_LOCAL_REFS(env, 1) {
- Stack *class_list;
- Stack *field_list;
- int nbytes;
-
- cnum = get_cnum(env, klass);
- class_list = stack_init( 16, 16, (int)sizeof(jclass));
- field_list = stack_init(128, 128, (int)sizeof(FieldInfo));
- add_class_fields(env, cnum, cnum, klass, field_list, class_list);
- *pn_fields = stack_depth(field_list);
- if ( (*pn_fields) > 0 ) {
- nbytes = (*pn_fields) * (int)sizeof(FieldInfo);
- *pfields = (FieldInfo*)HPROF_MALLOC(nbytes);
- (void)memcpy(*pfields, stack_element(field_list, 0), nbytes);
- }
- stack_term(field_list);
- stack_term(class_list);
- } END_WITH_LOCAL_REFS;
-}
-
-void
-getMethodClass(jmethodID method, jclass *pclazz)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(method!=NULL);
- *pclazz = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodDeclaringClass)
- (gdata->jvmti, method, pclazz);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get method class");
- }
-}
-
-jboolean
-isMethodNative(jmethodID method)
-{
- jvmtiError error;
- jboolean isNative;
-
- HPROF_ASSERT(method!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,IsMethodNative)
- (gdata->jvmti, method, &isNative);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot check is method native");
- }
- return isNative;
-}
-
-void
-getMethodName(jmethodID method, char** pname, char** psignature)
-{
- jvmtiError error;
- char *generic_signature;
-
- HPROF_ASSERT(method!=NULL);
- generic_signature = NULL;
- *pname = NULL;
- *psignature = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetMethodName)
- (gdata->jvmti, method, pname, psignature, &generic_signature);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get method name");
- }
- jvmtiDeallocate(generic_signature);
-}
-
-void
-getPotentialCapabilities(jvmtiCapabilities *pcapabilities)
-{
- jvmtiError error;
-
- (void)memset(pcapabilities,0,sizeof(jvmtiCapabilities));
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetPotentialCapabilities)
- (gdata->jvmti, pcapabilities);
- if (error != JVMTI_ERROR_NONE) {
- HPROF_ERROR(JNI_FALSE, "Unable to get potential JVMTI capabilities.");
- error_exit_process(1); /* Kill entire process, no core dump wanted */
- }
-}
-
-void
-addCapabilities(jvmtiCapabilities *pcapabilities)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,AddCapabilities)
- (gdata->jvmti, pcapabilities);
- if (error != JVMTI_ERROR_NONE) {
- HPROF_ERROR(JNI_FALSE, "Unable to get necessary JVMTI capabilities.");
- error_exit_process(1); /* Kill entire process, no core dump wanted */
- }
-}
-
-void
-setEventCallbacks(jvmtiEventCallbacks *pcallbacks)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
- (gdata->jvmti, pcallbacks, (int)sizeof(jvmtiEventCallbacks));
- if (error != JVMTI_ERROR_NONE) {
- HPROF_JVMTI_ERROR(error, "Cannot set jvmti callbacks");
- }
-
-}
-
-void *
-getThreadLocalStorage(jthread thread)
-{
- jvmtiError error;
- void *ptr;
-
- HPROF_ASSERT(thread!=NULL);
- ptr = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadLocalStorage)
- (gdata->jvmti, thread, &ptr);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- ptr = NULL;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread local storage");
- }
- return ptr;
-}
-
-void
-setThreadLocalStorage(jthread thread, void *ptr)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- error = JVMTI_FUNC_PTR(gdata->jvmti,SetThreadLocalStorage)
- (gdata->jvmti, thread, (const void *)ptr);
- if ( error == JVMTI_ERROR_WRONG_PHASE ) {
- /* Treat this as ok */
- error = JVMTI_ERROR_NONE;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot set thread local storage");
- }
-}
-
-void
-getThreadState(jthread thread, jint *threadState)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(threadState!=NULL);
- *threadState = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadState)
- (gdata->jvmti, thread, threadState);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread state");
- }
-}
-
-void
-getThreadInfo(jthread thread, jvmtiThreadInfo *info)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(info!=NULL);
- (void)memset((void*)info, 0, sizeof(jvmtiThreadInfo));
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadInfo)
- (gdata->jvmti, thread, info);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread info");
- }
-}
-
-void
-getThreadGroupInfo(jthreadGroup thread_group, jvmtiThreadGroupInfo *info)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- HPROF_ASSERT(info!=NULL);
- (void)memset((void*)info, 0, sizeof(jvmtiThreadGroupInfo));
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadGroupInfo)
- (gdata->jvmti, thread_group, info);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread group info");
- }
-}
-
-void
-getLoadedClasses(jclass **ppclasses, jint *pcount)
-/* WARNING: Must be called inside WITH_LOCAL_REFS */
-{
- jvmtiError error;
-
- *ppclasses = NULL;
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetLoadedClasses)
- (gdata->jvmti, pcount, ppclasses);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get all loaded class list");
- }
-}
-
-static void
-getLineNumberTable(jmethodID method, jvmtiLineNumberEntry **ppentries,
- jint *pcount)
-{
- jvmtiError error;
-
- HPROF_ASSERT(method!=NULL);
- *ppentries = NULL;
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetLineNumberTable)
- (gdata->jvmti, method, pcount, ppentries);
- if ( error == JVMTI_ERROR_ABSENT_INFORMATION ) {
- error = JVMTI_ERROR_NONE;
- *ppentries = NULL;
- *pcount = 0;
- }
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get source line numbers");
- }
-}
-
-static jint
-map_loc2line(jlocation location, jvmtiLineNumberEntry *table, jint count)
-{
- jint line_number;
- int i;
- int start;
- int half;
-
- HPROF_ASSERT(location>=0);
- HPROF_ASSERT(count>=0);
-
- line_number = -1;
- if ( count == 0 ) {
- return line_number;
- }
-
- /* Do a binary search */
- half = count >> 1;
- start = 0;
- while ( half > 0 ) {
- jlocation start_location;
-
- start_location = table[start + half].start_location;
- if ( location > start_location ) {
- start = start + half;
- } else if ( location == start_location ) {
- start = start + half;
- break;
- }
- half = half >> 1;
- }
-
- HPROF_ASSERT(start < count);
-
- /* Now start the table search */
- for ( i = start ; i < count ; i++ ) {
- if ( location < table[i].start_location ) {
- HPROF_ASSERT( ((int)location) < ((int)table[i].start_location) );
- break;
- }
- line_number = table[i].line_number;
- }
- HPROF_ASSERT(line_number > 0);
- return line_number;
-}
-
-jint
-getLineNumber(jmethodID method, jlocation location)
-{
- jvmtiLineNumberEntry *line_table;
- jint line_count;
- jint lineno;
-
- HPROF_ASSERT(method!=NULL);
- if ( location < 0 ) {
- HPROF_ASSERT(location > -4);
- return (jint)location;
- }
- lineno = -1;
-
- getLineNumberTable(method, &line_table, &line_count);
- lineno = map_loc2line(location, line_table, line_count);
- jvmtiDeallocate(line_table);
-
- return lineno;
-}
-
-jlong
-getMaxMemory(JNIEnv *env)
-{
- jlong max;
-
- HPROF_ASSERT(env!=NULL);
-
- max = (jlong)0;
- WITH_LOCAL_REFS(env, 1) {
- jclass clazz;
- jmethodID getRuntime;
- jobject runtime;
- jmethodID maxMemory;
-
- clazz = findClass(env, "java/lang/Runtime");
- getRuntime = getStaticMethodID(env, clazz, "getRuntime",
- "()Ljava/lang/Runtime;");
- runtime = callStaticObjectMethod(env, clazz, getRuntime);
- maxMemory = getMethodID(env, clazz, "maxMemory", "()J");
- max = callLongMethod(env, runtime, maxMemory);
- } END_WITH_LOCAL_REFS;
- return max;
-}
-
-void
-createAgentThread(JNIEnv *env, const char *name, jvmtiStartFunction func)
-{
- jvmtiError error;
-
- HPROF_ASSERT(name!=NULL);
- HPROF_ASSERT(func!=NULL);
-
- WITH_LOCAL_REFS(env, 1) {
- jclass clazz;
- jmethodID threadConstructor;
- jmethodID threadSetDaemon;
- jthread thread;
- jstring nameString;
- jthreadGroup systemThreadGroup;
- jthreadGroup * groups;
- jint groupCount;
-
- thread = NULL;
- systemThreadGroup = NULL;
- groups = NULL;
- clazz = class_get_class(env, gdata->thread_cnum);
- HPROF_ASSERT(clazz!=NULL);
- threadConstructor = getMethodID(env, clazz, "<init>",
- "(Ljava/lang/ThreadGroup;Ljava/lang/String;)V");
- threadSetDaemon = getMethodID(env, clazz, "setDaemon",
- "(Z)V");
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetTopThreadGroups)
- (gdata->jvmti, &groupCount, &groups);
- if ( error == JVMTI_ERROR_NONE ) {
- if ( groupCount > 0 ) {
- systemThreadGroup = groups[0];
- }
- jvmtiDeallocate(groups);
-
- nameString = newStringUTF(env, name);
- HPROF_ASSERT(nameString!=NULL);
- thread = newThreadObject(env, clazz, threadConstructor,
- systemThreadGroup, nameString);
- HPROF_ASSERT(thread!=NULL);
- callVoidMethod(env, thread, threadSetDaemon, JNI_TRUE);
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,RunAgentThread)
- (gdata->jvmti, thread, func, NULL, JVMTI_THREAD_MAX_PRIORITY);
-
- /* After the thread is running... */
-
- /* Make sure the TLS table has this thread as an agent thread */
- tls_agent_thread(env, thread);
- }
- } END_WITH_LOCAL_REFS;
-
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot create agent thread");
- }
-}
-
-jlong
-getThreadCpuTime(jthread thread)
-{
- jvmtiError error;
- jlong cpuTime;
-
- HPROF_ASSERT(thread!=NULL);
- cpuTime = -1;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadCpuTime)
- (gdata->jvmti, thread, &cpuTime);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get cpu time");
- }
- return cpuTime;
-}
-
-/* Get frame count */
-void
-getFrameCount(jthread thread, jint *pcount)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(pcount!=NULL);
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetFrameCount)
- (gdata->jvmti, thread, pcount);
- if ( error != JVMTI_ERROR_NONE ) {
- *pcount = 0;
- }
-}
-
-/* Get call trace */
-void
-getStackTrace(jthread thread, jvmtiFrameInfo *pframes, jint depth, jint *pcount)
-{
- jvmtiError error;
-
- HPROF_ASSERT(thread!=NULL);
- HPROF_ASSERT(pframes!=NULL);
- HPROF_ASSERT(depth >= 0);
- HPROF_ASSERT(pcount!=NULL);
- *pcount = 0;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetStackTrace)
- (gdata->jvmti, thread, 0, depth, pframes, pcount);
- if ( error != JVMTI_ERROR_NONE ) {
- *pcount = 0;
- }
-}
-
-void
-getThreadListStackTraces(jint count, jthread *threads,
- jint depth, jvmtiStackInfo **stack_info)
-{
- jvmtiError error;
-
- HPROF_ASSERT(threads!=NULL);
- HPROF_ASSERT(stack_info!=NULL);
- HPROF_ASSERT(depth >= 0);
- HPROF_ASSERT(count > 0);
- *stack_info = NULL;
- error = JVMTI_FUNC_PTR(gdata->jvmti,GetThreadListStackTraces)
- (gdata->jvmti, count, threads, depth, stack_info);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot get thread list stack info");
- }
-}
-
-void
-followReferences(jvmtiHeapCallbacks *pHeapCallbacks, void *user_data)
-{
- jvmtiError error;
-
- error = JVMTI_FUNC_PTR(gdata->jvmti,FollowReferences)
- (gdata->jvmti, 0, NULL, NULL, pHeapCallbacks, user_data);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot follow references");
- }
-}
-
-/* GC control */
-void
-runGC(void)
-{
- jvmtiError error;
- error = JVMTI_FUNC_PTR(gdata->jvmti,ForceGarbageCollection)
- (gdata->jvmti);
- if ( error != JVMTI_ERROR_NONE ) {
- HPROF_JVMTI_ERROR(error, "Cannot force garbage collection");
- }
-}
-
-/* ------------------------------------------------------------------- */
-/* Getting the initial JVMTI environment */
-
-void
-getJvmti(void)
-{
- jvmtiEnv *jvmti = NULL;
- jint res;
- jint jvmtiCompileTimeMajorVersion;
- jint jvmtiCompileTimeMinorVersion;
- jint jvmtiCompileTimeMicroVersion;
-
- res = JVM_FUNC_PTR(gdata->jvm,GetEnv)
- (gdata->jvm, (void **)&jvmti, JVMTI_VERSION_1);
- if (res != JNI_OK) {
- char buf[256];
-
- (void)md_snprintf(buf, sizeof(buf),
- "Unable to access JVMTI Version 1 (0x%x),"
- " is your JDK a 5.0 or newer version?"
- " JNIEnv's GetEnv() returned %d",
- JVMTI_VERSION_1, res);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_FALSE, buf);
- error_exit_process(1); /* Kill entire process, no core dump */
- }
- gdata->jvmti = jvmti;
-
- /* Check to make sure the version of jvmti.h we compiled with
- * matches the runtime version we are using.
- */
- jvmtiCompileTimeMajorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MAJOR )
- >> JVMTI_VERSION_SHIFT_MAJOR;
- jvmtiCompileTimeMinorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MINOR )
- >> JVMTI_VERSION_SHIFT_MINOR;
- jvmtiCompileTimeMicroVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MICRO )
- >> JVMTI_VERSION_SHIFT_MICRO;
- if ( !compatible_versions(jvmtiMajorVersion(), jvmtiMinorVersion(),
- jvmtiCompileTimeMajorVersion, jvmtiCompileTimeMinorVersion) ) {
- char buf[256];
-
- (void)md_snprintf(buf, sizeof(buf),
- "This " AGENTNAME " native library will not work with this VM's "
- "version of JVMTI (%d.%d.%d), it needs JVMTI %d.%d[.%d]."
- ,
- jvmtiMajorVersion(),
- jvmtiMinorVersion(),
- jvmtiMicroVersion(),
- jvmtiCompileTimeMajorVersion,
- jvmtiCompileTimeMinorVersion,
- jvmtiCompileTimeMicroVersion);
- buf[sizeof(buf)-1] = 0;
- HPROF_ERROR(JNI_FALSE, buf);
- error_exit_process(1); /* Kill entire process, no core dump wanted */
- }
-}