* src/native/vm/openjdk/jvm.cpp (JVM_IsInterrupted): Fixed for threads which
[cacao.git] / src / native / vm / openjdk / jvm.cpp
index 7a63880bab9f37cf002a76c0fa07959a9a75e56f..cc431263185f5366f223875e3ac581068eef4c7a 100644 (file)
@@ -50,7 +50,9 @@
 #include INCLUDE_JVM_MD_H
 #include INCLUDE_JVM_H
 
-#include "mm/memory.h"
+#include "fdlibm/fdlibm.h"
+
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 #include "native/native.hpp"
@@ -62,8 +64,9 @@
 
 #include "threads/lock.hpp"
 #include "threads/thread.hpp"
+#include "threads/threadlist.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/list.hpp"
 
 #include "vm/array.hpp"
@@ -85,7 +88,7 @@
 #include "vm/primitive.hpp"
 #include "vm/properties.hpp"
 #include "vm/resolve.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
 
@@ -435,64 +438,11 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
        java_lang_Throwable jlt(throwable);
        java_handle_bytearray_t* ba = jlt.get_backtrace();
 
-       // We need a critical section here as the stacktrace structure is
+       // XXX We need a critical section here as the stacktrace structure is
        // mapped onto a Java byte-array.
-       LLNI_CRITICAL_START;
-
        stacktrace_t* st = (stacktrace_t *) LLNI_array_data(ba);
 
-       if ((index < 0) || (index >= st->length)) {
-               /* XXX This should be an IndexOutOfBoundsException (check this
-                  again). */
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       // Get the stacktrace entry.
-       stacktrace_entry_t* ste = &(st->entries[index]);
-
-       // Get the codeinfo, methodinfo and classinfo.
-       codeinfo*   code = ste->code;
-       methodinfo* m    = code->m;
-       classinfo*  c    = m->clazz;
-
-       // Get filename.
-       java_handle_t* filename;
-
-       if (!(m->flags & ACC_NATIVE)) {
-               if (c->sourcefile != NULL)
-                       filename = javastring_new(c->sourcefile);
-               else
-                       filename = NULL;
-       }
-       else
-               filename = NULL;
-
-       // Get line number.
-       int32_t linenumber;
-
-       if (m->flags & ACC_NATIVE) {
-               linenumber = -2;
-       }
-       else {
-               // FIXME linenumbertable->find could change the methodinfo
-               // pointer when hitting an inlined method.
-               linenumber = code->linenumbertable->find(&m, ste->pc);
-               linenumber = (linenumber == 0) ? -1 : linenumber;
-       }
-
-       LLNI_CRITICAL_END;
-
-       // Get declaring class name.
-       java_handle_t* declaringclass = class_get_classname(c);
-
-       // Allocate a new StackTraceElement object.
-       java_lang_StackTraceElement jlste(declaringclass, javastring_new(m->name), filename, linenumber);
-
-       if (jlste.is_null())
-               return NULL;
-
-       return (jobject) jlste.get_handle();
+       return stacktrace_get_StackTraceElement(st, index);
 }
 
 
@@ -2183,8 +2133,7 @@ jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
-       /* The threadobject is null when a thread is created in Java. The
-          priority is set later during startup. */
+       /* The threadobject is null when a thread is created in Java. */
 
        if (t == NULL)
                return 0;
@@ -2289,6 +2238,8 @@ void JVM_Interrupt(JNIEnv* env, jobject jthread)
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
+       /* The threadobject is null when a thread is created in Java. */
+
        if (t == NULL)
                return;
 
@@ -2309,6 +2260,11 @@ jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrup
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
+       /* The threadobject is null when a thread is created in Java. */
+
+       if (t == NULL)
+               return JNI_FALSE;
+
        interrupted = thread_is_interrupted(t);
 
        if (interrupted && clear_interrupted)
@@ -2648,14 +2604,26 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 
        /* Create an array-class if necessary. */
 
-       if (class_is_primitive(c))
+       if (class_is_primitive(c)) {
                ac = Primitive::get_arrayclass_by_name(c->name);
+
+               // Arrays of void are not allowed.
+               if (ac == NULL) {
+                       exceptions_throw_illegalargumentexception();
+                       return NULL;
+               }
+
+               if (length > 1)
+                       ac = class_multiarray_of((length - 1), ac, true);
+       }
        else
-               ac = class_array_of(c, true);
+               ac = class_multiarray_of(length, c, true);
 
        if (ac == NULL)
                return NULL;
 
+       /* Allocate a new array on the heap. */
+
        a = builtin_multianewarray(length, (java_handle_t *) ac, dims);
 
        return (jobject) a;
@@ -2717,9 +2685,13 @@ jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
 
 jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
 {
-       log_println("JVM_Send: IMPLEMENT ME!");
+       TRACEJVMCALLSENTER(("JVM_Send(fd=%d, buf=%p, nBytes=%d, flags=%d", fd, buf, nBytes, flags));
 
-       return 0;
+       int result = os::send(fd, buf, nBytes, flags);
+
+       TRACEJVMCALLSEXIT(("->%d", result));
+
+       return result;
 }
 
 
@@ -2942,11 +2914,17 @@ void *JVM_FindLibraryEntry(void* handle, const char* name)
 
 /* JVM_IsNaN */
 
-jboolean JVM_IsNaN(jdouble a)
+jboolean JVM_IsNaN(jdouble d)
 {
-       log_println("JVM_IsNaN: IMPLEMENT ME!");
+       bool result;
 
-       return 0;
+       TRACEJVMCALLSENTER(("JVM_IsNaN(d=%f)", d));
+
+       result = isnan(d);
+
+       TRACEJVMCALLSEXIT(("->%d", result));
+
+       return result;
 }
 
 
@@ -3221,9 +3199,31 @@ jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlon
 
 jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 {
-       log_println("JVM_GetAllThreads: IMPLEMENT ME!");
+       // Get a list of all active threads.
+       list<threadobject*> active_threads;
+       ThreadList::get_active_threads(active_threads);
 
-       return NULL;
+       // Allocate array to hold the java.lang.Thread objects.
+       int32_t length = active_threads.size();
+       java_handle_objectarray_t* oa = builtin_anewarray(length, class_java_lang_Thread);
+
+       if (oa == NULL)
+               return NULL;
+
+       // Iterate over all threads (which were active just a second ago).
+       int32_t index = 0;
+       for (List<threadobject*>::iterator it = active_threads.begin(); it != active_threads.end(); it++) {
+               threadobject* t = *it;
+
+               java_handle_t* h = thread_get_object(t);
+               assert(h != NULL);
+
+               array_objectarray_element_set(oa, index, h);
+
+               index++;
+       }
+
+       return oa;
 }
 
 
@@ -3231,9 +3231,55 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 
 jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
 {
-       log_println("JVM_DumpThreads: IMPLEMENT ME!");
+       int32_t i;
 
-       return NULL;
+       TRACEJVMCALLS(("JVM_DumpThreads((env=%p, threadClass=%p, threads=%p)", env, threadClass, threads));
+
+       if (threads == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       // Get length of the threads array.
+       int32_t length = array_length_get((java_handle_t*) threads);
+
+       if (length <= 0) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       // Allocate array to hold stacktraces.
+       classinfo* arrayclass = class_array_of(class_java_lang_StackTraceElement, true);
+       java_handle_objectarray_t* oas = builtin_anewarray(length, arrayclass);
+
+       if (oas == NULL) {
+               return NULL;
+       }
+
+       // Iterate over all passed thread objects.
+       for (i = 0; i < length; i++) {
+               java_handle_t* thread = array_objectarray_element_get(threads, i);
+
+               // Get thread for the given thread object.
+               threadobject* t = thread_get_thread(thread);
+
+               // The threadobject is null when a thread is created in Java.
+               if (t == NULL)
+                       continue;
+
+               // Get stacktrace for given thread.
+               stacktrace_t* st = stacktrace_get_of_thread(t);
+
+               // Convert stacktrace into array of StackTraceElements.
+               java_handle_objectarray_t* oa = stacktrace_get_StackTraceElements(st);
+
+               if (oa == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oas, i, (java_handle_t*) oa);
+       }
+
+       return oas;
 }
 
 
@@ -3341,12 +3387,11 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
                        return NULL;
 
                array_intarray_element_set(ia, 0, THREAD_STATE_WAITING);
-               /* XXX Implement parked stuff. */
-/*             array_intarray_element_set(ia, 1, PARKED); */
+               array_intarray_element_set(ia, 1, THREAD_STATE_PARKED);
                break; 
 
     case THREAD_STATE_TIMED_WAITING:
-               ia = builtin_newarray_int(3);
+               ia = builtin_newarray_int(2);
 
                if (ia == NULL)
                        return NULL;
@@ -3354,8 +3399,7 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
                /* XXX Not sure about that one. */
 /*             array_intarray_element_set(ia, 0, SLEEPING); */
                array_intarray_element_set(ia, 0, THREAD_STATE_TIMED_WAITING);
-               /* XXX Implement parked stuff. */
-/*             array_intarray_element_set(ia, 2, PARKED); */
+               array_intarray_element_set(ia, 1, THREAD_STATE_TIMED_PARKED);
                break; 
 
     case THREAD_STATE_TERMINATED:
@@ -3453,31 +3497,40 @@ jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArra
                        return NULL;
 
                s = javastring_new(utf_new_char("WAITING.OBJECT_WAIT"));
-/*             s = javastring_new(utf_new_char("WAITING.PARKED")); */
 
                if (s == NULL)
                        return NULL;
 
                array_objectarray_element_set(oa, 0, s);
-/*             array_objectarray_element_set(oa, 1, s); */
+
+               s = javastring_new(utf_new_char("WAITING.PARKED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 1, s);
                break; 
 
     case THREAD_STATE_TIMED_WAITING:
-               oa = builtin_anewarray(3, class_java_lang_String);
+               oa = builtin_anewarray(2, class_java_lang_String);
 
                if (oa == NULL)
                        return NULL;
 
 /*             s = javastring_new(utf_new_char("TIMED_WAITING.SLEEPING")); */
                s = javastring_new(utf_new_char("TIMED_WAITING.OBJECT_WAIT"));
-/*             s = javastring_new(utf_new_char("TIMED_WAITING.PARKED")); */
 
                if (s == NULL)
                        return NULL;
 
-/*             array_objectarray_element_set(oa, 0, s); */
                array_objectarray_element_set(oa, 0, s);
-/*             array_objectarray_element_set(oa, 2, s); */
+
+               s = javastring_new(utf_new_char("TIMED_WAITING.PARKED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 1, s);
                break; 
 
     case THREAD_STATE_TERMINATED: