/* Copyright (C) 2021-2024 Free Software Foundation, Inc.
   Contributed by Oracle.

   This file is part of GNU Binutils.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3, or (at your option)
   any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, 51 Franklin Street - Fifth Floor, Boston,
   MA 02110-1301, USA.  */

#include "config.h"

#if defined(GPROFNG_JAVA_PROFILING)
#include <alloca.h>
#include <dlfcn.h> /* dlsym()	*/
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <sys/param.h> /* MAXPATHLEN */
#include <stddef.h>
#include <jni.h>
#include <jvmti.h>

#include "gp-defs.h"
#include "collector.h"
#include "gp-experiment.h"
#include "tsd.h"

/* ARCH_STRLEN is defined in dbe, copied here */
#define ARCH_STRLEN(s)      ((CALL_UTIL(strlen)(s) + 4 ) & ~0x3)

/* call frame */
typedef struct
{
  jint lineno;              /* line number in the source file */
  jmethodID method_id;      /* method executed in this frame */
} JVMPI_CallFrame;

/* call trace */
typedef struct
{
  JNIEnv *env_id;           /* Env where trace was recorded */
  jint num_frames;          /* number of frames in this trace */
  JVMPI_CallFrame *frames;  /* frames */
} JVMPI_CallTrace;

extern void __collector_jprofile_enable_synctrace (void);
int __collector_jprofile_start_attach (void);
static int init_interface (CollectorInterface*);
static int open_experiment (const char *);
static int close_experiment (void);
static int detach_experiment (void);
static void jprof_find_asyncgetcalltrace (void);
static char *apistr = NULL;

static ModuleInterface module_interface = {
  "*"SP_JCLASSES_FILE,      /* description, exempt from limit */
  init_interface,           /* initInterface */
  open_experiment,          /* openExperiment */
  NULL,                     /* startDataCollection */
  NULL,                     /* stopDataCollection */
  close_experiment,         /* closeExperiment */
  detach_experiment         /* detachExperiment (fork child) */
};

static CollectorInterface *collector_interface = NULL;
static CollectorModule jprof_hndl = COLLECTOR_MODULE_ERR;
static int __collector_java_attach = 0;
static JavaVM *jvm;
static jmethodID getResource = NULL;
static jmethodID toExternalForm = NULL;

/* Java profiling thread specific data */
typedef struct TSD_Entry
{
  JNIEnv *env;
  hrtime_t tstamp;
} TSD_Entry;

static unsigned tsd_key = COLLECTOR_TSD_INVALID_KEY;
static collector_mutex_t jclasses_lock = COLLECTOR_MUTEX_INITIALIZER;
static int java_gc_on = 0;
static int java_mem_mode = 0;
static int java_sync_mode = 0;
static int is_hotspot_vm = 0;
static void get_jvm_settings ();
static void rwrite (int fd, const void *buf, size_t nbyte);
static void addToDynamicArchive (const char* name, const unsigned char* class_data, int class_data_len);
static void (*AsyncGetCallTrace)(JVMPI_CallTrace*, jint, ucontext_t*) = NULL;
static void (*collector_heap_record)(int, int, void*) = NULL;
static void (*collector_jsync_begin)() = NULL;
static void (*collector_jsync_end)(hrtime_t, void *) = NULL;

#define gethrtime collector_interface->getHiResTime

/*
 * JVMTI declarations
 */

static jvmtiEnv *jvmti;
static void jvmti_VMInit (jvmtiEnv*, JNIEnv*, jthread);
static void jvmti_VMDeath (jvmtiEnv*, JNIEnv*);
static void jvmti_ThreadStart (jvmtiEnv*, JNIEnv*, jthread);
static void jvmti_ThreadEnd (jvmtiEnv*, JNIEnv*, jthread);
static void jvmti_CompiledMethodLoad (jvmtiEnv*, jmethodID, jint, const void*,
				      jint, const jvmtiAddrLocationMap*, const void*);
static void jvmti_CompiledMethodUnload (jvmtiEnv*, jmethodID, const void*);
static void jvmti_DynamicCodeGenerated (jvmtiEnv*, const char*, const void*, jint);
static void jvmti_ClassPrepare (jvmtiEnv*, JNIEnv*, jthread, jclass);
static void jvmti_ClassLoad (jvmtiEnv*, JNIEnv*, jthread, jclass);
//static void jvmti_ClassUnload( jvmtiEnv*, JNIEnv*, jthread, jclass );
static void jvmti_MonitorEnter (jvmtiEnv *, JNIEnv*, jthread, jobject);
static void jvmti_MonitorEntered (jvmtiEnv *, JNIEnv*, jthread, jobject);
#if 0
static void jvmti_MonitorWait (jvmtiEnv *, JNIEnv*, jthread, jobject, jlong);
static void jvmti_MonitorWaited (jvmtiEnv *, JNIEnv*, jthread, jobject, jboolean);
#endif
static void jvmti_ClassFileLoadHook (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jclass class_being_redefined,
				     jobject loader, const char* name, jobject protection_domain,
				     jint class_data_len, const unsigned char* class_data,
				     jint* new_class_data_len, unsigned char** new_class_data);
static void jvmti_GarbageCollectionStart (jvmtiEnv *);
static void
jvmti_GarbageCollectionFinish (jvmtiEnv *);
jvmtiEventCallbacks callbacks = {
  jvmti_VMInit,                 // 50 jvmtiEventVMInit;
  jvmti_VMDeath,                // 51 jvmtiEventVMDeath;
  jvmti_ThreadStart,            // 52 jvmtiEventThreadStart;
  jvmti_ThreadEnd,              // 53 jvmtiEventThreadEnd;
  jvmti_ClassFileLoadHook,      // 54 jvmtiEventClassFileLoadHook;
  jvmti_ClassLoad,              // 55 jvmtiEventClassLoad;
  jvmti_ClassPrepare,           // 56 jvmtiEventClassPrepare;
  NULL,                         // 57 reserved57;
  NULL,                         // 58 jvmtiEventException;
  NULL,                         // 59 jvmtiEventExceptionCatch;
  NULL,                         // 60 jvmtiEventSingleStep;
  NULL,                         // 61 jvmtiEventFramePop;
  NULL,                         // 62 jvmtiEventBreakpoint;
  NULL,                         // 63 jvmtiEventFieldAccess;
  NULL,                         // 64 jvmtiEventFieldModification;
  NULL,                         // 65 jvmtiEventMethodEntry;
  NULL,                         // 66 jvmtiEventMethodExit;
  NULL,                         // 67 jvmtiEventNativeMethodBind;
  jvmti_CompiledMethodLoad,     // 68 jvmtiEventCompiledMethodLoad;
  jvmti_CompiledMethodUnload,   // 69 jvmtiEventCompiledMethodUnload;
  jvmti_DynamicCodeGenerated,   // 70 jvmtiEventDynamicCodeGenerated;
  NULL,                         // 71 jvmtiEventDataDumpRequest;
  NULL,                         // 72 jvmtiEventDataResetRequest;
  NULL, /*jvmti_MonitorWait,*/  // 73 jvmtiEventMonitorWait;
  NULL, /*jvmti_MonitorWaited,*/ // 74 jvmtiEventMonitorWaited;
  jvmti_MonitorEnter,           // 75 jvmtiEventMonitorContendedEnter;
  jvmti_MonitorEntered,         // 76 jvmtiEventMonitorContendedEntered;
  NULL,                         // 77 jvmtiEventMonitorContendedExit;
  NULL,                         // 78 jvmtiEventReserved;
  NULL,                         // 79 jvmtiEventReserved;
  NULL,                         // 80 jvmtiEventReserved;
  jvmti_GarbageCollectionStart, // 81 jvmtiEventGarbageCollectionStart;
  jvmti_GarbageCollectionFinish, // 82 jvmtiEventGarbageCollectionFinish;
  NULL,                         // 83 jvmtiEventObjectFree;
  NULL                          // 84 jvmtiEventVMObjectAlloc;
};

typedef jint (JNICALL JNI_GetCreatedJavaVMs_t)(JavaVM **, jsize, jsize *);

int
init_interface (CollectorInterface *_collector_interface)
{
  collector_interface = _collector_interface;
  return COL_ERROR_NONE;
}

static int
open_experiment (const char *exp)
{
  if (collector_interface == NULL)
    return COL_ERROR_JAVAINIT;
  TprintfT (0, "jprofile: open_experiment %s\n", exp);
  const char *params = collector_interface->getParams ();
  const char *args = params;
  while (args)
    {
      if (__collector_strStartWith (args, "j:") == 0)
	{
	  args += 2;
	  break;
	}
      args = CALL_UTIL (strchr)(args, ';');
      if (args)
	args++;
    }
  if (args == NULL)     /* Java profiling not specified */
    return COL_ERROR_JAVAINIT;
  tsd_key = collector_interface->createKey (sizeof ( TSD_Entry), NULL, NULL);
  if (tsd_key == (unsigned) - 1)
    {
      TprintfT (0, "jprofile: TSD key create failed.\n");
      collector_interface->writeLog ("<event kind=\"%s\" id=\"%d\">TSD key not created</event>\n",
				     SP_JCMD_CERROR, COL_ERROR_JAVAINIT);
      return COL_ERROR_JAVAINIT;
    }
  else
    Tprintf (DBG_LT2, "jprofile: TSD key create succeeded %d.\n", tsd_key);

  args = params;
  while (args)
    {
      if (__collector_strStartWith (args, "H:") == 0)
	{
	  java_mem_mode = 1;
	  collector_heap_record = (void(*)(int, int, void*))dlsym (RTLD_DEFAULT, "__collector_heap_record");
	}
#if 0
      else if (__collector_strStartWith (args, "s:") == 0)
	{
	  java_sync_mode = 1;
	  collector_jsync_begin = (void(*)(hrtime_t, void *))dlsym (RTLD_DEFAULT, "__collector_jsync_begin");
	  collector_jsync_end = (void(*)(hrtime_t, void *))dlsym (RTLD_DEFAULT, "__collector_jsync_end");
	}
#endif
      args = CALL_UTIL (strchr)(args, ';');
      if (args)
	args++;
    }

  /* synchronization tracing is enabled by the synctrace module, later in initialization */
  __collector_java_mode = 1;
  java_gc_on = 1;
  return COL_ERROR_NONE;
}

/* routine called from the syntrace module to enable Java-API synctrace */
void
__collector_jprofile_enable_synctrace ()
{
  if (__collector_java_mode == 0)
    {
      TprintfT (DBG_LT1, "jprofile: not turning on Java synctrace; Java mode not enabled\n");
      return;
    }
  java_sync_mode = 1;
  collector_jsync_begin = (void(*)(hrtime_t, void *))dlsym (RTLD_DEFAULT, "__collector_jsync_begin");
  collector_jsync_end = (void(*)(hrtime_t, void *))dlsym (RTLD_DEFAULT, "__collector_jsync_end");
  TprintfT (DBG_LT1, "jprofile: turning on Java synctrace, and requesting events\n");
}

int
__collector_jprofile_start_attach (void)
{
  if (!__collector_java_mode || __collector_java_asyncgetcalltrace_loaded)
    return 0;
  void *g_sHandle = RTLD_DEFAULT;
  /* Now get the function addresses */
  JNI_GetCreatedJavaVMs_t *pfnGetCreatedJavaVMs;
  pfnGetCreatedJavaVMs = (JNI_GetCreatedJavaVMs_t *) dlsym (g_sHandle, "JNI_GetCreatedJavaVMs");
  if (pfnGetCreatedJavaVMs != NULL)
    {
      TprintfT (0, "jprofile attach: pfnGetCreatedJavaVMs is detected.\n");
      JavaVM * vmBuf[1]; // XXXX only detect on jvm
      jsize nVMs = 0;
      (*pfnGetCreatedJavaVMs)(vmBuf, 1, &nVMs);
      if (vmBuf[0] != NULL && nVMs > 0)
	{
	  jvm = vmBuf[0];
	  JNIEnv* jni_env = NULL;
	  (*jvm)->AttachCurrentThread (jvm, (void **) &jni_env, NULL);
	  Agent_OnLoad (jvm, NULL, NULL);
	  if ((*jvm)->GetEnv (jvm, (void **) &jni_env, JNI_VERSION_1_2) >= 0 && jni_env && jvmti)
	    {
	      jthread thread;
	      (*jvmti)->GetCurrentThread (jvmti, &thread);
	      jvmti_VMInit (jvmti, jni_env, thread);
	      (*jvmti)->GenerateEvents (jvmti, JVMTI_EVENT_COMPILED_METHOD_LOAD);
	      (*jvmti)->GenerateEvents (jvmti, JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
	      __collector_java_attach = 1;
	      (*jvm)->DetachCurrentThread (jvm);
	    }
	}
    }
  return 0;
}

static int
close_experiment (void)
{
  /* fixme XXXXX add content here */
  /* see detach_experiment() */
  __collector_java_mode = 0;
  __collector_java_asyncgetcalltrace_loaded = 0;
  __collector_java_attach = 0;
  java_gc_on = 0;
  java_mem_mode = 0;
  java_sync_mode = 0;
  is_hotspot_vm = 0;
  __collector_mutex_init (&jclasses_lock);
  tsd_key = COLLECTOR_TSD_INVALID_KEY;
  TprintfT (0, "jprofile: experiment closed.\n");
  return 0;
}

static int
detach_experiment (void)
/* fork child.  Clean up state but don't write to experiment */
{
  __collector_java_mode = 0;
  java_gc_on = 0;
  jvm = NULL;
  java_mem_mode = 0;
  java_sync_mode = 0;
  is_hotspot_vm = 0;
  jvmti = NULL;
  apistr = NULL;
  __collector_mutex_init (&jclasses_lock);
  tsd_key = COLLECTOR_TSD_INVALID_KEY;
  TprintfT (0, "jprofile: detached from experiment.\n");
  return 0;
}

JNIEXPORT jint JNICALL
JVM_OnLoad (JavaVM *vm, char *options, void *reserved)
{
  jvmtiError err;
  int use_jvmti = 0;
  if (!__collector_java_mode)
    {
      TprintfT (DBG_LT1, "jprofile: JVM_OnLoad invoked with java mode disabled\n");
      return JNI_OK;
    }
  else
    TprintfT (DBG_LT1, "jprofile: JVM_OnLoad invoked\n");
  jvm = vm;
  jvmti = NULL;
  if ((*jvm)->GetEnv (jvm, (void **) &jvmti, JVMTI_VERSION_1_0) >= 0 && jvmti)
    {
      TprintfT (DBG_LT1, "jprofile: JVMTI found\n");
      use_jvmti = 1;
    }
  if (!use_jvmti)
    {
      collector_interface->writeLog ("<event kind=\"%s\" id=\"%d\"/>\n",
				     SP_JCMD_CERROR, COL_ERROR_JVMNOTSUPP);
      return JNI_ERR;
    }
  else
    {
      Tprintf (DBG_LT0, "\tjprofile: Initializing for JVMTI\n");
      apistr = "JVMTI 1.0";

      // setup JVMTI
      jvmtiCapabilities cpblts;
      err = (*jvmti)->GetPotentialCapabilities (jvmti, &cpblts);
      if (err == JVMTI_ERROR_NONE)
	{
	  jvmtiCapabilities cpblts_set;
	  CALL_UTIL (memset)(&cpblts_set, 0, sizeof (cpblts_set));

	  /* Add only those capabilities that are among potential ones */
	  cpblts_set.can_get_source_file_name = cpblts.can_get_source_file_name;
	  Tprintf (DBG_LT1, "\tjprofile: adding can_get_source_file_name capability: %u\n", cpblts.can_get_source_file_name);

	  cpblts_set.can_generate_compiled_method_load_events = cpblts.can_generate_compiled_method_load_events;
	  Tprintf (DBG_LT1, "\tjprofile: adding can_generate_compiled_method_load_events capability: %u\n", cpblts.can_generate_compiled_method_load_events);

	  if (java_sync_mode)
	    {
	      cpblts_set.can_generate_monitor_events = cpblts.can_generate_monitor_events;
	      Tprintf (DBG_LT1, "\tjprofile: adding can_generate_monitor_events capability: %u\n", cpblts.can_generate_monitor_events);
	    }
	  if (java_gc_on)
	    {
	      cpblts_set.can_generate_garbage_collection_events = cpblts.can_generate_garbage_collection_events;
	      Tprintf (DBG_LT1, "\tjprofile: adding can_generate_garbage_collection_events capability: %u\n", cpblts.can_generate_garbage_collection_events);
	    }
	  err = (*jvmti)->AddCapabilities (jvmti, &cpblts_set);
	  Tprintf (DBG_LT1, "\tjprofile: AddCapabilities() returns: %d\n", err);
	}
      err = (*jvmti)->SetEventCallbacks (jvmti, &callbacks, sizeof ( callbacks));
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_PREPARE, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_COMPILED_METHOD_UNLOAD, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_DYNAMIC_CODE_GENERATED, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_START, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_THREAD_END, NULL);
      err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_CLASS_FILE_LOAD_HOOK, NULL);
      if (java_gc_on)
	{
	  err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_START, NULL);
	  err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_GARBAGE_COLLECTION_FINISH, NULL);
	}
      if (java_mem_mode)
	{
	  // err = (*jvmti)->SetEventNotificationMode( jvmti, JVMTI_ENABLE, <no event for heap tracing> , NULL );
	  collector_interface->writeLog ("<event kind=\"%s\" id=\"%d\"/>\n",
					 SP_JCMD_CWARN, COL_WARN_NO_JAVA_HEAP);
	  java_mem_mode = 0;
	}
      if (java_sync_mode)
	{
	  err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTER, NULL);
	  err = (*jvmti)->SetEventNotificationMode (jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_CONTENDED_ENTERED, NULL);
	  //err = (*jvmti)->SetEventNotificationMode( jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAIT, NULL );
	  //err = (*jvmti)->SetEventNotificationMode( jvmti, JVMTI_ENABLE, JVMTI_EVENT_MONITOR_WAITED, NULL );
	}
      Tprintf (DBG_LT0, "\tjprofile: JVMTI initialized\n");
    }

  /* JVM still uses collector API on Solaris to notify us about dynamically generated code.
   * If we ask it to generate events we'll end up with duplicate entries in the
   * map file.
   */
  if (use_jvmti)
    {
      err = (*jvmti)->GenerateEvents (jvmti, JVMTI_EVENT_DYNAMIC_CODE_GENERATED);
      err = (*jvmti)->GenerateEvents (jvmti, JVMTI_EVENT_COMPILED_METHOD_LOAD);
    }
  Tprintf (DBG_LT1, "\tjprofile: JVM_OnLoad ok\n");
  return JNI_OK;
}

/* This is currently just a placeholder */
JNIEXPORT jint JNICALL
Agent_OnLoad (JavaVM *vm, char *options, void *reserved)
{
  return JVM_OnLoad (vm, options, reserved);
}

static void
rwrite (int fd, const void *buf, size_t nbyte)
{
  size_t left = nbyte;
  size_t res;
  char *ptr = (char*) buf;
  while (left > 0)
    {
      res = CALL_UTIL (write)(fd, ptr, left);
      if (res == -1)
	{
	  /*  XXX: we can't write this record, we probably
	   *  can't write anything else. Ignore.
	   */
	  return;
	}
      left -= res;
      ptr += res;
    }
}

void
get_jvm_settings ()
{
  jint res;
  JNIEnv *jni;
  jclass jcls;
  jmethodID jmid;
  jstring jstrin;
  jstring jstrout;
  const char *str;
  res = (*jvm)->GetEnv (jvm, (void **) &jni, JNI_VERSION_1_2);
  if (res < 0)
    return;

  /* I'm not checking if results are valid as JVM is extremely
   * sensitive to exceptions that might occur during these JNI calls
   * and will die with a fatal error later anyway.
   */
  jcls = (*jni)->FindClass (jni, "java/lang/System");
  jmid = (*jni)->GetStaticMethodID (jni, jcls, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
  jstrin = (*jni)->NewStringUTF (jni, "java.class.path");
  jstrout = (*jni)->CallStaticObjectMethod (jni, jcls, jmid, jstrin);
  str = jstrout ? (*jni)->GetStringUTFChars (jni, jstrout, NULL) : NULL;
  if (str)
    {
      collector_interface->writeLog ("<setting %s=\"%s\"/>\n", SP_JCMD_SRCHPATH, str);
      (*jni)->ReleaseStringUTFChars (jni, jstrout, str);
    }
  jstrin = (*jni)->NewStringUTF (jni, "sun.boot.class.path");
  jstrout = (*jni)->CallStaticObjectMethod (jni, jcls, jmid, jstrin);
  str = jstrout ? (*jni)->GetStringUTFChars (jni, jstrout, NULL) : NULL;
  if (str)
    {
      collector_interface->writeLog ("<setting %s=\"%s\"/>\n", SP_JCMD_SRCHPATH, str);
      (*jni)->ReleaseStringUTFChars (jni, jstrout, str);
    }
  jstrin = (*jni)->NewStringUTF (jni, "java.home");
  jstrout = (*jni)->CallStaticObjectMethod (jni, jcls, jmid, jstrin);
  str = jstrout ? (*jni)->GetStringUTFChars (jni, jstrout, NULL) : NULL;
  if (str)
    {
      collector_interface->writeLog ("<setting %s=\"%s/../src.zip\"/>\n", SP_JCMD_SRCHPATH, str);
      (*jni)->ReleaseStringUTFChars (jni, jstrout, str);
    }
  jstrin = (*jni)->NewStringUTF (jni, "java.vm.version");
  jstrout = (*jni)->CallStaticObjectMethod (jni, jcls, jmid, jstrin);
  str = jstrout ? (*jni)->GetStringUTFChars (jni, jstrout, NULL) : NULL;
  if (str)
    {
      (void) collector_interface->writeLog ("<profile name=\"jprofile\" %s=\"%s\" %s=\"%s\"/>\n",
					    SP_JCMD_JVERSION, str, "api", apistr != NULL ? apistr : "N/A");
      if (__collector_strStartWith (str, "1.4.2_02") < 0)
	{
	  (void) collector_interface->writeLog ("<event kind=\"%s\" id=\"%d\"/>\n",
						SP_JCMD_CWARN, COL_WARN_OLDJAVA);
	}
      (*jni)->ReleaseStringUTFChars (jni, jstrout, str);
    }
  is_hotspot_vm = 0;
  jstrin = (*jni)->NewStringUTF (jni, "sun.management.compiler");
  jstrout = (*jni)->CallStaticObjectMethod (jni, jcls, jmid, jstrin);
  str = jstrout ? (*jni)->GetStringUTFChars (jni, jstrout, NULL) : NULL;
  if (str && __collector_strncmp (str, "HotSpot", 7) == 0)
    is_hotspot_vm = 1;

  /* Emulate System.setProperty( "collector.init", "true") */
  jmid = (*jni)->GetStaticMethodID (jni, jcls, "setProperty",
				    "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
  jstrin = (*jni)->NewStringUTF (jni, "collector.init");
  jstrout = (*jni)->NewStringUTF (jni, "true");
  (*jni)->CallStaticObjectMethod (jni, jcls, jmid, jstrin, jstrout);
}

/*
 * JVMTI code
 */

static void
jvmti_VMInit (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread)
{
  jint class_count = 0;
  jclass *classes = NULL;
  int i;
  TprintfT (DBG_LT1, "jprofile: jvmti_VMInit called\n");
  get_jvm_settings ();

  /* determine loaded classes */
  (*jvmti_env)->GetLoadedClasses (jvmti_env, &class_count, &classes);
  TprintfT (DBG_LT1, "jprofile: jvmti_VMInit initializing %d classes\n", class_count);
  for (i = 0; i < class_count; i++)
    {
      // PushLocalFrame
      jvmti_ClassPrepare (jvmti_env, jni_env, NULL, classes[i]);
      // PopLocalFrame
      // DeleteLocalRef( classes[i] );
    }
  (*jvmti_env)->Deallocate (jvmti_env, (unsigned char*) classes);
  getResource = (*jni_env)->GetMethodID (jni_env, (*jni_env)->FindClass (jni_env, "java/lang/ClassLoader"), "getResource", "(Ljava/lang/String;)Ljava/net/URL;");
  toExternalForm = (*jni_env)->GetMethodID (jni_env, (*jni_env)->FindClass (jni_env, "java/net/URL"), "toExternalForm", "()Ljava/lang/String;");

  /* find the stack unwind routine */
  jprof_find_asyncgetcalltrace ();
}

static void
jvmti_VMDeath (jvmtiEnv *jvmti_env, JNIEnv* jni_env)
{
  __collector_java_mode = 0;
  TprintfT (DBG_LT1, "jprofile: jvmti_VMDeath event received\n");
}

static void
jvmti_ThreadStart (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread)
{
  jvmtiError err;
  jvmtiThreadInfo t_info;
  char *thread_name, *group_name, *parent_name;
  hrtime_t hrt;
  collector_thread_t tid;
  thread_name = group_name = parent_name = NULL;
  hrt = gethrtime ();
  tid = __collector_thr_self ();
  TprintfT (DBG_LT1, "jprofile: jvmti_ThreadStart: thread: %lu jni_env=%p jthread=%p\n",
	    (unsigned long) tid, jni_env, thread);
  err = (*jvmti_env)->GetThreadInfo (jvmti_env, thread, &t_info);
  if (err == JVMTI_ERROR_NONE)
    {
      jvmtiThreadGroupInfo g_info;
      thread_name = t_info.name;
      if (t_info.thread_group)
	{
	  err = (*jvmti_env)->GetThreadGroupInfo (jvmti_env, t_info.thread_group, &g_info);
	  if (err == JVMTI_ERROR_NONE)
	    {
	      group_name = g_info.name;
	      if (g_info.parent)
		{
		  jvmtiThreadGroupInfo p_info;
		  err = (*jvmti_env)->GetThreadGroupInfo (jvmti_env, g_info.parent, &p_info);
		  if (err == JVMTI_ERROR_NONE)
		    {
		      parent_name = p_info.name;
		      // DeleteLocalRef( p_info.parent );
		    }
		  // DeleteLocalRef( g_info.parent );
		}
	    }
	}
      // DeleteLocalRef( t_info.thread_group );
      // DeleteLocalRef( t_info.context_class_loader );
    }
  if (thread_name == NULL)
    thread_name = "";
  if (group_name == NULL)
    group_name = "";
  if (parent_name == NULL)
    parent_name = "";
  collector_interface->writeLog ("<event kind=\"%s\" tstamp=\"%u.%09u\" name=\"%s\" grpname=\"%s\" prntname=\"%s\" tid=\"%lu\" jthr=\"0x%lx\" jenv=\"0x%lx\"/>\n",
				 SP_JCMD_JTHRSTART,
				 (unsigned) (hrt / NANOSEC), (unsigned) (hrt % NANOSEC),
				 thread_name,
				 group_name,
				 parent_name,
				 (unsigned long) tid,
				 (unsigned long) thread,
				 (unsigned long) jni_env
				 );
  TSD_Entry *tsd = collector_interface->getKey (tsd_key);
  if (tsd)
    tsd->env = jni_env;
}

static void
jvmti_ThreadEnd (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread)
{
  hrtime_t hrt = gethrtime ();
  collector_thread_t tid = __collector_thr_self ();
  TprintfT (DBG_LT1, "jprofile: jvmti_ThreadEnd: thread: %lu jni_env=%p jthread=%p\n",
	    (unsigned long) tid, jni_env, thread);

  collector_interface->writeLog ("<event kind=\"%s\" tstamp=\"%u.%09u\" tid=\"%lu\"  jthr=\"0x%lx\" jenv=\"0x%lx\"/>\n",
				 SP_JCMD_JTHREND,
				 (unsigned) (hrt / NANOSEC), (unsigned) (hrt % NANOSEC),
				 (unsigned long) tid,
				 (unsigned long) thread,
				 (unsigned long) jni_env
				 );
  TSD_Entry *tsd = collector_interface->getKey (tsd_key);
  if (tsd)
    tsd->env = NULL;
}

/* The following definitions are borrowed from file jvmticmlr.h, part of jdk7 */
typedef enum
{
  JVMTI_CMLR_DUMMY = 1,
  JVMTI_CMLR_INLINE_INFO = 2
} jvmtiCMLRKind;

/*
 * Record that represents arbitrary information passed through JVMTI
 * CompiledMethodLoadEvent void pointer.
 */
typedef struct _jvmtiCompiledMethodLoadRecordHeader
{
  jvmtiCMLRKind kind;       /* id for the kind of info passed in the record */
  jint majorinfoversion;    /* major and minor info version values. Init'ed */
  jint minorinfoversion;    /* to current version value in jvmtiExport.cpp. */
  struct _jvmtiCompiledMethodLoadRecordHeader* next;
} jvmtiCompiledMethodLoadRecordHeader;

/*
 * Record that gives information about the methods on the compile-time
 * stack at a specific pc address of a compiled method. Each element in
 * the methods array maps to same element in the bcis array.
 */
typedef struct _PCStackInfo
{
  void* pc;                 /* the pc address for this compiled method */
  jint numstackframes;      /* number of methods on the stack */
  jmethodID* methods;       /* array of numstackframes method ids */
  jint* bcis;               /* array of numstackframes bytecode indices */
} PCStackInfo;

/*
 * Record that contains inlining information for each pc address of
 * an nmethod.
 */
typedef struct _jvmtiCompiledMethodLoadInlineRecord
{
  jvmtiCompiledMethodLoadRecordHeader header; /* common header for casting */
  jint numpcs; /* number of pc descriptors in this nmethod */
  PCStackInfo* pcinfo; /* array of numpcs pc descriptors */
} jvmtiCompiledMethodLoadInlineRecord;

static void
jvmti_CompiledMethodLoad (jvmtiEnv *jvmti_env, jmethodID method,
			  jint code_size, const void *code_addr, jint map_length,
			  const jvmtiAddrLocationMap *map,
			  const void *compile_info)
{
  TprintfT (DBG_LT2, "jprofile: jvmti_CompiledMethodLoad: mid=0x%lx addr=%p sz=0x%lu map=%p info=%p\n",
	    (unsigned long) method, code_addr, (long) code_size, map, compile_info);
  char name[32];
  CALL_UTIL (snprintf)(name, sizeof (name), "0x%lx", (unsigned long) method);

  /* Parse compile_info to get pc -> bci mapping.
   * Don't interpret compile_info from JVMs other than HotSpot.
   */
  int lntsize = 0;
  DT_lineno *lntable = NULL;
  if (compile_info != NULL && is_hotspot_vm)
    {
      Tprintf (DBG_LT2, "Mapping from compile_info:\n");
      jvmtiCompiledMethodLoadRecordHeader *currec =
	      (jvmtiCompiledMethodLoadRecordHeader*) compile_info;
      while (currec != NULL)
	{
	  if (currec->kind == JVMTI_CMLR_INLINE_INFO)
	    {
	      jvmtiCompiledMethodLoadInlineRecord *inrec =
		      (jvmtiCompiledMethodLoadInlineRecord*) currec;
	      if (inrec->numpcs <= 0)
		break;
	      lntsize = inrec->numpcs;
	      lntable = (DT_lineno*) alloca (lntsize * sizeof (DT_lineno));
	      PCStackInfo *pcrec = inrec->pcinfo;
	      DT_lineno *lnorec = lntable;
	      for (int i = 0; i < lntsize; ++i)
		{
		  for (int j = pcrec->numstackframes - 1; j >= 0; --j)
		    if (pcrec->methods[j] == method)
		      {
			lnorec->offset = (char*) pcrec->pc - (char*) code_addr;
			lnorec->lineno = pcrec->bcis[j];
			Tprintf (DBG_LT2, "   pc: 0x%lx  bci: 0x%lx\n",
				 (long) lnorec->offset, (long) lnorec->lineno);
			++lnorec;
			break;
		      }
		  ++pcrec;
		}
	      break;
	    }
	  currec = currec->next;
	}
    }
  else if (map != NULL)
    {
      Tprintf (DBG_LT2, "Mapping from jvmtiAddrLocationMap:\n");
      lntsize = map_length;
      lntable = (DT_lineno*) alloca (lntsize * sizeof (DT_lineno));
      DT_lineno *lnorec = lntable;
      for (int i = 0; i < map_length; ++i)
	{
	  lnorec->offset = (char*) map[i].start_address - (char*) code_addr;
	  lnorec->lineno = (unsigned int) map[i].location;
	  Tprintf (DBG_LT2, "   pc: 0x%lx  bci: 0x%lx\n",
		   (long) lnorec->offset, (long) lnorec->lineno);
	  ++lnorec;
	}
    }
  __collector_int_func_load (DFUNC_JAVA, name, NULL, (void*) code_addr,
			     code_size, lntsize, lntable);
}

static void
jvmti_CompiledMethodUnload (jvmtiEnv *jvmti_env, jmethodID method, const void* code_addr)
{
  __collector_int_func_unload (DFUNC_API, (void*) code_addr);
}

static void
jvmti_DynamicCodeGenerated (jvmtiEnv *jvmti_env, const char*name, const void *code_addr, jint code_size)
{
  __collector_int_func_load (DFUNC_API, (char*) name, NULL, (void*) code_addr,
			     code_size, 0, NULL);
}

static void
addToDynamicArchive (const char* name, const unsigned char* class_data, int class_data_len)
{
  char path[MAXPATHLEN + 1];
  mode_t fmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
  mode_t dmode = fmode | S_IXUSR | S_IXGRP | S_IXOTH;
  if (name == NULL)
    name = "";
  const char *expdir = collector_interface->getExpDir ();
  if (CALL_UTIL (strlen)(expdir) +
      CALL_UTIL (strlen)(SP_DYNAMIC_CLASSES) +
      CALL_UTIL (strlen)(name) + 8 > sizeof (path))
    return;
  CALL_UTIL (snprintf)(path, sizeof (path), "%s/%s/%s.class", expdir, SP_DYNAMIC_CLASSES, name);

  /* Create all path components step by step starting with SP_DYNAMIC_CLASSES */
  char *str = path + CALL_UTIL (strlen)(expdir) + 1 + CALL_UTIL (strlen)(SP_DYNAMIC_CLASSES);
  while (str)
    {
      *str = '\0';
      if (CALL_UTIL (mkdir)(path, dmode) != 0)
	{
	  /* Checking for EEXIST is not enough, access() is more reliable */
	  if (CALL_UTIL (access)(path, F_OK) != 0)
	    {
	      collector_interface->writeLog ("<event kind=\"%s\" id=\"%d\" ec=\"%d\">%s</event>\n",
					     SP_JCMD_CERROR, COL_ERROR_MKDIR, errno, path);
	      return;
	    }
	}
      *str++ = '/';
      str = CALL_UTIL (strchr)(str, '/');
    }

  int fd = CALL_UTIL (open)(path, O_WRONLY | O_CREAT | O_TRUNC, fmode);
  if (fd < 0)
    {
      collector_interface->writeLog ("<event kind=\"%s\" id=\"%d\" ec=\"%d\">%s</event>\n",
				     SP_JCMD_CERROR, COL_ERROR_OVWOPEN, errno, path);
      return;
    }
  rwrite (fd, class_data, class_data_len);
  CALL_UTIL (close)(fd);
}

static void
jvmti_ClassFileLoadHook (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jclass class_being_redefined,
			 jobject loader, const char* name, jobject protection_domain, jint class_data_len,
			 const unsigned char* class_data, jint* new_class_data_len, unsigned char** new_class_data)
{
  jclass loaderlass;
  int err;
  jvmtiPhase phase_ptr;
  char *cname = NULL;
  (*jvmti_env)->GetPhase (jvmti_env, &phase_ptr);

  /* skip non live phases */
  if (phase_ptr != JVMTI_PHASE_LIVE)
    return;

  /* skip system class loaders */
  if (!loader)
    return;
  loaderlass = (*jni_env)->GetObjectClass (jni_env, loader);
  err = (*jvmti_env)->GetClassSignature (jvmti_env, loaderlass, &cname, NULL);
  if (err != JVMTI_ERROR_NONE || !cname || *cname == (char) 0)
    return;

  /* skip classes loaded with AppClassLoader (java.class.path) */
  if (__collector_strcmp (cname, "Lsun/misc/Launcher$AppClassLoader;") == 0)
    return;
  addToDynamicArchive (name, class_data, (int) class_data_len);
}

#define NO_CLASS_NAME "<noname>"
#define NO_SOURCE_FILE "<Unknown>"

static void
record_jclass (uint64_t class_id, hrtime_t hrt, const char *cname, const char *sname)
{
  size_t clen = ARCH_STRLEN (cname);
  size_t slen = ARCH_STRLEN (sname);
  size_t sz = sizeof (ARCH_jclass) + clen + slen;
  ARCH_jclass *jcls = (ARCH_jclass*) alloca (sz);
  jcls->comm.tsize = sz;
  jcls->comm.type = ARCH_JCLASS;
  jcls->class_id = class_id;
  jcls->tstamp = hrt;
  char *str = (char*) (jcls + 1);
  size_t i = CALL_UTIL (strlcpy)(str, cname, clen);
  str += i;
  while (i++ < clen)
    *str++ = (char) 0; /* pad with 0's */
  i = CALL_UTIL (strlcpy)(str, sname, slen);
  str += i;
  while (i++ < slen)
    *str++ = (char) 0; /* pad with 0's */
  collector_interface->writeDataPacket (jprof_hndl, (CM_Packet*) jcls);
}

static void
record_jmethod (uint64_t class_id, uint64_t method_id,
		const char *mname, const char *msign)
{
  size_t mnlen = mname ? ARCH_STRLEN (mname) : 0;
  size_t mslen = msign ? ARCH_STRLEN (msign) : 0;
  size_t sz = sizeof (ARCH_jmethod) + mnlen + mslen;
  ARCH_jmethod *jmth = (ARCH_jmethod*) alloca (sz);
  if (jmth == NULL)
    {
      TprintfT (DBG_LT1, "jprofile: record_jmethod ERROR: failed to alloca(%ld)\n", (long) sz);
      return;
    }
  jmth->comm.tsize = sz;
  jmth->comm.type = ARCH_JMETHOD;
  jmth->class_id = class_id;
  jmth->method_id = method_id;
  char *str = (char*) (jmth + 1);
  if (mname)
    {
      size_t i = CALL_UTIL (strlcpy)(str, mname, mnlen);
      str += i;
      while (i++ < mnlen)
	*str++ = (char) 0; /* pad with 0's */
    }
  if (msign)
    {
      size_t i = CALL_UTIL (strlcpy)(str, msign, mslen);
      str += i;
      while (i++ < mslen)
	*str++ = (char) 0; /* pad with 0's */
    }
  collector_interface->writeDataPacket (jprof_hndl, (CM_Packet*) jmth);
}

static void
jvmti_ClassPrepare (jvmtiEnv *jvmti_env, JNIEnv* jni_env,
		    jthread thread, jclass klass)
{
  hrtime_t hrt;
  jint mnum;
  jmethodID *mptr;
  char *cname, *sname;
  char *str1 = NULL;
  int err = (*jvmti_env)->GetClassSignature (jvmti_env, klass, &str1, NULL);
  if (err != JVMTI_ERROR_NONE || str1 == NULL || *str1 == (char) 0)
    cname = NO_CLASS_NAME;
  else
    cname = str1;
  if (*cname != 'L')
    {
      DprintfT (SP_DUMP_JAVA | SP_DUMP_TIME, "jvmti_ClassPrepare: GetClassSignature failed. err=%d cname=%s\n", err, cname);
      return;
    }
  char *str2 = NULL;
  err = (*jvmti_env)->GetSourceFileName (jvmti_env, klass, &str2);
  if (err != JVMTI_ERROR_NONE || str2 == NULL || *str2 == (char) 0)
    sname = NO_SOURCE_FILE;
  else
    sname = str2;
  DprintfT (SP_DUMP_JAVA | SP_DUMP_TIME, "jvmti_ClassPrepare: cname=%s sname=%s\n", STR (cname), STR (sname));

  /* Lock the whole file */
  __collector_mutex_lock (&jclasses_lock);
  hrt = gethrtime ();
  record_jclass ((unsigned long) klass, hrt, cname, sname);
  (*jvmti_env)->Deallocate (jvmti_env, (unsigned char *) str1);
  (*jvmti_env)->Deallocate (jvmti_env, (unsigned char *) str2);
  err = (*jvmti_env)->GetClassMethods (jvmti_env, klass, &mnum, &mptr);
  if (err == JVMTI_ERROR_NONE)
    {
      for (int i = 0; i < mnum; i++)
	{
	  char *mname, *msign;
	  err = (*jvmti_env)->GetMethodName (jvmti_env, mptr[i], &mname, &msign, NULL);
	  if (err != JVMTI_ERROR_NONE)
	    continue;
	  record_jmethod ((unsigned long) klass, (unsigned long) mptr[i], mname, msign);
	  // DeleteLocalRef( mptr[i] );
	}
      (*jvmti_env)->Deallocate (jvmti_env, (unsigned char*) mptr);
    }
  /* Unlock the file */
  __collector_mutex_unlock (&jclasses_lock);
}

/*
 * The CLASS_LOAD event is enabled to enable AsyncGetCallTrace
 */
static void
jvmti_ClassLoad (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, jclass klass)
{
  char *cname;
  char *str1 = NULL;
  int err = (*jvmti_env)->GetClassSignature (jvmti_env, klass, &str1, NULL);
  if (err != JVMTI_ERROR_NONE || str1 == NULL || *str1 == (char) 0)
    cname = NO_CLASS_NAME;
  else
    cname = str1;
  jstring str = NULL;
  const char* resourceName;
  jobject classLoader = NULL;
  err = (*jvmti)->GetClassLoader (jvmti, klass, &classLoader);
  DprintfT (SP_DUMP_JAVA | SP_DUMP_TIME, "jprofile: jvmti_ClassLoad err=%d cname=%s\n", err, STR (cname));
  if (err == 0)
    {
      if (classLoader == NULL)
	{
	  // bootstrap class loader
	  resourceName = "";
	}
      else
	{
	  char* name = (char *) alloca ((CALL_UTIL (strlen)(str1) + 32) * sizeof (char));
	  CALL_UTIL (strlcpy)(name, str1 + 1, CALL_UTIL (strlen)(str1));
	  name[CALL_UTIL (strlen)(name) - 1] = '\0'; // remove the last ';'
	  char* p;
	  for (p = name; *p != '\0'; p++)
	    if (*p == '.')
	      *p = '/';
	  CALL_UTIL (strlcat)(name, ".class", CALL_UTIL (strlen)(name) + CALL_UTIL (strlen)(".class") + 1);
	  if (getResource == NULL || toExternalForm == NULL)
	    {
	      resourceName = "";
	      DprintfT (SP_DUMP_JAVA | SP_DUMP_TIME, "jvmti_ClassLoad: class %s failed to get path with method missing\n", STR (cname));
	    }
	  else
	    {
	      jobject url = (*jni_env)->CallObjectMethod (jni_env, classLoader, getResource, (*jni_env)->NewStringUTF (jni_env, name));
	      if (url == NULL)
		{
		  resourceName = "";
		  DprintfT (SP_DUMP_JAVA | SP_DUMP_TIME, "jvmti_ClassLoad: class %s failed to get path\n", STR (cname));
		}
	      else
		{
		  str = (jstring) (*jni_env)->CallObjectMethod (jni_env, url, toExternalForm);
		  resourceName = (*jni_env)->GetStringUTFChars (jni_env, str, NULL);
		  DprintfT (SP_DUMP_JAVA | SP_DUMP_TIME, "jvmti_ClassLoad: ARCH_JCLASS_LOCATION(Ox%x) class_id=0x%lx  className='%s' fileName '%s'\n",
			    (int) ARCH_JCLASS_LOCATION, (unsigned long) klass, STR (cname), STR (resourceName));
		  size_t clen = ARCH_STRLEN (cname);
		  size_t slen = ARCH_STRLEN (resourceName);
		  size_t sz = sizeof (ARCH_jclass) + clen + slen;
		  ARCH_jclass_location *jcls = (ARCH_jclass_location*) alloca (sz);
		  jcls->comm.tsize = sz;
		  jcls->comm.type = ARCH_JCLASS_LOCATION;
		  jcls->class_id = (unsigned long) klass;
		  char *str = (char*) (jcls + 1);
		  size_t i = CALL_UTIL (strlcpy)(str, cname, clen);
		  str += i;
		  while (i++ < clen)
		    {
		      *str++ = (char) 0; /* pad with 0's */
		    }
		  i = CALL_UTIL (strlcpy)(str, resourceName, slen);
		  str += i;
		  while (i++ < slen)
		    {
		      *str++ = (char) 0; /* pad with 0's */
		    }
		  /* Lock the whole file */
		  __collector_mutex_lock (&jclasses_lock);
		  collector_interface->writeDataPacket (jprof_hndl, (CM_Packet*) jcls);
		  /* Unlock the file */
		  __collector_mutex_unlock (&jclasses_lock);
		}
	    }
	}
    }
}

static void
jvmti_MonitorEnter (jvmtiEnv *jvmti_env, JNIEnv* jni_env,
		    jthread thread, jobject object)
{
  if (collector_jsync_begin)
    collector_jsync_begin ();
  TSD_Entry *tsd = collector_interface->getKey (tsd_key);
  if (tsd == NULL)
    return;
  tsd->tstamp = gethrtime ();
}

static void
jvmti_MonitorEntered (jvmtiEnv *jvmti_env, JNIEnv* jni_env,
		      jthread thread, jobject object)
{
  TSD_Entry *tsd = collector_interface->getKey (tsd_key);
  if (tsd == NULL)
    return;
  if (collector_jsync_end)
    collector_jsync_end (tsd->tstamp, object);
}

static void
jvmti_GarbageCollectionStart (jvmtiEnv *jvmti_env)
{
  hrtime_t hrt = gethrtime ();
  collector_interface->writeLog ("<event kind=\"%s\" tstamp=\"%u.%09u\"/>\n",
				 SP_JCMD_GCSTART,
				 (unsigned) (hrt / NANOSEC), (unsigned) (hrt % NANOSEC)
				 );
  TprintfT (DBG_LT1, "jprofile: jvmti_GarbageCollectionStart.\n");
}

static void
jvmti_GarbageCollectionFinish (jvmtiEnv *jvmti_env)
{
  hrtime_t hrt = gethrtime ();
  collector_interface->writeLog ("<event kind=\"%s\" tstamp=\"%u.%09u\"/>\n",
				 SP_JCMD_GCEND,
				 (unsigned) (hrt / NANOSEC), (unsigned) (hrt % NANOSEC)
				 );
  TprintfT (DBG_LT1, "jprofile: jvmti_GarbageCollectionFinish.\n");
}

#if 0
static void
jvmti_MonitorWait (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
		   jobject object, jlong timed_out)
{
  if (collector_sync_begin)
    collector_sync_begin ();
  TSD_Entry *tsd = collector_interface->getKey (tsd_key);
  if (tsd == NULL)
    return;
  tsd->tstamp = gethrtime ();
}

static void
jvmti_MonitorWaited (jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread,
		     jobject object, jboolean timed_out)
{
  TSD_Entry *tsd = collector_interface->getKey (tsd_key);
  if (tsd == NULL)
    return;
  if (collector_sync_end)
    collector_sync_end (tsd->tstamp, object);
}
#endif

static void
jprof_find_asyncgetcalltrace ()
{
  void *jvmhandle;
  if (__collector_VM_ReadByteInstruction == NULL)
    __collector_VM_ReadByteInstruction = (int(*)()) dlsym (RTLD_DEFAULT, "Async_VM_ReadByteInstruction");

  /* look for stack unwind function using default path */
  AsyncGetCallTrace = (void (*)(JVMPI_CallTrace*, jint, ucontext_t*))
	  dlsym (RTLD_DEFAULT, "AsyncGetCallTrace");
  if (AsyncGetCallTrace != NULL)
    {
      __collector_java_asyncgetcalltrace_loaded = 1;
      TprintfT (DBG_LT1, "jprofile: AsyncGetCallTrace found with RTLD_DEFAULT\n");
    }
  else
    {
      /* not found there, find libjvm.so, and ask again */
      jvmhandle = dlopen ("libjvm.so", RTLD_LAZY | RTLD_NOLOAD);
      if (jvmhandle != NULL)
	{
	  AsyncGetCallTrace = (void (*)(JVMPI_CallTrace*, jint, ucontext_t*))
		  dlsym (jvmhandle, "AsyncGetCallTrace");
	}
    }

  if (AsyncGetCallTrace == NULL)
    {
      /* we could not find it -- write collector error */
      TprintfT (0, "jprofile: ERROR -- AsyncGetCallTrace not found in address space\n");
      char *err = dlerror ();
      collector_interface->writeLog ("<event kind=\"%s\" id=\"%d\">%s</event>\n",
				     SP_JCMD_CERROR, COL_ERROR_JVMNOJSTACK, err ? err : "");
      __collector_java_mode = 0;
    }
  else
    {
      __collector_java_asyncgetcalltrace_loaded = 1;
      TprintfT (DBG_LT1, "jprofile: AsyncGetCallTrace initialized in jprof_jvmpi_init_done_event\n");
    }
}

int
__collector_ext_jstack_unwind (char *ptr, int sz, ucontext_t *uc)
{
  if (AsyncGetCallTrace == NULL)
    {
      TprintfT (DBG_LT0, "jprofile: __collector_ext_jstack_unwind: AsyncGetCallTrace is NULL\n");
      return 0;
    }

  TSD_Entry *tsd = collector_interface->getKey (tsd_key);
  if (tsd == NULL)
    {
      TprintfT (DBG_LT3, "jprofile: __collector_ext_jstack_unwind: tsd is NULL\n");
      return 0;
    }
  if (__collector_java_attach && tsd->env == NULL && jvmti != NULL && jvm != NULL)
    {
      TprintfT (DBG_LT3, "jprofile: __collector_ext_jstack_unwind: tsd->env is NULL under attach\n");
      JNIEnv* jni_env = NULL;
      (*jvm)->GetEnv (jvm, (void **) &jni_env, JNI_VERSION_1_2);
      tsd->env = jni_env;
    }
  if (tsd->env == NULL)
    {
      TprintfT (DBG_LT3, "jprofile: __collector_ext_jstack_unwind: tsd->env is NULL\n");
      return 0;
    }

  /* skip the Java stack whenever another signal handler is present */
  if (uc->uc_link)
    {
      TprintfT (DBG_LT3, "jprofile: __collector_ext_jstack_unwind: uc->uc_link is non-NULL\n");
      return 0;
    }
  /* we don't expect Java frames in signal handlers, so
   * unroll the list of saved contexts to the topmost one
   */
  while (uc->uc_link)
    uc = uc->uc_link;
  Java_info *jinfo = (Java_info*) ptr;
  jinfo->kind = JAVA_INFO;
  jinfo->hsize = sizeof (Java_info);
  ptr += sizeof (Java_info);
  sz -= sizeof (Java_info);

  JVMPI_CallTrace jtrace;
  jtrace.env_id = tsd->env;
  jtrace.frames = (JVMPI_CallFrame*) ptr;

  /* nframes is how many frames we have room for */
  jint nframes = sz / sizeof (JVMPI_CallFrame);

#if WSIZE(64)
  /* bug 6909545: garbage in 64-bit JAVA_INFO */
  CALL_UTIL (memset)(jtrace.frames, 0, nframes * sizeof (JVMPI_CallFrame));
#endif

#if ARCH(SPARC)
  // 21328946 JDK bug 8129933 causes <no java callstack recorded> on sparc-Linux
  // convert from ucontext_t to sigcontext
  struct sigcontext sctx;
  sctx.sigc_regs.tpc = uc->uc_mcontext.mc_gregs[MC_PC];
  __collector_memcpy (sctx.sigc_regs.u_regs, &uc->uc_mcontext.mc_gregs[3], sizeof (sctx.sigc_regs.u_regs));
  uc = (ucontext_t *) (&sctx);
#endif /* SPARC */
  AsyncGetCallTrace (&jtrace, nframes, uc);

  if (jtrace.num_frames == nframes)
    {
      JVMPI_CallFrame *last = &jtrace.frames[nframes - 1];
      last->method_id = (jmethodID) SP_TRUNC_STACK_MARKER;
      last->lineno = 0;
    }

  /* nframes is how many frames we actually got */
  nframes = jtrace.num_frames;
  TprintfT (DBG_LT3, "jprofile: __collector_ext_jstack_unwind: AsyncGetCallTrace jtrace.numframes = %d\n", nframes);
  if (nframes <= 0)
    {
      /* negative values are error codes */
      TprintfT (0, "jprofile: __collector_ext_jstack_unwind: AsyncGetCallTrace returned error: jtrace.numframes = %d\n", nframes);
      nframes = 1;
      JVMPI_CallFrame *err = (JVMPI_CallFrame*) ptr;
      err->lineno = jtrace.num_frames; // bci = error code
      err->method_id = 0; // artificial method id
    }
  jinfo->hsize += nframes * sizeof (JVMPI_CallFrame);
  return jinfo->hsize;
}

/*
 *	Collector Java API implementation
 */
void
Java_com_sun_forte_st_collector_CollectorAPI__1sample(JNIEnv *jEnv, jclass jCls, jstring jName)
{
  JNIEnv *jni;
  jint res = (*jvm)->GetEnv (jvm, (void **) &jni, JNI_VERSION_1_2);
  if (res < 0)
    return;
  const char *name = jName ? (*jni)->GetStringUTFChars (jni, jName, NULL) : NULL;
  __collector_sample ((char*) name);
}

void
Java_com_sun_forte_st_collector_CollectorAPI__1pause(JNIEnv *jEnv, jclass jCls)
{
  __collector_pause_m ("JAPI");
}

void
Java_com_sun_forte_st_collector_CollectorAPI__1resume(JNIEnv *jEnv, jclass jCls)
{
  __collector_resume ();
}

void
Java_com_sun_forte_st_collector_CollectorAPI__1terminate(JNIEnv *jEnv, jclass jCls)
{
  __collector_terminate_expt ();
}
#endif /* GPROFNG_JAVA_PROFILING */

static void init_module () __attribute__ ((constructor));
static void
init_module ()
{
#if defined(GPROFNG_JAVA_PROFILING)
  __collector_dlsym_guard = 1;
  RegModuleFunc reg_module = (RegModuleFunc) dlsym (RTLD_DEFAULT, "__collector_register_module");
  __collector_dlsym_guard = 0;
  if (reg_module)
    {
      jprof_hndl = reg_module (&module_interface);
      TprintfT (0, "jprofile: init_module.\n");
    }
#endif /* GPROFNG_JAVA_PROFILING */
}

int __collector_java_mode = 0;
int __collector_java_asyncgetcalltrace_loaded = 0;
