-/* src/native/jvmti.c - implementation of the Java Virtual Machine Tool
- Interface functions
+/* src/native/jvmti/jvmti.c - implementation of the Java Virtual Machine
+ Tool Interface functions
- Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
- R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
- C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
- Institut f. Computersprachen - TU Wien
+ Copyright (C) 1996-2005, 2006 R. Grafl, A. Krall, C. Kruegel,
+ C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
+ E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
+ J. Wenninger, Institut f. Computersprachen - TU Wien
This file is part of CACAO.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
- 02111-1307, USA.
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ 02110-1301, USA.
- Contact: cacao@complang.tuwien.ac.at
+ Contact: cacao@cacaojvm.org
Author: Martin Platter
- Changes:
-
+ Changes: Edwin Steiner
+ Samuel Vinson
+ Christan Thalinger
- $Id: jvmti.c 3062 2005-07-19 10:03:00Z motse $
-
*/
+#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/jvmti.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 "mm/boehm.h"
+#include "vm/class.h"
+#include "vm/classcache.h"
+#include "mm/gc-common.h"
#include "toolbox/logging.h"
#include "vm/options.h"
-#include "cacao/cacao.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_io_InputStream.h"
+#include "native/include/java_lang_Cloneable.h"
+#include "native/include/java_lang_ThreadGroup.h"
+#include "native/include/java_lang_VMObject.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"
+
+#if defined(ENABLE_THREADS)
+#include "threads/native/threads.h"
+#include <sched.h>
+#include <pthread.h>
+#endif
+
+#include "dbg.h"
-#include <string.h>
-#include <linux/unistd.h>
-#include <sys/time.h>
+
+typedef struct _environment environment;
+static environment *envs=NULL;
+pthread_mutex_t dbgcomlock;
+
+extern const struct JNIInvokeInterface _Jv_JNIInvokeInterface;
static jvmtiPhase phase;
+typedef struct _jvmtiEventModeLL jvmtiEventModeLL;
+struct _jvmtiEventModeLL {
+ jvmtiEventMode mode;
+ jthread event_thread;
+ jvmtiEventModeLL *next;
+};
-typedef struct {
+typedef struct _jvmtiThreadLocalStorage jvmtiThreadLocalStorage;
+struct _jvmtiThreadLocalStorage{
+ jthread thread;
+ void *data;
+ jvmtiThreadLocalStorage *next;
+};
+
+struct _environment {
jvmtiEnv env;
+ environment *next;
jvmtiEventCallbacks callbacks;
- jobject *events; /* hashtable for enabled/disabled jvmtiEvents */
+ /* table for enabled/disabled jvmtiEvents - first element contains global
+ behavior */
+ jvmtiEventModeLL events[JVMTI_EVENT_END_ENUM - JVMTI_EVENT_START_ENUM];
jvmtiCapabilities capabilities;
void *EnvironmentLocalStorage;
-} environment;
-
-
-/* jmethodID and jclass caching */
-static jclass ihmclass = NULL;
-static jmethodID ihmmid = NULL;
+ jvmtiThreadLocalStorage *tls;
+};
-jvmtiEnv JVMTI_EnvTable;
-jvmtiCapabilities JVMTI_Capabilities;
+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) \
+ return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
+#define CHECK_THREAD_IS_ALIVE(t) if(check_thread_is_alive(t) == \
+ JVMTI_ERROR_THREAD_NOT_ALIVE) \
+ return JVMTI_ERROR_THREAD_NOT_ALIVE;
+
+
+
+
+/* check_thread_is_alive *******************************************************
+
+ checks if the given thread is 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)
+ return JVMTI_ERROR_THREAD_NOT_ALIVE;
+ return JVMTI_ERROR_NONE;
+}
+
+/* execute_callback ************************************************************
+
+ executes the registerd callbacks for the given jvmti event with parameter
+ in the data structure.
+
+*******************************************************************************/
+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:
+ 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->object,
+ data->name,
+ data->protection_domain,
+ data->jint1,
+ 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:
+ 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_NATIVE_METHOD_BIND:
+ 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->new_address_ptr);
+ break;
+
+
+ case JVMTI_EVENT_DYNAMIC_CODE_GENERATED:
+ 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;
+
+
+
+ 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->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_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_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;
+
+ 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;
+ }
+}
+
+
+/* dofireEvent ******************************************************************
+
+ sends event if it is enabled either globally or for some threads
+
+*******************************************************************************/
+static void dofireEvent(jvmtiEvent e, genericEventData* data) {
+ environment* env;
+ jvmtiEventModeLL *evm;
+ functionptr ec;
+
+ env = envs;
+ 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) {
+ if (evm->mode == JVMTI_ENABLE) {
+ 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];
+ if (ec != NULL) execute_callback(e, ec, data);
+ }
+
+ env=env->next;
+ }
+}
+
+
+/* fireEvent ******************************************************************
+
+ fire event callback with data arguments. This function mainly fills the
+ missing EventData.
+
+*******************************************************************************/
+void jvmti_fireEvent(genericEventData* d) {
+ jthread thread;
+ /* XXX todo : respect event order JVMTI-Spec:Multiple Co-located Events */
+
+ if (d->ev == JVMTI_EVENT_VM_START)
+ thread = NULL;
+ else
+ thread = jvmti_get_current_thread();
+
+
+ d->thread = thread;
+ dofireEvent(d->ev,d);
+}
/* SetEventNotificationMode ****************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEventNotificationMode (jvmtiEnv * env, jvmtiEventMode mode,
jvmtiEvent event_type, jthread event_thread, ...)
{
+ environment* cacao_env;
+ jvmtiEventModeLL *ll;
+
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_ONLOAD)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
-
+
+ if(event_thread != NULL) {
+ if (!builtin_instanceof(event_thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+ CHECK_THREAD_IS_ALIVE(event_thread);
+ }
+
+ cacao_env = (environment*) env;
+ if ((mode != JVMTI_ENABLE) && (mode != JVMTI_DISABLE))
+ return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+ 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;
+ case JVMTI_EVENT_SINGLE_STEP:
+ CHECK_CAPABILITY(env,can_generate_single_step_events)
+ break;
+ case JVMTI_EVENT_FRAME_POP:
+ CHECK_CAPABILITY(env,can_generate_frame_pop_events)
+ break;
+ case JVMTI_EVENT_BREAKPOINT:
+ CHECK_CAPABILITY(env,can_generate_breakpoint_events)
+ break;
+ case JVMTI_EVENT_FIELD_ACCESS:
+ CHECK_CAPABILITY(env,can_generate_field_access_events)
+ break;
+ case JVMTI_EVENT_FIELD_MODIFICATION:
+ CHECK_CAPABILITY(env,can_generate_field_modification_events)
+ break;
+ case JVMTI_EVENT_METHOD_ENTRY:
+ CHECK_CAPABILITY(env,can_generate_method_entry_events)
+ break;
+ case JVMTI_EVENT_METHOD_EXIT:
+ CHECK_CAPABILITY(env, can_generate_method_exit_events)
+ break;
+ case JVMTI_EVENT_NATIVE_METHOD_BIND:
+ CHECK_CAPABILITY(env, can_generate_native_method_bind_events)
+ break;
+ case JVMTI_EVENT_COMPILED_METHOD_LOAD:
+ case JVMTI_EVENT_COMPILED_METHOD_UNLOAD:
+ CHECK_CAPABILITY(env,can_generate_compiled_method_load_events)
+ break;
+ case JVMTI_EVENT_MONITOR_WAIT:
+ case JVMTI_EVENT_MONITOR_WAITED:
+ case JVMTI_EVENT_MONITOR_CONTENDED_ENTER:
+ case JVMTI_EVENT_MONITOR_CONTENDED_ENTERED:
+ CHECK_CAPABILITY(env,can_generate_monitor_events)
+ break;
+ case JVMTI_EVENT_GARBAGE_COLLECTION_START:
+ case JVMTI_EVENT_GARBAGE_COLLECTION_FINISH:
+ CHECK_CAPABILITY(env,can_generate_garbage_collection_events)
+ break;
+ case JVMTI_EVENT_OBJECT_FREE:
+ CHECK_CAPABILITY(env,can_generate_object_free_events)
+ break;
+ case JVMTI_EVENT_VM_OBJECT_ALLOC:
+ CHECK_CAPABILITY(env,can_generate_vm_object_alloc_events)
+ 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;
+ }
+
+
+ if (event_thread != NULL) {
+ /* thread level control */
+ if ((JVMTI_EVENT_VM_INIT == mode) ||
+ (JVMTI_EVENT_VM_DEATH == mode) ||
+ (JVMTI_EVENT_VM_START == mode) ||
+ (JVMTI_EVENT_THREAD_START == mode) ||
+ (JVMTI_EVENT_COMPILED_METHOD_LOAD == mode) ||
+ (JVMTI_EVENT_COMPILED_METHOD_UNLOAD == mode) ||
+ (JVMTI_EVENT_DYNAMIC_CODE_GENERATED == mode) ||
+ (JVMTI_EVENT_DATA_DUMP_REQUEST == mode))
+ return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+ ll = &(cacao_env->events[event_type-JVMTI_EVENT_START_ENUM]);
+ while (ll->next != NULL) {
+ ll = ll->next;
+ if (ll->event_thread == event_thread) {
+ ll->mode=mode;
+ return JVMTI_ERROR_NONE;
+ }
+ }
+ ll->next = heap_allocate(sizeof(jvmtiEventModeLL),true,NULL);
+ ll->next->mode=mode;
+ } else {
+ /* global control */
+ cacao_env->events[event_type-JVMTI_EVENT_START_ENUM].mode=mode;
+ }
+
+
return JVMTI_ERROR_NONE;
}
-
/* GetAllThreads ***************************************************************
Get all live threads
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetAllThreads (jvmtiEnv * env, jint * threads_count_ptr,
jthread ** threads_ptr)
{
- int i = 0;
- threadobject* thread;
-
+ threadobject** threads;
+ int i;
+ jvmtiError retval;
+
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
if ((threads_count_ptr == NULL) || (threads_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- thread = mainthreadobj;
- do {
- i++;
- thread = thread->info.prev;
- } while (thread != mainthreadobj);
-
- *threads_count_ptr = i;
+ retval=jvmti_get_all_threads(threads_count_ptr, &threads);
+ if (retval != JVMTI_ERROR_NONE) return retval;
- *threads_ptr = (jthread*) heap_allocate(sizeof(jthread) * i,true,NULL);
- i=0;
- do {
- memcpy(*threads_ptr[i],thread,sizeof(jthread));
- thread = thread->info.prev;
- i++;
- } while (thread != mainthreadobj);
+ *threads_ptr =
+ heap_allocate(sizeof(jthread*)* (*threads_count_ptr),true,NULL);
+ for (i=0; i<*threads_count_ptr; i++)
+ (*threads_ptr)[i] = threads[i]->o.thread;
+
return JVMTI_ERROR_NONE;
}
/* SuspendThread ***************************************************************
-
+ Suspend specified thread
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThread (jvmtiEnv * env, jthread thread)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
- CHECK_PHASE(JVMTI_PHASE_LIVE)
- CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_PHASE_START
+ CHECK_PHASE(JVMTI_PHASE_LIVE)
+ CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_suspend);
+
+ 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;
}
-/* *****************************************************************************
+/* ResumeThread ***************************************************************
-
+ Resume a suspended thread
*******************************************************************************/
-jvmtiError
+static jvmtiError
ResumeThread (jvmtiEnv * env, jthread thread)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_suspend);
+
+ 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;
}
-/* *****************************************************************************
+/* StopThread *****************************************************************
-
+ Send asynchronous exception to the specified thread. Similar to
+ java.lang.Thread.stop(). Used to kill thread.
*******************************************************************************/
-jvmtiError
+static jvmtiError
StopThread (jvmtiEnv * env, jthread thread, jobject exception)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_signal_thread);
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+ return JVMTI_ERROR_NOT_AVAILABLE;
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* InterruptThread ************************************************************
-
+ Interrupt specified thread. Similar to java.lang.Thread.interrupt()
*******************************************************************************/
-jvmtiError
+static jvmtiError
InterruptThread (jvmtiEnv * env, jthread thread)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_signal_thread)
+
+#if defined(ENABLE_THREADS)
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_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 ***************************************************************
- Get thread information. The fields of the jvmtiThreadInfo structure are
- filled in with details of the specified thread.
+ Get thread information. Details of the specified thread are stored in the
+ jvmtiThreadInfo structure.
*******************************************************************************/
-jvmtiError
-GetThreadInfo (jvmtiEnv * env, jthread thread, jvmtiThreadInfo * info_ptr)
+static jvmtiError
+GetThreadInfo (jvmtiEnv * env, jthread t, jvmtiThreadInfo * info_ptr)
{
+ utf *name;
+ java_lang_Thread* th = (java_lang_Thread*)t;
+
+
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ 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;
+
+ 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 *********************************************************
-
+ 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)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ int i,j,size=20;
+ java_objectheader **om;
+ lock_record_pool_t* lrp;
+ threadobject* t;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_get_owned_monitor_info);
+
+ if ((owned_monitors_ptr == NULL)||(owned_monitor_count_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+ 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)
+
+ om=MNEW(java_objectheader*,size);
+
+ 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 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].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_monitor_count_ptr = i;
+
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetCurrentContendedMonitor *************************************************
-
+ Get the object the specified thread waits for.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentContendedMonitor (jvmtiEnv * env, jthread thread,
jobject * monitor_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ int j;
+ lock_record_pool_t* lrp;
+ 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)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (monitor_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+ *monitor_ptr=NULL;
+
+ 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) && (*monitor_ptr == NULL)) {
+ /* iterate over every lock record in a pool */
+ for (j=0; j<lrp->header.size; j++) {
+ /* 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);
+
+
+#endif
return JVMTI_ERROR_NONE;
}
+typedef struct {
+ jvmtiStartFunction sf;
+ jvmtiEnv* jvmti_env;
+ void* arg;
+} runagentparam;
-/* *****************************************************************************
-
+static void *threadstartup(void *t) {
+ runagentparam *rap = (runagentparam*)t;
+ rap->sf(rap->jvmti_env,(JNIEnv*)&_Jv_JNINativeInterface,rap->arg);
+ return NULL;
+}
+
+/* RunAgentThread *************************************************************
+
+ Starts the execution of an agent thread of the specified native function
+ within the specified thread
*******************************************************************************/
-jvmtiError
+static jvmtiError
RunAgentThread (jvmtiEnv * env, jthread thread, jvmtiStartFunction proc,
const void *arg, jint priority)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ pthread_attr_t threadattr;
+ struct sched_param sp;
+ runagentparam rap;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if((thread != NULL)&&(!builtin_instanceof(thread,class_java_lang_Thread)))
+ return JVMTI_ERROR_INVALID_THREAD;
+ if (proc == NULL) return JVMTI_ERROR_NULL_POINTER;
+ if ((priority < JVMTI_THREAD_MIN_PRIORITY) ||
+ (priority > JVMTI_THREAD_MAX_PRIORITY))
+ return JVMTI_ERROR_INVALID_PRIORITY;
+
+ /* 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;
+ rap.arg = (void*)arg;
+ rap.jvmti_env = env;
+
+#if defined(ENABLE_THREADS)
+ pthread_attr_init(&threadattr);
+ pthread_attr_setdetachstate(&threadattr, PTHREAD_CREATE_DETACHED);
+ if (priority == JVMTI_THREAD_MIN_PRIORITY) {
+ sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
+ }
+ if (priority == JVMTI_THREAD_MAX_PRIORITY) {
+ sp.__sched_priority = sched_get_priority_min(SCHED_FIFO);
+ }
+ pthread_attr_setschedparam(&threadattr,&sp);
+ if (pthread_create(&((threadobject*)
+ thread)->tid, &threadattr, &threadstartup, &rap)) {
+ log_text("pthread_create failed");
+ assert(0);
+ }
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetTopThreadGroups *********************************************************
-
+ Get all top-level thread groups in the VM.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTopThreadGroups (jvmtiEnv * env, jint * group_count_ptr,
jthreadGroup ** groups_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ jint threads_count_ptr;
+ threadobject *threads_ptr;
+ int i,j,x,size=20;
+ jthreadGroup **tg,*ttgp;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if ((groups_ptr == NULL) || (group_count_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+#if defined(ENABLE_THREADS)
+ tg = MNEW(jthreadGroup*,size);
+ x = 0;
+ if (JVMTI_ERROR_NONE!=GetAllThreads(env,&threads_count_ptr,(jthread**)&threads_ptr))
+ return JVMTI_ERROR_INTERNAL;
+
+ for (i=0;i<threads_count_ptr;i++){
+ if (threads_ptr[i].o.thread->group == NULL) {
+ log_text("threadgroup not set");
+ return JVMTI_ERROR_INTERNAL;
+ }
+ ttgp = (jthreadGroup*)((java_lang_ThreadGroup*)threads_ptr[i].o.thread->group)->parent;
+ if (ttgp == NULL) {
+ j=0;
+ while((j<x)&&(tg[j]!=ttgp)) { /* unique ? */
+ j++;
+ }
+ if (j == x) {
+ if (x >= size){
+ MREALLOC(tg,jthreadGroup*,size,size*2);
+ size=size*2;
+ }
+ tg[x]=ttgp;
+ x++;
+ }
+ }
+ }
+
+ *groups_ptr = heap_allocate(sizeof(jthreadGroup*)*x,true,NULL);
+ memcpy(*groups_ptr,tg,x*sizeof(jthreadGroup*));
+ MFREE(tg,jthreadGroup*,size);
+
+ *group_count_ptr = x;
+
+#else
+ return JVMTI_ERROR_NOT_AVAILABLE;
+#endif
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetThreadGroupInfo *********************************************************
-
+ Get information about the specified thread group.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadGroupInfo (jvmtiEnv * env, jthreadGroup group,
jvmtiThreadGroupInfo * info_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ int size;
+ char* name;
+ java_lang_ThreadGroup* grp;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+ if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
+ return JVMTI_ERROR_INVALID_THREAD_GROUP;
+
+ grp = (java_lang_ThreadGroup*)group;
+
+ info_ptr->parent = (jthreadGroup)
+ Java_java_lang_VMObject_clone(NULL,
+ (jclass)grp->header.vftbl->class,
+ (java_lang_Cloneable*) &grp->parent);
+
+ name = javastring_tochar((java_objectheader*)grp->name);
+ size = strlen(name);
+ info_ptr->name=heap_allocate(size*sizeof(char),true,NULL);
+ strncpy(info_ptr->name,name,size);
+ info_ptr->max_priority= (jint)grp->maxpri;
+ info_ptr->is_daemon= (jboolean)grp->daemon_flag;
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetThreadGroupChildren *****************************************************
-
+ Get the live threads and active subgroups in this thread group.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadGroupChildren (jvmtiEnv * env, jthreadGroup group,
jint * thread_count_ptr, jthread ** threads_ptr,
jint * group_count_ptr, jthreadGroup ** groups_ptr)
{
+ java_lang_ThreadGroup* tgp;
+
CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if ((thread_count_ptr == NULL) || (threads_ptr == NULL) ||
+ (group_count_ptr == NULL) || (groups_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+ if (!builtin_instanceof(group,class_java_lang_ThreadGroup))
+ return JVMTI_ERROR_INVALID_THREAD_GROUP;
+
+ tgp = (java_lang_ThreadGroup*)group;
+
+ *thread_count_ptr = (jint)tgp->threads->elementCount;
+
+ *threads_ptr =
+ heap_allocate(sizeof(jthread)*(*thread_count_ptr),true,NULL);
+
+ memcpy(*threads_ptr, &tgp->threads->elementData,
+ (*thread_count_ptr)*sizeof(java_objectarray*));
+
+ *group_count_ptr = (jint) tgp->groups->elementCount;
+
+ *groups_ptr =
+ heap_allocate(sizeof(jthreadGroup)*(*group_count_ptr),true,NULL);
+
+ memcpy(*groups_ptr, &tgp->threads->elementData,
+ (*group_count_ptr)*sizeof(jthreadGroup*));
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* getcacaostacktrace *********************************************************
+ Helper function that retrives stack trace for specified thread.
+*******************************************************************************/
+
+static jvmtiError getcacaostacktrace(stacktracebuffer** trace, jthread thread) {
+ threadobject *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. Calling function
+ has to take care of suspending/resuming thread.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameCount (jvmtiEnv * env, jthread thread, jint * count_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ stacktracebuffer* trace;
+ jvmtiError er;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if (thread != NULL){
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+
+ CHECK_THREAD_IS_ALIVE(thread);
+ }
+
+ if(count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+ er = getcacaostacktrace(&trace, thread);
+ 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;
+ threadobject* t = (threadobject*)th->vmThread;
+
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+
+ if (thread_state_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+ *thread_state_ptr = 0;
+#if defined(ENABLE_THREADS)
+ if((th->vmThread == NULL)&&(th->group == NULL)) { /* alive ? */
+ /* not alive */
+ 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;
+ /* 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;
+ if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER;
+ if (false /* t->ee.waiting ? */) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING;
+ if (false) *thread_state_ptr |= JVMTI_THREAD_STATE_WAITING_INDEFINITELY;
+ 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->sleeping) *thread_state_ptr |= JVMTI_THREAD_STATE_SLEEPING;
+ }
+#else
+ return JVMTI_ERROR_INTERNAL;
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetFrameLocation ************************************************************
-
+ Get the location of the instruction currently executing
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFrameLocation (jvmtiEnv * env, jthread thread, jint depth,
jmethodID * method_ptr, jlocation * location_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ stackframeinfo *sfi;
+ int i;
+ threadobject* th;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ 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 = th->_stackframeinfo;
+
+ i = 0;
+ while ((sfi != NULL) && (i<depth)) {
+ sfi = sfi->prev;
+ i++;
+ }
+
+ if (i>depth) return JVMTI_ERROR_NO_MORE_FRAMES;
+
+ *method_ptr=(jmethodID)sfi->method;
+ *location_ptr = 0; /* todo: location MachinePC not avilable - Linenumber not expected */
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* NotifyFramePop *************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
NotifyFramePop (jvmtiEnv * env, jthread thread, jint depth)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_generate_frame_pop_events)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetLocalObject *************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalObject (jvmtiEnv * env,
jthread thread, jint depth, jint slot, jobject * value_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_access_local_variables)
+
+ log_text ("JVMTI-Call: TBD-OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetLocalInt ****************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalInt (jvmtiEnv * env,
jthread thread, jint depth, jint slot, jint * value_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_access_local_variables)
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jlong * value_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_access_local_variables)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jfloat * value_ptr)
{
CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_access_local_variables)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jdouble * value_ptr)
{
CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_access_local_variables)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalObject (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jobject value)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_access_local_variables)
+
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalInt (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jint value)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_access_local_variables)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalLong (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jlong value)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_access_local_variables)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalFloat (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jfloat value)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_access_local_variables)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetLocalDouble (jvmtiEnv * env, jthread thread, jint depth, jint slot,
jdouble value)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_access_local_variables)
+
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* CreateRawMonitor ***********************************************************
-
+ This function creates a new raw monitor.
*******************************************************************************/
-jvmtiError
+static jvmtiError
CreateRawMonitor (jvmtiEnv * env, const char *name,
jrawMonitorID * monitor_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ struct _jrawMonitorID *monitor = (struct _jrawMonitorID*) monitor_ptr;
+
+ CHECK_PHASE_START
+ CHECK_PHASE(JVMTI_PHASE_ONLOAD)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if ((name == NULL) || (monitor_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+#if defined(ENABLE_THREADS)
+ monitor->name=javastring_new_from_ascii(name);
+#else
+ log_text ("CreateRawMonitor not supported");
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* DestroyRawMonitor **********************************************************
-
+ This function destroys a raw monitor.
*******************************************************************************/
-jvmtiError
+static jvmtiError
DestroyRawMonitor (jvmtiEnv * env, jrawMonitorID monitor)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
+ CHECK_PHASE(JVMTI_PHASE_ONLOAD)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
- return JVMTI_ERROR_NONE;
+
+ if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+ return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+ return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+ lock_monitor_exit((java_objectheader *) monitor->name);
+
+ heap_free(monitor);
+#else
+ log_text ("DestroyRawMonitor not supported");
+#endif
+
+ return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* RawMonitorEnter ************************************************************
-
+ Gain exclusive ownership of a raw monitor
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorEnter (jvmtiEnv * env, jrawMonitorID monitor)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
- CHECK_PHASE(JVMTI_PHASE_LIVE)
- CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+ return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+ lock_monitor_enter((java_objectheader *) monitor->name);
+#else
+ log_text ("RawMonitorEnter not supported");
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* RawMonitorExit *************************************************************
-
+ Release raw monitor
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorExit (jvmtiEnv * env, jrawMonitorID monitor)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
- CHECK_PHASE(JVMTI_PHASE_LIVE)
- CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+ return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+ /* assure current thread owns this monitor */
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+ return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+ lock_monitor_exit((java_objectheader *) monitor->name);
+#else
+ log_text ("RawMonitorExit not supported");
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* RawMonitorWait *************************************************************
-
+ Wait for notification of the raw monitor.
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorWait (jvmtiEnv * env, jrawMonitorID monitor, jlong millis)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
- CHECK_PHASE(JVMTI_PHASE_LIVE)
- CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+ return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+ /* assure current thread owns this monitor */
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+ return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+ 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;
+
+#else
+ log_text ("RawMonitorWait not supported");
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* RawMonitorNotify ***********************************************************
-
+ Notify one thread waiting on the given monitor.
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotify (jvmtiEnv * env, jrawMonitorID monitor)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
- CHECK_PHASE(JVMTI_PHASE_LIVE)
- CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+ return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+ /* assure current thread owns this monitor */
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+ return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+ lock_notify_object((java_objectheader*)&monitor->name);
+#else
+ log_text ("RawMonitorNotify not supported");
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* RawMonitorNotifyAll *********************************************************
-
+ Notify all threads waiting on the given monitor.
*******************************************************************************/
-jvmtiError
+static jvmtiError
RawMonitorNotifyAll (jvmtiEnv * env, jrawMonitorID monitor)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
- CHECK_PHASE(JVMTI_PHASE_LIVE)
- CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (!builtin_instanceof((java_objectheader*)monitor->name,class_java_lang_String))
+ return JVMTI_ERROR_INVALID_MONITOR;
+
+#if defined(ENABLE_THREADS)
+ /* assure current thread owns this monitor */
+ if (!lock_is_held_by_current_thread((java_objectheader*)monitor->name))
+ return JVMTI_ERROR_NOT_MONITOR_OWNER;
+
+ lock_notify_all_object((java_objectheader*)&monitor->name);
+#else
+ log_text ("RawMonitorNotifyAll not supported");
+#endif
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* SetBreakpoint **************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetBreakpoint (jvmtiEnv * env, jmethodID method, jlocation location)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ 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
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_generate_breakpoint_events)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* SetFieldAccessWatch ********************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_generate_field_access_events)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearFieldAccessWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_generate_field_access_events)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_generate_field_modification_events)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
ClearFieldModificationWatch (jvmtiEnv * env, jclass klass, jfieldID field)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_generate_field_modification_events)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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;
}
-/* *****************************************************************************
+/* GetClassStatus *************************************************************
-
+ Get status of the class.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassStatus (jvmtiEnv * env, jclass klass, jint * status_ptr)
{
+ classinfo *c;
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
+
+ if (status_ptr == NULL)
+ return JVMTI_ERROR_NULL_POINTER;
+
+ c = (classinfo*)klass;
+ *status_ptr = 0;
+
+/* if (c) *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_VERIFIED; ? */
+ if (c->state & CLASS_LINKED)
+ *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PREPARED;
+
+ if (c->state & CLASS_INITIALIZED)
+ *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_INITIALIZED;
+
+ if (c->state & CLASS_ERROR)
+ *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ERROR;
+
+ if (c->vftbl->arraydesc != NULL)
+ *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_ARRAY;
+
+ if (Java_java_lang_VMClass_isPrimitive(NULL,NULL,(struct java_lang_Class*)c))
+ *status_ptr = *status_ptr | JVMTI_CLASS_STATUS_PRIMITIVE;
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSourceFileName (jvmtiEnv * env, jclass klass, char **source_name_ptr)
{
int size;
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_get_source_file_name)
if ((klass == NULL)||(source_name_ptr == NULL))
return JVMTI_ERROR_NULL_POINTER;
- size = (((classinfo*)klass)->sourcefile->blength);
+ size = utf_bytes(((classinfo*)klass)->sourcefile)+1;
*source_name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
memcpy(*source_name_ptr,((classinfo*)klass)->sourcefile->text, size);
+ (*source_name_ptr)[size]='\0';
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetClassModifiers **********************************************************
-
+ For class klass return the access flags
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassModifiers (jvmtiEnv * env, jclass klass, jint * modifiers_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (modifiers_ptr == NULL)
+ return JVMTI_ERROR_NULL_POINTER;
+
+ if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
+
+ *modifiers_ptr = (jint) ((classinfo*)klass)->flags;
+
return JVMTI_ERROR_NONE;
}
/* GetClassMethods *************************************************************
- For the class indicated by klass, return a count of methods and a list of
- method IDs
+ For class klass return a count of methods and a list of method IDs
*******************************************************************************/
-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;
+ if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
+
*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)
{
}
-/* *****************************************************************************
+/* GetImplementedInterfaces ***************************************************
-
+ Return the direct super-interfaces of this class.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetImplementedInterfaces (jvmtiEnv * env, jclass klass,
jint * interface_count_ptr,
jclass ** interfaces_ptr)
{
- CHECK_PHASE_START
+ int i;
+ classref_or_classinfo *interfaces;
+ classinfo *tmp;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if ((interfaces_ptr == NULL) || (interface_count_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+ if (!builtin_instanceof((java_objectheader*)klass,class_java_lang_Class))
+ return JVMTI_ERROR_INVALID_CLASS;
+
+
+ *interface_count_ptr = (jint)((classinfo*)klass)->interfacescount;
+ *interfaces_ptr =
+ heap_allocate(sizeof(jclass*) * (*interface_count_ptr),true,NULL);
+
+ interfaces = ((classinfo*)klass)->interfaces;
+ for (i=0; i<*interface_count_ptr; i++) {
+ if (IS_CLASSREF(interfaces[i]))
+ tmp = load_class_bootstrap(interfaces[i].ref->name);
+ else
+ tmp = interfaces[i].cls;
+
+ *interfaces_ptr[i]=tmp;
+ }
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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
if (is_array_class_ptr == NULL)
return JVMTI_ERROR_NULL_POINTER;
- *is_array_class_ptr = ((classinfo*)klass)->name->text[0] == '[';
+ *is_array_class_ptr = ((classinfo*)klass)->vftbl->arraydesc != NULL;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetClassLoader (jvmtiEnv * env, jclass klass, jobject * classloader_ptr)
{
CHECK_PHASE_START
}
-/* *****************************************************************************
+/* GetObjectHashCode **********************************************************
-
+ Return hash code for object object
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectHashCode (jvmtiEnv * env, jobject object, jint * hash_code_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if (hash_code_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+ if (!builtin_instanceof(object,class_java_lang_Object))
+ return JVMTI_ERROR_INVALID_OBJECT;
+
+ *hash_code_ptr = Java_java_lang_VMSystem_identityHashCode(NULL,NULL,(struct java_lang_Object*)object);
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectMonitorUsage (jvmtiEnv * env, jobject object,
jvmtiMonitorUsage * info_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_get_monitor_info)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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;
-
- size = (((fieldinfo*)field)->name->blength);
- *name_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
- memcpy(*name_ptr,((fieldinfo*)field)->name->text, size);
- size = (((fieldinfo*)field)->descriptor->blength);
- *signature_ptr = (char*) heap_allocate(sizeof(char)* size,true,NULL);
- memcpy(*signature_ptr,((fieldinfo*)field)->descriptor->text, size);
-
- *generic_ptr = NULL;
+ 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 (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);
+ }
+
+ 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);
+ }
+
+ 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;
-
- /* todo: find declaring class */
+ 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;
}
-/* *****************************************************************************
+/* GetFieldModifiers **********************************************************
-
+ Return access flags of field field
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetFieldModifiers (jvmtiEnv * env, jclass klass, jfieldID field,
jint * modifiers_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ 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;
+
+ *modifiers_ptr = ((fieldinfo*)field)->flags;
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* IsFieldSynthetic ***********************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsFieldSynthetic (jvmtiEnv * env, jclass klass, jfieldID field,
jboolean * is_synthetic_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_get_synthetic_attribute)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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;
- *name_ptr = (char*)heap_allocate(m->name->blength,true,NULL);
- memcpy(*name_ptr, m->name->text, m->name->blength);
+ if (method == NULL) return JVMTI_ERROR_INVALID_METHODID;
- *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;
+ 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);
+ }
+
+ 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;
- *size_ptr = (jint)((methodinfo*)method)->paramcount;
+ *size_ptr = (jint)((methodinfo*)method)->parseddesc->paramslots;
return JVMTI_ERROR_NONE;
}
-/* GetLineNumberTable ***********************************************************
+/* GetLineNumberTable **********************************************************
- For the method indicated by method, return a table of source line number
- entries.
+ 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)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_get_line_numbers)
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 =
- (jlocation) method->linenumbers[i].start_pc;
- (*table_ptr[i]).line_number =
+ (*table_ptr)[i].start_location =
+ (jlocation) ((methodinfo*)method)->linenumbers[i].start_pc;
+ (*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;
- *start_location_ptr = (jlocation)m->mcode;
- *end_location_ptr = (jlocation)(m->mcode)+m->mcodelength;
+ /* 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
+ * than one location. -Edwin */
+
+ /* XXX Don't know if that's the right way to deal with not-yet-
+ * compiled methods. -Edwin */
+
+ 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;*/
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetLocalVariableTable (jvmtiEnv * env, jmethodID method,
jint * entry_count_ptr,
jvmtiLocalVariableEntry ** table_ptr)
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_access_local_variables)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: TBD OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetBytecodes (jvmtiEnv * env, jmethodID method,
jint * bytecode_count_ptr, unsigned char **bytecodes_ptr)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_get_bytecodes)
if ((method == NULL) || (bytecode_count_ptr == NULL) ||
(bytecodes_ptr == NULL)) return JVMTI_ERROR_NULL_POINTER;
*******************************************************************************/
-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)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_get_synthetic_attribute)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
-GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr,
- jclass ** classes_ptr)
+static jvmtiError
+GetLoadedClasses (jvmtiEnv * env, jint * class_count_ptr, jclass ** classes_ptr)
{
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 ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (class_count_ptr == NULL)
+ return JVMTI_ERROR_NULL_POINTER;
+
+ if (classes_ptr == NULL)
+ return JVMTI_ERROR_NULL_POINTER;
+
+ 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)
{
+ log_text("GetClassLoaderClasses called");
+
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;
+ if ((class_count_ptr == NULL) || (classes_ptr == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
- return JVMTI_ERROR_NONE;
+ /* behave like jdk 1.1 and make no distinction between initiating and
+ defining class loaders */
+
+ return GetLoadedClasses(env, class_count_ptr, classes_ptr);
}
-/* *****************************************************************************
+/* PopFrame *******************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
PopFrame (jvmtiEnv * env, jthread thread)
{
CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_pop_frame)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* RedefineClasses ************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
RedefineClasses (jvmtiEnv * env, jint class_count,
const jvmtiClassDefinition * class_definitions)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ 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;
}
/* GetCapabilities ************************************************************
- Returns via capabilities_ptr the optional JVM TI features which this
- environment currently possesses.
+ Returns the optional JVM TI features which this environment currently
+ possesses.
*******************************************************************************/
-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)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_get_source_debug_extension)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
IsMethodObsolete (jvmtiEnv * env, jmethodID method,
jboolean * is_obsolete_ptr)
{
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_redefine_classes)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
-
+/* SuspendThreadList **********************************************************
+ Suspend all threads in the request list.
*******************************************************************************/
-jvmtiError
+static jvmtiError
SuspendThreadList (jvmtiEnv * env, jint request_count,
const jthread * request_list, jvmtiError * results)
{
- CHECK_PHASE_START
+ int i;
+ int suspendme = -1;
+ jthread me;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_suspend);
+
+ 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)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ int i;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_suspend);
+
+ 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;
}
-/* *****************************************************************************
+/* GetStackTrace **************************************************************
-
+ Get information about the stack of a thread
*******************************************************************************/
-jvmtiError
-GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
- jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
+static jvmtiError
+GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
+ jint max_frame_count, jvmtiFrameInfo * frame_buffer,
+ jint * count_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ stacktracebuffer* trace;
+ jvmtiError er;
+ int i,j;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if (thread != NULL){
+ if(!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_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) {
+ 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;
+ /* XXX todo: location BCI/MachinePC not avilable - Linenumber not expected */
+ frame_buffer[j].location = 0;
+ }
+
+ heap_free(trace);
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetThreadListStackTraces ***************************************************
-
+ Get information about the stacks of the supplied threads.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadListStackTraces (jvmtiEnv * env, jint thread_count,
const jthread * thread_list,
jint max_frame_count,
jvmtiStackInfo ** stack_info_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ int i;
+ jvmtiError er;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if ((stack_info_ptr == NULL)||(thread_list == NULL))
+ return JVMTI_ERROR_NULL_POINTER;
+
+ if (thread_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+ if (max_frame_count < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
+
+ *stack_info_ptr = (jvmtiStackInfo*)
+ heap_allocate(sizeof(jvmtiStackInfo) * thread_count, true, NULL);
+
+ for(i=0; i<thread_count; i++) { /* fill in stack info sturcture array */
+ (*stack_info_ptr)[i].thread=thread_list[i];
+ GetThreadState(env,thread_list[i],&((*stack_info_ptr)[i].state));
+ (*stack_info_ptr)[i].frame_buffer =
+ heap_allocate(sizeof(jvmtiFrameInfo) * max_frame_count,true,NULL);
+ er = GetStackTrace(env,thread_list[i],0,max_frame_count,
+ (*stack_info_ptr)[i].frame_buffer,
+ &((*stack_info_ptr)[i].frame_count));
+
+ if (er != JVMTI_ERROR_NONE) return er;
+ }
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetAllStackTraces **********************************************************
-
+ Get stack traces of all live threads
*******************************************************************************/
-jvmtiError
-GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
+static jvmtiError
+GetAllStackTraces (jvmtiEnv * env, jint max_frame_count,
+ jvmtiStackInfo ** stack_info_ptr, jint * thread_count_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ jthread *threads_ptr;
+ jvmtiError er;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if (thread_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+ 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);
+
+ if (er != JVMTI_ERROR_NONE) return er;
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetThreadLocalStorage ******************************************************
-
+ Get the value of the JVM TI thread-local storage.
*******************************************************************************/
-jvmtiError
-SetThreadLocalStorage (jvmtiEnv * env, jthread thread, const void *data)
+static jvmtiError
+GetThreadLocalStorage (jvmtiEnv * env, jthread thread, void **data_ptr)
{
- CHECK_PHASE_START
+ jvmtiThreadLocalStorage *tls;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if(thread == NULL)
+ thread = (jthread) THREADOBJECT;
+ else {
+ if (!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+ CHECK_THREAD_IS_ALIVE(thread);
+ }
+
+ if(data_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+ tls = ((environment*)env)->tls;
+ while ((tls->thread != thread) && (tls != NULL)) {
+ tls = tls->next;
+ }
+
+ if (tls == NULL) return JVMTI_ERROR_INTERNAL; /* env/thread pair not found */
+
+ *data_ptr = tls->data;
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* SetThreadLocalStorage *******************************************************
-
+ Stores a pointer value associated with each environment-thread pair. The
+ value is NULL unless set with this function. Agents can allocate memory in
+ which they store thread specific information
*******************************************************************************/
jvmtiError
-GetStackTrace (jvmtiEnv * env, jthread thread, jint start_depth,
- jint max_frame_count, jvmtiFrameInfo * frame_buffer,
- jint * count_ptr)
+SetThreadLocalStorage (jvmtiEnv * jenv, jthread thread, const void *data)
{
- CHECK_PHASE_START
+ jvmtiThreadLocalStorage *tls, *pre;
+ environment* env = (environment*)jenv;
+
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if(thread == NULL)
+ thread = (jthread) THREADOBJECT;
+ else {
+ if (!builtin_instanceof(thread,class_java_lang_Thread))
+ return JVMTI_ERROR_INVALID_THREAD;
+ CHECK_THREAD_IS_ALIVE(thread);
+ }
+
+ if (env->tls == NULL) {
+ tls = env->tls = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
+ } else {
+ tls = env->tls;
+ while ((tls->thread != thread) && (tls->next != NULL)) {
+ tls = tls->next;
+ }
+ if (tls->thread != thread) {
+ tls->next = heap_allocate(sizeof(jvmtiThreadLocalStorage),true,NULL);
+ tls = tls->next;
+ }
+ }
+
+ if (data != NULL) {
+ tls->data = (void*)data;
+ } else {
+ /* remove current tls */
+ pre = env->tls;
+ while (pre->next == tls) pre = pre->next;
+ pre->next = tls->next;
+ }
return JVMTI_ERROR_NONE;
}
+
/* *****************************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTag (jvmtiEnv * env, jobject object, jlong * tag_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_tag_objects)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetTag (jvmtiEnv * env, jobject object, jlong tag)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_tag_objects)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* ForceGarbageCollection *****************************************************
-
+ Force boehm-gc to perform a garbage collection
*******************************************************************************/
-jvmtiError
+static jvmtiError
ForceGarbageCollection (jvmtiEnv * env)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ gc_call();
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* IterateOverObjectsReachableFromObject **************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverObjectsReachableFromObject (jvmtiEnv * env, jobject object,
jvmtiObjectReferenceCallback
object_reference_callback,
void *user_data)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_tag_objects)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* IterateOverReachableObjects ************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverReachableObjects (jvmtiEnv * env, jvmtiHeapRootCallback
heap_root_callback,
jvmtiStackReferenceCallback
jvmtiObjectReferenceCallback
object_ref_callback, void *user_data)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_tag_objects)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* IterateOverHeap ************************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverHeap (jvmtiEnv * env, jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback heap_object_callback,
void *user_data)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_tag_objects)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* IterateOverInstancesOfClass ************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
IterateOverInstancesOfClass (jvmtiEnv * env, jclass klass,
jvmtiHeapObjectFilter object_filter,
jvmtiHeapObjectCallback
heap_object_callback, void *user_data)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_tag_objects)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectsWithTags (jvmtiEnv * env, jint tag_count, const jlong * tags,
jint * count_ptr, jobject ** object_result_ptr,
jlong ** tag_result_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_tag_objects)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetJNIFunctionTable (jvmtiEnv * env,
const jniNativeInterface * function_table)
{
CHECK_PHASE_END;;
if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
- ptr_env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
- memcpy(ptr_env, function_table, sizeof(jniNativeInterface));
+ _Jv_env->env = (void*)heap_allocate(sizeof(jniNativeInterface),true,NULL);
+ 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
if (function_table == NULL) return JVMTI_ERROR_NULL_POINTER;
*function_table = (jniNativeInterface*)
heap_allocate(sizeof(jniNativeInterface),true,NULL);
- memcpy(*function_table, ptr_env, sizeof(jniNativeInterface));
+ memcpy(*function_table, _Jv_env->env, sizeof(jniNativeInterface));
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetEventCallbacks (jvmtiEnv * env,
const jvmtiEventCallbacks * callbacks,
jint size_of_callbacks)
CHECK_PHASE_END;
if (size_of_callbacks < 0) return JVMTI_ERROR_ILLEGAL_ARGUMENT;
-
- if (callbacks == NULL) { /* remove the existing callbacks */
- memset(&(((environment* )env)->callbacks), 0, sizeof(jvmtiEventCallbacks));
+
+
+ if (callbacks == NULL) { /* remove the existing callbacks */
+ memset(&(((environment* )env)->callbacks), 0,
+ sizeof(jvmtiEventCallbacks));
}
memcpy (&(((environment* )env)->callbacks),callbacks,size_of_callbacks);
}
-/* *****************************************************************************
+/* GenerateEvents *************************************************************
-
+ Generate events (CompiledMethodLoad and DynamicCodeGenerated) to represent
+ the current state of the VM.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GenerateEvents (jvmtiEnv * env, jvmtiEvent event_type)
{
CHECK_PHASE_START
- CHECK_PHASE(JVMTI_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* )env)->events = NULL;
- ((environment* )env)->EnvironmentLocalStorage = NULL;
- /* let Boehm GC do the rest */
+ environment* cacao_env = (environment*)env;
+ environment* tenvs = envs;
+ jvmtiThreadLocalStorage *jtls, *tjtls;
+
+ if (tenvs != cacao_env) {
+ while (tenvs->next != cacao_env) {
+ tenvs = tenvs->next;
+ }
+ tenvs->next = cacao_env->next;
+ } else
+ envs = NULL;
+
+ 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;
+ *format_ptr = JVMTI_JLOCATION_OTHER;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSystemProperties (jvmtiEnv * env, jint * count_ptr, char ***property_ptr)
{
- jmethodID mid;
- jmethodID moremid;
+ jmethodID mid, moremid;
classinfo *sysclass, *propclass, *enumclass;
java_objectheader *sysprop, *keys, *obj;
char* ch;
if (!sysclass) throw_main_exception_exit();
- mid = class_resolvemethod(sysclass,
+ mid = (jmethodID)class_resolvemethod(sysclass,
utf_new_char("getProperties"),
utf_new_char("()Ljava/util/Properties;"));
if (!mid) throw_main_exception_exit();
- sysprop = asm_calljavafunction(mid, sysclass, NULL, NULL, NULL);
+ sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, sysclass, mid);
if (!sysprop) throw_main_exception_exit();
propclass = sysprop->vftbl->class;
- mid = class_resolvemethod(propclass,
+ mid = (jmethodID)class_resolvemethod(propclass,
utf_new_char("size"),
utf_new_char("()I"));
if (!mid) throw_main_exception_exit();
*count_ptr =
- JNI_JNIEnvTable.CallIntMethod(NULL, sysprop, mid);
+ _Jv_JNINativeInterface.CallIntMethod(NULL, sysprop, mid);
*property_ptr = heap_allocate(sizeof(char*) * (*count_ptr) ,true,NULL);
- mid = class_resolvemethod(propclass,
+ mid = (jmethodID)class_resolvemethod(propclass,
utf_new_char("keys"),
utf_new_char("()Ljava/util/Enumeration;"));
if (!mid) throw_main_exception_exit();
- keys = JNI_JNIEnvTable.CallObjectMethod(NULL, sysprop, mid);
+ keys = _Jv_JNINativeInterface.CallObjectMethod(NULL, sysprop, mid);
enumclass = keys->vftbl->class;
- moremid = class_resolvemethod(enumclass,
+ moremid = (jmethodID)class_resolvemethod(enumclass,
utf_new_char("hasMoreElements"),
utf_new_char("()Z"));
if (!moremid) throw_main_exception_exit();
- mid = class_resolvemethod(propclass,
+ mid = (jmethodID)class_resolvemethod(propclass,
utf_new_char("nextElement"),
utf_new_char("()Ljava/lang/Object;"));
if (!mid) throw_main_exception_exit();
i = 0;
- while (JNI_JNIEnvTable.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
- obj = JNI_JNIEnvTable.CallObjectMethod(NULL, keys, mid);
+ while (_Jv_JNINativeInterface.CallBooleanMethod(NULL,keys,(jmethodID)moremid)) {
+ obj = _Jv_JNINativeInterface.CallObjectMethod(NULL, keys, mid);
ch = javastring_tochar(obj);
*property_ptr[i] = heap_allocate(sizeof(char*) * strlen (ch),true,NULL);
memcpy(*property_ptr[i], ch, strlen (ch));
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetSystemProperty (jvmtiEnv * env, const char *property, char **value_ptr)
{
jmethodID mid;
sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
if (!sysclass) throw_main_exception_exit();
- mid = class_resolvemethod(sysclass,
+ mid = (jmethodID)class_resolvemethod(sysclass,
utf_new_char("getProperties"),
utf_new_char("()Ljava/util/Properties;"));
if (!mid) throw_main_exception_exit();
- sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
+ sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
propclass = sysprop->vftbl->class;
- mid = class_resolvemethod(propclass,
+ mid = (jmethodID)class_resolvemethod(propclass,
utf_new_char("getProperty"),
utf_new_char("(Ljava/lang/String;)Ljava/lang/String;"));
if (!mid) throw_main_exception_exit();
- obj = (java_objectheader*)JNI_JNIEnvTable.CallObjectMethod(
- NULL, sysprop, mid, javastring_new_char(property));
+ obj = (java_objectheader*)_Jv_JNINativeInterface.CallObjectMethod(
+ NULL, sysprop, mid, javastring_new_from_ascii(property));
if (!obj) return JVMTI_ERROR_NOT_AVAILABLE;
ch = javastring_tochar(obj);
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetSystemProperty (jvmtiEnv * env, const char *property, const char *value)
{
jmethodID mid;
sysclass = load_class_from_sysloader(utf_new_char("java/lang/System"));
if (!sysclass) throw_main_exception_exit();
- mid = class_resolvemethod(sysclass,
+ mid = (jmethodID)class_resolvemethod(sysclass,
utf_new_char("getProperties"),
utf_new_char("()Ljava/util/Properties;"));
if (!mid) throw_main_exception_exit();
- sysprop = JNI_JNIEnvTable.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
+ sysprop = _Jv_JNINativeInterface.CallStaticObjectMethod(NULL, (jclass)sysclass, mid);
propclass = sysprop->vftbl->class;
- mid = class_resolvemethod(propclass,
+ mid = (jmethodID)class_resolvemethod(propclass,
utf_new_char("setProperty"),
utf_new_char("(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;"));
if (!mid) throw_main_exception_exit();
- JNI_JNIEnvTable.CallObjectMethod(
- NULL, sysprop, mid, javastring_new_char(property),javastring_new_char(value));
+ _Jv_JNINativeInterface.CallObjectMethod(
+ NULL, sysprop, mid, javastring_new_from_ascii(property),javastring_new_from_ascii(value));
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetPhase (jvmtiEnv * env, jvmtiPhase * phase_ptr)
{
if (phase_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetCurrentThreadCpuTimerInfo ************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
+
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetCurrentThreadCpuTime ****************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetCurrentThreadCpuTime (jvmtiEnv * env, jlong * nanos_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
+ CHECK_CAPABILITY(env,can_get_current_thread_cpu_time)
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetThreadCpuTimerInfo ******************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadCpuTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
- CHECK_PHASE_START
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_get_thread_cpu_time)
+
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetThreadCpuTime ***********************************************************
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetThreadCpuTime (jvmtiEnv * env, jthread thread, jlong * nanos_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ CHECK_CAPABILITY(env,can_get_thread_cpu_time)
+ log_text ("JVMTI-Call: OPTIONAL IMPLEMENT ME!!!");
return JVMTI_ERROR_NONE;
}
-/* *****************************************************************************
+/* GetTimerInfo ***************************************************************
-
+ Get information about the GetTime timer.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTimerInfo (jvmtiEnv * env, jvmtiTimerInfo * info_ptr)
{
- CHECK_PHASE_START
- CHECK_PHASE(JVMTI_PHASE_START)
- CHECK_PHASE(JVMTI_PHASE_LIVE)
- CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+ if (info_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+ info_ptr->max_value = !0x0;
+ info_ptr->may_skip_forward = true;
+ info_ptr->may_skip_backward = true;
+ info_ptr->kind = JVMTI_TIMER_TOTAL_CPU;
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetTime (jvmtiEnv * env, jlong * nanos_ptr)
{
/* Note: this implementation copied directly from Japhar's, by Chris Toshok. */
if (nanos_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
if (gettimeofday (&tp, NULL) == -1)
- JNI_JNIEnvTable.FatalError (NULL, "gettimeofday call failed.");
+ _Jv_JNINativeInterface.FatalError (NULL, "gettimeofday call failed.");
*nanos_ptr = (jlong) tp.tv_sec;
*nanos_ptr *= 1000;
*******************************************************************************/
-jvmtiError
-GetPotentialCapabilities (jvmtiEnv * env,
- jvmtiCapabilities * capabilities_ptr)
+static jvmtiError
+GetPotentialCapabilities (jvmtiEnv * env, jvmtiCapabilities * capabilities_ptr)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_ONLOAD)
}
-jvmtiError static capabilityerror()
-{
- return JVMTI_ERROR_MUST_POSSESS_CAPABILITY;
-}
-
-#define CHECK_POTENTIAL_AVAILABLE(CAN) \
- if ((capabilities_ptr->CAN == 1) && \
- (JVMTI_Capabilities.CAN == 0)) \
- return JVMTI_ERROR_NOT_AVAILABLE;
-
+#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;
return JVMTI_ERROR_NULL_POINTER;
cacao_env = (environment*)env;
+
+ CHECK_ADD_CAPABILITY(cacao_env,can_tag_objects)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_modification_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_field_access_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_bytecodes)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_synthetic_attribute)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_owned_monitor_info)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_current_contended_monitor)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_monitor_info)
+ CHECK_ADD_CAPABILITY(cacao_env,can_pop_frame)
+ CHECK_ADD_CAPABILITY(cacao_env,can_redefine_classes)
+ CHECK_ADD_CAPABILITY(cacao_env,can_signal_thread)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_source_file_name)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_line_numbers)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_source_debug_extension)
+ CHECK_ADD_CAPABILITY(cacao_env,can_access_local_variables)
+ CHECK_ADD_CAPABILITY(cacao_env,can_maintain_original_method_order)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_single_step_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_exception_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_frame_pop_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_breakpoint_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_suspend)
+ CHECK_ADD_CAPABILITY(cacao_env,can_redefine_any_class)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
+ CHECK_ADD_CAPABILITY(cacao_env,can_get_thread_cpu_time)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_entry_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_method_exit_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_monitor_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
+ CHECK_ADD_CAPABILITY(cacao_env,can_generate_object_free_events)
- CHECK_POTENTIAL_AVAILABLE(can_tag_objects)
- else {
- cacao_env->capabilities.can_tag_objects = 1;
- env->GetTag = &GetTag;
- env->SetTag = &SetTag;
- env->IterateOverObjectsReachableFromObject =
- &IterateOverObjectsReachableFromObject;
- env->IterateOverReachableObjects =
- &IterateOverReachableObjects;
- env->IterateOverHeap = &IterateOverHeap;
- env->IterateOverInstancesOfClass = &IterateOverInstancesOfClass;
- env->GetObjectsWithTags = &GetObjectsWithTags;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_field_modification_events)
- else {
- cacao_env->capabilities.can_generate_field_modification_events = 1;
- env->SetFieldModificationWatch = &SetFieldModificationWatch;
- env->SetEventNotificationMode = &SetEventNotificationMode;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_field_access_events)
- else {
- cacao_env->capabilities.can_generate_field_access_events = 1;
- env->SetFieldAccessWatch = &SetFieldAccessWatch;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_bytecodes)
- else {
- cacao_env->capabilities.can_get_bytecodes = 1;
- env->GetBytecodes = &GetBytecodes;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_synthetic_attribute)
- else {
- cacao_env->capabilities.can_get_synthetic_attribute = 1;
- env->IsFieldSynthetic = &IsFieldSynthetic;
- env->IsMethodSynthetic = &IsMethodSynthetic;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_owned_monitor_info)
- else {
- cacao_env->capabilities.can_get_owned_monitor_info = 1;
- env->GetOwnedMonitorInfo = &GetOwnedMonitorInfo;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_current_contended_monitor)
- else {
- cacao_env->capabilities.can_get_current_contended_monitor = 1;
- env->GetCurrentContendedMonitor = &GetCurrentContendedMonitor;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_monitor_info)
- else {
- cacao_env->capabilities.can_get_monitor_info = 1;
- env->GetObjectMonitorUsage = &GetObjectMonitorUsage;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_pop_frame)
- else {
- cacao_env->capabilities.can_pop_frame = 1;
- env->PopFrame = &PopFrame;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_redefine_classes)
- else {
- cacao_env->capabilities.can_redefine_classes = 1;
- env->RedefineClasses = &RedefineClasses;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_signal_thread)
- else {
- cacao_env->capabilities.can_signal_thread = 1;
- env->StopThread = &StopThread;
- env->InterruptThread = &InterruptThread;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_source_file_name)
- else {
- cacao_env->capabilities.can_get_source_file_name = 1;
- env->GetSourceFileName = &GetSourceFileName;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_line_numbers)
- else {
- cacao_env->capabilities.can_get_line_numbers = 1;
- env->GetLineNumberTable = &GetLineNumberTable;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_source_debug_extension)
- else {
- cacao_env->capabilities.can_get_source_debug_extension = 1;
- env->GetSourceDebugExtension = &GetSourceDebugExtension;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_access_local_variables)
- else {
- cacao_env->capabilities.can_access_local_variables = 1;
- env->GetLocalObject = &GetLocalObject;
- env->GetLocalInt = &GetLocalInt;
- env->GetLocalLong = &GetLocalLong;
- env->GetLocalFloat = &GetLocalFloat;
- env->GetLocalDouble = &GetLocalDouble;
- env->SetLocalObject = &SetLocalObject;
- env->SetLocalInt = &SetLocalInt;
- env->SetLocalLong = &SetLocalLong;
- env->SetLocalFloat = &SetLocalFloat;
- env->SetLocalDouble = &SetLocalDouble;
- env->GetLocalVariableTable = &GetLocalVariableTable;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_maintain_original_method_order)
- else {
- cacao_env->capabilities.can_maintain_original_method_order = 1;
- env->GetClassMethods = &GetClassMethods;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_single_step_events)
- else {
- cacao_env->capabilities.can_generate_single_step_events = 1;
- env->SetEventNotificationMode = &SetEventNotificationMode;
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_exception_events)
- else {
- cacao_env->capabilities.can_generate_exception_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_frame_pop_events)
- else {
- cacao_env->capabilities.can_generate_frame_pop_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_breakpoint_events)
- else {
- cacao_env->capabilities.can_generate_breakpoint_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_suspend)
- else {
- cacao_env->capabilities.can_suspend = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_redefine_any_class)
- else {
- cacao_env->capabilities.can_redefine_any_class = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_current_thread_cpu_time)
- else {
- cacao_env->capabilities.can_get_current_thread_cpu_time = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_get_thread_cpu_time)
- else {
- cacao_env->capabilities.can_get_thread_cpu_time = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_method_entry_events)
- else {
- cacao_env->capabilities.can_generate_method_entry_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_method_exit_events)
- else {
- cacao_env->capabilities.can_generate_method_exit_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_all_class_hook_events)
- else {
- cacao_env->capabilities.can_generate_all_class_hook_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_compiled_method_load_events)
- else {
- cacao_env->capabilities.can_generate_compiled_method_load_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_monitor_events)
- else {
- cacao_env->capabilities.can_generate_monitor_events= 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_vm_object_alloc_events)
- else {
- cacao_env->capabilities.can_generate_vm_object_alloc_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_native_method_bind_events)
- else {
- cacao_env->capabilities.can_generate_native_method_bind_events = 1;
- /* env-> = &; */
- }
-
- CHECK_POTENTIAL_AVAILABLE(can_generate_garbage_collection_events)
- else {
- cacao_env->capabilities.can_generate_garbage_collection_events = 1;
- /* env-> = &; */
- }
- CHECK_POTENTIAL_AVAILABLE(can_generate_object_free_events)
- else {
- cacao_env->capabilities.can_generate_object_free_events = 1;
- /* env-> = &; */
- }
-
return JVMTI_ERROR_NONE;
}
+
+#define CHECK_DEL_CAPABILITY(env,CAN) \
+ if (capabilities_ptr->CAN == 1) \
+ env->capabilities.CAN = 0;
+
/* RelinquishCapabilities *****************************************************
Relinquish the capabilities pointed to by capabilities_ptr.
*******************************************************************************/
-jvmtiError
+static jvmtiError
RelinquishCapabilities (jvmtiEnv * env,
const jvmtiCapabilities * capabilities_ptr)
{
return JVMTI_ERROR_NULL_POINTER;
cacao_env = (environment*)env;
-
- if (capabilities_ptr->can_tag_objects == 1) {
- cacao_env->capabilities.can_tag_objects = 0;
- env->GetTag = &capabilityerror;
- env->SetTag = &capabilityerror;
- env->IterateOverObjectsReachableFromObject = &capabilityerror;
- env->IterateOverReachableObjects = &capabilityerror;
- env->IterateOverHeap = &capabilityerror;
- env->IterateOverInstancesOfClass = &capabilityerror;
- env->GetObjectsWithTags = &capabilityerror;
- }
-
-/* todo if ((capabilities_ptr-> == 1) {
- cacao_env->capabilities. = 0;
- env->SetFieldModificationWatch = &capabilityerror;
- }*/
+ CHECK_DEL_CAPABILITY(cacao_env,can_tag_objects)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_modification_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_field_access_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_bytecodes)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_synthetic_attribute)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_owned_monitor_info)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_current_contended_monitor)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_monitor_info)
+ CHECK_DEL_CAPABILITY(cacao_env,can_pop_frame)
+ CHECK_DEL_CAPABILITY(cacao_env,can_redefine_classes)
+ CHECK_DEL_CAPABILITY(cacao_env,can_signal_thread)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_source_file_name)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_line_numbers)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_source_debug_extension)
+ CHECK_DEL_CAPABILITY(cacao_env,can_access_local_variables)
+ CHECK_DEL_CAPABILITY(cacao_env,can_maintain_original_method_order)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_single_step_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_exception_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_frame_pop_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_breakpoint_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_suspend)
+ CHECK_DEL_CAPABILITY(cacao_env,can_redefine_any_class)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_current_thread_cpu_time)
+ CHECK_DEL_CAPABILITY(cacao_env,can_get_thread_cpu_time)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_entry_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_method_exit_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_all_class_hook_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_compiled_method_load_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_monitor_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_vm_object_alloc_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_native_method_bind_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_garbage_collection_events)
+ CHECK_DEL_CAPABILITY(cacao_env,can_generate_object_free_events)
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
+ CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if (processor_count_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+
+ log_text ("GetAvailableProcessors IMPLEMENT ME!!!");
+
+ *processor_count_ptr = 1; /* where do I get this ?*/
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-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;
- ((environment*)env)->EnvironmentLocalStorage = data;
+ ((environment*)env)->EnvironmentLocalStorage = (void*) data;
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiError
+static jvmtiError
AddToBootstrapClassLoaderSearch (jvmtiEnv * env, const char *segment)
{
char* tmp_bcp;
*******************************************************************************/
-jvmtiError
+static jvmtiError
SetVerboseFlag (jvmtiEnv * env, jvmtiVerboseFlag flag, jboolean value)
{
switch (flag) {
case JVMTI_VERBOSE_OTHER:
- runverbose = value;
+ /* where is this defined ?
+ runverbose = value;
+ */
break;
case JVMTI_VERBOSE_GC:
opt_verbosegc = value;
/* GetObjectSize **************************************************************
- For the object indicated by object, return the size of the object. This size
- is an implementation-specific approximation of the amount of storage consumed
- by this object.
+ For the object object return the size.
*******************************************************************************/
-jvmtiError
+static jvmtiError
GetObjectSize (jvmtiEnv * env, jobject object, jlong * size_ptr)
{
CHECK_PHASE_START
CHECK_PHASE(JVMTI_PHASE_START)
CHECK_PHASE(JVMTI_PHASE_LIVE)
CHECK_PHASE_END;
-
- log_text ("JVMTI-Call: IMPLEMENT ME!!!");
+
+ if (size_ptr == NULL) return JVMTI_ERROR_NULL_POINTER;
+ if (!builtin_instanceof(object,class_java_lang_Object))
+ return JVMTI_ERROR_INVALID_OBJECT;
+
+ *size_ptr = ((java_objectheader*)object)->vftbl->class->instancesize;
+
return JVMTI_ERROR_NONE;
}
*******************************************************************************/
-jvmtiCapabilities JVMTI_Capabilities = {
+static jvmtiCapabilities JVMTI_Capabilities = {
0, /* can_tag_objects */
0, /* can_generate_field_modification_events */
0, /* can_generate_field_access_events */
1, /* can_get_bytecodes */
0, /* can_get_synthetic_attribute */
+
+#if defined(ENABLE_THREADS)
+ 1, /* can_get_owned_monitor_info */
+ 1, /* can_get_current_contended_monitor */
+#else
0, /* can_get_owned_monitor_info */
0, /* can_get_current_contended_monitor */
+#endif
+
0, /* can_get_monitor_info */
0, /* can_pop_frame */
0, /* can_redefine_classes */
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 */
0, /* can_generate_object_free_events */
};
-jvmtiEnv JVMTI_EnvTable = {
+static struct jvmtiEnv_struct JVMTI_EnvTable = {
NULL,
&SetEventNotificationMode,
NULL,
&GetObjectSize
};
-void jvmti_init() {
- ihmclass = load_class_from_sysloader(
- utf_new_char_classname ("java/util/IdentityHashMap"));
- if (ihmclass == NULL) {
- log_text("JVMTI-Init: unable to find java.util.IdentityHashMap");
- }
-
- ihmmid = class_resolvemethod(ihmclass,
- utf_new_char("<init>"),
- utf_new_char("()V"));
- if (ihmmid == NULL) {
- log_text("JVMTI-Init: unable to find constructor in java.util.IdentityHashMap");
- }
-}
+/* jvmti_set_phase ************************************************************
+
+ sets a new jvmti phase a fires an apropriate event.
+
+*******************************************************************************/
+
+void jvmti_set_phase(jvmtiPhase p) {
+ genericEventData d;
+
+ fprintf (stderr,"set JVMTI phase %d\n",p);
+ fflush(stderr);
-void set_jvmti_phase(jvmtiPhase p) {
- phase = p;
switch (p) {
case JVMTI_PHASE_ONLOAD:
- /* todo */
- break;
+ phase = p;
+ return;
case JVMTI_PHASE_PRIMORDIAL:
- /* todo */
- break;
+ phase = p;
+ return;
case JVMTI_PHASE_START:
- /* todo: send VM Start Event*/
+ phase = p;
+ d.ev = JVMTI_EVENT_VM_START;
break;
case JVMTI_PHASE_LIVE:
- /* todo: send VMInit Event */
- break;
+ 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:
- /* todo: send VMDeath Event */
+ phase = p;
+ d.ev = JVMTI_EVENT_VM_DEATH;
break;
+ default:
+ log_text("wrong jvmti phase to be set");
+ exit(1);
}
+
+ jvmti_fireEvent(&d);
}
-jvmtiEnv* new_jvmtienv() {
+
+/* jvmti_new_environment ******************************************************
+
+ creates a new JVMTI environment
+
+*******************************************************************************/
+
+jvmtiEnv* jvmti_new_environment() {
environment* env;
- java_objectheader *o;
- env = heap_allocate(sizeof(environment),true,NULL);
- memcpy(&(env->env),&JVMTI_EnvTable,sizeof(jvmtiEnv));
- env->events = (jobject*)builtin_new(ihmclass);
- asm_calljavafunction(ihmmid, o, NULL, NULL, NULL);
+ if (envs == NULL) {
+ envs = heap_allocate(sizeof(environment),true,NULL);
+ env = envs;
+ } else {
+ env = envs;
+ 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;
- return &(env->env);
+ env->tls = NULL;
+
+ /* initialize cacao debugging facilities */
+ jvmti_cacao_debug_init();
+
+ return (jvmtiEnv*)env;
+}
+
+/* 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 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 = GCMNEW(char, i);
+
+ strcpy(*libname, opt_arg);
+ }
+ else {
+ /* -agentlib */
+
+ 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 */
+ 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 */
+ 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");
+
+ retval =
+ ((JNIEXPORT jint JNICALL (*) (JavaVM *vm, char *options, void *reserved))
+ onload) ((JavaVM *) _Jv_jvm, arg, NULL);
+
+ if (retval != 0) exit (retval);
}
+
+/* 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
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: c
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */