In general we should use vm_call_method() to call methods from VM. Calling
methods from VM is not only about calling native function, but we
also have to save any pending exceptions before that. Besides that, using
vm_call_method() increases maintainability.

Calling methods by getting trampoline address and calling it can
steel be used where performance is important and we are sure
that no exception can be signalled in this place.

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 arch/mmix/include/arch/call.h        |   10 +++
 arch/mmix/include/arch/stack-frame.h |    5 ++
 include/vm/preload.h                 |    1 +
 include/vm/stack-trace.h             |    1 +
 jit/exception.c                      |   13 +---
 test/jit/Makefile                    |    2 +
 test/vm/preload-stub.c               |    1 +
 test/vm/stack-trace-stub.c           |   11 +++
 vm/object.c                          |   12 +---
 vm/preload.c                         |    7 ++
 vm/stack-trace.c                     |  129 ++++++++--------------------------
 11 files changed, 75 insertions(+), 117 deletions(-)
 create mode 100644 arch/mmix/include/arch/call.h
 create mode 100644 test/vm/stack-trace-stub.c

diff --git a/arch/mmix/include/arch/call.h b/arch/mmix/include/arch/call.h
new file mode 100644
index 0000000..fb42708
--- /dev/null
+++ b/arch/mmix/include/arch/call.h
@@ -0,0 +1,10 @@
+#ifndef __MMIX_CALL_H
+#define __MMIX_CALL_H
+
+#define native_call(target, args, args_count, result)  \
+       do { result = 0; } while (0)
+
+#define vm_native_call(target, args, args_count, result)       \
+       do { result = 0; } while (0)
+
+#endif /* __MMIX_CALL_H */
diff --git a/arch/mmix/include/arch/stack-frame.h 
b/arch/mmix/include/arch/stack-frame.h
index be65acb..9d41753 100644
--- a/arch/mmix/include/arch/stack-frame.h
+++ b/arch/mmix/include/arch/stack-frame.h
@@ -4,11 +4,16 @@
 #include <stdbool.h>
 
 struct jit_stack_frame {
+       void *prev;
        unsigned long return_address;
 };
 
 struct native_stack_frame {
+       void *prev;
        unsigned long return_address;
 };
 
+#define __override_return_address(ret) ;
+#define __cleanup_args(argssize) ;
+
 #endif /* MMIX_STACK_FRAME_H */
diff --git a/include/vm/preload.h b/include/vm/preload.h
index f480408..233c0e6 100644
--- a/include/vm/preload.h
+++ b/include/vm/preload.h
@@ -46,6 +46,7 @@ extern struct vm_method *vm_java_lang_Throwable_getCause;
 extern struct vm_method *vm_java_lang_Throwable_toString;
 extern struct vm_method *vm_java_lang_Throwable_getStackTrace;
 extern struct vm_method *vm_java_lang_Throwable_setStackTrace;
+extern struct vm_method *vm_java_lang_StackTraceElement_init;
 extern struct vm_method *vm_java_lang_StackTraceElement_getFileName;
 extern struct vm_method *vm_java_lang_StackTraceElement_getClassName;
 extern struct vm_method *vm_java_lang_StackTraceElement_getMethodName;
diff --git a/include/vm/stack-trace.h b/include/vm/stack-trace.h
index f326c41..8bc4b8e 100644
--- a/include/vm/stack-trace.h
+++ b/include/vm/stack-trace.h
@@ -8,6 +8,7 @@
 #include "vm/vm.h"
 
 #include <stdbool.h>
+#include <stdlib.h>
 
 struct compilation_unit;
 struct vm_method;
diff --git a/jit/exception.c b/jit/exception.c
index d8eeed5..16b1c5a 100644
--- a/jit/exception.c
+++ b/jit/exception.c
@@ -34,6 +34,8 @@
 #include "jit/compiler.h"
 
 #include "lib/buffer.h"
+
+#include "vm/call.h"
 #include "vm/class.h"
 #include "vm/die.h"
 #include "vm/guard-page.h"
@@ -112,19 +114,12 @@ int signal_new_exception_with_cause(struct vm_class *vmc,
                                    struct vm_object *cause,
                                    const char *msg)
 {
-       struct vm_object *exception;
-       vm_throwable_init_cause_fn init_cause;
-
-       init_cause = vm_method_trampoline_ptr(vm_java_lang_Throwable_initCause);
+       struct vm_object *exception = new_exception(vmc, msg);
 
-       exception = new_exception(vmc, msg);
        if (!exception)
                return -1;
 
-       init_cause(exception, cause);
-       if (exception_occurred())
-               return -1;
-
+       vm_call_method(vm_java_lang_Throwable_initCause, exception, cause);
        signal_exception(exception);
        return 0;
 }
diff --git a/test/jit/Makefile b/test/jit/Makefile
index 21ca733..75055d7 100644
--- a/test/jit/Makefile
+++ b/test/jit/Makefile
@@ -48,6 +48,7 @@ TOPLEVEL_OBJS := \
        lib/list.o \
        lib/radix-tree.o \
        lib/string.o \
+       vm/call.o \
        vm/bytecode.o \
        vm/bytecodes.o \
        vm/die.o \
@@ -65,6 +66,7 @@ TOPLEVEL_OBJS := \
        test/vm/object-stub.o \
        test/vm/preload-stub.o \
        test/vm/jni-stub.o \
+       test/vm/stack-trace-stub.o \
        test/jit/trace-stub.o
 
 TEST_OBJS := \
diff --git a/test/vm/preload-stub.c b/test/vm/preload-stub.c
index 0fb7714..25c5b2b 100644
--- a/test/vm/preload-stub.c
+++ b/test/vm/preload-stub.c
@@ -37,6 +37,7 @@ struct vm_method *vm_java_lang_Throwable_getCause;
 struct vm_method *vm_java_lang_Throwable_toString;
 struct vm_method *vm_java_lang_Throwable_getStackTrace;
 struct vm_method *vm_java_lang_Throwable_setStackTrace;
+struct vm_method *vm_java_lang_StackTraceElement_init;
 struct vm_method *vm_java_lang_StackTraceElement_getFileName;
 struct vm_method *vm_java_lang_StackTraceElement_getClassName;
 struct vm_method *vm_java_lang_StackTraceElement_getMethodName;
diff --git a/test/vm/stack-trace-stub.c b/test/vm/stack-trace-stub.c
new file mode 100644
index 0000000..4159d4a
--- /dev/null
+++ b/test/vm/stack-trace-stub.c
@@ -0,0 +1,11 @@
+#include "vm/stack-trace.h"
+
+int vm_enter_jni(void *caller_frame, unsigned long call_site_addr,
+                struct vm_method *method)
+{
+       return 0;
+}
+
+void vm_leave_jni(void)
+{
+}
diff --git a/vm/object.c b/vm/object.c
index fa90147..8005f31 100644
--- a/vm/object.c
+++ b/vm/object.c
@@ -7,6 +7,7 @@
 
 #include "jit/exception.h"
 
+#include "vm/call.h"
 #include "vm/class.h"
 #include "vm/classloader.h"
 #include "vm/die.h"
@@ -332,7 +333,6 @@ typedef void (*exception_init_fn)(struct vm_object *, 
struct vm_object *);
 struct vm_object *new_exception(struct vm_class *vmc, const char *message)
 {
        struct vm_object *message_str;
-       exception_init_fn init;
        struct vm_method *mb;
        struct vm_object *obj;
 
@@ -352,17 +352,11 @@ struct vm_object *new_exception(struct vm_class *vmc, 
const char *message)
                }
        }
 
-       mb = vm_class_get_method(vmc,
-               "<init>", "(Ljava/lang/String;)V");
+       mb = vm_class_get_method(vmc, "<init>", "(Ljava/lang/String;)V");
        if (!mb)
                error("constructor not found");
 
-       init = vm_method_call_ptr(mb);
-       init(obj, message_str);
-
-       if (exception_occurred())
-               return NULL;
-
+       vm_call_method(mb, obj, message_str);
        return obj;
 }
 
diff --git a/vm/preload.c b/vm/preload.c
index 5b767e0..4bfb9df 100644
--- a/vm/preload.c
+++ b/vm/preload.c
@@ -142,6 +142,7 @@ struct vm_method *vm_java_lang_Throwable_getCause;
 struct vm_method *vm_java_lang_Throwable_toString;
 struct vm_method *vm_java_lang_Throwable_getStackTrace;
 struct vm_method *vm_java_lang_Throwable_setStackTrace;
+struct vm_method *vm_java_lang_StackTraceElement_init;
 struct vm_method *vm_java_lang_StackTraceElement_getFileName;
 struct vm_method *vm_java_lang_StackTraceElement_getClassName;
 struct vm_method *vm_java_lang_StackTraceElement_getMethodName;
@@ -222,6 +223,12 @@ static const struct method_preload_entry 
method_preload_entries[] = {
                "(Ljava/lang/Object;)Z",
                &vm_java_lang_StackTraceElement_equals,
        },
+       {
+               &vm_java_lang_StackTraceElement,
+               "<init>",
+               "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Z)V",
+               &vm_java_lang_StackTraceElement_init,
+       },
 };
 
 int preload_vm_classes(void)
diff --git a/vm/stack-trace.c b/vm/stack-trace.c
index 76f4a50..45f625b 100644
--- a/vm/stack-trace.c
+++ b/vm/stack-trace.c
@@ -57,21 +57,8 @@ __thread unsigned long vm_native_stack_offset;
 
 __thread struct native_stack_frame *bottom_stack_frame;
 
-typedef void (*ste_init_fn)(struct vm_object *, struct vm_object *, int,
-                           struct vm_object *, struct vm_object *, int);
-typedef struct vm_object *(*throwable_tostring_fn)(struct vm_object *);
-typedef struct vm_object *(*throwable_stacktracestring_fn)(struct vm_object *);
-
-static ste_init_fn ste_init;
-static throwable_tostring_fn throwable_tostring;
-static throwable_stacktracestring_fn throwable_stacktracestring;
-
 void init_stack_trace_printing(void)
 {
-       struct vm_method *ste_init_mb;
-       struct vm_method *throwable_tostring_mb;
-       struct vm_method *throwable_stacktracestring_mb;
-
        vm_native_stack_offset = 0;
        jni_stack_offset = 0;
 
@@ -87,30 +74,6 @@ void init_stack_trace_printing(void)
        valid_size = JNI_STACK_SIZE * sizeof(struct jni_stack_entry);
        jni_stack_offset_guard = alloc_offset_guard(valid_size, 1);
        jni_stack_badoffset = valid_size + jni_stack_offset_guard;
-
-       /* Preload methods */
-       ste_init_mb = vm_class_get_method_recursive(
-               vm_java_lang_StackTraceElement,
-               "<init>",
-               "(Ljava/lang/String;ILjava/lang/String;Ljava/lang/String;Z)V");
-
-       throwable_tostring_mb =
-               vm_class_get_method_recursive(vm_java_lang_Throwable,
-                       "toString", "()Ljava/lang/String;");
-
-       throwable_stacktracestring_mb =
-               vm_class_get_method_recursive(vm_java_lang_Throwable,
-                       "stackTraceString", "()Ljava/lang/String;");
-
-       ste_init = vm_method_call_ptr(ste_init_mb);
-       throwable_tostring = vm_method_call_ptr(throwable_tostring_mb);
-       throwable_stacktracestring =
-               vm_method_call_ptr(throwable_stacktracestring_mb);
-
-       if (!ste_init_mb ||
-           !throwable_tostring ||
-           !throwable_stacktracestring)
-               error("initialization failed");
 }
 
 static bool jni_stack_is_full(void)
@@ -478,7 +441,8 @@ new_stack_trace_element(struct vm_method *mb, unsigned long 
bc_offset)
        if(!ste)
                return NULL;
 
-       ste_init(ste, file_name, line_no, class_name, method_name, is_native);
+       vm_call_method(vm_java_lang_StackTraceElement_init, ste, file_name,
+                      line_no, class_name, method_name, is_native);
 
        return ste;
 }
@@ -577,33 +541,13 @@ native_vmthrowable_get_stack_trace(struct vm_object *this,
        return result;
 }
 
-typedef struct vm_object *(*vm_java_lang_Throwable_toString_fn)
-       (struct vm_object *);
-typedef struct vm_object *(*vm_java_lang_Throwable_getCause_fn)
-       (struct vm_object *);
-typedef struct vm_object *(*vm_java_lang_Throwable_getStackTrace_fn)
-       (struct vm_object *);
-typedef struct vm_object *(*vm_java_lang_StackTraceElement_getFileName_fn)
-       (struct vm_object *);
-typedef struct vm_object *(*vm_java_lang_StackTraceElement_getClassName_fn)
-       (struct vm_object *);
-typedef struct vm_object *(*vm_java_lang_StackTraceElement_getMethodName_fn)
-       (struct vm_object *);
-typedef int (*vm_java_lang_StackTraceElement_getLineNumber_fn)
-       (struct vm_object *);
-typedef bool (*vm_java_lang_StackTraceElement_isNativeMethod_fn)
-       (struct vm_object *);
-typedef bool (*vm_java_lang_StackTraceElement_equals_fn)
-       (struct vm_object *, struct vm_object *);
-
 static void
 vm_throwable_to_string(struct vm_object *this, struct string *str)
 {
-       vm_java_lang_Throwable_toString_fn toString =
-               vm_method_call_ptr(vm_java_lang_Throwable_toString);
        struct vm_object *string_obj;
 
-       string_obj = toString(this);
+       string_obj = vm_call_method_object(vm_java_lang_Throwable_toString,
+                                          this);
        if (!string_obj)
                return;
 
@@ -615,36 +559,25 @@ vm_throwable_to_string(struct vm_object *this, struct 
string *str)
 static void vm_stack_trace_element_to_string(struct vm_object *elem,
                                             struct string *str)
 {
-       vm_java_lang_StackTraceElement_getFileName_fn getFileName;
-       vm_java_lang_StackTraceElement_getClassName_fn getClassName;
-       vm_java_lang_StackTraceElement_getMethodName_fn getMethodName;
-       vm_java_lang_StackTraceElement_getLineNumber_fn getLineNumber;
-       vm_java_lang_StackTraceElement_isNativeMethod_fn isNativeMethod;
        struct vm_object *method_name;
        struct vm_object *file_name;
        struct vm_object *class_name;
        char *method_name_str;
        char *file_name_str;
        char *class_name_str;
-       int line_number;
-       bool is_native;
-
-       getMethodName = vm_method_call_ptr(
-               vm_java_lang_StackTraceElement_getMethodName);
-       getFileName = vm_method_call_ptr(
-               vm_java_lang_StackTraceElement_getFileName);
-       getClassName = vm_method_call_ptr(
-               vm_java_lang_StackTraceElement_getClassName);
-       getLineNumber = vm_method_call_ptr(
-               vm_java_lang_StackTraceElement_getLineNumber);
-       isNativeMethod = vm_method_call_ptr(
-               vm_java_lang_StackTraceElement_isNativeMethod);
-
-       file_name = getFileName(elem);
-       line_number = getLineNumber(elem);
-       class_name = getClassName(elem);
-       method_name = getMethodName(elem);
-       is_native = isNativeMethod(elem);
+       jint line_number;
+       jboolean is_native;
+
+       file_name = vm_call_method_object(
+                       vm_java_lang_StackTraceElement_getFileName, elem);
+       line_number = vm_call_method_jint(
+                       vm_java_lang_StackTraceElement_getLineNumber, elem);
+       class_name = vm_call_method_object(
+                       vm_java_lang_StackTraceElement_getClassName, elem);
+       method_name = vm_call_method_object(
+                       vm_java_lang_StackTraceElement_getMethodName, elem);
+       is_native = vm_call_method_jboolean(
+                       vm_java_lang_StackTraceElement_isNativeMethod, elem);
 
        if (class_name) {
                class_name_str = vm_string_to_cstr(class_name);
@@ -709,29 +642,25 @@ vm_throwable_stack_trace(struct vm_object *this, struct 
string *str,
 static void
 vm_throwable_print_stack_trace(struct vm_object *this, struct string *str)
 {
-       vm_java_lang_Throwable_getCause_fn getCause;
-       vm_java_lang_Throwable_getStackTrace_fn getStackTrace;
-       vm_java_lang_StackTraceElement_equals_fn ste_equals;
        struct vm_object *stack;
+       struct vm_object *cause;
 
-       getCause =
-               vm_method_call_ptr(vm_java_lang_Throwable_getCause);
-       getStackTrace =
-               vm_method_call_ptr(vm_java_lang_Throwable_getStackTrace);
-       ste_equals =
-               vm_method_call_ptr(vm_java_lang_StackTraceElement_equals);
+       stack = vm_call_method_object(
+                               vm_java_lang_Throwable_getStackTrace, this);
 
-       stack = getStackTrace(this);
        vm_throwable_stack_trace(this, str, stack, 0);
 
-       struct vm_object *cause = this;
-       while ((cause = getCause(cause))) {
+       cause = this;
+       while ((cause = vm_call_method_object(vm_java_lang_Throwable_getCause,
+                                             cause)))
+       {
                struct vm_object *p_stack;
 
                str_append(str, "Caused by: ");
 
                p_stack = stack;
-               stack = getStackTrace(cause);
+               stack = vm_call_method_object(
+                               vm_java_lang_Throwable_getStackTrace, cause);
 
                if (p_stack == NULL || p_stack->array_length == 0) {
                        vm_throwable_stack_trace(cause, str, stack, 0);
@@ -743,8 +672,10 @@ vm_throwable_print_stack_trace(struct vm_object *this, 
struct string *str)
                int p_frame = p_stack->array_length - 1;
 
                while (frame > 0 && p_frame > 0) {
-                       if (!ste_equals(array_get_field_ptr(stack, frame),
-                                       array_get_field_ptr(p_stack, p_frame)))
+                       if (!vm_call_method_jboolean(
+                               vm_java_lang_StackTraceElement_equals,
+                               array_get_field_ptr(stack, frame),
+                               array_get_field_ptr(p_stack, p_frame)))
                                break;
 
                        equal++;
-- 
1.6.0.6


------------------------------------------------------------------------------
_______________________________________________
Jatovm-devel mailing list
Jatovm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/jatovm-devel

Reply via email to