Changes: Edwin Steiner
Samuel Vinson
-
+ Christan Thalinger
- $Id: jvmti.c 4926 2006-05-15 21:32:09Z edwin $
-
*/
+
+#include "config.h"
+
#include <assert.h>
+#include <string.h>
+#include <linux/unistd.h>
+#include <sys/time.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <ltdl.h>
+#include <unistd.h>
+#include <sched.h>
#include "native/jni.h"
#include "native/native.h"
#include "native/jvmti/cacaodbg.h"
#include "native/jvmti/jvmti.h"
+#include "vm/jit/stacktrace.h"
#include "vm/global.h"
#include "vm/loader.h"
#include "vm/builtin.h"
#include "vm/jit/asmpart.h"
#include "vm/class.h"
#include "vm/classcache.h"
-#include "mm/boehm.h"
+#include "mm/gc-common.h"
#include "toolbox/logging.h"
#include "vm/options.h"
#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 "native/include/java_lang_VMSystem.h"
#include "native/include/java_lang_VMClass.h"
#include "vm/suck.h"
-#include "boehm-gc/include/gc.h"
-
-#include <string.h>
-#include <linux/unistd.h>
-#include <sys/time.h>
-#include "toolbox/logging.h"
-#include <stdlib.h>
-#include <sys/types.h>
-#include <ltdl.h>
-#include <unistd.h>
-#include <sched.h>
+#include "boehm-gc/include/gc.h"
#if defined(ENABLE_THREADS)
#include "threads/native/threads.h"
#include <pthread.h>
#endif
-#include "native/jvmti/stacktrace.h"
#include "dbg.h"
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) \
+#define CHECK_CAPABILITY(env,CAP) if(((environment*) \
+ env)->capabilities.CAP == 0) \
return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
-#define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t)== \
- JVMTI_ERROR_THREAD_NOT_ALIVE) \
+#define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
+ JVMTI_ERROR_THREAD_NOT_ALIVE) \
return JVMTI_ERROR_THREAD_NOT_ALIVE;
*******************************************************************************/
static jvmtiError check_thread_is_alive(jthread t) {
- if(t==NULL) return JVMTI_ERROR_THREAD_NOT_ALIVE;
- if(((java_lang_Thread*) t)->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;
}
-/* execcallback ***************************************************************
+/* execute_callback ************************************************************
executes the registerd callbacks for the given jvmti event with parameter
in the data structure.
*******************************************************************************/
-static void execcallback(jvmtiEvent e, functionptr ec, genericEventData* data) {
+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,
data->class_data,
data->new_class_data_len,
data->new_class_data);
+
+ /* if class data has been modified use it as class data for other agents
+ waiting for the same event */
+ if (data->new_class_data != NULL) {
+ data->jint1 = *(data->new_class_data_len);
+ data->class_data = *(data->new_class_data);
+ }
break;
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;
}
}
functionptr ec;
env = envs;
- while (env!=NULL) {
+ while (env != NULL) {
if (env->events[e-JVMTI_EVENT_START_ENUM].mode == JVMTI_DISABLE) {
evm = env->events[e-JVMTI_EVENT_START_ENUM].next;
/* test if the event is enable for some threads */
- while (evm!=NULL) {
+ while (evm != NULL) {
if (evm->mode == JVMTI_ENABLE) {
- data->jvmti_env=&env->env;
- ec = ((functionptr*)(&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
- execcallback(e, ec, data);
+ ec = ((functionptr*)
+ (&env->callbacks))[e-JVMTI_EVENT_START_ENUM];
+ if (ec != NULL) {
+ data->jvmti_env=&env->env;
+ 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);
+ if (ec != NULL) 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 = getcurrentthread();
- else
+ if (d->ev == JVMTI_EVENT_VM_START)
thread = NULL;
+ else
+ thread = jvmti_get_current_thread();
+
- fprintf (stderr,"jvmti: fireEvent: %d\n",d->ev);
d->thread = thread;
dofireEvent(d->ev,d);
-
- /* 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, ...)
{
if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
- 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)
break;
}
+
if (event_thread != NULL) {
/* thread level control */
if ((JVMTI_EVENT_VM_INIT == mode) ||
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
jthread ** threads_ptr)
{
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 =
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_suspend);
- log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
- return JVMTI_ERROR_NOT_AVAILABLE;
+ if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
+ if (!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+ CHECK_THREAD_IS_ALIVE(thread);
+ /* threads_suspend_thread will implement suspend
+ threads_suspend_thread (
+ (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
ResumeThread (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_suspend);
- log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
- return JVMTI_ERROR_NOT_AVAILABLE;
+ if(thread == NULL) return JVMTI_ERROR_INVALID_THREAD;
+ if (!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+ CHECK_THREAD_IS_ALIVE(thread);
+
+ /* threads_resume_thread will implement resume
+ threads_resume_thread (
+ (threadobject*)((java_lang_Thread*) thread)->vmThread))*/
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
StopThread (jvmtiEnv * env, jthread thread, jobject exception)
{
CHECK_PHASE_START
*******************************************************************************/
-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 defined(ENABLE_THREADS)
if(!builtin_instanceof(thread,class_java_lang_Thread))
return JVMTI_ERROR_INVALID_THREAD;
- CHECK_THREAD_IS_ALIVE(thread);
+ CHECK_THREAD_IS_ALIVE(thread);
+
+ threads_thread_interrupt(((java_lang_Thread *) thread)->vmThread);
+
return JVMTI_ERROR_NONE;
+#else
+ return JVMTI_ERROR_NOT_AVAILABLE;
+#endif
}
/* GetThreadInfo ***************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
{
+ utf *name;
java_lang_Thread* th = (java_lang_Thread*)t;
- log_text("GetThreadInfo called");
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+
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);
+
+ name = javastring_toutf(th->name,false);
+ info_ptr->name=(char*)heap_allocate(sizeof(char)*(utf_bytes(name)+1),true,NULL);
+ utf_sprint_convert_to_latin1(info_ptr->name, name);
return JVMTI_ERROR_NONE;
}
/* GetOwnedMonitorInfo *********************************************************
- Get information about the monitors owned by the specified thread
+ Gets all monitors owned by the specified thread
*******************************************************************************/
-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;
lock_record_pool_t* lrp;
-
- log_text("GetOwnedMonitorInfo called - todo: fix object mapping");
+ threadobject* t;
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_get_owned_monitor_info);
- if ((owned_monitors_ptr==NULL)||(owned_monitor_count_ptr==NULL))
+ if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- if(!builtin_instanceof(thread,class_java_lang_Thread))
- return JVMTI_ERROR_INVALID_THREAD;
-
- CHECK_THREAD_IS_ALIVE(thread);
+ if (thread == NULL) {
+ t = jvmti_get_current_thread();
+ } else {
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+
+ CHECK_THREAD_IS_ALIVE(thread);
+ t = (threadobject*) thread;
+ }
#if defined(ENABLE_THREADS)
pthread_mutex_lock(&lock_global_pool_lock);
lrp=lock_global_pool;
+ /* iterate over all lock record pools */
while (lrp != NULL) {
+ /* iterate over every lock record in a pool */
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].owner==(threadobject*)thread)&&
- (!lrp->lr[j].waiting)) {
- if (i>=size) {
- MREALLOC(om,java_objectheader*,size,size*2);
- size=size*2;
+ /* if the lock record is owned by the given thread add it to
+ the result array */
+ if(lrp->lr[j].owner == t) {
+ if (i >= size) {
+ MREALLOC(om, java_objectheader*, size, size * 2);
+ size = size * 2;
}
- om[i]=lrp->lr[j].o;
+ om[i] = lrp->lr[j].obj;
i++;
- }
+ }
}
lrp=lrp->header.next;
}
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*));
- MFREE(om,java_objectheader*,size);
+ *owned_monitors_ptr =
+ heap_allocate(sizeof(java_objectheader*) * i, true, NULL);
+ memcpy(*owned_monitors_ptr, om, i * sizeof(java_objectheader*));
+ MFREE(om, java_objectheader*, size);
*owned_monitor_count_ptr = i;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
jobject * monitor_ptr)
{
int j;
lock_record_pool_t* lrp;
- java_objectheader* monitor;
+ threadobject* t;
+ lock_waiter_t* waiter;
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
CHECK_CAPABILITY(env, can_get_current_contended_monitor)
- if (monitor_ptr==NULL) return JVMTI_ERROR_NULL_POINTER;
+ if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
*monitor_ptr=NULL;
- if(!builtin_instanceof(thread,class_java_lang_Thread))
- return JVMTI_ERROR_INVALID_THREAD;
-
- CHECK_THREAD_IS_ALIVE(thread);
-
+ if (thread == NULL) {
+ t = jvmti_get_current_thread();
+ } else {
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+
+ CHECK_THREAD_IS_ALIVE(thread);
+ t = (threadobject*) thread;
+ }
#if defined(ENABLE_THREADS)
lrp=lock_global_pool;
- while ((lrp != NULL)&&(monitor==NULL)) {
+ /* iterate over all lock record pools */
+ while ((lrp != NULL) && (*monitor_ptr == NULL)) {
+ /* iterate over every lock record in a pool */
for (j=0; j<lrp->header.size; j++) {
- if((lrp->lr[j].owner==(threadobject*)thread)&&(lrp->lr[j].waiting)) {
- monitor=lrp->lr[j].o;
- break;
- }
+ /* iterate over every thread that is wait on this lock record */
+ waiter = lrp->lr[j].waiters;
+ while (waiter != NULL)
+ /* if the waiting thread equals to the given thread we are
+ done. Stop iterateting. */
+ if(waiter->waiter == t) {
+ *monitor_ptr=lrp->lr[j].obj;
+ break;
+ }
}
lrp=lrp->header.next;
}
pthread_mutex_unlock(&lock_global_pool_lock);
- if (monitor!=NULL) {
- *monitor_ptr = heap_allocate(sizeof(java_objectheader*),true,NULL);
- *monitor_ptr = (jobject)monitor;
- }
#endif
return JVMTI_ERROR_NONE;
*******************************************************************************/
-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
+ /* XXX: Threads started with this function should not be visible to
Java programming language queries but are included in JVM TI queries */
rap.sf = proc;
}
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;
*******************************************************************************/
-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)
*thread_count_ptr = (jint)tgp->threads->elementCount;
- *threads_ptr = heap_allocate(sizeof(jthread*)*(*thread_count_ptr),true,NULL);
+ *threads_ptr =
+ heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
memcpy(*threads_ptr, &tgp->threads->elementData,
- (*thread_count_ptr)*sizeof(jthread*));
+ (*thread_count_ptr)*sizeof(java_objectarray*));
*group_count_ptr = (jint) tgp->groups->elementCount;
- *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*(*group_count_ptr),true,NULL);
+ *groups_ptr =
+ heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
memcpy(*groups_ptr, &tgp->threads->elementData,
(*group_count_ptr)*sizeof(jthreadGroup*));
/* getcacaostacktrace *********************************************************
Helper function that retrives stack trace for specified thread.
- Has to take care of suspend/resume issuses
-
+
*******************************************************************************/
+
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); */
+ bool resume;
+
+ if (thread == NULL) {
+ t = jvmti_get_current_thread();
+ *trace = stacktrace_create(t);
+ } else {
+ t = (threadobject*)((java_lang_Thread*)thread)->vmThread;
+/* if (t != jvmti_get_current_thread())
+ resume = threads_suspend_thread_if_running(thread);
+
+ *trace = stacktrace_create(thread );
+
+ if (resume)
+ threads_resume_thread ( thread );*/
+ }
return JVMTI_ERROR_NONE;
}
/* GetFrameCount **************************************************************
- Get the number of frames in the specified thread's stack.
+ Get the number of frames in the specified thread's stack. Calling function
+ has to take care of suspending/resuming thread.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
{
stacktracebuffer* trace;
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if(!builtin_instanceof(thread,class_java_lang_Thread))
- return JVMTI_ERROR_INVALID_THREAD;
+ if (thread != NULL){
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
- CHECK_THREAD_IS_ALIVE(thread);
+ CHECK_THREAD_IS_ALIVE(thread);
+ }
if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
er = getcacaostacktrace(&trace, thread);
- if (er==JVMTI_ERROR_NONE) return er;
+ if (er == JVMTI_ERROR_NONE) {
+ heap_free(trace);
+ return er;
+ }
*count_ptr = trace->used;
+ heap_free(trace);
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadState (jvmtiEnv * env, jthread thread, jint * thread_state_ptr)
{
java_lang_Thread* th = (java_lang_Thread*)thread;
*thread_state_ptr = 0;
#if defined(ENABLE_THREADS)
- if((th->vmThread==NULL)&&(th->group==NULL)) { /* alive ? */
+ 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 */
*thread_state_ptr = JVMTI_THREAD_STATE_ALIVE;
if (t->interrupted) *thread_state_ptr |= JVMTI_THREAD_STATE_INTERRUPTED;
- /* todo */
+ /* XXX todo - info not available */
if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_SUSPENDED;
if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_IN_NATIVE;
if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_RUNNABLE;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
jmethodID * method_ptr, jlocation * location_ptr)
{
stackframeinfo *sfi;
int i;
+ threadobject* th;
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if(!builtin_instanceof(thread,class_java_lang_Thread))
- return JVMTI_ERROR_INVALID_THREAD;
-
- CHECK_THREAD_IS_ALIVE(thread);
+ if (thread == NULL) {
+ th = jvmti_get_current_thread();
+ } else {
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+
+ CHECK_THREAD_IS_ALIVE(thread);
+ th = (threadobject*) ((java_lang_Thread*)thread)->vmThread;
+ }
if (depth < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
if ((method_ptr == NULL)&&(location_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- sfi = ((threadobject*)thread)->info._stackframeinfo;
+ sfi = th->_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)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
{
CHECK_PHASE_START
if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- lock_monitor_exit((threadobject*)THREADOBJECT, (java_objectheader*)monitor->name);
+ lock_monitor_exit((java_objectheader *) monitor->name);
- /* GC will clean monitor up */
+ heap_free(monitor);
#else
log_text ("DestroyRawMonitor not supported");
#endif
*******************************************************************************/
-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(ENABLE_THREADS)
- builtin_monitorenter((java_objectheader*)monitor->name);
+ lock_monitor_enter((java_objectheader *) monitor->name);
#else
log_text ("RawMonitorEnter not supported");
#endif
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
return JVMTI_ERROR_NOT_MONITOR_OWNER;
- builtin_monitorexit((java_objectheader*)monitor->name);
+ lock_monitor_exit((java_objectheader *) monitor->name);
#else
log_text ("RawMonitorExit not supported");
#endif
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
{
if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
*******************************************************************************/
-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)
{
- int nsize,psize;
-
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- if ((generic_ptr== NULL)||(signature_ptr == NULL))
- return JVMTI_ERROR_NULL_POINTER;
-
- nsize=((classinfo*)klass)->name->blength;
- psize=((classinfo*)klass)->packagename->blength;
-
- *signature_ptr = (char*)
- heap_allocate(sizeof(char)* nsize+psize+4,true,NULL);
+
+ if (klass == NULL) return JVMTI_ERROR_INVALID_CLASS;
+ if (!builtin_instanceof(klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
- *signature_ptr[0]='L';
- memcpy(&(*signature_ptr[1]),((classinfo*)klass)->packagename->text, psize);
- *signature_ptr[psize+2]='/';
- memcpy(&(*signature_ptr[psize+3]),((classinfo*)klass)->name->text, nsize);
- *signature_ptr[nsize+psize+3]=';';
- *signature_ptr[nsize+psize+4]='\0';
+ if (signature_ptr != NULL) {
+ *signature_ptr = (char*)
+ heap_allocate(sizeof(char) *
+ utf_bytes(((classinfo*)klass)->name)+1,true,NULL);
+
+ utf_sprint_convert_to_latin1(*signature_ptr,((classinfo*)klass)->name);
+ }
- *generic_ptr = NULL;
+ if (generic_ptr!= NULL)
+ *generic_ptr = NULL;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
{
classinfo *c;
*status_ptr = 0;
/* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
- if (c->state&=CLASS_LINKED)
+ if (c->state & CLASS_LINKED)
*status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
- if (c->state&=CLASS_INITIALIZED)
+ if (c->state & CLASS_INITIALIZED)
*status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
- if (c->state&=CLASS_ERROR)
+ if (c->state & CLASS_ERROR)
*status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
if (c->vftbl->arraydesc != NULL)
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
{
int size;
if ((klass == NULL)||(source_name_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- size = (((classinfo*)klass)->sourcefile->blength)+1;
+ size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
*source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
*******************************************************************************/
-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)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- if ((field == NULL)||(name_ptr == NULL)||(signature_ptr == NULL))
- return JVMTI_ERROR_NULL_POINTER;
+
+ if (klass == NULL)
+ return JVMTI_ERROR_INVALID_CLASS;
+ else
+ if (!builtin_instanceof(klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
+ if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
- size = (((fieldinfo*)field)->name->blength);
- *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
- memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
+ if (name_ptr != NULL) {
+ size = utf_bytes(((fieldinfo*)field)->name)+1;
+ *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
+ utf_sprint_convert_to_latin1(*name_ptr, ((fieldinfo*)field)->name);
+ }
- size = (((fieldinfo*)field)->descriptor->blength);
- *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
- memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
+ if (signature_ptr != NULL) {
+ size = utf_bytes(((fieldinfo*)field)->descriptor)+1;
+ *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
+ utf_sprint_convert_to_latin1(*signature_ptr,
+ ((fieldinfo*)field)->descriptor);
+ }
- *generic_ptr = NULL;
+ if (generic_ptr != NULL)
+ *generic_ptr = NULL;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldDeclaringClass (jvmtiEnv * env, jclass klass, jfieldID field,
jclass * declaring_class_ptr)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
+
+ if (klass == NULL)
+ return JVMTI_ERROR_INVALID_CLASS;
+ else
+ if (!builtin_instanceof(klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
+
+ if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
+
+ if (declaring_class_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
*declaring_class_ptr = (jclass) ((fieldinfo*)field)->class;
return JVMTI_ERROR_NONE;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
jint * modifiers_ptr)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- if (!builtin_instanceof((java_objectheader*)klass, class_java_lang_Class))
- return JVMTI_ERROR_INVALID_OBJECT;
+
+ if (klass == NULL)
+ return JVMTI_ERROR_INVALID_CLASS;
+ else
+ if (!builtin_instanceof(klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
+
+ if (field == NULL) return JVMTI_ERROR_INVALID_FIELDID;
if (modifiers_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
- /* todo: JVMTI_ERROR_INVALID_FIELDID; */
-
*modifiers_ptr = ((fieldinfo*)field)->flags;
return JVMTI_ERROR_NONE;
*******************************************************************************/
-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)
{
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if ((method == NULL) || (name_ptr == NULL) || (signature_ptr == NULL)
- || (generic_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
-
- if (m->name == NULL) return JVMTI_ERROR_INTERNAL;
- *name_ptr = (char*)
- heap_allocate(sizeof(char) * (m->name->blength),true,NULL);
- utf_sprint_convert_to_latin1(*name_ptr, m->name);
+ if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
- *signature_ptr = (char*)
- heap_allocate(sizeof(char) * (m->descriptor->blength),true,NULL);
- utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
+ if (name_ptr != NULL) {
+ *name_ptr = (char*)
+ heap_allocate(sizeof(char) * (utf_bytes(m->name)+1),true,NULL);
+ utf_sprint_convert_to_latin1(*name_ptr, m->name);
+ }
+
+ if (signature_ptr != NULL) {
+ *signature_ptr = (char*)
+ heap_allocate(sizeof(char)*(utf_bytes(m->descriptor)+1),true,NULL);
+ utf_sprint_convert_to_latin1(*signature_ptr, m->descriptor);
+ }
- /* there is no generic signature attribute */
- *generic_ptr = NULL;
+ if (generic_ptr != NULL) {
+ /* there is no generic signature attribute */
+ *generic_ptr = NULL;
+ }
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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
if (((methodinfo*)method)->flags & ACC_NATIVE)
return JVMTI_ERROR_NATIVE_METHOD;
-
+
*max_ptr = (jint) ((methodinfo*)method)->maxlocals;
return JVMTI_ERROR_NONE;
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetArgumentsSize (jvmtiEnv * env, jmethodID method, jint * size_ptr)
{
CHECK_PHASE_START
if (((methodinfo*)method)->flags & ACC_NATIVE)
return JVMTI_ERROR_NATIVE_METHOD;
-/* todo *size_ptr = (jint)((methodinfo*)method)->paramcount;*/
+ *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
return JVMTI_ERROR_NONE;
}
-/* GetLineNumberTable ***********************************************************
+/* GetLineNumberTable **********************************************************
Return table of source line number entries for a given method
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLineNumberTable (jvmtiEnv * env, jmethodID method,
jint * entry_count_ptr, jvmtiLineNumberEntry ** table_ptr)
{
if ((method == NULL) || (entry_count_ptr == NULL) || (table_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
+
if (((methodinfo*)method)->flags & ACC_NATIVE)
return JVMTI_ERROR_NATIVE_METHOD;
+
if (((methodinfo*)method)->linenumbers == NULL)
return JVMTI_ERROR_ABSENT_INFORMATION;
for (i=0; i < *entry_count_ptr; i++) {
- (*table_ptr[i]).start_location =
+ (*table_ptr)[i].start_location =
(jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
- (*table_ptr[i]).line_number =
+ (*table_ptr)[i].line_number =
(jint) ((methodinfo*)method)->linenumbers[i].line_number;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetMethodLocation (jvmtiEnv * env, jmethodID method,
jlocation * start_location_ptr,
jlocation * end_location_ptr)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if ((method == NULL) || (start_location_ptr == NULL) ||
- (end_location_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
+ if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
+
+ if (((methodinfo*)method)->flags & ACC_NATIVE)
+ return JVMTI_ERROR_NATIVE_METHOD;
+
+ if ((start_location_ptr == NULL) || (end_location_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
/* XXX we return the location of the most recent code. Don't know
* if there is a way to teach jvmti that a method can have more
/* 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;
-
+ fprintf(stderr,"GetMethodLocation *** XXX todo \n");
+
+
+ /* -1 states location information is not available */
+ *start_location_ptr = (jlocation)-1;
+ *end_location_ptr = (jlocation)-1;
+
+/*
*start_location_ptr = (jlocation)m->code->mcode;
- *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;
+ *end_location_ptr = (jlocation)(m->code->mcode)+m->code->mcodelength;*/
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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;
- char* data;
- hashtable* ht;
- classcache_name_entry *cne;
- classcache_class_entry *cce;
-
- log_text ("GetLoadedClasses called %d ", phase);
-
-
- /* XXX todo */
-
- *class_count_ptr = 0;
-
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
- if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
-
- log_text ("GetLoadedClasses1");
-
-/*
- CLASSCACHE_LOCK();
- log_text ("GetLoadedClasses2");
- getchildproc(&data, &hashtable_classcache, sizeof(hashtable));
- ht = (hashtable*) &data;
-
- log_text ("GetLoadedClasses got ht pointer");
- *classes_ptr =
- heap_allocate(sizeof(jclass*) * (ht->entries),true,NULL);
- fprintf (stderr,"hashtable_classcache.entries = %d\n",ht->entries);
- fflush(stderr);
-
- *class_count_ptr = ht->entries;
- log_text ("GetLoadedClasses %d", *class_count_ptr);
- j=0;
- look in every slot of the hashtable
- for (i=0; i<ht->size; i++) {
- cne = ht->ptr[i];
-
- 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;
- j++;
- }
- cce = cce->next;
- }
- cne = cne->hashlink;
- }
- }
-
- log_text ("GetLoadedClasses continue");
-
- CLASSCACHE_UNLOCK();
+ if (class_count_ptr == NULL)
+ return JVMTI_ERROR_NULL_POINTER;
-*/
+ if (classes_ptr == NULL)
+ return JVMTI_ERROR_NULL_POINTER;
- log_text ("GetLoadedClasses finished");
+ classcache_jvmti_GetLoadedClasses(class_count_ptr, classes_ptr);
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassLoaderClasses (jvmtiEnv * env, jobject initiating_loader,
jint * class_count_ptr, jclass ** classes_ptr)
{
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-/* if (class_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
- if (classes_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;*/
+ if ((class_count_ptr == NULL) || (classes_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
/* behave like jdk 1.1 and make no distinction between initiating and
defining class loaders */
*******************************************************************************/
-jvmtiError
+static jvmtiError
PopFrame (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
*******************************************************************************/
-jvmtiError
+static jvmtiError
RedefineClasses (jvmtiEnv * env, jint class_count,
const jvmtiClassDefinition * class_definitions)
{
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_redefine_classes)
CHECK_CAPABILITY(env,can_redefine_any_class)
+
log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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 **********************************************************
-
+ Suspend all threads in the request list.
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThreadList (jvmtiEnv * env, jint request_count,
const jthread * request_list, jvmtiError * results)
{
+ int i;
+ int suspendme = -1;
+ jthread me;
+
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_suspend);
-
- log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
+ if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+ if ((request_list == NULL) || (results == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+ me = jvmti_get_current_thread();
+
+ for (i=0;i<request_count;i++) {
+ if (request_list[i] == me)
+ suspendme = i;
+ else
+ results[i]=SuspendThread(env, request_list[i]);
+ }
+
+ if (suspendme != -1)
+ results[suspendme]=SuspendThread(env, request_list[suspendme]);
return JVMTI_ERROR_NONE;
}
/* ResumeThreadList ***********************************************************
-
+ Resumes all threads in the request list.
*******************************************************************************/
-jvmtiError
+static jvmtiError
ResumeThreadList (jvmtiEnv * env, jint request_count,
const jthread * request_list, jvmtiError * results)
{
+ int i;
+
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
CHECK_CAPABILITY(env,can_suspend);
-
- log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
+
+ if (request_count<0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+ if ((request_list == NULL) || (results == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+ for (i=0;i<request_count;i++)
+ results[i]=ResumeThread(env, request_list[i]);
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)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if(!builtin_instanceof(thread,class_java_lang_Thread))
- return JVMTI_ERROR_INVALID_THREAD;
+ if (thread != NULL){
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
- CHECK_THREAD_IS_ALIVE(thread);
+ CHECK_THREAD_IS_ALIVE(thread);
+ }
if((count_ptr == NULL)||(frame_buffer == NULL))
return JVMTI_ERROR_NULL_POINTER;
if (max_frame_count <0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
er = getcacaostacktrace(&trace, thread);
- if (er==JVMTI_ERROR_NONE) return er;
+ if (er == JVMTI_ERROR_NONE) {
+ heap_free(trace);
+ return er;
+ }
if ((trace->used >= start_depth) || ((trace->used * -1) > start_depth))
return JVMTI_ERROR_ILLEGAL_ARGUMENT;
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 */
+ /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
frame_buffer[j].location = 0;
}
+
+ heap_free(trace);
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)
{
if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
- /* todo: all threads have to be suspended */
-
if (JVMTI_ERROR_NONE!=GetAllThreads(env,thread_count_ptr,&threads_ptr))
return JVMTI_ERROR_INTERNAL;
GetThreadListStackTraces(env, *thread_count_ptr, threads_ptr,
max_frame_count, stack_info_ptr);
- /* todo: resume all threads have to be suspended */
if (er != JVMTI_ERROR_NONE) return er;
return JVMTI_ERROR_NONE;
*******************************************************************************/
-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)
{
*******************************************************************************/
-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)
if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
if (callbacks == NULL) { /* remove the existing callbacks */
memset(&(((environment* )env)->callbacks), 0,
sizeof(jvmtiEventCallbacks));
*******************************************************************************/
-jvmtiError
+static jvmtiError
GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_generate_compiled_method_load_events);
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetExtensionFunctions (jvmtiEnv * env, jint * extension_count_ptr,
jvmtiExtensionFunctionInfo ** extensions)
{
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if ((extension_count_ptr== NULL)||(extensions == NULL))
+ if ((extension_count_ptr == NULL)||(extensions == NULL))
return JVMTI_ERROR_NULL_POINTER;
/* cacao has no extended functions yet */
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetExtensionEvents (jvmtiEnv * env, jint * extension_count_ptr,
jvmtiExtensionEventInfo ** extensions)
{
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- if ((extension_count_ptr== NULL)||(extensions == NULL))
+ if ((extension_count_ptr == NULL)||(extensions == NULL))
return JVMTI_ERROR_NULL_POINTER;
/* cacao has no extended events yet */
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetExtensionEventCallback (jvmtiEnv * env, jint extension_event_index,
jvmtiExtensionEvent callback)
{
*******************************************************************************/
-jvmtiError
+static jvmtiError
DisposeEnvironment (jvmtiEnv * env)
{
environment* cacao_env = (environment*)env;
cacao_env->tls = NULL;
- pthread_mutex_lock(&dbgcomlock);
- dbgcom->running--;
- if (dbgcom->running == 0) {
- TRAP;
- }
- pthread_mutex_unlock(&dbgcomlock);
+ 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;
+ *format_ptr = JVMTI_JLOCATION_OTHER;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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
-GetPotentialCapabilities (jvmtiEnv * env,
- jvmtiCapabilities * capabilities_ptr)
+static jvmtiError
+GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_ONLOAD)
}
-#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)
{
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetAvailableProcessors *****************************************************
-
+ Get number of processors available to the virtual machine.
*******************************************************************************/
-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
0, /* can_access_local_variables */
0, /* can_maintain_original_method_order */
0, /* can_generate_single_step_events */
- 0, /* can_generate_exception_events */
+ 1, /* can_generate_exception_events */
0, /* can_generate_frame_pop_events */
- 0, /* can_generate_breakpoint_events */
- 0, /* can_suspend */
+ 1, /* can_generate_breakpoint_events */
+ 1, /* can_suspend */
0, /* can_redefine_any_class */
0, /* can_get_current_thread_cpu_time */
0, /* can_get_thread_cpu_time */
- 0, /* can_generate_method_entry_events */
+ 1, /* can_generate_method_entry_events */
0, /* can_generate_method_exit_events */
0, /* can_generate_all_class_hook_events */
0, /* can_generate_compiled_method_load_events */
- 0, /* can_generate_monitor_events */
+ 1, /* can_generate_monitor_events */
0, /* can_generate_vm_object_alloc_events */
0, /* can_generate_native_method_bind_events */
0, /* can_generate_garbage_collection_events */
&GetObjectSize
};
+/* jvmti_set_phase ************************************************************
+
+ sets a new jvmti phase a fires an apropriate event.
+
+*******************************************************************************/
-void set_jvmti_phase(jvmtiPhase p) {
+void jvmti_set_phase(jvmtiPhase p) {
genericEventData d;
fprintf (stderr,"set JVMTI phase %d\n",p);
case JVMTI_PHASE_START:
phase = p;
d.ev = JVMTI_EVENT_VM_START;
- /* this event is sent during start or live phase */
- log_text("set sysbrk in setthreadobj");
- setsysbrkpt(SETTHREADOBJECTBRK,(void*)&threads_set_current_threadobject);
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() {
+
+/* jvmti_new_environment ******************************************************
+
+ creates a new JVMTI environment
+
+*******************************************************************************/
+
+jvmtiEnv* jvmti_new_environment() {
environment* env;
- pid_t dbgserver;
- char* comaddr;
if (envs == NULL) {
envs = heap_allocate(sizeof(environment),true,NULL);
RelinquishCapabilities(&(env->env),&(env->capabilities));
env->EnvironmentLocalStorage = NULL;
env->tls = NULL;
-
- /* start new cacaodbgserver if needed*/
- pthread_mutex_lock(&dbgcomlock);
- if (dbgcom == NULL) {
- dbgcom = heap_allocate(sizeof(cacaodbgcommunication),true,NULL);
- dbgcom->running = 1;
- dbgcom->breakpointhandler = (void*)cacaobreakpointhandler;
- dbgserver = fork();
- if (dbgserver == (-1)) {
- log_text("cacaodbgserver fork error");
- exit(1);
- } else {
- if (dbgserver == 0) {
- comaddr = MNEW(char,11);
- snprintf(comaddr,11,"%p",dbgcom);
- if (execlp("cacaodbgserver","cacaodbgserver",comaddr,(char *) NULL) == -1) {
- log_text("unable to execute cacaodbgserver");
- exit(1);
- }
- }
- }
- } else {
- dbgcom->running++;
- }
- pthread_mutex_unlock(&dbgcomlock);
- sched_yield();
-
+
+ /* initialize cacao debugging facilities */
+ jvmti_cacao_debug_init();
return (jvmtiEnv*)env;
}
-void agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
+/* jvmti_agentload ************************************************************
+
+ loads the indicated shared library containing the jvmti agent and calls the
+ Agent_OnLoad function.
+
+*******************************************************************************/
+
+void jvmti_agentload(char* opt_arg, bool agentbypath, lt_dlhandle *handle, char **libname) {
lt_ptr onload;
char *arg;
int i=0,len;
jint retval;
-
len = strlen(opt_arg);
- /* separate argumtents */
- while ((opt_arg[i]!='=')&&(i<=len)) i++;
- arg = &opt_arg[i];
+ /* separate arguments */
+
+ while ((opt_arg[i] != '=') && (i < len))
+ i++;
+
+ opt_arg[i] = '\0';
+
+ if (i < len)
+ arg = &opt_arg[i + 1];
+ else
+ arg = "";
if (agentbypath) {
/* -agentpath */
- *libname=heap_allocate(sizeof(char)*i,true,NULL);
- strncpy(*libname,opt_arg,i-1);
- (*libname)[i-1]='\0';
- } else {
+
+ *libname = GCMNEW(char, i);
+
+ strcpy(*libname, opt_arg);
+ }
+ 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);
+
+ len = strlen("lib") + i + strlen(".so") + strlen("0");
+
+ *libname = GCMNEW(char, len);
+
+ strcpy(*libname, "lib");
+ strcat(*libname, opt_arg);
+ strcat(*libname, ".so");
}
/* try to open the library */
if (retval != 0) exit (retval);
}
-void agentunload() {
+/* jvmti_agentunload **********************************************************
+
+ calls the Agent_UnLoad function in the jvmti agent if present.
+
+*******************************************************************************/
+
+void jvmti_agentunload() {
if (unload != NULL) {
((JNIEXPORT void JNICALL (*) (JavaVM *vm)) unload)
((JavaVM*) &_Jv_JNIInvokeInterface);
}
}
+
/*
* These are local overrides for various environment variables in Emacs.
* Please do not remove this and leave it at the end of the file, where