Author: Martin Platter
Changes: Edwin Steiner
+ Samuel Vinson
- $Id: jvmti.c 4874 2006-05-05 14:36:18Z edwin $
+ $Id: jvmti.c 4944 2006-05-23 15:31:19Z motse $
*/
#include "vm/stringlocal.h"
#include "mm/memory.h"
#include "threads/native/threads.h"
+#include "threads/native/lock.h"
#include "vm/exceptions.h"
#include "native/include/java_util_Vector.h"
#include "native/include/java_io_PrintStream.h"
#include "toolbox/logging.h"
#include <stdlib.h>
#include <sys/types.h>
-#include <sys/wait.h>
-#include <sys/user.h>
-#include <signal.h>
#include <ltdl.h>
+#include <unistd.h>
+#include <sched.h>
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
#include "threads/native/threads.h"
#include <sched.h>
#include <pthread.h>
#include "dbg.h"
+
typedef struct _environment environment;
-environment *envs=NULL;
+static environment *envs=NULL;
+pthread_mutex_t dbgcomlock;
extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
struct _jvmtiThreadLocalStorage{
jthread thread;
- jvmtiThreadLocalStorage *next;
void *data;
+ jvmtiThreadLocalStorage *next;
};
struct _environment {
jvmtiEnv env;
+ environment *next;
jvmtiEventCallbacks callbacks;
/* table for enabled/disabled jvmtiEvents - first element contains global
behavior */
jvmtiCapabilities capabilities;
void *EnvironmentLocalStorage;
jvmtiThreadLocalStorage *tls;
- environment *next;
};
static struct jvmtiEnv_struct JVMTI_EnvTable;
static jvmtiCapabilities JVMTI_Capabilities;
static lt_ptr unload;
-#define CHECK_PHASE_START if (!(0
+#define CHECK_PHASE_START if (!(false
#define CHECK_PHASE(chkphase) || (phase == chkphase)
#define CHECK_PHASE_END )) return JVMTI_ERROR_WRONG_PHASE
#define CHECK_CAPABILITY(env,CAP) if(((environment*)env)->capabilities.CAP == 0) \
*******************************************************************************/
static jvmtiError check_thread_is_alive(jthread t) {
- char* data;
- java_lang_Thread* th;
- if(t==NULL)
- return JVMTI_ERROR_THREAD_NOT_ALIVE;
- getchildproc(&data, t, sizeof(java_lang_Thread));
- th = (java_lang_Thread*)data;
- if(th->vmThread==NULL)
+ if(t==NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
+ if(((java_lang_Thread*) t)->vmThread==NULL)
return JVMTI_ERROR_THREAD_NOT_ALIVE;
return JVMTI_ERROR_NONE;
}
in the data structure.
*******************************************************************************/
-static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
- JNIEnv* jni_env = (JNIEnv*)&_Jv_JNINativeInterface;
+static void execute_callback(jvmtiEvent e, functionptr ec,
+ genericEventData* data) {
+ JNIEnv* jni_env = (JNIEnv*)_Jv_env;
fprintf(stderr,"execcallback called (event: %d)\n",e);
switch (e) {
case JVMTI_EVENT_VM_INIT:
+ if (phase != JVMTI_PHASE_LIVE) return;
case JVMTI_EVENT_THREAD_START:
case JVMTI_EVENT_THREAD_END:
- ((jvmtiEventThreadStart)ec) (data->jvmti_env, jni_env, data->thread);
+ if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+ ((jvmtiEventThreadStart)ec)(data->jvmti_env,jni_env,data->thread);
break;
-
case JVMTI_EVENT_CLASS_FILE_LOAD_HOOK:
+ if ((phase == JVMTI_PHASE_START) ||
+ (phase == JVMTI_PHASE_LIVE) ||
+ (phase == JVMTI_PHASE_PRIMORDIAL))
((jvmtiEventClassFileLoadHook)ec) (data->jvmti_env,
jni_env,
data->klass,
case JVMTI_EVENT_CLASS_PREPARE:
case JVMTI_EVENT_CLASS_LOAD:
- ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
- data->thread, data->klass);
+ if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
+ ((jvmtiEventClassLoad)ec) (data->jvmti_env, jni_env,
+ data->thread, data->klass);
break;
case JVMTI_EVENT_VM_DEATH:
+ if (phase != JVMTI_PHASE_LIVE) return;
case JVMTI_EVENT_VM_START:
+ if ((phase == JVMTI_PHASE_START) || (phase == JVMTI_PHASE_LIVE))
((jvmtiEventVMStart)ec) (data->jvmti_env, jni_env);
break;
- case JVMTI_EVENT_EXCEPTION:
- ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->object,
- data->catch_method,
- data->catch_location);
- break;
-
- case JVMTI_EVENT_EXCEPTION_CATCH:
- ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->object);
- break;
-
- case JVMTI_EVENT_BREAKPOINT:
- case JVMTI_EVENT_SINGLE_STEP:
- ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location);
- break;
-
- case JVMTI_EVENT_FRAME_POP:
- ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->b);
- break;
-
- case JVMTI_EVENT_FIELD_ACCESS:
- ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->klass,
- data->object,
- data->field);
- break;
-
- case JVMTI_EVENT_FIELD_MODIFICATION:
- ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->location,
- data->klass,
- data->object,
- data->field,
- data->signature_type,
- data->value);
- break;
-
- case JVMTI_EVENT_METHOD_ENTRY:
- ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method);
- break;
-
- case JVMTI_EVENT_METHOD_EXIT:
- ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->b,
- data->value);
- break;
-
case JVMTI_EVENT_NATIVE_METHOD_BIND:
- ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->method,
- data->address,
- data->new_address_ptr);
- break;
-
- case JVMTI_EVENT_COMPILED_METHOD_LOAD:
- ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
- data->method,
- data->jint1,
- data->address,
- data->jint2,
- data->map,
- data->compile_info);
- break;
-
- case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
- ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
+ if ((phase == JVMTI_PHASE_START) ||
+ (phase == JVMTI_PHASE_LIVE) ||
+ (phase == JVMTI_PHASE_PRIMORDIAL))
+ ((jvmtiEventNativeMethodBind)ec) (data->jvmti_env, jni_env,
+ data->thread,
data->method,
- data->address);
+ data->address,
+ data->new_address_ptr);
break;
+
case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
- ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
- data->name,
- data->address,
- data->jint1);
+ if ((phase == JVMTI_PHASE_START) ||
+ (phase == JVMTI_PHASE_LIVE) ||
+ (phase == JVMTI_PHASE_PRIMORDIAL))
+ ((jvmtiEventDynamicCodeGenerated)ec) (data->jvmti_env,
+ data->name,
+ data->address,
+ data->jint1);
break;
- case JVMTI_EVENT_GARBAGE_COLLECTION_START:
- case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
- case JVMTI_EVENT_DATA_DUMP_REQUEST:
- ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
- break;
- case JVMTI_EVENT_MONITOR_WAIT:
- ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->object,
- data->jlong);
- break;
- case JVMTI_EVENT_MONITOR_WAITED:
- ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
+ default:
+ if (phase != JVMTI_PHASE_LIVE) return;
+ switch (e) {
+ case JVMTI_EVENT_EXCEPTION:
+ ((jvmtiEventException)ec) (data->jvmti_env, jni_env,
data->thread,
+ data->method,
+ data->location,
data->object,
- data->b);
- break;
-
-
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
- case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
- ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
+ data->catch_method,
+ data->catch_location);
+ break;
+
+ case JVMTI_EVENT_EXCEPTION_CATCH:
+ ((jvmtiEventExceptionCatch)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->location,
+ data->object);
+ break;
+
+ case JVMTI_EVENT_BREAKPOINT:
+ case JVMTI_EVENT_SINGLE_STEP:
+ ((jvmtiEventSingleStep)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->location);
+ break;
+
+ case JVMTI_EVENT_FRAME_POP:
+ ((jvmtiEventFramePop)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->b);
+ break;
+
+
+ case JVMTI_EVENT_FIELD_ACCESS:
+ ((jvmtiEventFieldAccess)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->location,
+ data->klass,
+ data->object,
+ data->field);
+ break;
+
+ case JVMTI_EVENT_FIELD_MODIFICATION:
+
+ ((jvmtiEventFieldModification)ec) (data->jvmti_env, jni_env,
data->thread,
- data->object);
- break;
+ data->method,
+ data->location,
+ data->klass,
+ data->object,
+ data->field,
+ data->signature_type,
+ data->value);
+ break;
+
+ case JVMTI_EVENT_METHOD_ENTRY:
+ ((jvmtiEventMethodEntry)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method);
+ break;
+
+ case JVMTI_EVENT_METHOD_EXIT:
+ ((jvmtiEventMethodExit)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->method,
+ data->b,
+ data->value);
+ break;
+
+ case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+ ((jvmtiEventCompiledMethodLoad)ec) (data->jvmti_env,
+ data->method,
+ data->jint1,
+ data->address,
+ data->jint2,
+ data->map,
+ data->compile_info);
+ break;
+
+ case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+ ((jvmtiEventCompiledMethodUnload)ec) (data->jvmti_env,
+ data->method,
+ data->address);
+ break;
+
+ case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+ case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+ case JVMTI_EVENT_DATA_DUMP_REQUEST:
+ ((jvmtiEventDataDumpRequest)ec) (data->jvmti_env);
+ break;
+
+ case JVMTI_EVENT_MONITOR_WAIT:
+ ((jvmtiEventMonitorWait)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object,
+ data->jlong);
+ break;
+
+ case JVMTI_EVENT_MONITOR_WAITED:
+ ((jvmtiEventMonitorWaited)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object,
+ data->b);
+ break;
- case JVMTI_EVENT_OBJECT_FREE:
- ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
- break;
- case JVMTI_EVENT_VM_OBJECT_ALLOC:
- ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
- data->thread,
- data->object,
- data->klass,
- data->jlong);
- break;
+ case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+ case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+ ((jvmtiEventMonitorContendedEnter)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object);
+ break;
+ case JVMTI_EVENT_OBJECT_FREE:
+ ((jvmtiEventObjectFree)ec) (data->jvmti_env, data->jlong);
+ break;
- default:
- log_text ("unknown event");
+ case JVMTI_EVENT_VM_OBJECT_ALLOC:
+ ((jvmtiEventVMObjectAlloc)ec) (data->jvmti_env, jni_env,
+ data->thread,
+ data->object,
+ data->klass,
+ data->jlong);
+ break;
+ default:
+ log_text ("unknown event");
+ }
+ break;
}
}
if (evm->mode == JVMTI_ENABLE) {
data->jvmti_env=&env->env;
ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
- execcallback(e, ec, data);
+ execute_callback(e, ec, data);
}
evm=evm->next;
}
} else { /* event enabled globally */
data->jvmti_env=&env->env;
ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
- execcallback(e, ec, data);
+ execute_callback(e, ec, data);
}
env=env->next;
missing EventData.
*******************************************************************************/
-void fireEvent(genericEventData* d) {
+void jvmti_fireEvent(genericEventData* d) {
jthread thread;
- /* todo : respect event order JVMTI-Spec:Multiple Co-located Events */
+ /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
if (d->ev != JVMTI_EVENT_VM_START)
- thread = (jthread)getcurrentthread();
+ thread = jvmti_get_current_thread();
else
thread = NULL;
- fprintf (stderr,"debugger: fireEvent: %d\n",d->ev);
d->thread = thread;
dofireEvent(d->ev,d);
-
- fprintf (stderr,"debugger: fireEvent 2\n");
- /* if we need to send a VM_INIT event then also send a THREAD_START event */
- if (d->ev == JVMTI_EVENT_VM_INIT)
- dofireEvent(JVMTI_EVENT_THREAD_START,d);
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
jvmtiEvent event_type, jthread event_thread, ...)
{
CHECK_THREAD_IS_ALIVE(event_thread);
}
+
cacao_env = (environment*) env;
if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- if ((event_type < JVMTI_EVENT_START_ENUM) ||
- (event_type > JVMTI_EVENT_END_ENUM))
- return JVMTI_ERROR_INVALID_EVENT_TYPE;
-
-
- switch (event_type) { /* check capability */
+ switch (event_type) { /* check capability and set system breakpoint */
case JVMTI_EVENT_EXCEPTION:
case JVMTI_EVENT_EXCEPTION_CATCH:
CHECK_CAPABILITY(env,can_generate_exception_events)
case JVMTI_EVENT_VM_OBJECT_ALLOC:
CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
break;
+ case JVMTI_EVENT_THREAD_START:
+ jvmti_set_system_breakpoint(THREADSTARTBRK, mode);
+ break;
+ case JVMTI_EVENT_THREAD_END:
+ jvmti_set_system_breakpoint(THREADENDBRK, mode);
+ break;
+
default:
/* all other events are required */
+ if ((event_type < JVMTI_EVENT_START_ENUM) ||
+ (event_type > JVMTI_EVENT_END_ENUM))
+ return JVMTI_ERROR_INVALID_EVENT_TYPE;
break;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
jthread ** threads_ptr)
{
- threadobject* threads;
+ threadobject** threads;
int i;
jvmtiError retval;
- log_text ("GetAllThreads called");
-
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- retval=allthreads(threads_count_ptr,&threads);
+ retval=jvmti_get_all_threads(threads_count_ptr, &threads);
if (retval != JVMTI_ERROR_NONE) return retval;
*threads_ptr =
heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
- for (i=0; i<*threads_count_ptr; i++)
- (*threads_ptr)[i] = threadobject2jthread(&threads[i]);
+ for (i=0; i<*threads_count_ptr; i++)
+ (*threads_ptr)[i] = threads[i]->o.thread;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- CHECK_CAPABILITY(env,can_suspend)
+ CHECK_CAPABILITY(env,can_suspend);
-/*
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- suspend_thread((thread *) thread->thread);
-#endif
-
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- suspend_thread((threadobject*) thread);
-#endif
-*/
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+ return JVMTI_ERROR_NOT_AVAILABLE;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
ResumeThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- CHECK_CAPABILITY(env,can_suspend)
+ CHECK_CAPABILITY(env,can_suspend);
-/*
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- resume_thread((thread *) this->thread);
-#endif
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+ return JVMTI_ERROR_NOT_AVAILABLE;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- resume_thread((threadobject*) thread);
-#endif
-*/
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
StopThread (jvmtiEnv * env, jthread thread, jobject exception)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- CHECK_CAPABILITY(env,can_signal_thread)
+ CHECK_CAPABILITY(env,can_signal_thread);
- log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+ return JVMTI_ERROR_NOT_AVAILABLE;
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
InterruptThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_signal_thread)
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
+ return JVMTI_ERROR_NOT_AVAILABLE;
+
if(!builtin_instanceof(thread,class_java_lang_Thread))
return JVMTI_ERROR_INVALID_THREAD;
CHECK_THREAD_IS_ALIVE(thread);
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
-/* interruptThread((java_lang_VMThread*)thread);*/
-#else
- return JVMTI_ERROR_NOT_AVAILABLE;
-#endif
-
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
-GetThreadInfo (jvmtiEnv * env, jthread th, jvmtiThreadInfo * info_ptr)
+static jvmtiError
+GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
{
- int size;
- char* data;
- struct java_lang_Thread *t;
-
- log_text("GetThreadInfo called");
+ java_lang_Thread* th = (java_lang_Thread*)t;
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- getchildproc(&data,th,sizeof(struct java_lang_Thread));
- t = (java_lang_Thread*)data;
- info_ptr->priority=(jint)t->priority;
- info_ptr->is_daemon=(jboolean)t->daemon;
- info_ptr->thread_group=(jthreadGroup)t->group;
- info_ptr->context_class_loader=(jobject)t->contextClassLoader;
- getchildproc(&data,t->name,sizeof(struct java_lang_String));
- size = ((struct java_lang_String*)data)->count;
- getchildproc(&(info_ptr->name),((struct java_lang_String*)data)->value,size);
- info_ptr->name[size]='\0';
-
+ info_ptr->priority=(jint)th->priority;
+ info_ptr->is_daemon=(jboolean)th->daemon;
+ info_ptr->thread_group=(jthreadGroup)th->group;
+ info_ptr->context_class_loader=(jobject)th->contextClassLoader;
+ info_ptr->name= javastring_tochar((java_objectheader *)th->name);
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetOwnedMonitorInfo (jvmtiEnv * env, jthread thread,
jint * owned_monitor_count_ptr,
jobject ** owned_monitors_ptr)
{
int i,j,size=20;
java_objectheader **om;
- lockRecordPool* lrp;
- char *data;
+ lock_record_pool_t* lrp;
log_text("GetOwnedMonitorInfo called");
CHECK_THREAD_IS_ALIVE(thread);
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
om=MNEW(java_objectheader*,size);
- stopdebuggee();
-
- /* global_pool is in the same place in the child process memory because the
- the child is a copy of this process */
- getchildproc(&data, &global_pool,sizeof(lockRecordPool*));
- lrp=(lockRecordPool*)data;
+ pthread_mutex_lock(&lock_global_pool_lock);
+ lrp=lock_global_pool;
while (lrp != NULL) {
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].ownerThread==(threadobject*)thread)&&
+/* if((lrp->lr[j].owner==(threadobject*)thread)&&
(!lrp->lr[j].waiting)) {
if (i>=size) {
MREALLOC(om,java_objectheader*,size,size*2);
}
om[i]=lrp->lr[j].o;
i++;
- }
+ }*/
}
lrp=lrp->header.next;
}
- pthread_mutex_unlock(&pool_lock);
+ pthread_mutex_unlock(&lock_global_pool_lock);
*owned_monitors_ptr = heap_allocate(sizeof(java_objectheader*)*i,true,NULL);
memcpy(*owned_monitors_ptr,om,i*sizeof(java_objectheader*));
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
jobject * monitor_ptr)
{
int j;
- lockRecordPool* lrp;
+ lock_record_pool_t* lrp;
java_objectheader* monitor;
CHECK_PHASE_START
CHECK_THREAD_IS_ALIVE(thread);
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
- pthread_mutex_lock(&pool_lock);
+ pthread_mutex_lock(&lock_global_pool_lock);
- lrp=global_pool;
+ lrp=lock_global_pool;
while ((lrp != NULL)&&(monitor==NULL)) {
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].ownerThread==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
+/* if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
monitor=lrp->lr[j].o;
break;
- }
+ }*/
}
lrp=lrp->header.next;
}
- pthread_mutex_unlock(&pool_lock);
+ pthread_mutex_unlock(&lock_global_pool_lock);
if (monitor!=NULL) {
*monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
static void *threadstartup(void *t) {
runagentparam *rap = (runagentparam*)t;
- rap->sf(rap->jvmti_env,&_Jv_JNINativeInterface,rap->arg);
+ rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
return NULL;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
const void *arg, jint priority)
{
(priority > JVMTI_THREAD_MAX_PRIORITY))
return JVMTI_ERROR_INVALID_PRIORITY;
+ /* XXX: Threads started with with this function should not be visible to
+ Java programming language queries but are included in JVM TI queries */
+
rap.sf = proc;
rap.arg = (void*)arg;
rap.jvmti_env = env;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
pthread_attr_init(&threadattr);
pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
if (priority == JVMTI_THREAD_MIN_PRIORITY) {
}
pthread_attr_setschedparam(&threadattr,&sp);
if (pthread_create(&((threadobject*)
- thread)->info.tid, &threadattr, &threadstartup, &rap)) {
+ thread)->tid, &threadattr, &threadstartup, &rap)) {
log_text("pthread_create failed");
assert(0);
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
jthreadGroup ** groups_ptr)
{
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ log_text("GetTopThreadGroups called");
+
if ((groups_ptr == NULL) || (group_count_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
tg = MNEW(jthreadGroup*,size);
x = 0;
if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
j++;
}
-
if (j == x) {
if (x >= size){
MREALLOC(tg,jthreadGroup*,size,size*2);
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
jvmtiThreadGroupInfo * info_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
jint * thread_count_ptr, jthread ** threads_ptr,
jint * group_count_ptr, jthreadGroup ** groups_ptr)
Has to take care of suspend/resume issuses
*******************************************************************************/
-static jvmtiError getcacaostacktrace(char** trace, jthread thread) {
+static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
+ threadobject *t;
log_text("getcacaostacktrace");
-
+ t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
+
+/* XXX todo
+ *trace = stacktrace_create(t); */
return JVMTI_ERROR_NONE;
}
/* GetFrameCount **************************************************************
+
Get the number of frames in the specified thread's stack.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
{
- char* trace;
+ stacktracebuffer* trace;
jvmtiError er;
CHECK_PHASE_START
er = getcacaostacktrace(&trace, thread);
if (er==JVMTI_ERROR_NONE) return er;
-/* todo: *count_ptr = trace->size;*/
+ *count_ptr = trace->used;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
{
java_lang_Thread* th = (java_lang_Thread*)thread;
if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*thread_state_ptr = 0;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
/* not alive */
- if (((threadobject*)th->vmThread)->info.tid == 0)
+ if (((threadobject*)th->vmThread)->tid == 0)
*thread_state_ptr = JVMTI_THREAD_STATE_TERMINATED;
} else {
/* alive */
if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT;
if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_OBJECT_WAIT;
if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_PARKED;
- if (t->isSleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
+ if (t->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
}
#else
return JVMTI_ERROR_INTERNAL;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
jmethodID * method_ptr, jlocation * location_ptr)
{
if ((method_ptr == NULL)&&(location_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- sfi = ((threadobject*)thread)->info._stackframeinfo;
+ sfi = ((threadobject*)thread)->_stackframeinfo;
i = 0;
while ((sfi != NULL) && (i<depth)) {
*******************************************************************************/
-jvmtiError
+static jvmtiError
NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalObject (jvmtiEnv * env,
jthread thread, jint depth, jint slot, jobject * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalInt (jvmtiEnv * env,
jthread thread, jint depth, jint slot, jint * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jlong * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jfloat * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jdouble * value_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jobject value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jint value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jlong value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jfloat value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jdouble value)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
CreateRawMonitor (jvmtiEnv * env, const char *name,
jrawMonitorID * monitor_ptr)
{
if ((name == NULL) || (monitor_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
monitor->name=javastring_new_from_ascii(name);
#else
log_text ("CreateRawMonitor not supported");
*******************************************************************************/
-jvmtiError
+static jvmtiError
DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
{
CHECK_PHASE_START
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
return JVMTI_ERROR_INVALID_MONITOR;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
+#if defined(ENABLE_THREADS)
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- monitorExit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
+ lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
/* GC will clean monitor up */
#else
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
return JVMTI_ERROR_INVALID_MONITOR;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
builtin_monitorenter((java_objectheader*)monitor->name);
#else
log_text ("RawMonitorEnter not supported");
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
return JVMTI_ERROR_INVALID_MONITOR;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
builtin_monitorexit((java_objectheader*)monitor->name);
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
return JVMTI_ERROR_INVALID_MONITOR;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- wait_cond_for_object(&monitor->name->header, millis,0);
+ lock_wait_for_object(&monitor->name->header, millis,0);
if (builtin_instanceof((java_objectheader*)exceptionptr, load_class_bootstrap(utf_new_char("java/lang/InterruptedException"))))
return JVMTI_ERROR_INTERRUPT;
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
return JVMTI_ERROR_INVALID_MONITOR;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT,(java_objectheader*)monitor->name))
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- signal_cond_for_object((java_objectheader*)&monitor->name);
+ lock_notify_object((java_objectheader*)&monitor->name);
#else
log_text ("RawMonitorNotify not supported");
#endif
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
return JVMTI_ERROR_INVALID_MONITOR;
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
/* assure current thread owns this monitor */
- if (!threadHoldsLock((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name))
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- broadcast_cond_for_object((java_objectheader*)&monitor->name);
+ lock_notify_all_object((java_objectheader*)&monitor->name);
#else
log_text ("RawMonitorNotifyAll not supported");
#endif
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_generate_breakpoint_events)
-
+
/* addbrkpt */
log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
Allocate (jvmtiEnv * env, jlong size, unsigned char **mem_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
Deallocate (jvmtiEnv * env, unsigned char *mem)
{
/* let Boehm GC do the job */
+ heap_free(mem);
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassSignature (jvmtiEnv * env, jclass klass, char **signature_ptr,
char **generic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
{
classinfo *c;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
{
int size;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassMethods (jvmtiEnv * env, jclass klass, jint * method_count_ptr,
jmethodID ** methods_ptr)
{
- CHECK_PHASE_START
+ int i;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
+
if ((klass == NULL)||(methods_ptr == NULL)||(method_count_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
*method_count_ptr = (jint)((classinfo*)klass)->methodscount;
*methods_ptr = (jmethodID*)
heap_allocate(sizeof(jmethodID) * (*method_count_ptr),true,NULL);
-
- memcpy (*methods_ptr, ((classinfo*)klass)->methods,
- sizeof(jmethodID) * (*method_count_ptr));
-
+
+ for (i=0; i<*method_count_ptr;i++)
+ (*methods_ptr)[i]=(jmethodID) &(((classinfo*)klass)->methods[i]);
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassFields (jvmtiEnv * env, jclass klass, jint * field_count_ptr,
jfieldID ** fields_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
jint * interface_count_ptr,
jclass ** interfaces_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsInterface (jvmtiEnv * env, jclass klass, jboolean * is_interface_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsArrayClass (jvmtiEnv * env, jclass klass, jboolean * is_array_class_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
jvmtiMonitorUsage * info_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldName (jvmtiEnv * env, jclass klass, jfieldID field,
char **name_ptr, char **signature_ptr, char **generic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
jclass * declaring_class_ptr)
{
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- /* todo: how do I find declaring class other then iterate over all fields in all classes ?*/
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ *declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
jint * modifiers_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
jboolean * is_synthetic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodName (jvmtiEnv * env, jmethodID method, char **name_ptr,
char **signature_ptr, char **generic_ptr)
{
if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
|| (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
- *name_ptr = (char*)heap_allocate(m->name->blength,true,NULL);
- memcpy(*name_ptr, m->name->text, m->name->blength);
+ *name_ptr = (char*)
+ heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
+ utf_sprint_convert_to_latin1(*name_ptr, m->name);
+
+ *signature_ptr = (char*)
+ heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
+ utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
- *signature_ptr = (char*)heap_allocate(m->descriptor->blength,true,NULL);
- memcpy(*signature_ptr, m->descriptor->text, m->descriptor->blength);
-
/* there is no generic signature attribute */
*generic_ptr = NULL;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodDeclaringClass (jvmtiEnv * env, jmethodID method,
jclass * declaring_class_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodModifiers (jvmtiEnv * env, jmethodID method, jint * modifiers_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMaxLocals (jvmtiEnv * env, jmethodID method, jint * max_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLineNumberTable (jvmtiEnv * env, jmethodID method,
jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodLocation (jvmtiEnv * env, jmethodID method,
jlocation * start_location_ptr,
jlocation * end_location_ptr)
/* XXX Don't know if that's the right way to deal with not-yet-
* compiled methods. -Edwin */
+
if (!m->code)
return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
jint * entry_count_ptr,
jvmtiLocalVariableEntry ** table_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetBytecodes (jvmtiEnv * env, jmethodID method,
jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsMethodNative (jvmtiEnv * env, jmethodID method, jboolean * is_native_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsMethodSynthetic (jvmtiEnv * env, jmethodID method,
jboolean * is_synthetic_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
{
int i,j;
classcache_name_entry *cne;
classcache_class_entry *cce;
- log_text ("GetLoadedClasses called");
+ log_text ("GetLoadedClasses called %d ", phase);
+
+
+ /* XXX todo */
+
+ *class_count_ptr = 0;
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
log_text ("GetLoadedClasses1");
- stopdebuggee();
+/*
+ CLASSCACHE_LOCK();
log_text ("GetLoadedClasses2");
- /* hashtable_classcache is in the same place in the child process memory
- because the child is a copy of this process */
getchildproc(&data, &hashtable_classcache, sizeof(hashtable));
ht = (hashtable*) &data;
fflush(stderr);
*class_count_ptr = ht->entries;
+ log_text ("GetLoadedClasses %d", *class_count_ptr);
j=0;
- /* look in every slot of the hashtable */
+ look in every slot of the hashtable
for (i=0; i<ht->size; i++) {
cne = ht->ptr[i];
- while (cne != NULL) { /* iterate over hashlink */
+ while (cne != NULL) { iterate over hashlink
getchildproc(&data, cne, sizeof(classcache_name_entry));
cne =(classcache_name_entry*) &data;
- cce = cne->classes;
- while (cce != NULL){ /* iterate over classes with same name */
- getchildproc(&data, cce, sizeof(classcache_class_entry));
- cce =(classcache_class_entry*) &data;
-
- if (cce->classobj != NULL) { /* get only loaded classes */
- assert(j<ht->entries);
- *classes_ptr[j]=cce->classobj;
+ cce = cne->classes;
+ while (cce != NULL){ iterate over classes with same name
+ getchildproc(&data, cce, sizeof(classcache_class_entry));
+ cce =(classcache_class_entry*) &data;
+
+ if (cce->classobj != NULL) { get only loaded classes
+ assert(j<ht->entries);
+ * classes_ptr[j]=cce->classobj;
j++;
}
cce = cce->next;
cne = cne->hashlink;
}
}
-
+
log_text ("GetLoadedClasses continue");
- contdebuggee(0);
+ CLASSCACHE_UNLOCK();
+
+*/
log_text ("GetLoadedClasses finished");
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
jint * class_count_ptr, jclass ** classes_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
PopFrame (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
RedefineClasses (jvmtiEnv * env, jint class_count,
const jvmtiClassDefinition * class_definitions)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetVersionNumber (jvmtiEnv * env, jint * version_ptr)
{
if (version_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
- *version_ptr = JVMTI_VERSION_1_0;
+ *version_ptr = JVMTI_VERSION;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
{
if (capabilities_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSourceDebugExtension (jvmtiEnv * env, jclass klass,
char **source_debug_extension_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsMethodObsolete (jvmtiEnv * env, jmethodID method,
jboolean * is_obsolete_ptr)
{
}
-/* *****************************************************************************
+/* SuspendThreadList **********************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThreadList (jvmtiEnv * env, jint request_count,
const jthread * request_list, jvmtiError * results)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- CHECK_CAPABILITY(env,can_suspend)
+ CHECK_CAPABILITY(env,can_suspend);
- log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* ResumeThreadList ***********************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
ResumeThreadList (jvmtiEnv * env, jint request_count,
const jthread * request_list, jvmtiError * results)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- CHECK_CAPABILITY(env,can_suspend)
+ CHECK_CAPABILITY(env,can_suspend);
- log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
jint max_frame_count, jvmtiFrameInfo * frame_buffer,
jint * count_ptr)
{
- char* trace;
+ stacktracebuffer* trace;
jvmtiError er;
-/* int i,j;*/
+ int i,j;
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
er = getcacaostacktrace(&trace, thread);
if (er==JVMTI_ERROR_NONE) return er;
-/* todo: if ((trace->size >= start_depth) || ((trace->size * -1) > start_depth))
- return JVMTI_ERROR_ILLEGAL_ARGUMENT; */
+ if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
+ return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-/* for (i=start_depth, j=0;i<trace->size;i++,j++) {
- frame_buffer[j].method = (jmethodID)trace[i].start->method;
- todo: location MachinePC not avilable - Linenumber not expected
+ for (i=start_depth, j=0;i<trace->used;i++,j++) {
+ frame_buffer[j].method = (jmethodID)trace->entries[i].method;
+ /* todo: location BCI/MachinePC not avilable - Linenumber not expected */
frame_buffer[j].location = 0;
- }*/
+ }
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
const jthread * thread_list,
jint max_frame_count,
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
{
jvmtiThreadLocalStorage *tls;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetTag (jvmtiEnv * env, jobject object, jlong tag)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
ForceGarbageCollection (jvmtiEnv * env)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
jvmtiObjectReferenceCallback
object_reference_callback,
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
heap_root_callback,
jvmtiStackReferenceCallback
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback heap_object_callback,
void *user_data)
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
jint * count_ptr, jobject ** object_result_ptr,
jlong ** tag_result_ptr)
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetJNIFunctionTable (jvmtiEnv * env,
const jniNativeInterface * function_table)
{
if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
_Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
- memcpy(_Jv_env->env, function_table, sizeof(jniNativeInterface));
+ memcpy((void*)_Jv_env->env, function_table, sizeof(jniNativeInterface));
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetJNIFunctionTable (jvmtiEnv * env, jniNativeInterface ** function_table)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEventCallbacks (jvmtiEnv * env,
const jvmtiEventCallbacks * callbacks,
jint size_of_callbacks)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
jvmtiExtensionFunctionInfo ** extensions)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
jvmtiExtensionEventInfo ** extensions)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
jvmtiExtensionEvent callback)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
DisposeEnvironment (jvmtiEnv * env)
{
environment* cacao_env = (environment*)env;
environment* tenvs = envs;
- memset(&((cacao_env)->events[0]),0,sizeof(jvmtiEventModeLL)*
- (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
- (cacao_env)->EnvironmentLocalStorage = NULL;
-
- if (tenvs!=cacao_env) {
+ jvmtiThreadLocalStorage *jtls, *tjtls;
+
+ if (tenvs != cacao_env) {
while (tenvs->next != cacao_env) {
tenvs = tenvs->next;
}
} else
envs = NULL;
- /* let Boehm GC do the rest */
+ cacao_env->env=NULL;
+ memset(&(cacao_env->callbacks),0,sizeof(jvmtiEventCallbacks)*
+ (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+ memset(cacao_env->events,0,sizeof(jvmtiEventModeLL)*
+ (JVMTI_EVENT_END_ENUM-JVMTI_EVENT_START_ENUM));
+ cacao_env->EnvironmentLocalStorage = NULL;
+
+ jtls = cacao_env->tls;
+ while (jtls != NULL) {
+ tjtls = jtls;
+ jtls = jtls->next;
+ tjtls->next = NULL;
+ }
+ cacao_env->tls = NULL;
+
+
+ jvmti_cacaodbgserver_quit();
+
+ /* let the GC do the rest */
return JVMTI_ERROR_NONE;
}
memcpy(*name_ptr, &str, sizeof(str)); \
break
-jvmtiError
+static jvmtiError
GetErrorName (jvmtiEnv * env, jvmtiError error, char **name_ptr)
{
if (name_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetJLocationFormat (jvmtiEnv * env, jvmtiJlocationFormat * format_ptr)
{
*format_ptr = JVMTI_JLOCATION_MACHINEPC;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
{
jmethodID mid, moremid;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
{
jmethodID mid;
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
{
jmethodID mid;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
{
if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTime (jvmtiEnv * env, jlong * nanos_ptr)
{
/* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetPotentialCapabilities (jvmtiEnv * env,
jvmtiCapabilities * capabilities_ptr)
{
}
-#define CHECK_ADD_CAPABILITY(env,CAN) \
- if ((capabilities_ptr->CAN == 1) && \
- (JVMTI_Capabilities.CAN == 0)) \
- return JVMTI_ERROR_NOT_AVAILABLE; \
- env->capabilities.CAN = 1;
+#define CHECK_ADD_CAPABILITY(env,CAN) \
+ if (capabilities_ptr->CAN == 1) { \
+ if (JVMTI_Capabilities.CAN == 0) \
+ return JVMTI_ERROR_NOT_AVAILABLE; \
+ else \
+ env->capabilities.CAN = 1; \
+ }
/* AddCapabilities ************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
AddCapabilities (jvmtiEnv * env, const jvmtiCapabilities * capabilities_ptr)
{
environment* cacao_env;
*******************************************************************************/
-jvmtiError
+static jvmtiError
RelinquishCapabilities (jvmtiEnv * env,
const jvmtiCapabilities * capabilities_ptr)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAvailableProcessors (jvmtiEnv * env, jint * processor_count_ptr)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetEnvironmentLocalStorage (jvmtiEnv * env, void **data_ptr)
{
if ((env == NULL) || (data_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEnvironmentLocalStorage (jvmtiEnv * env, const void *data)
{
if (env == NULL) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-jvmtiError
+static jvmtiError
AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
{
char* tmp_bcp;
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
{
switch (flag) {
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
{
CHECK_PHASE_START
1, /* can_get_bytecodes */
0, /* can_get_synthetic_attribute */
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
+#if defined(ENABLE_THREADS)
1, /* can_get_owned_monitor_info */
1, /* can_get_current_contended_monitor */
#else
0, /* can_get_monitor_info */
0, /* can_pop_frame */
0, /* can_redefine_classes */
-#if defined(USE_THREADS) && defined(NATIVE_THREADS)
- /* current implementation does not work if called from another process */
0, /* can_signal_thread */
-#else
- 0, /* can_signal_thread */
-#endif
1, /* can_get_source_file_name */
1, /* can_get_line_numbers */
0, /* can_get_source_debug_extension */
0, /* can_generate_exception_events */
0, /* can_generate_frame_pop_events */
0, /* can_generate_breakpoint_events */
-#if defined(USE_THREADS) && !defined(NATIVE_THREADS)
- /* current implementation does not work if called from another process */
- 0, /* can_suspend */
-#else
0, /* can_suspend */
-#endif
0, /* can_redefine_any_class */
0, /* can_get_current_thread_cpu_time */
0, /* can_get_thread_cpu_time */
};
-void set_jvmti_phase(jvmtiPhase p) {
+void jvmti_set_phase(jvmtiPhase p) {
genericEventData d;
- fprintf (stderr,"set JVMTI pid %d phase %d\n",getpid(),p);
+ fprintf (stderr,"set JVMTI phase %d\n",p);
fflush(stderr);
switch (p) {
case JVMTI_PHASE_START:
phase = p;
d.ev = JVMTI_EVENT_VM_START;
- /* this event is sent during start or live phase */
- log_text("debugger process - set brk in setthreadobj");
- setsysbrkpt(SETTHREADOBJECTBRK,(void*)&setthreadobject);
break;
case JVMTI_PHASE_LIVE:
phase = p;
d.ev = JVMTI_EVENT_VM_INIT;
+ jvmti_fireEvent(&d);
+ /* thread start event for main thread */
+ d.ev = JVMTI_EVENT_THREAD_START;
break;
case JVMTI_PHASE_DEAD:
phase = p;
exit(1);
}
- fireEvent(&d);
+ jvmti_fireEvent(&d);
}
-jvmtiEnv* new_jvmtienv() {
+jvmtiEnv* jvmti_new_environment() {
environment* env;
if (envs == NULL) {
env = envs;
} else {
env = envs;
- if (env != NULL)
- while (env->next!=NULL) {
- env=env->next;
- }
- env = heap_allocate(sizeof(environment),true,NULL);
+ while (env->next != NULL) env = env->next;
+ env->next = heap_allocate(sizeof(environment),true,NULL);
+ env = env->next;
}
+
env->env = heap_allocate(sizeof(struct jvmtiEnv_struct),true,NULL);
memcpy(env->env,&JVMTI_EnvTable,sizeof(struct jvmtiEnv_struct));
memset(&(env->events),JVMTI_DISABLE,(JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM)*
sizeof(jvmtiEventModeLL));
/* To possess a capability, the agent must add the capability.*/
- memset(&(env->capabilities), 1, sizeof(jvmtiCapabilities));
+ memset(&(env->capabilities), 0, sizeof(jvmtiCapabilities));
RelinquishCapabilities(&(env->env),&(env->capabilities));
env->EnvironmentLocalStorage = NULL;
env->tls = NULL;
+
+ /* initialize cacao debugging facilities */
+ jvmti_cacao_debug_init();
return (jvmtiEnv*)env;
}
-void agentload(char* opt_arg) {
- lt_dlhandle handle;
- lt_ptr onload;
- char *libname, *arg;
+void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
+ lt_ptr onload;
+ char *arg;
int i=0,len;
jint retval;
- classinfo* ci;
+
len = strlen(opt_arg);
- while ((opt_arg[i]!='=')&&(i<len)) i++;
-
- libname=MNEW(char,i);
- strncpy(libname,opt_arg,i-1);
- libname[i-1]='\0';
-
- arg=MNEW(char, len-i);
- strcpy(arg,&opt_arg[i+1]);
+ /* separate argumtents */
+ while ((opt_arg[i]!='=')&&(i<=len)) i++;
+ arg = &opt_arg[i];
+
+ if (agentbypath) {
+ /* -agentpath */
+ *libname=heap_allocate(sizeof(char)*i,true,NULL);
+ strncpy(*libname,opt_arg,i-1);
+ (*libname)[i-1]='\0';
+ } else {
+ /* -agentlib */
+ *libname=heap_allocate(sizeof(char)*(i+7),true,NULL);
+ strncpy(*libname,"lib",3);
+ strncpy(&(*libname)[3],opt_arg,i-1);
+ strncpy(&(*libname)[i+2],".so",3);
+ }
/* try to open the library */
-
- if (!(handle = lt_dlopen(libname)))
- return;
-
+ lt_dlinit();
+ if (!(*handle = lt_dlopen(*libname))) {
+ fprintf(stderr,"Could not find agent library: %s (%s)\n",*libname,lt_dlerror());
+ vm_shutdown(1);
+ }
+
/* resolve Agent_OnLoad function */
- onload = lt_dlsym(handle, "Agent_OnLoad");
- if (onload == NULL) {
- fprintf(stderr, "unable to load Agent_OnLoad function in %s\n", libname);
- exit(1);
+ if (!(onload = lt_dlsym(*handle, "Agent_OnLoad"))) {
+ fprintf(stderr,"unable to load Agent_OnLoad function in %s (%s)\n",*libname,lt_dlerror());
+ vm_shutdown(1);
}
/* resolve Agent_UnLoad function */
- unload = lt_dlsym(handle, "Agent_Unload");
-
- /* add library to native library hashtable */
- ci = load_class_from_sysloader(utf_new_char("java.lang.Object"));
- native_hashtable_library_add(utf_new_char(libname), ci->classloader, handle);
+ unload = lt_dlsym(*handle, "Agent_Unload");
retval =
((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
- onload) ((JavaVM*) &_Jv_JNIInvokeInterface, arg, NULL);
-
- MFREE(libname,char,i);
- MFREE(arg,char,len-i);
-
+ onload) ((JavaVM *) _Jv_jvm, arg, NULL);
+
if (retval != 0) exit (retval);
}
-void agentunload() {
+void jvmti_agentunload() {
if (unload != NULL) {
((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
((JavaVM*) &_Jv_JNIInvokeInterface);