This lets us enabled/disable specific VM faults from regression tests

Signed-off-by: Tomek Grabiec <tgrab...@gmail.com>
---
 Makefile                         |    3 +-
 include/vm/fault-inject.h        |   23 ++++++++++++
 regression/jato/internal/VM.java |    4 ++
 vm/class.c                       |   26 ++++++++++++++
 vm/fault-inject.c                |   69 ++++++++++++++++++++++++++++++++++++++
 vm/jato.c                        |    3 ++
 6 files changed, 127 insertions(+), 1 deletions(-)
 create mode 100644 include/vm/fault-inject.h
 create mode 100644 vm/fault-inject.c

diff --git a/Makefile b/Makefile
index 640e2dd..0273900 100644
--- a/Makefile
+++ b/Makefile
@@ -107,7 +107,8 @@ VM_OBJS = \
        vm/types.o              \
        vm/utf8.o               \
        vm/zalloc.o             \
-       vm/preload.o
+       vm/preload.o            \
+       vm/fault-inject.o
 
 LIB_OBJS = \
        lib/bitset.o            \
diff --git a/include/vm/fault-inject.h b/include/vm/fault-inject.h
new file mode 100644
index 0000000..33d58fe
--- /dev/null
+++ b/include/vm/fault-inject.h
@@ -0,0 +1,23 @@
+#ifndef JATO_VM_FAULT_INJECT_H
+#define JATO_VM_FAULT_INJECT_H
+
+#include <stdbool.h>
+
+#include "vm/natives.h"
+
+struct vm_object;
+
+enum vm_fault {
+       VM_FAULT_CLASS_INIT = 1,
+       VM_FAULT_MAX
+};
+
+bool vm_fault_enabled(enum vm_fault fault);
+struct vm_object *vm_fault_arg(enum vm_fault fault);
+
+void __vm_native native_vm_enable_fault(enum vm_fault fault,
+                                       struct vm_object *arg);
+
+void __vm_native native_vm_disable_fault(enum vm_fault fault);
+
+#endif
diff --git a/regression/jato/internal/VM.java b/regression/jato/internal/VM.java
index 14015be..18721bd 100644
--- a/regression/jato/internal/VM.java
+++ b/regression/jato/internal/VM.java
@@ -1,6 +1,10 @@
 package jato.internal;
 
 public class VM {
+  public static final int FAULT_IN_CLASS_INIT = 1;
+
   public static native void exit(int status);
   public static native void println(String line);
+  public static native void enableFault(int kind, Object arg);
+  public static native void disableFault(int kind);
 };
diff --git a/vm/class.c b/vm/class.c
index 961449d..96405db 100644
--- a/vm/class.c
+++ b/vm/class.c
@@ -37,6 +37,7 @@
 #include <vm/class.h>
 #include <vm/classloader.h>
 #include <vm/die.h>
+#include <vm/fault-inject.h>
 #include <vm/field.h>
 #include <vm/preload.h>
 #include <vm/method.h>
@@ -284,6 +285,19 @@ int vm_class_link_bogus_class(struct vm_class *vmc, const 
char *class_name)
        return 0;
 }
 
+static bool vm_class_check_class_init_fault(struct vm_class *vmc,
+                                           struct vm_object *arg)
+{
+       char * str;
+       bool fault;
+
+       str = vm_string_to_cstr(arg);
+       fault = (strcmp(str, vmc->name) == 0);
+       free(str);
+
+       return fault;
+}
+
 int vm_class_init(struct vm_class *vmc)
 {
        struct vm_object *exception;
@@ -299,6 +313,18 @@ int vm_class_init(struct vm_class *vmc)
        /* XXX: Not entirely true, but we need it to break the recursion. */
        vmc->state = VM_CLASS_INITIALIZED;
 
+       /* Fault injection, for testing purposes */
+       if (vm_fault_enabled(VM_FAULT_CLASS_INIT)) {
+               struct vm_object *arg;
+
+               arg = vm_fault_arg(VM_FAULT_CLASS_INIT);
+               if (vm_class_check_class_init_fault(vmc, arg)) {
+                       signal_new_exception(vm_java_lang_RuntimeException,
+                                            NULL);
+                       goto error;
+               }
+       }
+
        /* JVM spec, 2nd. ed., 2.17.1: "But before Terminator can be
         * initialized, its direct superclass must be initialized, as well
         * as the direct superclass of its direct superclass, and so on,
diff --git a/vm/fault-inject.c b/vm/fault-inject.c
new file mode 100644
index 0000000..87cf3e7
--- /dev/null
+++ b/vm/fault-inject.c
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2009 Tomasz Grabiec
+ *
+ * This file is released under the GPL version 2 with the following
+ * clarification and special exception:
+ *
+ *     Linking this library statically or dynamically with other modules is
+ *     making a combined work based on this library. Thus, the terms and
+ *     conditions of the GNU General Public License cover the whole
+ *     combination.
+ *
+ *     As a special exception, the copyright holders of this library give you
+ *     permission to link this library with independent modules to produce an
+ *     executable, regardless of the license terms of these independent
+ *     modules, and to copy and distribute the resulting executable under terms
+ *     of your choice, provided that you also meet, for each linked independent
+ *     module, the terms and conditions of the license of that module. An
+ *     independent module is a module which is not derived from or based on
+ *     this library. If you modify this library, you may extend this exception
+ *     to your version of the library, but you are not obligated to do so. If
+ *     you do not wish to do so, delete this exception statement from your
+ *     version.
+ *
+ * Please refer to the file LICENSE for details.
+ */
+
+#include "vm/fault-inject.h"
+#include "vm/object.h"
+
+struct vm_fault_entry {
+       bool enabled;
+       struct vm_object *arg;
+};
+
+static struct vm_fault_entry vm_fault_entries[VM_FAULT_MAX];
+
+bool vm_fault_enabled(enum vm_fault fault)
+{
+       if (fault < 0 || fault >= VM_FAULT_MAX)
+               return false;
+
+       return vm_fault_entries[fault].enabled;
+}
+
+struct vm_object *vm_fault_arg(enum vm_fault fault)
+{
+       if (fault < 0 || fault >= VM_FAULT_MAX)
+               return NULL;
+
+       return vm_fault_entries[fault].arg;
+}
+
+void __vm_native native_vm_enable_fault(enum vm_fault fault,
+                                       struct vm_object *arg)
+{
+       if (fault < 0 || fault >= VM_FAULT_MAX)
+               return;
+
+       vm_fault_entries[fault].enabled = true;
+       vm_fault_entries[fault].arg = arg;
+}
+
+void __vm_native native_vm_disable_fault(enum vm_fault fault)
+{
+       if (fault < 0 || fault >= VM_FAULT_MAX)
+               return;
+
+       vm_fault_entries[fault].enabled = false;
+}
diff --git a/vm/jato.c b/vm/jato.c
index 6595699..61ae285 100644
--- a/vm/jato.c
+++ b/vm/jato.c
@@ -42,6 +42,7 @@
 
 #include "vm/class.h"
 #include "vm/classloader.h"
+#include "vm/fault-inject.h"
 #include "vm/preload.h"
 #include "vm/method.h"
 #include "vm/natives.h"
@@ -211,6 +212,8 @@ static struct vm_native natives[] = {
        DEFINE_NATIVE("java/lang/VMSystem", "identityHashCode", 
&native_vmsystem_identityhashcode),
        DEFINE_NATIVE("java/lang/VMThrowable", "fillInStackTrace", 
&native_vmthrowable_fill_in_stack_trace),
        DEFINE_NATIVE("java/lang/VMThrowable", "getStackTrace", 
&native_vmthrowable_get_stack_trace),
+       DEFINE_NATIVE("jato/internal/VM", "enableFault", 
&native_vm_enable_fault),
+       DEFINE_NATIVE("jato/internal/VM", "disableFault", 
&native_vm_disable_fault),
 };
 
 static void jit_init_natives(void)
-- 
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