Merged to new default.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Sat, 18 Oct 2008 12:46:51 +0000 (14:46 +0200)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Sat, 18 Oct 2008 12:46:51 +0000 (14:46 +0200)
--HG--
branch : subtype-trunk
rename : src/vm/linker.c => src/vm/linker.cpp
rename : src/vm/linker.h => src/vm/linker.hpp

44 files changed:
configure.ac
src/mm/cacao-gc/mark.c
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp
src/native/vm/gnuclasspath/java_lang_reflect_VMField.cpp
src/native/vm/gnuclasspath/java_lang_reflect_VMMethod.cpp
src/native/vm/reflection.cpp
src/vm/Makefile.am
src/vm/access.c [deleted file]
src/vm/access.cpp [new file with mode: 0644]
src/vm/access.h [deleted file]
src/vm/access.hpp [new file with mode: 0644]
src/vm/class.cpp
src/vm/class.hpp
src/vm/classcache.cpp
src/vm/classcache.hpp
src/vm/javaobjects.cpp
src/vm/jit/builtin.cpp
src/vm/jit/inline/inline.cpp
src/vm/jit/inline/inline.hpp
src/vm/jit/intrp/asmpart.c
src/vm/jit/intrp/disass.cpp
src/vm/jit/intrp/intrp.h
src/vm/jit/parse.cpp
src/vm/jit/verify/icmds.cpp
src/vm/jit/verify/typecheck-common.cpp
src/vm/jit/verify/typecheck-common.hpp
src/vm/jit/verify/typecheck-stackbased.cpp
src/vm/jit/verify/typecheck-typeinferer.cpp
src/vm/jit/verify/typecheck-typeinferer.hpp
src/vm/jit/verify/typecheck.cpp
src/vm/jit/verify/typecheck.hpp
src/vm/jit/verify/typeinfo.cpp
src/vm/jit/verify/typeinfo.hpp
src/vm/linker.c [deleted file]
src/vm/linker.cpp [new file with mode: 0644]
src/vm/linker.h [deleted file]
src/vm/linker.hpp [new file with mode: 0644]
src/vm/loader.cpp
src/vm/method.cpp
src/vm/method.hpp
src/vm/primitive.hpp
src/vm/resolve.cpp
src/vm/zip.cpp
src/vm/zip.hpp

index 22572676c463fc6dd4acf765fb6bdd7652567397..9312ab4e99ee8d68aba26d7d9d9e85bcd8e1dda0 100644 (file)
@@ -384,8 +384,6 @@ AC_CHECK_FUNCS([strlen])
 AC_CHECK_FUNCS([strncmp])
 AC_CHECK_FUNCS([strstr])
 AC_CHECK_FUNCS([time])
-AC_CHECK_FUNCS([va_end])
-AC_CHECK_FUNCS([va_start])
 AC_CHECK_FUNCS([write])
 
 
index 1a64e8626f3433442a55641478c35c2e6828b3c3..fedfb9abb750990dd7b339b972510ad343280603 100644 (file)
@@ -34,7 +34,7 @@
 #include "toolbox/logging.h"
 
 #include "vm/global.h"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/vm.hpp"
 
 
index 41bfe177945a698c4a16fd78f0d1020f5ad244fc..7e2c0b8359a2536f3a634e57d743ba1f983c16d0 100644 (file)
@@ -53,7 +53,7 @@
 #include "vm/globals.hpp"
 #include "vm/initialize.hpp"
 #include "vm/javaobjects.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
index 4d2edb56b0bd4048f68e627f0d289b02612d8800..c39f05866aefa52573980a0917b8e11c6de2c1ee 100644 (file)
@@ -41,7 +41,7 @@
 # include "native/vm/reflection.hpp"
 #endif
 
-#include "vm/access.h"
+#include "vm/access.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
index 7d345caa655a4173d9f7ae04df31418159c8d718..e4cbf89a2e4cb5049fa8a01ec32cbdd717885e57 100644 (file)
@@ -41,7 +41,7 @@
 
 #include "native/vm/reflection.hpp"
 
-#include "vm/access.h"
+#include "vm/access.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/class.hpp"
 #include "vm/exceptions.hpp"
index a26a50c4a300044e39992c83eef1c6b5a9bee74a..73a8545b8afef1b164d7e7987378f5782e0b7db4 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "native/vm/reflection.hpp"
 
-#include "vm/access.h"
+#include "vm/access.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
index 829fed607d0331a7b25074685fc27001f03cb8b7..4dd35b7777dffcaf8468de71eaf49b9965f24311 100644 (file)
@@ -77,8 +77,8 @@ noinst_LTLIBRARIES = \
        libvm.la
 
 libvm_la_SOURCES = \
-       access.c \
-       access.h \
+       access.cpp \
+       access.hpp \
        $(ANNOTATION_SOURCES) \
        array.cpp \
        array.hpp \
@@ -102,8 +102,8 @@ libvm_la_SOURCES = \
        initialize.hpp \
        javaobjects.cpp \
        javaobjects.hpp \
-       linker.c \
-       linker.h \
+       linker.cpp \
+       linker.hpp \
        loader.cpp \
        loader.hpp \
        method.cpp \
diff --git a/src/vm/access.c b/src/vm/access.c
deleted file mode 100644 (file)
index 218cff6..0000000
+++ /dev/null
@@ -1,356 +0,0 @@
-/* src/vm/access.c - checking access rights
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   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., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/llni.h"
-
-#include "vm/access.h"
-#include "vm/jit/builtin.hpp"
-#include "vm/class.hpp"
-#include "vm/exceptions.hpp"
-#include "vm/field.hpp"
-#include "vm/globals.hpp"
-#include "vm/method.hpp"
-
-#include "vm/jit/stacktrace.hpp"
-
-
-/* access_is_accessible_class **************************************************
-   Check if a class is accessible from another class
-  
-   IN:
-       referer..........the class containing the reference
-       cls..............the result of resolving the reference
-  
-   RETURN VALUE:
-       true.............access permitted
-       false............access denied
-   
-   NOTE:
-       This function performs the checks listed in section 5.4.4.
-          "Access Control" of "The Java(TM) Virtual Machine Specification,
-          Second Edition".
-
-*******************************************************************************/
-
-bool access_is_accessible_class(classinfo *referer, classinfo *cls)
-{
-       assert(referer);
-       assert(cls);
-
-       /* Public classes are always accessible. */
-
-       if (cls->flags & ACC_PUBLIC)
-               return true;
-
-       /* A class in the same package is always accessible. */
-
-       if (SAME_PACKAGE(referer, cls))
-               return true;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       /* Code for Sun's OpenJDK (see
-          hotspot/src/share/vm/runtime/reflection.cpp
-          (Reflection::verify_class_access)): Allow all accesses from
-          sun/reflect/MagicAccessorImpl subclasses to succeed
-          trivially. */
-
-       /* NOTE: This check must be before checks that could return
-          false. */
-
-       if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
-               return true;
-#endif
-
-       /* A non-public class in another package is not accessible. */
-
-       return false;
-}
-
-
-/* access_is_accessible_member *************************************************
-   Check if a field or method is accessible from a given class
-  
-   IN:
-       referer..........the class containing the reference
-       declarer.........the class declaring the member
-       memberflags......the access flags of the member
-  
-   RETURN VALUE:
-       true.............access permitted
-       false............access denied
-
-   NOTE:
-       This function only performs the checks listed in section 5.4.4.
-          "Access Control" of "The Java(TM) Virtual Machine Specification,
-          Second Edition".
-
-          In particular a special condition for protected access with is
-          part of the verification process according to the spec is not
-          checked in this function.
-   
-*******************************************************************************/
-
-bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
-                                                                s4 memberflags)
-{
-       assert(referer);
-       assert(declarer);
-
-       /* Public members are accessible. */
-
-       if (memberflags & ACC_PUBLIC)
-               return true;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       /* Code for Sun's OpenJDK (see
-          hotspot/src/share/vm/runtime/reflection.cpp
-          (Reflection::verify_class_access)): Allow all accesses from
-          sun/reflect/MagicAccessorImpl subclasses to succeed
-          trivially. */
-
-       /* NOTE: This check must be before checks that could return
-          false. */
-
-       if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
-               return true;
-#endif
-
-       /* {declarer is not an interface} */
-
-       /* private members are only accessible by the class itself */
-
-       if (memberflags & ACC_PRIVATE)
-               return (referer == declarer);
-
-       /* {the member is protected or package private} */
-
-       /* protected and package private members are accessible in the
-          same package */
-
-       if (SAME_PACKAGE(referer, declarer))
-               return true;
-
-       /* package private members are not accessible outside the package */
-
-       if (!(memberflags & ACC_PROTECTED))
-               return false;
-
-       /* {the member is protected and declarer is in another package} */
-
-       /* a necessary condition for access is that referer is a subclass
-          of declarer */
-
-       assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
-
-       if (class_isanysubclass(referer, declarer))
-               return true;
-
-       return false;
-}
-
-
-/* access_check_field **********************************************************
-   Check if the (indirect) caller has access rights to the specified
-   field.
-  
-   IN:
-       f................the field to check
-          callerdepth......number of callers to ignore
-                           For example if the stacktrace looks like this:
-
-                                  [0] java.lang.reflect.Method.invokeNative (Native Method)
-                                  [1] java.lang.reflect.Method.invoke
-                                  [2] <caller>
-
-                                       you must specify 2 so the access rights of <caller> 
-                                               are checked.
-  
-   RETURN VALUE:
-       true.............access permitted
-       false............access denied, an exception has been thrown
-   
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-bool access_check_field(fieldinfo *f, int callerdepth)
-{
-       classinfo *callerclass;
-       char      *msg;
-       int        msglen;
-       utf       *u;
-
-       /* If everything is public, there is nothing to check. */
-
-       if ((f->clazz->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
-               return true;
-
-       /* Get the caller's class. */
-
-       callerclass = stacktrace_get_caller_class(callerdepth);
-
-       if (callerclass == NULL)
-               return false;
-
-       /* Check access rights. */
-
-       if (!access_is_accessible_member(callerclass, f->clazz, f->flags)) {
-               msglen =
-                       utf_bytes(f->clazz->name) +
-                       strlen(".") +
-                       utf_bytes(f->name) +
-                       strlen(" not accessible from ") +
-                       utf_bytes(callerclass->name) +
-                       strlen("0");
-
-               msg = MNEW(char, msglen);
-
-               utf_copy_classname(msg, f->clazz->name);
-               strcat(msg, ".");
-               utf_cat_classname(msg, f->name);
-               strcat(msg, " not accessible from ");
-               utf_cat_classname(msg, callerclass->name);
-
-               u = utf_new_char(msg);
-
-               MFREE(msg, char, msglen);
-               
-               exceptions_throw_illegalaccessexception(u);
-
-               return false;
-       }
-
-       /* access granted */
-
-       return true;
-}
-#endif
-
-
-/* access_check_method *********************************************************
-   Check if the (indirect) caller has access rights to the specified
-   method.
-  
-   IN:
-       m................the method to check
-          callerdepth......number of callers to ignore
-                           For example if the stacktrace looks like this:
-
-                                  [1] java.lang.reflect.Method.invokeNative (Native Method)
-                                  [1] java.lang.reflect.Method.invoke
-                                  [2] <caller>
-
-                                       you must specify 2 so the access rights of <caller> 
-                                               are checked.
-  
-   RETURN VALUE:
-       true.............access permitted
-       false............access denied, an exception has been thrown
-   
-*******************************************************************************/
-
-#if defined(ENABLE_JAVASE)
-bool access_check_method(methodinfo *m, int callerdepth)
-{
-       classinfo *callerclass;
-       char      *msg;
-       int        msglen;
-       utf       *u;
-
-       /* If everything is public, there is nothing to check. */
-
-       if ((m->clazz->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
-               return true;
-
-       /* Get the caller's class. */
-
-       callerclass = stacktrace_get_caller_class(callerdepth);
-
-       if (callerclass == NULL)
-               return false;
-
-       /* Check access rights. */
-
-       if (!access_is_accessible_member(callerclass, m->clazz, m->flags)) {
-               msglen =
-                       utf_bytes(m->clazz->name) +
-                       strlen(".") +
-                       utf_bytes(m->name) +
-                       utf_bytes(m->descriptor) +
-                       strlen(" not accessible from ") +
-                       utf_bytes(callerclass->name) +
-                       strlen("0");
-
-               msg = MNEW(char, msglen);
-
-               utf_copy_classname(msg, m->clazz->name);
-               strcat(msg, ".");
-               utf_cat_classname(msg, m->name);
-               utf_cat_classname(msg, m->descriptor);
-               strcat(msg, " not accessible from ");
-               utf_cat_classname(msg, callerclass->name);
-
-               u = utf_new_char(msg);
-
-               MFREE(msg, char, msglen);
-               
-               exceptions_throw_illegalaccessexception(u);
-
-               return false;
-       }
-
-       /* access granted */
-
-       return true;
-}
-#endif
-
-
-/*
- * 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:
- */
-
diff --git a/src/vm/access.cpp b/src/vm/access.cpp
new file mode 100644 (file)
index 0000000..a0abbc1
--- /dev/null
@@ -0,0 +1,364 @@
+/* src/vm/access.c - checking access rights
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/llni.h"
+
+#include "vm/access.hpp"
+#include "vm/jit/builtin.hpp"
+#include "vm/class.hpp"
+#include "vm/exceptions.hpp"
+#include "vm/field.hpp"
+#include "vm/globals.hpp"
+#include "vm/method.hpp"
+
+#include "vm/jit/stacktrace.hpp"
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* access_is_accessible_class **************************************************
+   Check if a class is accessible from another class
+  
+   IN:
+       referer..........the class containing the reference
+       cls..............the result of resolving the reference
+  
+   RETURN VALUE:
+       true.............access permitted
+       false............access denied
+   
+   NOTE:
+       This function performs the checks listed in section 5.4.4.
+          "Access Control" of "The Java(TM) Virtual Machine Specification,
+          Second Edition".
+
+*******************************************************************************/
+
+bool access_is_accessible_class(classinfo *referer, classinfo *cls)
+{
+       assert(referer);
+       assert(cls);
+
+       /* Public classes are always accessible. */
+
+       if (cls->flags & ACC_PUBLIC)
+               return true;
+
+       /* A class in the same package is always accessible. */
+
+       if (SAME_PACKAGE(referer, cls))
+               return true;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       /* Code for Sun's OpenJDK (see
+          hotspot/src/share/vm/runtime/reflection.cpp
+          (Reflection::verify_class_access)): Allow all accesses from
+          sun/reflect/MagicAccessorImpl subclasses to succeed
+          trivially. */
+
+       /* NOTE: This check must be before checks that could return
+          false. */
+
+       if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
+               return true;
+#endif
+
+       /* A non-public class in another package is not accessible. */
+
+       return false;
+}
+
+
+/* access_is_accessible_member *************************************************
+   Check if a field or method is accessible from a given class
+  
+   IN:
+       referer..........the class containing the reference
+       declarer.........the class declaring the member
+       memberflags......the access flags of the member
+  
+   RETURN VALUE:
+       true.............access permitted
+       false............access denied
+
+   NOTE:
+       This function only performs the checks listed in section 5.4.4.
+          "Access Control" of "The Java(TM) Virtual Machine Specification,
+          Second Edition".
+
+          In particular a special condition for protected access with is
+          part of the verification process according to the spec is not
+          checked in this function.
+   
+*******************************************************************************/
+
+bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
+                                                                s4 memberflags)
+{
+       assert(referer);
+       assert(declarer);
+
+       /* Public members are accessible. */
+
+       if (memberflags & ACC_PUBLIC)
+               return true;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       /* Code for Sun's OpenJDK (see
+          hotspot/src/share/vm/runtime/reflection.cpp
+          (Reflection::verify_class_access)): Allow all accesses from
+          sun/reflect/MagicAccessorImpl subclasses to succeed
+          trivially. */
+
+       /* NOTE: This check must be before checks that could return
+          false. */
+
+       if (class_issubclass(referer, class_sun_reflect_MagicAccessorImpl))
+               return true;
+#endif
+
+       /* {declarer is not an interface} */
+
+       /* private members are only accessible by the class itself */
+
+       if (memberflags & ACC_PRIVATE)
+               return (referer == declarer);
+
+       /* {the member is protected or package private} */
+
+       /* protected and package private members are accessible in the
+          same package */
+
+       if (SAME_PACKAGE(referer, declarer))
+               return true;
+
+       /* package private members are not accessible outside the package */
+
+       if (!(memberflags & ACC_PROTECTED))
+               return false;
+
+       /* {the member is protected and declarer is in another package} */
+
+       /* a necessary condition for access is that referer is a subclass
+          of declarer */
+
+       assert((referer->state & CLASS_LINKED) && (declarer->state & CLASS_LINKED));
+
+       if (class_isanysubclass(referer, declarer))
+               return true;
+
+       return false;
+}
+
+
+/* access_check_field **********************************************************
+   Check if the (indirect) caller has access rights to the specified
+   field.
+  
+   IN:
+       f................the field to check
+          callerdepth......number of callers to ignore
+                           For example if the stacktrace looks like this:
+
+                                  [0] java.lang.reflect.Method.invokeNative (Native Method)
+                                  [1] java.lang.reflect.Method.invoke
+                                  [2] <caller>
+
+                                       you must specify 2 so the access rights of <caller> 
+                                               are checked.
+  
+   RETURN VALUE:
+       true.............access permitted
+       false............access denied, an exception has been thrown
+   
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+bool access_check_field(fieldinfo *f, int callerdepth)
+{
+       classinfo *callerclass;
+       char      *msg;
+       int        msglen;
+       utf       *u;
+
+       /* If everything is public, there is nothing to check. */
+
+       if ((f->clazz->flags & ACC_PUBLIC) && (f->flags & ACC_PUBLIC))
+               return true;
+
+       /* Get the caller's class. */
+
+       callerclass = stacktrace_get_caller_class(callerdepth);
+
+       if (callerclass == NULL)
+               return false;
+
+       /* Check access rights. */
+
+       if (!access_is_accessible_member(callerclass, f->clazz, f->flags)) {
+               msglen =
+                       utf_bytes(f->clazz->name) +
+                       strlen(".") +
+                       utf_bytes(f->name) +
+                       strlen(" not accessible from ") +
+                       utf_bytes(callerclass->name) +
+                       strlen("0");
+
+               msg = MNEW(char, msglen);
+
+               utf_copy_classname(msg, f->clazz->name);
+               strcat(msg, ".");
+               utf_cat_classname(msg, f->name);
+               strcat(msg, " not accessible from ");
+               utf_cat_classname(msg, callerclass->name);
+
+               u = utf_new_char(msg);
+
+               MFREE(msg, char, msglen);
+               
+               exceptions_throw_illegalaccessexception(u);
+
+               return false;
+       }
+
+       /* access granted */
+
+       return true;
+}
+#endif
+
+
+/* access_check_method *********************************************************
+   Check if the (indirect) caller has access rights to the specified
+   method.
+  
+   IN:
+       m................the method to check
+          callerdepth......number of callers to ignore
+                           For example if the stacktrace looks like this:
+
+                                  [1] java.lang.reflect.Method.invokeNative (Native Method)
+                                  [1] java.lang.reflect.Method.invoke
+                                  [2] <caller>
+
+                                       you must specify 2 so the access rights of <caller> 
+                                               are checked.
+  
+   RETURN VALUE:
+       true.............access permitted
+       false............access denied, an exception has been thrown
+   
+*******************************************************************************/
+
+#if defined(ENABLE_JAVASE)
+bool access_check_method(methodinfo *m, int callerdepth)
+{
+       classinfo *callerclass;
+       char      *msg;
+       int        msglen;
+       utf       *u;
+
+       /* If everything is public, there is nothing to check. */
+
+       if ((m->clazz->flags & ACC_PUBLIC) && (m->flags & ACC_PUBLIC))
+               return true;
+
+       /* Get the caller's class. */
+
+       callerclass = stacktrace_get_caller_class(callerdepth);
+
+       if (callerclass == NULL)
+               return false;
+
+       /* Check access rights. */
+
+       if (!access_is_accessible_member(callerclass, m->clazz, m->flags)) {
+               msglen =
+                       utf_bytes(m->clazz->name) +
+                       strlen(".") +
+                       utf_bytes(m->name) +
+                       utf_bytes(m->descriptor) +
+                       strlen(" not accessible from ") +
+                       utf_bytes(callerclass->name) +
+                       strlen("0");
+
+               msg = MNEW(char, msglen);
+
+               utf_copy_classname(msg, m->clazz->name);
+               strcat(msg, ".");
+               utf_cat_classname(msg, m->name);
+               utf_cat_classname(msg, m->descriptor);
+               strcat(msg, " not accessible from ");
+               utf_cat_classname(msg, callerclass->name);
+
+               u = utf_new_char(msg);
+
+               MFREE(msg, char, msglen);
+               
+               exceptions_throw_illegalaccessexception(u);
+
+               return false;
+       }
+
+       /* access granted */
+
+       return true;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+
+
+/*
+ * 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:
+ */
+
diff --git a/src/vm/access.h b/src/vm/access.h
deleted file mode 100644 (file)
index d1a51f8..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/* src/vm/access.h - checking access rights
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   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., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _ACCESS_H
-#define _ACCESS_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vm/class.hpp"
-#include "vm/field.hpp"
-#include "vm/global.h"
-#include "vm/method.hpp"
-
-
-/* macros *********************************************************************/
-
-#define SAME_PACKAGE(a,b)                                  \
-                       ((a)->classloader == (b)->classloader &&       \
-                        (a)->packagename == (b)->packagename)
-
-
-/* function prototypes ********************************************************/
-
-bool access_is_accessible_class(classinfo *referer, classinfo *cls);
-
-bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
-                                                                int32_t memberflags);
-
-#if defined(ENABLE_JAVASE)
-bool access_check_field(fieldinfo *f, int callerdepth);
-bool access_check_method(methodinfo *m, int callerdepth);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ACCESS_H */
-
-
-/*
- * 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:
- */
-
diff --git a/src/vm/access.hpp b/src/vm/access.hpp
new file mode 100644 (file)
index 0000000..9ec44c9
--- /dev/null
@@ -0,0 +1,82 @@
+/* src/vm/access.h - checking access rights
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _ACCESS_H
+#define _ACCESS_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/class.hpp"
+#include "vm/field.hpp"
+#include "vm/global.h"
+#include "vm/method.hpp"
+
+
+/* macros *********************************************************************/
+
+#define SAME_PACKAGE(a,b)                                  \
+                       ((a)->classloader == (b)->classloader &&       \
+                        (a)->packagename == (b)->packagename)
+
+
+/* function prototypes ********************************************************/
+
+bool access_is_accessible_class(classinfo *referer, classinfo *cls);
+
+bool access_is_accessible_member(classinfo *referer, classinfo *declarer,
+                                                                int32_t memberflags);
+
+#if defined(ENABLE_JAVASE)
+bool access_check_field(fieldinfo *f, int callerdepth);
+bool access_check_method(methodinfo *m, int callerdepth);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ACCESS_H */
+
+
+/*
+ * 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:
+ */
+
index a230c0d81fbd53848e2d914bfdf542982dd51581..1305fc0a288a9d401a55ab8f1d9577a375fdacdf 100644 (file)
@@ -51,7 +51,7 @@
 #include "vm/global.h"
 #include "vm/globals.hpp"
 #include "vm/javaobjects.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/resolve.hpp"
index 6f56a31a3f90bb5de71d6dcb711a4fc11df981e2..d1584b1c4228073671997988bbf27eb9038c663c 100644 (file)
@@ -45,7 +45,7 @@ typedef struct extra_classref extra_classref;
 
 #include "vm/field.hpp"
 #include "vm/global.h"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/method.hpp"
 #include "vm/references.h"
index 5458ec80bf42ff013475ebbec7c74032e228075d..93db61a9b4eeaafbbf5bc37a6ad168a4d1473cc8 100644 (file)
@@ -1586,7 +1586,7 @@ dump_it:
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 84ba7365846d585439a4941bae284bad6b5a7131..aef65e21c4e4af5fccea718c8f8a04cbd2410a4e 100644 (file)
@@ -167,7 +167,7 @@ void classcache_debug_dump(FILE *file,utf *only);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 6858eb6e006ad430e980071ace9abacbfd7b247f..b8a0d601326b5b830b68e14a474d44ca009341df 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "native/vm/reflection.hpp"
 
-#include "vm/access.h"
+#include "vm/access.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
index 1b9ccb99c0eb23d4fc18d6df2d62d6d88b848c41..100ad48d6c55c23c6b43eaec535c99211517d3d3 100644 (file)
@@ -67,7 +67,7 @@
 #include "vm/global.h"
 #include "vm/globals.hpp"
 #include "vm/initialize.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
index cb6d37cb701ca79ce1ba45554f7a534dab522a77..73c8667d2ee95dca23bd2a420fbfb9ef18c4da3b 100644 (file)
@@ -3235,7 +3235,7 @@ bool inline_inline(jitdata *jd)
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 629f649a9dca2a570603b0cefb8ede76fdc63a2c..373de8facbaf0f0c3c525bdd0422e472fbeddbb2 100644 (file)
@@ -53,7 +53,7 @@ bool inline_inline(jitdata *jd);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index d84edec56ce7ac0d2104491959b888215cb98aa7..dc31a95d3026280f8106ed5f35b2999ad77256e6 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "vm/jit/builtin.hpp"
 #include "vm/class.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 
index 4219f0012aca3e5d91b97aa0be9bdf07ffe15608..f2b74ef1c7ff7cc6df426578e11bacdfc73d0805 100644 (file)
@@ -231,7 +231,7 @@ void printarg_avftbl  (vftbl_t *          avftbl  )
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 7c74c9a87644280a15abc4708ab204f756ceb950..6b3b60e400fcf478545cca2ba74748b525884c28 100644 (file)
@@ -46,7 +46,7 @@ typedef s4 Cell;
 
 #include "vm/class.hpp"
 #include "vm/global.h"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/method.hpp"
 #include "vm/references.h"
 #include "vm/resolve.hpp"
index ddc5d9b80eda12cc1ca3759dfc2c5983a310aaec..63a15bb8960880051544123019bd3abda7a0e836 100644 (file)
@@ -41,7 +41,7 @@
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/resolve.hpp"
index 65adf817db6f44f51b129b69d84b782cf84ad2a6..0d3457e56b8877277652bf71a9954a41d3a467c9 100644 (file)
@@ -770,7 +770,7 @@ case ICMD_DUP2_X2: /* {STACKBASED} */
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 62818a158bf3dc4351e472969fefe2c41141030d..88f38615bff1908d566eb9559d916ae0cba37054 100644 (file)
@@ -549,7 +549,7 @@ bool typecheck_init_locals(verifier_state *state, bool newthis)
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index bc47e375d1b27353073a3097fa6e68a9f03b5345..f6cb2e4c428b99ac7bf6b386f7b631285a02ac30 100644 (file)
@@ -306,7 +306,7 @@ bool typecheck_init_locals(verifier_state *state, bool newthis);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index ceb27be3ef93405d8688c0e07fa54ce55063c89d..8ac6267b802f65a9dbff59bddd52761a238fc15d 100644 (file)
@@ -1024,7 +1024,7 @@ static void typecheck_stackbased_show_state(verifier_state *state,
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 6f8ee53cd69b9030021301bbcdcd76f8ef913dfa..7626890762e3150811d039daf9e155ccc5bb11c3 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "toolbox/logging.h"
 
-#include "vm/access.h"
+#include "vm/access.hpp"
 #include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
@@ -483,7 +483,7 @@ bool typecheck_infer_types(jitdata *jd)
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 7bffa52014f185c8d5e00b17a15c9e782159747b..a3e79b8ab254228fbc938267ca55cf98a931b4d6 100644 (file)
@@ -61,7 +61,7 @@ bool typecheck_infer_types(jitdata *jd);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 574e33a81a1cfa42a4ad8dd0e8eddef8c8f2bb67..d63c422007abe0180f8f967c261d7f63df2d2489 100644 (file)
@@ -147,7 +147,7 @@ error reporting.
 
 #include "toolbox/logging.h"
 
-#include "vm/access.h"
+#include "vm/access.hpp"
 #include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
@@ -832,7 +832,7 @@ bool typecheck(jitdata *jd)
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index dac58ca419cd757c977cf3182d0663e6c9bb6e7b..8e0305c6c903c7c514777ac354f5af86c7fcd225 100644 (file)
@@ -56,7 +56,7 @@ bool typecheck_stackbased(jitdata *jd);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 1a02ca001819993ed04e2f20f6d1077922f9fa77..4df771a9da68dccb5f8fadefd9aa365a749ab21c 100644 (file)
@@ -2563,7 +2563,7 @@ typevector_print(FILE *file,varinfo *vec,int size)
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 00d78e0080b921f29b42d56046e49c82dc7c9e29..ea4292528cc3a1876206bec31935a84e6ae56bff 100644 (file)
@@ -530,7 +530,7 @@ void typevector_print(FILE *file,varinfo *vec,int size);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
diff --git a/src/vm/linker.c b/src/vm/linker.c
deleted file mode 100644 (file)
index a6e33c2..0000000
+++ /dev/null
@@ -1,1372 +0,0 @@
-/* src/vm/linker.c - class linker functions
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   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., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#include "config.h"
-
-#include <assert.h>
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "native/native.hpp"
-
-#include "threads/lock.hpp"
-#include "threads/mutex.hpp"
-
-#include "toolbox/logging.h"
-
-#include "vm/access.h"
-#include "vm/array.hpp"
-#include "vm/class.hpp"
-#include "vm/classcache.hpp"
-#include "vm/exceptions.hpp"
-#include "vm/globals.hpp"
-#include "vm/loader.hpp"
-#include "vm/options.h"
-#include "vm/primitive.hpp"
-#include "vm/rt-timing.h"
-#include "vm/string.hpp"
-#include "vm/vm.hpp"
-
-#include "vm/jit/asmpart.h"
-#include "vm/jit/stubs.hpp"
-
-
-/* debugging macros ***********************************************************/
-
-#if !defined(NDEBUG)
-# define TRACELINKCLASS(c) \
-    do { \
-        if (opt_TraceLinkClass) { \
-            log_start(); \
-            log_print("[Linking "); \
-            class_print((c)); \
-            log_print("]"); \
-            log_finish(); \
-        } \
-    } while (0)
-#else
-# define TRACELINKCLASS(c)
-#endif
-
-
-/* #include "vm/resolve.hpp" */
-/* copied prototype to avoid bootstrapping problem: */
-classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-#if !defined(NDEBUG) && defined(ENABLE_INLINING)
-#define INLINELOG(code)  do { if (opt_TraceInlining) { code } } while (0)
-#else
-#define INLINELOG(code)
-#endif
-
-
-/* global variables ***********************************************************/
-
-static s4 interfaceindex;       /* sequential numbering of interfaces         */
-static s4 classvalue;
-
-
-/* private functions **********************************************************/
-
-static classinfo *link_class_intern(classinfo *c);
-static arraydescriptor *link_array(classinfo *c);
-static void linker_compute_class_values(classinfo *c);
-static void linker_compute_subclasses(classinfo *c);
-static bool linker_addinterface(classinfo *c, classinfo *ic);
-static s4 class_highestinterface(classinfo *c);
-
-
-/* linker_init *****************************************************************
-
-   Initializes the linker subsystem and links classes required for the
-   primitive table.
-
-*******************************************************************************/
-
-void linker_preinit(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("linker_preinit");
-
-       /* Reset interface index. */
-
-       interfaceindex = 0;
-
-       /* Link the most basic classes. */
-
-       if (!link_class(class_java_lang_Object))
-               vm_abort("linker_preinit: linking java/lang/Object failed");
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_Cloneable))
-               vm_abort("linker_preinit: linking java/lang/Cloneable failed");
-
-       if (!link_class(class_java_io_Serializable))
-               vm_abort("linker_preinit: linking java/io/Serializable failed");
-#endif
-}
-
-
-/* linker_init *****************************************************************
-
-   Links all classes required in the VM.
-
-*******************************************************************************/
-
-void linker_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("linker_init");
-
-       /* Link java.lang.Class as first class of the system, because we
-       need it's vftbl for all other classes so we can use a class as
-       object. */
-
-       if (!link_class(class_java_lang_Class))
-               vm_abort("linker_init: linking java/lang/Class failed");
-
-       /* Now set the header.vftbl of all classes which were created
-       before java.lang.Class was linked. */
-
-       class_postset_header_vftbl();
-
-       /* Link primitive-type wrapping classes. */
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_Void))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       if (!link_class(class_java_lang_Boolean))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Byte))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Character))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Short))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Integer))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Long))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Float))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Double))
-               vm_abort("linker_init: linking failed");
-
-       /* Link important system classes. */
-
-       if (!link_class(class_java_lang_String))
-               vm_abort("linker_init: linking java/lang/String failed");
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_ClassLoader))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_SecurityManager))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       if (!link_class(class_java_lang_System))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_Thread))
-               vm_abort("linker_init: linking failed");
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_ThreadGroup))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       if (!link_class(class_java_lang_Throwable))
-               vm_abort("linker_init: linking failed");
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       if (!link_class(class_java_lang_VMSystem))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_VMThread))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_VMThrowable))
-               vm_abort("linker_init: linking failed");
-#endif
-
-       /* Important system exceptions. */
-
-       if (!link_class(class_java_lang_Exception))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_ClassNotFoundException))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_RuntimeException))
-               vm_abort("linker_init: linking failed");
-
-       /* some classes which may be used more often */
-
-#if defined(ENABLE_JAVASE)
-       if (!link_class(class_java_lang_StackTraceElement))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_Constructor))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_Field))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_Method))
-               vm_abort("linker_init: linking failed");
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
-       if (!link_class(class_java_lang_reflect_VMConstructor))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_VMField))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_lang_reflect_VMMethod))
-               vm_abort("linker_init: linking failed");
-# endif
-
-       if (!link_class(class_java_security_PrivilegedAction))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_util_Vector))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_java_util_HashMap))
-               vm_abort("linker_init: linking failed");
-
-# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       if (!link_class(class_sun_misc_Signal))
-               vm_abort("linker_init: linking failed");
-
-       if (!link_class(class_sun_reflect_MagicAccessorImpl))
-               vm_abort("linker_init: linking failed");
-# endif
-
-       if (!link_class(arrayclass_java_lang_Object))
-               vm_abort("linker_init: linking failed");
-#endif
-
-
-       /* create pseudo classes used by the typechecker */
-
-    /* pseudo class for Arraystubs (extends java.lang.Object) */
-
-       pseudo_class_Arraystub                   =
-               class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
-       pseudo_class_Arraystub->state           |= CLASS_LOADED;
-       pseudo_class_Arraystub->super            = class_java_lang_Object;
-
-#if defined(ENABLE_JAVASE)
-
-       pseudo_class_Arraystub->interfacescount  = 2;
-       pseudo_class_Arraystub->interfaces       = MNEW(classinfo*, 2);
-       pseudo_class_Arraystub->interfaces[0]    = class_java_lang_Cloneable;
-       pseudo_class_Arraystub->interfaces[1]    = class_java_io_Serializable;
-
-#elif defined(ENABLE_JAVAME_CLDC1_1)
-
-       pseudo_class_Arraystub->interfacescount    = 0;
-       pseudo_class_Arraystub->interfaces         = NULL;
-
-#else
-# error unknown Java configuration
-#endif
-
-       if (!classcache_store_unique(pseudo_class_Arraystub))
-               vm_abort("linker_init: could not cache pseudo_class_Arraystub");
-
-       if (!link_class(pseudo_class_Arraystub))
-               vm_abort("linker_init: linking pseudo_class_Arraystub failed");
-
-       /* pseudo class representing the null type */
-
-       pseudo_class_Null         = class_create_classinfo(utf_new_char("$NULL$"));
-       pseudo_class_Null->state |= CLASS_LOADED;
-       pseudo_class_Null->super  = class_java_lang_Object;
-
-       if (!classcache_store_unique(pseudo_class_Null))
-               vm_abort("linker_init: could not cache pseudo_class_Null");
-
-       if (!link_class(pseudo_class_Null))
-               vm_abort("linker_init: linking failed");
-
-       /* pseudo class representing new uninitialized objects */
-    
-       pseudo_class_New         = class_create_classinfo(utf_new_char("$NEW$"));
-       pseudo_class_New->state |= CLASS_LOADED;
-       pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
-       pseudo_class_New->super  = class_java_lang_Object;
-
-       if (!classcache_store_unique(pseudo_class_New))
-               vm_abort("linker_init: could not cache pseudo_class_New");
-
-       /* Correct vftbl-entries (retarded loading and linking of class
-          java/lang/String). */
-
-       stringtable_update();
-}
-
-
-/* link_class ******************************************************************
-
-   Wrapper function for link_class_intern to ease monitor enter/exit
-   and exception handling.
-
-*******************************************************************************/
-
-classinfo *link_class(classinfo *c)
-{
-       classinfo *r;
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_end;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       if (c == NULL) {
-               exceptions_throw_nullpointerexception();
-               return NULL;
-       }
-
-       LOCK_MONITOR_ENTER(c);
-
-       /* Maybe the class is currently linking or is already linked.*/
-
-       if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
-               LOCK_MONITOR_EXIT(c);
-
-               return c;
-       }
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getcompilingtime)
-               compilingtime_stop();
-
-       if (opt_getloadingtime)
-               loadingtime_start();
-#endif
-
-       /* call the internal function */
-
-       r = link_class_intern(c);
-
-       /* If return value is NULL, we had a problem and the class is not
-          linked. */
-
-       if (r == NULL)
-               c->state &= ~CLASS_LINKING;
-
-#if defined(ENABLE_STATISTICS)
-       /* measure time */
-
-       if (opt_getloadingtime)
-               loadingtime_stop();
-
-       if (opt_getcompilingtime)
-               compilingtime_start();
-#endif
-
-       LOCK_MONITOR_EXIT(c);
-
-       RT_TIMING_GET_TIME(time_end);
-
-       RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
-
-       return r;
-}
-
-
-/* linker_overwrite_method *****************************************************
-
-   Overwrite a method with another one, update method flags and check
-   assumptions.
-
-   IN:
-      mg................the general method being overwritten
-         ms................the overwriting (more specialized) method
-         wl................worklist where to add invalidated methods
-
-   RETURN VALUE:
-      true..............everything ok
-         false.............an exception has been thrown
-
-*******************************************************************************/
-
-static bool linker_overwrite_method(methodinfo *mg,
-                                                                       methodinfo *ms,
-                                                                       method_worklist **wl)
-{
-       classinfo *cg;
-       classinfo *cs;
-
-       cg = mg->clazz;
-       cs = ms->clazz;
-
-       /* overriding a final method is illegal */
-
-       if (mg->flags & ACC_FINAL) {
-               exceptions_throw_verifyerror(mg, "Overriding final method");
-               return false;
-       }
-
-       /* method ms overwrites method mg */
-
-#if defined(ENABLE_VERIFIER)
-       /* Add loading constraints (for the more general types of method mg). */
-       /* Not for <init>, as it is not invoked virtually.                    */
-
-       if ((ms->name != utf_init)
-                       && !classcache_add_constraints_for_params(
-                               cs->classloader, cg->classloader, mg))
-       {
-               return false;
-       }
-#endif
-
-       /* inherit the vftbl index, and record the overwriting */
-
-       ms->vftblindex = mg->vftblindex;
-       ms->overwrites = mg;
-
-       /* update flags and check assumptions */
-       /* <init> methods are a special case, as they are never dispatched dynamically */
-
-       if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
-               do {
-
-#if defined(ENABLE_TLH)
-                       if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
-                               printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
-                                       ms->clazz->name->text, ms->name->text);
-                               ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;                                 
-                       }
-#endif
-
-                       if (mg->flags & ACC_METHOD_IMPLEMENTED) {
-                               /* this adds another implementation */
-
-                               mg->flags &= ~ACC_METHOD_MONOMORPHIC;
-
-                               INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
-
-                               method_break_assumption_monomorphic(mg, wl);
-                       }
-                       else {
-                               /* this is the first implementation */
-
-                               mg->flags |= ACC_METHOD_IMPLEMENTED;
-
-                               INLINELOG( printf("becomes implemented: "); method_println(mg); );
-                       }
-
-                       ms = mg;
-                       mg = mg->overwrites;
-               } while (mg != NULL);
-       }
-
-       return true;
-}
-
-
-/* link_class_intern ***********************************************************
-
-   Tries to link a class. The function calculates the length in bytes
-   that an instance of this class requires as well as the VTBL for
-   methods and interface methods.
-       
-*******************************************************************************/
-
-static int build_display_inner(classinfo *topc, classinfo *c, int i)
-{
-       int depth;
-       if (!c)
-               return 0;
-       do {
-               if (c->vftbl->arraydesc)
-               {
-                       arraydescriptor *a = c->vftbl->arraydesc;
-                       if (a->elementvftbl && a->elementvftbl->clazz->super)
-                       {
-                               classinfo *cls = a->elementvftbl->clazz->super;
-                               int n;
-                               for (n=0; n<a->dimension; n++)
-                                       cls = class_array_of(cls, true);
-                               depth = build_display_inner(topc, cls, i+1);
-                               break;
-                       }
-                       if (a->componentvftbl && a->elementvftbl)
-                       {
-                               depth = build_display_inner(topc, a->componentvftbl->clazz, i+1);
-                               break;
-                       }
-               }
-               depth = build_display_inner(topc, c->super, i+1);
-       } while (false);
-       if (depth >= DISPLAY_SIZE)
-       {
-               if (depth == DISPLAY_SIZE)
-               {
-                       topc->vftbl->subtype_overflow = malloc(sizeof(void*) * (i+1));
-#if defined(ENABLE_STATISTICS)
-                       if (opt_stat)
-                               count_vftbl_len += sizeof(void*) * (i+1);
-#endif
-               }
-               topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
-               return depth + 1;
-       }
-       topc->vftbl->subtype_display[depth] = c->vftbl;
-       return depth + 1;
-}
-
-static void build_display(classinfo *c)
-{
-       int depth;
-       int i;
-
-       depth = build_display_inner(c, c, 0) - 1;
-       c->vftbl->subtype_depth = depth;
-       if (depth >= DISPLAY_SIZE)
-       {
-               c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
-       }
-       else
-       {
-               c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
-               for (i=depth+1; i<=DISPLAY_SIZE; i++)
-                       c->vftbl->subtype_display[i] = NULL;
-       }
-}
-
-static classinfo *link_class_intern(classinfo *c)
-{
-       classinfo *super;             /* super class                              */
-       classinfo *tc;                /* temporary class variable                 */
-       s4 supervftbllength;          /* vftbllegnth of super class               */
-       s4 vftbllength;               /* vftbllength of current class             */
-       s4 interfacetablelength;      /* interface table length                   */
-       vftbl_t *v;                   /* vftbl of current class                   */
-       s4 i;                         /* interface/method/field counter           */
-       arraydescriptor *arraydesc;   /* descriptor for array classes             */
-       method_worklist *worklist;    /* worklist for recompilation               */
-#if defined(ENABLE_RT_TIMING)
-       struct timespec time_start, time_resolving, time_compute_vftbl,
-                                       time_abstract, time_compute_iftbl, time_fill_vftbl,
-                                       time_offsets, time_fill_iftbl, time_finalizer,
-                                       time_subclasses;
-#endif
-
-       RT_TIMING_GET_TIME(time_start);
-
-       TRACELINKCLASS(c);
-
-       /* the class must be loaded */
-
-       /* XXX should this be a specific exception? */
-       assert(c->state & CLASS_LOADED);
-
-       /* This is check in link_class. */
-
-       assert(!(c->state & CLASS_LINKED));
-
-       /* cache the self-reference of this class                          */
-       /* we do this for cases where the defining loader of the class     */
-       /* has not yet been recorded as an initiating loader for the class */
-       /* this is needed so subsequent code can assume that self-refs     */
-       /* will always resolve lazily                                      */
-       /* No need to do it for the bootloader - it is always registered   */
-       /* as initiating loader for the classes it loads.                  */
-       if (c->classloader)
-               classcache_store(c->classloader,c,false);
-
-       /* this class is currently linking */
-
-       c->state |= CLASS_LINKING;
-
-       arraydesc = NULL;
-       worklist = NULL;
-
-       /* Link the super interfaces. */
-
-       for (i = 0; i < c->interfacescount; i++) {
-               tc = c->interfaces[i];
-
-               if (!(tc->state & CLASS_LINKED))
-                       if (!link_class(tc))
-                               return NULL;
-       }
-       
-       /* check super class */
-
-       super = NULL;
-
-       /* Check for java/lang/Object. */
-
-       if (c->super == NULL) {
-               c->index = 0;
-               c->instancesize = sizeof(java_object_t);
-               
-               vftbllength = supervftbllength = 0;
-
-               c->finalizer = NULL;
-       }
-       else {
-               /* Get super class. */
-
-               super = c->super;
-
-               /* Link the super class if necessary. */
-               
-               if (!(super->state & CLASS_LINKED))
-                       if (!link_class(super))
-                               return NULL;
-
-               /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
-                  flags. */
-
-               c->flags |= (super->flags &
-                                        (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
-
-               /* handle array classes */
-
-               if (c->name->text[0] == '[')
-                       if (!(arraydesc = link_array(c)))
-                               return NULL;
-
-               if (c->flags & ACC_INTERFACE)
-                       c->index = interfaceindex++;
-               else
-                       c->index = super->index + 1;
-               
-               c->instancesize = super->instancesize;
-
-               vftbllength = supervftbllength = super->vftbl->vftbllength;
-               
-               c->finalizer = super->finalizer;
-       }
-       RT_TIMING_GET_TIME(time_resolving);
-
-
-       /* compute vftbl length */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               if (!(m->flags & ACC_STATIC)) { /* is instance method */
-                       tc = super;
-
-                       while (tc) {
-                               s4 j;
-
-                               for (j = 0; j < tc->methodscount; j++) {
-                                       if (method_canoverwrite(m, &(tc->methods[j]))) {
-                                               if (tc->methods[j].flags & ACC_PRIVATE)
-                                                       goto notfoundvftblindex;
-
-                                               /* package-private methods in other packages */
-                                               /* must not be overridden                    */
-                                               /* (see Java Language Specification 8.4.8.1) */
-                                               if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
-                                                        && !SAME_PACKAGE(c,tc) ) 
-                                               {
-                                                   goto notfoundvftblindex;
-                                               }
-
-                                               if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
-                                                       return NULL;
-
-                                               goto foundvftblindex;
-                                       }
-                               }
-
-                               tc = tc->super;
-                       }
-
-               notfoundvftblindex:
-                       m->vftblindex = (vftbllength++);
-               foundvftblindex:
-                       ;
-               }
-       }
-       RT_TIMING_GET_TIME(time_compute_vftbl);
-
-
-       /* Check all interfaces of an abstract class (maybe be an
-          interface too) for unimplemented methods.  Such methods are
-          called miranda-methods and are marked with the ACC_MIRANDA
-          flag.  VMClass.getDeclaredMethods does not return such
-          methods. */
-
-       if (c->flags & ACC_ABSTRACT) {
-               classinfo  *ic;
-               methodinfo *im;
-               s4 abstractmethodscount;
-               s4 j;
-               s4 k;
-
-               abstractmethodscount = 0;
-
-               /* check all interfaces of the abstract class */
-
-               for (i = 0; i < c->interfacescount; i++) {
-                       ic = c->interfaces[i];
-
-                       for (j = 0; j < ic->methodscount; j++) {
-                               im = &(ic->methods[j]);
-
-                               /* skip `<clinit>' and `<init>' */
-
-                               if ((im->name == utf_clinit) || (im->name == utf_init))
-                                       continue;
-
-                               for (tc = c; tc != NULL; tc = tc->super) {
-                                       for (k = 0; k < tc->methodscount; k++) {
-                                               if (method_canoverwrite(im, &(tc->methods[k])))
-                                                       goto noabstractmethod;
-                                       }
-                               }
-
-                               abstractmethodscount++;
-
-                       noabstractmethod:
-                               ;
-                       }
-               }
-
-               if (abstractmethodscount > 0) {
-                       methodinfo *am;
-
-                       /* reallocate methods memory */
-
-                       c->methods = MREALLOC(c->methods, methodinfo, c->methodscount,
-                                                                 c->methodscount + abstractmethodscount);
-
-                       for (i = 0; i < c->interfacescount; i++) {
-                               ic = c->interfaces[i];
-
-                               for (j = 0; j < ic->methodscount; j++) {
-                                       im = &(ic->methods[j]);
-
-                                       /* skip `<clinit>' and `<init>' */
-
-                                       if ((im->name == utf_clinit) || (im->name == utf_init))
-                                               continue;
-
-                                       for (tc = c; tc != NULL; tc = tc->super) {
-                                               for (k = 0; k < tc->methodscount; k++) {
-                                                       if (method_canoverwrite(im, &(tc->methods[k])))
-                                                               goto noabstractmethod2;
-                                               }
-                                       }
-
-                                       /* Copy the method found into the new c->methods
-                                          array and tag it as miranda-method. */
-
-                                       am = &(c->methods[c->methodscount]);
-                                       c->methodscount++;
-
-                                       MCOPY(am, im, methodinfo, 1);
-
-                                       am->vftblindex  = (vftbllength++);
-                                       am->clazz       = c;
-                                       am->flags      |= ACC_MIRANDA;
-
-                               noabstractmethod2:
-                                       ;
-                               }
-                       }
-               }
-       }
-       RT_TIMING_GET_TIME(time_abstract);
-
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_vftbl_len +=
-                       sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
-#endif
-
-       /* compute interfacetable length */
-
-       interfacetablelength = 0;
-
-       for (tc = c; tc != NULL; tc = tc->super) {
-               for (i = 0; i < tc->interfacescount; i++) {
-                       s4 h = class_highestinterface(tc->interfaces[i]) + 1;
-
-                       if (h > interfacetablelength)
-                               interfacetablelength = h;
-               }
-       }
-       RT_TIMING_GET_TIME(time_compute_iftbl);
-
-       /* allocate virtual function table */
-
-       v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
-                                                         sizeof(methodptr) * (vftbllength - 1) +
-                                                         sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
-       v = (vftbl_t *) (((methodptr *) v) +
-                                        (interfacetablelength - 1) * (interfacetablelength > 1));
-
-       c->vftbl                = v;
-       v->clazz                = c;
-       v->vftbllength          = vftbllength;
-       v->interfacetablelength = interfacetablelength;
-       v->arraydesc            = arraydesc;
-
-       /* store interface index in vftbl */
-
-       if (c->flags & ACC_INTERFACE)
-               v->baseval = -(c->index);
-
-       /* copy virtual function table of super class */
-
-       for (i = 0; i < supervftbllength; i++) 
-               v->table[i] = super->vftbl->table[i];
-
-       /* Fill the remaining vftbl slots with the AbstractMethodError
-          stub (all after the super class slots, because they are already
-          initialized). */
-
-       for (; i < vftbllength; i++) {
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-               else
-# endif
-                       v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
-#else
-               v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-#endif
-       }
-
-       /* add method stubs into virtual function table */
-
-       for (i = 0; i < c->methodscount; i++) {
-               methodinfo *m = &(c->methods[i]);
-
-               assert(m->stubroutine == NULL);
-
-               /* Don't create a compiler stub for abstract methods as they
-                  throw an AbstractMethodError with the default stub in the
-                  vftbl.  This entry is simply copied by sub-classes. */
-
-               if (m->flags & ACC_ABSTRACT)
-                       continue;
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (opt_intrp)
-                       m->stubroutine = intrp_createcompilerstub(m);
-               else
-#endif
-                       m->stubroutine = CompilerStub_generate(m);
-#else
-               m->stubroutine = intrp_createcompilerstub(m);
-#endif
-
-               /* static methods are not in the vftbl */
-
-               if (m->flags & ACC_STATIC)
-                       continue;
-
-               /* insert the stubroutine into the vftbl */
-
-               v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
-       }
-       RT_TIMING_GET_TIME(time_fill_vftbl);
-
-       /* compute instance size and offset of each field */
-       
-       for (i = 0; i < c->fieldscount; i++) {
-               s4 dsize;
-               fieldinfo *f = &(c->fields[i]);
-               
-               if (!(f->flags & ACC_STATIC)) {
-                       dsize = descriptor_typesize(f->parseddesc);
-                       c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
-                       f->offset = c->instancesize;
-                       c->instancesize += dsize;
-               }
-       }
-       RT_TIMING_GET_TIME(time_offsets);
-
-       /* initialize interfacetable and interfacevftbllength */
-
-       v->interfacevftbllength = MNEW(s4, interfacetablelength);
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
-#endif
-
-       for (i = 0; i < interfacetablelength; i++) {
-               v->interfacevftbllength[i] = 0;
-               v->interfacetable[-i] = NULL;
-       }
-
-       /* add interfaces */
-
-       for (tc = c; tc != NULL; tc = tc->super)
-               for (i = 0; i < tc->interfacescount; i++)
-                       if (!linker_addinterface(c, tc->interfaces[i]))
-                               return NULL;
-
-       RT_TIMING_GET_TIME(time_fill_iftbl);
-
-       /* add finalizer method (not for java.lang.Object) */
-
-       if (super) {
-               methodinfo *fi;
-
-               fi = class_findmethod(c, utf_finalize, utf_void__void);
-
-               if (fi)
-                       if (!(fi->flags & ACC_STATIC))
-                               c->finalizer = fi;
-       }
-       RT_TIMING_GET_TIME(time_finalizer);
-
-       /* final tasks */
-
-       linker_compute_subclasses(c);
-
-       /* FIXME: this is completely useless now */
-       RT_TIMING_GET_TIME(time_subclasses);
-
-       build_display(c);
-
-       /* revert the linking state and class is linked */
-
-       c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
-
-       /* check worklist */
-
-       /* XXX must this also be done in case of exception? */
-
-       while (worklist != NULL) {
-               method_worklist *wi = worklist;
-
-               worklist = worklist->next;
-
-               INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
-               jit_invalidate_code(wi->m);
-
-               /* XXX put worklist into dump memory? */
-               FREE(wi, method_worklist);
-       }
-
-       RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
-       RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
-       RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
-       RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
-       RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
-       RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
-       RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
-       RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
-       RT_TIMING_TIME_DIFF(time_finalizer    ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
-
-       /* just return c to show that we didn't had a problem */
-
-       return c;
-}
-
-
-/* link_array ******************************************************************
-
-   This function is called by link_class to create the arraydescriptor
-   for an array class.
-
-   This function returns NULL if the array cannot be linked because
-   the component type has not been linked yet.
-
-*******************************************************************************/
-
-static arraydescriptor *link_array(classinfo *c)
-{
-       classinfo       *comp;
-       s4               namelen;
-       arraydescriptor *desc;
-       vftbl_t         *compvftbl;
-       utf             *u;
-
-       comp = NULL;
-       namelen = c->name->blength;
-
-       /* Check the component type */
-
-       switch (c->name->text[1]) {
-       case '[':
-               /* c is an array of arrays. */
-               u = utf_new(c->name->text + 1, namelen - 1);
-               if (!(comp = load_class_from_classloader(u, c->classloader)))
-                       return NULL;
-               break;
-
-       case 'L':
-               /* c is an array of objects. */
-               u = utf_new(c->name->text + 2, namelen - 3);
-               if (!(comp = load_class_from_classloader(u, c->classloader)))
-                       return NULL;
-               break;
-       }
-
-       /* If the component type has not been linked, link it now */
-
-       assert(!comp || (comp->state & CLASS_LOADED));
-
-       if (comp && !(comp->state & CLASS_LINKED))
-               if (!link_class(comp))
-                       return NULL;
-
-       /* Allocate the arraydescriptor */
-
-       desc = NEW(arraydescriptor);
-
-       if (comp) {
-               /* c is an array of references */
-               desc->arraytype = ARRAYTYPE_OBJECT;
-               desc->componentsize = sizeof(void*);
-               desc->dataoffset = OFFSET(java_objectarray_t, data);
-               
-               compvftbl = comp->vftbl;
-
-               if (!compvftbl) {
-                       log_text("Component class has no vftbl");
-                       assert(0);
-               }
-
-               desc->componentvftbl = compvftbl;
-               
-               if (compvftbl->arraydesc) {
-                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
-
-                       if (compvftbl->arraydesc->dimension >= 255) {
-                               log_text("Creating array of dimension >255");
-                               assert(0);
-                       }
-
-                       desc->dimension = compvftbl->arraydesc->dimension + 1;
-                       desc->elementtype = compvftbl->arraydesc->elementtype;
-
-               } else {
-                       desc->elementvftbl = compvftbl;
-                       desc->dimension = 1;
-                       desc->elementtype = ARRAYTYPE_OBJECT;
-               }
-
-       } else {
-               /* c is an array of a primitive type */
-               switch (c->name->text[1]) {
-               case 'Z':
-                       desc->arraytype = ARRAYTYPE_BOOLEAN;
-                       desc->dataoffset = OFFSET(java_booleanarray_t,data);
-                       desc->componentsize = sizeof(u1);
-                       break;
-
-               case 'B':
-                       desc->arraytype = ARRAYTYPE_BYTE;
-                       desc->dataoffset = OFFSET(java_bytearray_t,data);
-                       desc->componentsize = sizeof(u1);
-                       break;
-
-               case 'C':
-                       desc->arraytype = ARRAYTYPE_CHAR;
-                       desc->dataoffset = OFFSET(java_chararray_t,data);
-                       desc->componentsize = sizeof(u2);
-                       break;
-
-               case 'D':
-                       desc->arraytype = ARRAYTYPE_DOUBLE;
-                       desc->dataoffset = OFFSET(java_doublearray_t,data);
-                       desc->componentsize = sizeof(double);
-                       break;
-
-               case 'F':
-                       desc->arraytype = ARRAYTYPE_FLOAT;
-                       desc->dataoffset = OFFSET(java_floatarray_t,data);
-                       desc->componentsize = sizeof(float);
-                       break;
-
-               case 'I':
-                       desc->arraytype = ARRAYTYPE_INT;
-                       desc->dataoffset = OFFSET(java_intarray_t,data);
-                       desc->componentsize = sizeof(s4);
-                       break;
-
-               case 'J':
-                       desc->arraytype = ARRAYTYPE_LONG;
-                       desc->dataoffset = OFFSET(java_longarray_t,data);
-                       desc->componentsize = sizeof(s8);
-                       break;
-
-               case 'S':
-                       desc->arraytype = ARRAYTYPE_SHORT;
-                       desc->dataoffset = OFFSET(java_shortarray_t,data);
-                       desc->componentsize = sizeof(s2);
-                       break;
-
-               default:
-                       exceptions_throw_noclassdeffounderror(c->name);
-                       return NULL;
-               }
-               
-               desc->componentvftbl = NULL;
-               desc->elementvftbl = NULL;
-               desc->dimension = 1;
-               desc->elementtype = desc->arraytype;
-       }
-
-       return desc;
-}
-
-
-/* linker_compute_subclasses ***************************************************
-
-   XXX
-
-   ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
-   This function needs to take the class renumber lock and stop the
-   world during class renumbering. The lock is used in C code which
-   is not that performance critical. Whereas JIT code uses critical
-   sections to atomically access the class values.
-
-*******************************************************************************/
-
-static void linker_compute_subclasses(classinfo *c)
-{
-
-       if (!(c->flags & ACC_INTERFACE)) {
-               c->nextsub = NULL;
-               c->sub     = NULL;
-               c->vftbl->baseval = 1; /* so it does not look like an interface */
-       }
-
-       if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
-               c->nextsub    = c->super->sub;
-               c->super->sub = c;
-       }
-
-       classvalue = 0;
-
-}
-
-
-/* linker_compute_class_values *************************************************
-
-   XXX
-
-*******************************************************************************/
-
-static void linker_compute_class_values(classinfo *c)
-{
-       classinfo *subs;
-
-       c->vftbl->baseval = ++classvalue;
-
-       subs = c->sub;
-
-       while (subs) {
-               linker_compute_class_values(subs);
-
-               subs = subs->nextsub;
-       }
-
-       c->vftbl->diffval = classvalue - c->vftbl->baseval;
-}
-
-
-/* linker_addinterface *********************************************************
-
-   Is needed by link_class for adding a VTBL to a class. All
-   interfaces implemented by ic are added as well.
-
-   RETURN VALUE:
-      true.........everything ok
-         false........an exception has been thrown
-
-*******************************************************************************/
-
-static bool linker_addinterface(classinfo *c, classinfo *ic)
-{
-       s4          j, k;
-       vftbl_t    *v;
-       s4          i;
-       classinfo  *sc;
-       methodinfo *m;
-
-       v = c->vftbl;
-       i = ic->index;
-
-       if (i >= v->interfacetablelength)
-               vm_abort("Internal error: interfacetable overflow");
-
-       /* if this interface has already been added, return immediately */
-
-       if (v->interfacetable[-i] != NULL)
-               return true;
-
-       if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
-               v->interfacevftbllength[i] = 1;
-               v->interfacetable[-i]      = MNEW(methodptr, 1);
-               v->interfacetable[-i][0]   = NULL;
-       }
-       else {
-               v->interfacevftbllength[i] = ic->methodscount;
-               v->interfacetable[-i]      = MNEW(methodptr, ic->methodscount);
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       count_vftbl_len += sizeof(methodptr) *
-                               (ic->methodscount + (ic->methodscount == 0));
-#endif
-
-               for (j = 0; j < ic->methodscount; j++) {
-                       for (sc = c; sc != NULL; sc = sc->super) {
-                               for (k = 0; k < sc->methodscount; k++) {
-                                       m = &(sc->methods[k]);
-
-                                       if (method_canoverwrite(m, &(ic->methods[j]))) {
-                                               /* method m overwrites the (abstract) method */
-#if defined(ENABLE_VERIFIER)
-                                               /* Add loading constraints (for the more
-                                                  general types of the method
-                                                  ic->methods[j]).  */
-                                               if (!classcache_add_constraints_for_params(
-                                                                       c->classloader, ic->classloader,
-                                                                       &(ic->methods[j])))
-                                               {
-                                                       return false;
-                                               }
-#endif
-
-                                               /* XXX taken from gcj */
-                                               /* check for ACC_STATIC: IncompatibleClassChangeError */
-
-                                               /* check for !ACC_PUBLIC: IllegalAccessError */
-
-                                               /* check for ACC_ABSTRACT: AbstracMethodError,
-                                                  not sure about that one */
-
-                                               v->interfacetable[-i][j] = v->table[m->vftblindex];
-                                               goto foundmethod;
-                                       }
-                               }
-                       }
-
-                       /* If no method was found, insert the AbstractMethodError
-                          stub. */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-                       if (opt_intrp)
-                               v->interfacetable[-i][j] =
-                                       (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-                       else
-# endif
-                               v->interfacetable[-i][j] =
-                                       (methodptr) (ptrint) &asm_abstractmethoderror;
-#else
-                       v->interfacetable[-i][j] =
-                               (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
-#endif
-
-               foundmethod:
-                       ;
-               }
-       }
-
-       /* add superinterfaces of this interface */
-
-       for (j = 0; j < ic->interfacescount; j++)
-               if (!linker_addinterface(c, ic->interfaces[j]))
-                       return false;
-
-       /* everything ok */
-
-       return true;
-}
-
-
-/* class_highestinterface ******************************************************
-
-   Used by the function link_class to determine the amount of memory
-   needed for the interface table.
-
-*******************************************************************************/
-
-static s4 class_highestinterface(classinfo *c)
-{
-       s4 h;
-       s4 h2;
-       s4 i;
-       
-    /* check for ACC_INTERFACE bit already done in link_class_intern */
-
-    h = c->index;
-
-       for (i = 0; i < c->interfacescount; i++) {
-               h2 = class_highestinterface(c->interfaces[i]);
-
-               if (h2 > h)
-                       h = h2;
-       }
-
-       return h;
-}
-
-
-/*
- * 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:
- */
diff --git a/src/vm/linker.cpp b/src/vm/linker.cpp
new file mode 100644 (file)
index 0000000..6a6c308
--- /dev/null
@@ -0,0 +1,1378 @@
+/* src/vm/linker.c - class linker functions
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#include "config.h"
+
+#include <assert.h>
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.h"
+
+#include "native/native.hpp"
+
+#include "threads/lock.hpp"
+#include "threads/mutex.hpp"
+
+#include "toolbox/logging.h"
+
+#include "vm/access.hpp"
+#include "vm/array.hpp"
+#include "vm/class.hpp"
+#include "vm/classcache.hpp"
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/loader.hpp"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/rt-timing.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/jit/asmpart.h"
+#include "vm/jit/stubs.hpp"
+
+
+/* debugging macros ***********************************************************/
+
+#if !defined(NDEBUG)
+# define TRACELINKCLASS(c) \
+    do { \
+        if (opt_TraceLinkClass) { \
+            log_start(); \
+            log_print("[Linking "); \
+            class_print((c)); \
+            log_print("]"); \
+            log_finish(); \
+        } \
+    } while (0)
+#else
+# define TRACELINKCLASS(c)
+#endif
+
+
+/* #include "vm/resolve.hpp" */
+/* copied prototype to avoid bootstrapping problem: */
+classinfo *resolve_classref_or_classinfo_eager(classref_or_classinfo cls, bool checkaccess);
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+#if !defined(NDEBUG) && defined(ENABLE_INLINING)
+#define INLINELOG(code)  do { if (opt_TraceInlining) { code } } while (0)
+#else
+#define INLINELOG(code)
+#endif
+
+
+/* global variables ***********************************************************/
+
+static s4 interfaceindex;       /* sequential numbering of interfaces         */
+static s4 classvalue;
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* private functions **********************************************************/
+
+static classinfo *link_class_intern(classinfo *c);
+static arraydescriptor *link_array(classinfo *c);
+static void linker_compute_class_values(classinfo *c);
+static void linker_compute_subclasses(classinfo *c);
+static bool linker_addinterface(classinfo *c, classinfo *ic);
+static s4 class_highestinterface(classinfo *c);
+
+
+/* linker_init *****************************************************************
+
+   Initializes the linker subsystem and links classes required for the
+   primitive table.
+
+*******************************************************************************/
+
+void linker_preinit(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("linker_preinit");
+
+       /* Reset interface index. */
+
+       interfaceindex = 0;
+
+       /* Link the most basic classes. */
+
+       if (!link_class(class_java_lang_Object))
+               vm_abort("linker_preinit: linking java/lang/Object failed");
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_Cloneable))
+               vm_abort("linker_preinit: linking java/lang/Cloneable failed");
+
+       if (!link_class(class_java_io_Serializable))
+               vm_abort("linker_preinit: linking java/io/Serializable failed");
+#endif
+}
+
+
+/* linker_init *****************************************************************
+
+   Links all classes required in the VM.
+
+*******************************************************************************/
+
+void linker_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("linker_init");
+
+       /* Link java.lang.Class as first class of the system, because we
+       need it's vftbl for all other classes so we can use a class as
+       object. */
+
+       if (!link_class(class_java_lang_Class))
+               vm_abort("linker_init: linking java/lang/Class failed");
+
+       /* Now set the header.vftbl of all classes which were created
+       before java.lang.Class was linked. */
+
+       class_postset_header_vftbl();
+
+       /* Link primitive-type wrapping classes. */
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_Void))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       if (!link_class(class_java_lang_Boolean))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Byte))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Character))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Short))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Integer))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Long))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Float))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Double))
+               vm_abort("linker_init: linking failed");
+
+       /* Link important system classes. */
+
+       if (!link_class(class_java_lang_String))
+               vm_abort("linker_init: linking java/lang/String failed");
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_ClassLoader))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_SecurityManager))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       if (!link_class(class_java_lang_System))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_Thread))
+               vm_abort("linker_init: linking failed");
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_ThreadGroup))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       if (!link_class(class_java_lang_Throwable))
+               vm_abort("linker_init: linking failed");
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       if (!link_class(class_java_lang_VMSystem))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_VMThread))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_VMThrowable))
+               vm_abort("linker_init: linking failed");
+#endif
+
+       /* Important system exceptions. */
+
+       if (!link_class(class_java_lang_Exception))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_ClassNotFoundException))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_RuntimeException))
+               vm_abort("linker_init: linking failed");
+
+       /* some classes which may be used more often */
+
+#if defined(ENABLE_JAVASE)
+       if (!link_class(class_java_lang_StackTraceElement))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_Constructor))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_Field))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_Method))
+               vm_abort("linker_init: linking failed");
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       if (!link_class(class_java_lang_reflect_VMConstructor))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_VMField))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_lang_reflect_VMMethod))
+               vm_abort("linker_init: linking failed");
+# endif
+
+       if (!link_class(class_java_security_PrivilegedAction))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_util_Vector))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_java_util_HashMap))
+               vm_abort("linker_init: linking failed");
+
+# if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       if (!link_class(class_sun_misc_Signal))
+               vm_abort("linker_init: linking failed");
+
+       if (!link_class(class_sun_reflect_MagicAccessorImpl))
+               vm_abort("linker_init: linking failed");
+# endif
+
+       if (!link_class(arrayclass_java_lang_Object))
+               vm_abort("linker_init: linking failed");
+#endif
+
+
+       /* create pseudo classes used by the typechecker */
+
+    /* pseudo class for Arraystubs (extends java.lang.Object) */
+
+       pseudo_class_Arraystub                   =
+               class_create_classinfo(utf_new_char("$ARRAYSTUB$"));
+       pseudo_class_Arraystub->state           |= CLASS_LOADED;
+       pseudo_class_Arraystub->super            = class_java_lang_Object;
+
+#if defined(ENABLE_JAVASE)
+
+       pseudo_class_Arraystub->interfacescount  = 2;
+       pseudo_class_Arraystub->interfaces       = MNEW(classinfo*, 2);
+       pseudo_class_Arraystub->interfaces[0]    = class_java_lang_Cloneable;
+       pseudo_class_Arraystub->interfaces[1]    = class_java_io_Serializable;
+
+#elif defined(ENABLE_JAVAME_CLDC1_1)
+
+       pseudo_class_Arraystub->interfacescount    = 0;
+       pseudo_class_Arraystub->interfaces         = NULL;
+
+#else
+# error unknown Java configuration
+#endif
+
+       if (!classcache_store_unique(pseudo_class_Arraystub))
+               vm_abort("linker_init: could not cache pseudo_class_Arraystub");
+
+       if (!link_class(pseudo_class_Arraystub))
+               vm_abort("linker_init: linking pseudo_class_Arraystub failed");
+
+       /* pseudo class representing the null type */
+
+       pseudo_class_Null         = class_create_classinfo(utf_new_char("$NULL$"));
+       pseudo_class_Null->state |= CLASS_LOADED;
+       pseudo_class_Null->super  = class_java_lang_Object;
+
+       if (!classcache_store_unique(pseudo_class_Null))
+               vm_abort("linker_init: could not cache pseudo_class_Null");
+
+       if (!link_class(pseudo_class_Null))
+               vm_abort("linker_init: linking failed");
+
+       /* pseudo class representing new uninitialized objects */
+    
+       pseudo_class_New         = class_create_classinfo(utf_new_char("$NEW$"));
+       pseudo_class_New->state |= CLASS_LOADED;
+       pseudo_class_New->state |= CLASS_LINKED; /* XXX is this allright? */
+       pseudo_class_New->super  = class_java_lang_Object;
+
+       if (!classcache_store_unique(pseudo_class_New))
+               vm_abort("linker_init: could not cache pseudo_class_New");
+
+       /* Correct vftbl-entries (retarded loading and linking of class
+          java/lang/String). */
+
+       stringtable_update();
+}
+
+
+/* link_class ******************************************************************
+
+   Wrapper function for link_class_intern to ease monitor enter/exit
+   and exception handling.
+
+*******************************************************************************/
+
+classinfo *link_class(classinfo *c)
+{
+       classinfo *r;
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_end;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       if (c == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       LOCK_MONITOR_ENTER(c);
+
+       /* Maybe the class is currently linking or is already linked.*/
+
+       if ((c->state & CLASS_LINKING) || (c->state & CLASS_LINKED)) {
+               LOCK_MONITOR_EXIT(c);
+
+               return c;
+       }
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getcompilingtime)
+               compilingtime_stop();
+
+       if (opt_getloadingtime)
+               loadingtime_start();
+#endif
+
+       /* call the internal function */
+
+       r = link_class_intern(c);
+
+       /* If return value is NULL, we had a problem and the class is not
+          linked. */
+
+       if (r == NULL)
+               c->state &= ~CLASS_LINKING;
+
+#if defined(ENABLE_STATISTICS)
+       /* measure time */
+
+       if (opt_getloadingtime)
+               loadingtime_stop();
+
+       if (opt_getcompilingtime)
+               compilingtime_start();
+#endif
+
+       LOCK_MONITOR_EXIT(c);
+
+       RT_TIMING_GET_TIME(time_end);
+
+       RT_TIMING_TIME_DIFF(time_start,time_end,RT_TIMING_LINK_TOTAL);
+
+       return r;
+}
+
+
+/* linker_overwrite_method *****************************************************
+
+   Overwrite a method with another one, update method flags and check
+   assumptions.
+
+   IN:
+      mg................the general method being overwritten
+         ms................the overwriting (more specialized) method
+         wl................worklist where to add invalidated methods
+
+   RETURN VALUE:
+      true..............everything ok
+         false.............an exception has been thrown
+
+*******************************************************************************/
+
+static bool linker_overwrite_method(methodinfo *mg,
+                                                                       methodinfo *ms,
+                                                                       method_worklist **wl)
+{
+       classinfo *cg;
+       classinfo *cs;
+
+       cg = mg->clazz;
+       cs = ms->clazz;
+
+       /* overriding a final method is illegal */
+
+       if (mg->flags & ACC_FINAL) {
+               exceptions_throw_verifyerror(mg, "Overriding final method");
+               return false;
+       }
+
+       /* method ms overwrites method mg */
+
+#if defined(ENABLE_VERIFIER)
+       /* Add loading constraints (for the more general types of method mg). */
+       /* Not for <init>, as it is not invoked virtually.                    */
+
+       if ((ms->name != utf_init)
+                       && !classcache_add_constraints_for_params(
+                               cs->classloader, cg->classloader, mg))
+       {
+               return false;
+       }
+#endif
+
+       /* inherit the vftbl index, and record the overwriting */
+
+       ms->vftblindex = mg->vftblindex;
+       ms->overwrites = mg;
+
+       /* update flags and check assumptions */
+       /* <init> methods are a special case, as they are never dispatched dynamically */
+
+       if ((ms->flags & ACC_METHOD_IMPLEMENTED) && ms->name != utf_init) {
+               do {
+
+#if defined(ENABLE_TLH)
+                       if (mg->flags & ACC_METHOD_MONOMORPHY_USED) {
+                               printf("%s/%s is evil! the siner is %s/%s\n", mg->clazz->name->text, mg->name->text,
+                                       ms->clazz->name->text, ms->name->text);
+                               ms->flags |= ACC_METHOD_PARENT_MONOMORPHY_USED;                                 
+                       }
+#endif
+
+                       if (mg->flags & ACC_METHOD_IMPLEMENTED) {
+                               /* this adds another implementation */
+
+                               mg->flags &= ~ACC_METHOD_MONOMORPHIC;
+
+                               INLINELOG( printf("becomes polymorphic: "); method_println(mg); );
+
+                               method_break_assumption_monomorphic(mg, wl);
+                       }
+                       else {
+                               /* this is the first implementation */
+
+                               mg->flags |= ACC_METHOD_IMPLEMENTED;
+
+                               INLINELOG( printf("becomes implemented: "); method_println(mg); );
+                       }
+
+                       ms = mg;
+                       mg = mg->overwrites;
+               } while (mg != NULL);
+       }
+
+       return true;
+}
+
+
+/* link_class_intern ***********************************************************
+
+   Tries to link a class. The function calculates the length in bytes
+   that an instance of this class requires as well as the VTBL for
+   methods and interface methods.
+       
+*******************************************************************************/
+
+static int build_display_inner(classinfo *topc, classinfo *c, int i)
+{
+       int depth;
+       if (!c)
+               return 0;
+       do {
+               if (c->vftbl->arraydesc)
+               {
+                       arraydescriptor *a = c->vftbl->arraydesc;
+                       if (a->elementvftbl && a->elementvftbl->clazz->super)
+                       {
+                               classinfo *cls = a->elementvftbl->clazz->super;
+                               int n;
+                               for (n=0; n<a->dimension; n++)
+                                       cls = class_array_of(cls, true);
+                               depth = build_display_inner(topc, cls, i+1);
+                               break;
+                       }
+                       if (a->componentvftbl && a->elementvftbl)
+                       {
+                               depth = build_display_inner(topc, a->componentvftbl->clazz, i+1);
+                               break;
+                       }
+               }
+               depth = build_display_inner(topc, c->super, i+1);
+       } while (false);
+       if (depth >= DISPLAY_SIZE)
+       {
+               if (depth == DISPLAY_SIZE)
+               {
+                       topc->vftbl->subtype_overflow = malloc(sizeof(void*) * (i+1));
+#if defined(ENABLE_STATISTICS)
+                       if (opt_stat)
+                               count_vftbl_len += sizeof(void*) * (i+1);
+#endif
+               }
+               topc->vftbl->subtype_overflow[depth - DISPLAY_SIZE] = c->vftbl;
+               return depth + 1;
+       }
+       topc->vftbl->subtype_display[depth] = c->vftbl;
+       return depth + 1;
+}
+
+static void build_display(classinfo *c)
+{
+       int depth;
+       int i;
+
+       depth = build_display_inner(c, c, 0) - 1;
+       c->vftbl->subtype_depth = depth;
+       if (depth >= DISPLAY_SIZE)
+       {
+               c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[DISPLAY_SIZE]);
+       }
+       else
+       {
+               c->vftbl->subtype_offset = OFFSET(vftbl_t, subtype_display[0]) + sizeof(void*) * depth;
+               for (i=depth+1; i<=DISPLAY_SIZE; i++)
+                       c->vftbl->subtype_display[i] = NULL;
+       }
+}
+
+static classinfo *link_class_intern(classinfo *c)
+{
+       classinfo *super;             /* super class                              */
+       classinfo *tc;                /* temporary class variable                 */
+       s4 supervftbllength;          /* vftbllegnth of super class               */
+       s4 vftbllength;               /* vftbllength of current class             */
+       s4 interfacetablelength;      /* interface table length                   */
+       vftbl_t *v;                   /* vftbl of current class                   */
+       s4 i;                         /* interface/method/field counter           */
+       arraydescriptor *arraydesc;   /* descriptor for array classes             */
+       method_worklist *worklist;    /* worklist for recompilation               */
+#if defined(ENABLE_RT_TIMING)
+       struct timespec time_start, time_resolving, time_compute_vftbl,
+                                       time_abstract, time_compute_iftbl, time_fill_vftbl,
+                                       time_offsets, time_fill_iftbl, time_finalizer,
+                                       time_subclasses;
+#endif
+
+       RT_TIMING_GET_TIME(time_start);
+
+       TRACELINKCLASS(c);
+
+       /* the class must be loaded */
+
+       /* XXX should this be a specific exception? */
+       assert(c->state & CLASS_LOADED);
+
+       /* This is check in link_class. */
+
+       assert(!(c->state & CLASS_LINKED));
+
+       /* cache the self-reference of this class                          */
+       /* we do this for cases where the defining loader of the class     */
+       /* has not yet been recorded as an initiating loader for the class */
+       /* this is needed so subsequent code can assume that self-refs     */
+       /* will always resolve lazily                                      */
+       /* No need to do it for the bootloader - it is always registered   */
+       /* as initiating loader for the classes it loads.                  */
+       if (c->classloader)
+               classcache_store(c->classloader,c,false);
+
+       /* this class is currently linking */
+
+       c->state |= CLASS_LINKING;
+
+       arraydesc = NULL;
+       worklist = NULL;
+
+       /* Link the super interfaces. */
+
+       for (i = 0; i < c->interfacescount; i++) {
+               tc = c->interfaces[i];
+
+               if (!(tc->state & CLASS_LINKED))
+                       if (!link_class(tc))
+                               return NULL;
+       }
+       
+       /* check super class */
+
+       super = NULL;
+
+       /* Check for java/lang/Object. */
+
+       if (c->super == NULL) {
+               c->index = 0;
+               c->instancesize = sizeof(java_object_t);
+               
+               vftbllength = supervftbllength = 0;
+
+               c->finalizer = NULL;
+       }
+       else {
+               /* Get super class. */
+
+               super = c->super;
+
+               /* Link the super class if necessary. */
+               
+               if (!(super->state & CLASS_LINKED))
+                       if (!link_class(super))
+                               return NULL;
+
+               /* OR the ACC_CLASS_HAS_POINTERS and the ACC_CLASS_REFERENCE_*
+                  flags. */
+
+               c->flags |= (super->flags &
+                                        (ACC_CLASS_HAS_POINTERS | ACC_CLASS_REFERENCE_MASK));
+
+               /* handle array classes */
+
+               if (c->name->text[0] == '[')
+                       if (!(arraydesc = link_array(c)))
+                               return NULL;
+
+               if (c->flags & ACC_INTERFACE)
+                       c->index = interfaceindex++;
+               else
+                       c->index = super->index + 1;
+               
+               c->instancesize = super->instancesize;
+
+               vftbllength = supervftbllength = super->vftbl->vftbllength;
+               
+               c->finalizer = super->finalizer;
+       }
+       RT_TIMING_GET_TIME(time_resolving);
+
+
+       /* compute vftbl length */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               if (!(m->flags & ACC_STATIC)) { /* is instance method */
+                       tc = super;
+
+                       while (tc) {
+                               s4 j;
+
+                               for (j = 0; j < tc->methodscount; j++) {
+                                       if (method_canoverwrite(m, &(tc->methods[j]))) {
+                                               if (tc->methods[j].flags & ACC_PRIVATE)
+                                                       goto notfoundvftblindex;
+
+                                               /* package-private methods in other packages */
+                                               /* must not be overridden                    */
+                                               /* (see Java Language Specification 8.4.8.1) */
+                                               if ( !(tc->methods[j].flags & (ACC_PUBLIC | ACC_PROTECTED)) 
+                                                        && !SAME_PACKAGE(c,tc) ) 
+                                               {
+                                                   goto notfoundvftblindex;
+                                               }
+
+                                               if (!linker_overwrite_method(&(tc->methods[j]), m, &worklist))
+                                                       return NULL;
+
+                                               goto foundvftblindex;
+                                       }
+                               }
+
+                               tc = tc->super;
+                       }
+
+               notfoundvftblindex:
+                       m->vftblindex = (vftbllength++);
+               foundvftblindex:
+                       ;
+               }
+       }
+       RT_TIMING_GET_TIME(time_compute_vftbl);
+
+
+       /* Check all interfaces of an abstract class (maybe be an
+          interface too) for unimplemented methods.  Such methods are
+          called miranda-methods and are marked with the ACC_MIRANDA
+          flag.  VMClass.getDeclaredMethods does not return such
+          methods. */
+
+       if (c->flags & ACC_ABSTRACT) {
+               classinfo  *ic;
+               methodinfo *im;
+               s4 abstractmethodscount;
+               s4 j;
+               s4 k;
+
+               abstractmethodscount = 0;
+
+               /* check all interfaces of the abstract class */
+
+               for (i = 0; i < c->interfacescount; i++) {
+                       ic = c->interfaces[i];
+
+                       for (j = 0; j < ic->methodscount; j++) {
+                               im = &(ic->methods[j]);
+
+                               /* skip `<clinit>' and `<init>' */
+
+                               if ((im->name == utf_clinit) || (im->name == utf_init))
+                                       continue;
+
+                               for (tc = c; tc != NULL; tc = tc->super) {
+                                       for (k = 0; k < tc->methodscount; k++) {
+                                               if (method_canoverwrite(im, &(tc->methods[k])))
+                                                       goto noabstractmethod;
+                                       }
+                               }
+
+                               abstractmethodscount++;
+
+                       noabstractmethod:
+                               ;
+                       }
+               }
+
+               if (abstractmethodscount > 0) {
+                       methodinfo *am;
+
+                       /* reallocate methods memory */
+
+                       c->methods = (methodinfo*) MREALLOC(c->methods, methodinfo, c->methodscount,
+                                                                 c->methodscount + abstractmethodscount);
+
+                       for (i = 0; i < c->interfacescount; i++) {
+                               ic = c->interfaces[i];
+
+                               for (j = 0; j < ic->methodscount; j++) {
+                                       im = &(ic->methods[j]);
+
+                                       /* skip `<clinit>' and `<init>' */
+
+                                       if ((im->name == utf_clinit) || (im->name == utf_init))
+                                               continue;
+
+                                       for (tc = c; tc != NULL; tc = tc->super) {
+                                               for (k = 0; k < tc->methodscount; k++) {
+                                                       if (method_canoverwrite(im, &(tc->methods[k])))
+                                                               goto noabstractmethod2;
+                                               }
+                                       }
+
+                                       /* Copy the method found into the new c->methods
+                                          array and tag it as miranda-method. */
+
+                                       am = &(c->methods[c->methodscount]);
+                                       c->methodscount++;
+
+                                       MCOPY(am, im, methodinfo, 1);
+
+                                       am->vftblindex  = (vftbllength++);
+                                       am->clazz       = c;
+                                       am->flags      |= ACC_MIRANDA;
+
+                               noabstractmethod2:
+                                       ;
+                               }
+                       }
+               }
+       }
+       RT_TIMING_GET_TIME(time_abstract);
+
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_vftbl_len +=
+                       sizeof(vftbl_t) + (sizeof(methodptr) * (vftbllength - 1));
+#endif
+
+       /* compute interfacetable length */
+
+       interfacetablelength = 0;
+
+       for (tc = c; tc != NULL; tc = tc->super) {
+               for (i = 0; i < tc->interfacescount; i++) {
+                       s4 h = class_highestinterface(tc->interfaces[i]) + 1;
+
+                       if (h > interfacetablelength)
+                               interfacetablelength = h;
+               }
+       }
+       RT_TIMING_GET_TIME(time_compute_iftbl);
+
+       /* allocate virtual function table */
+
+       v = (vftbl_t *) mem_alloc(sizeof(vftbl_t) +
+                                                         sizeof(methodptr) * (vftbllength - 1) +
+                                                         sizeof(methodptr*) * (interfacetablelength - (interfacetablelength > 0)));
+       v = (vftbl_t *) (((methodptr *) v) +
+                                        (interfacetablelength - 1) * (interfacetablelength > 1));
+
+       c->vftbl                = v;
+       v->clazz                = c;
+       v->vftbllength          = vftbllength;
+       v->interfacetablelength = interfacetablelength;
+       v->arraydesc            = arraydesc;
+
+       /* store interface index in vftbl */
+
+       if (c->flags & ACC_INTERFACE)
+               v->baseval = -(c->index);
+
+       /* copy virtual function table of super class */
+
+       for (i = 0; i < supervftbllength; i++) 
+               v->table[i] = super->vftbl->table[i];
+
+       /* Fill the remaining vftbl slots with the AbstractMethodError
+          stub (all after the super class slots, because they are already
+          initialized). */
+
+       for (; i < vftbllength; i++) {
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (opt_intrp)
+                       v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+               else
+# endif
+                       v->table[i] = (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+               v->table[i] = (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
+       }
+
+       /* add method stubs into virtual function table */
+
+       for (i = 0; i < c->methodscount; i++) {
+               methodinfo *m = &(c->methods[i]);
+
+               assert(m->stubroutine == NULL);
+
+               /* Don't create a compiler stub for abstract methods as they
+                  throw an AbstractMethodError with the default stub in the
+                  vftbl.  This entry is simply copied by sub-classes. */
+
+               if (m->flags & ACC_ABSTRACT)
+                       continue;
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (opt_intrp)
+                       m->stubroutine = intrp_createcompilerstub(m);
+               else
+#endif
+                       m->stubroutine = (u1*) CompilerStub::generate(m);
+#else
+               m->stubroutine = intrp_createcompilerstub(m);
+#endif
+
+               /* static methods are not in the vftbl */
+
+               if (m->flags & ACC_STATIC)
+                       continue;
+
+               /* insert the stubroutine into the vftbl */
+
+               v->table[m->vftblindex] = (methodptr) (ptrint) m->stubroutine;
+       }
+       RT_TIMING_GET_TIME(time_fill_vftbl);
+
+       /* compute instance size and offset of each field */
+       
+       for (i = 0; i < c->fieldscount; i++) {
+               s4 dsize;
+               fieldinfo *f = &(c->fields[i]);
+               
+               if (!(f->flags & ACC_STATIC)) {
+                       dsize = descriptor_typesize(f->parseddesc);
+                       c->instancesize = MEMORY_ALIGN(c->instancesize, dsize);
+                       f->offset = c->instancesize;
+                       c->instancesize += dsize;
+               }
+       }
+       RT_TIMING_GET_TIME(time_offsets);
+
+       /* initialize interfacetable and interfacevftbllength */
+
+       v->interfacevftbllength = MNEW(s4, interfacetablelength);
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               count_vftbl_len += (4 + sizeof(s4)) * v->interfacetablelength;
+#endif
+
+       for (i = 0; i < interfacetablelength; i++) {
+               v->interfacevftbllength[i] = 0;
+               v->interfacetable[-i] = NULL;
+       }
+
+       /* add interfaces */
+
+       for (tc = c; tc != NULL; tc = tc->super)
+               for (i = 0; i < tc->interfacescount; i++)
+                       if (!linker_addinterface(c, tc->interfaces[i]))
+                               return NULL;
+
+       RT_TIMING_GET_TIME(time_fill_iftbl);
+
+       /* add finalizer method (not for java.lang.Object) */
+
+       if (super) {
+               methodinfo *fi;
+
+               fi = class_findmethod(c, utf_finalize, utf_void__void);
+
+               if (fi)
+                       if (!(fi->flags & ACC_STATIC))
+                               c->finalizer = fi;
+       }
+       RT_TIMING_GET_TIME(time_finalizer);
+
+       /* final tasks */
+
+       linker_compute_subclasses(c);
+
+       /* FIXME: this is completely useless now */
+       RT_TIMING_GET_TIME(time_subclasses);
+
+       build_display(c);
+
+       /* revert the linking state and class is linked */
+
+       c->state = (c->state & ~CLASS_LINKING) | CLASS_LINKED;
+
+       /* check worklist */
+
+       /* XXX must this also be done in case of exception? */
+
+       while (worklist != NULL) {
+               method_worklist *wi = worklist;
+
+               worklist = worklist->next;
+
+               INLINELOG( printf("MUST BE RECOMPILED: "); method_println(wi->m); );
+               jit_invalidate_code(wi->m);
+
+               /* XXX put worklist into dump memory? */
+               FREE(wi, method_worklist);
+       }
+
+       RT_TIMING_TIME_DIFF(time_start        ,time_resolving    ,RT_TIMING_LINK_RESOLVE);
+       RT_TIMING_TIME_DIFF(time_resolving    ,time_compute_vftbl,RT_TIMING_LINK_C_VFTBL);
+       RT_TIMING_TIME_DIFF(time_compute_vftbl,time_abstract     ,RT_TIMING_LINK_ABSTRACT);
+       RT_TIMING_TIME_DIFF(time_abstract     ,time_compute_iftbl,RT_TIMING_LINK_C_IFTBL);
+       RT_TIMING_TIME_DIFF(time_compute_iftbl,time_fill_vftbl   ,RT_TIMING_LINK_F_VFTBL);
+       RT_TIMING_TIME_DIFF(time_fill_vftbl   ,time_offsets      ,RT_TIMING_LINK_OFFSETS);
+       RT_TIMING_TIME_DIFF(time_offsets      ,time_fill_iftbl   ,RT_TIMING_LINK_F_IFTBL);
+       RT_TIMING_TIME_DIFF(time_fill_iftbl   ,time_finalizer    ,RT_TIMING_LINK_FINALIZER);
+       RT_TIMING_TIME_DIFF(time_finalizer    ,time_subclasses   ,RT_TIMING_LINK_SUBCLASS);
+
+       /* just return c to show that we didn't had a problem */
+
+       return c;
+}
+
+
+/* link_array ******************************************************************
+
+   This function is called by link_class to create the arraydescriptor
+   for an array class.
+
+   This function returns NULL if the array cannot be linked because
+   the component type has not been linked yet.
+
+*******************************************************************************/
+
+static arraydescriptor *link_array(classinfo *c)
+{
+       classinfo       *comp;
+       s4               namelen;
+       arraydescriptor *desc;
+       vftbl_t         *compvftbl;
+       utf             *u;
+
+       comp = NULL;
+       namelen = c->name->blength;
+
+       /* Check the component type */
+
+       switch (c->name->text[1]) {
+       case '[':
+               /* c is an array of arrays. */
+               u = utf_new(c->name->text + 1, namelen - 1);
+               if (!(comp = load_class_from_classloader(u, c->classloader)))
+                       return NULL;
+               break;
+
+       case 'L':
+               /* c is an array of objects. */
+               u = utf_new(c->name->text + 2, namelen - 3);
+               if (!(comp = load_class_from_classloader(u, c->classloader)))
+                       return NULL;
+               break;
+       }
+
+       /* If the component type has not been linked, link it now */
+
+       assert(!comp || (comp->state & CLASS_LOADED));
+
+       if (comp && !(comp->state & CLASS_LINKED))
+               if (!link_class(comp))
+                       return NULL;
+
+       /* Allocate the arraydescriptor */
+
+       desc = NEW(arraydescriptor);
+
+       if (comp) {
+               /* c is an array of references */
+               desc->arraytype = ARRAYTYPE_OBJECT;
+               desc->componentsize = sizeof(void*);
+               desc->dataoffset = OFFSET(java_objectarray_t, data);
+               
+               compvftbl = comp->vftbl;
+
+               if (!compvftbl) {
+                       log_text("Component class has no vftbl");
+                       assert(0);
+               }
+
+               desc->componentvftbl = compvftbl;
+               
+               if (compvftbl->arraydesc) {
+                       desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
+
+                       if (compvftbl->arraydesc->dimension >= 255) {
+                               log_text("Creating array of dimension >255");
+                               assert(0);
+                       }
+
+                       desc->dimension = compvftbl->arraydesc->dimension + 1;
+                       desc->elementtype = compvftbl->arraydesc->elementtype;
+
+               } else {
+                       desc->elementvftbl = compvftbl;
+                       desc->dimension = 1;
+                       desc->elementtype = ARRAYTYPE_OBJECT;
+               }
+
+       } else {
+               /* c is an array of a primitive type */
+               switch (c->name->text[1]) {
+               case 'Z':
+                       desc->arraytype = ARRAYTYPE_BOOLEAN;
+                       desc->dataoffset = OFFSET(java_booleanarray_t,data);
+                       desc->componentsize = sizeof(u1);
+                       break;
+
+               case 'B':
+                       desc->arraytype = ARRAYTYPE_BYTE;
+                       desc->dataoffset = OFFSET(java_bytearray_t,data);
+                       desc->componentsize = sizeof(u1);
+                       break;
+
+               case 'C':
+                       desc->arraytype = ARRAYTYPE_CHAR;
+                       desc->dataoffset = OFFSET(java_chararray_t,data);
+                       desc->componentsize = sizeof(u2);
+                       break;
+
+               case 'D':
+                       desc->arraytype = ARRAYTYPE_DOUBLE;
+                       desc->dataoffset = OFFSET(java_doublearray_t,data);
+                       desc->componentsize = sizeof(double);
+                       break;
+
+               case 'F':
+                       desc->arraytype = ARRAYTYPE_FLOAT;
+                       desc->dataoffset = OFFSET(java_floatarray_t,data);
+                       desc->componentsize = sizeof(float);
+                       break;
+
+               case 'I':
+                       desc->arraytype = ARRAYTYPE_INT;
+                       desc->dataoffset = OFFSET(java_intarray_t,data);
+                       desc->componentsize = sizeof(s4);
+                       break;
+
+               case 'J':
+                       desc->arraytype = ARRAYTYPE_LONG;
+                       desc->dataoffset = OFFSET(java_longarray_t,data);
+                       desc->componentsize = sizeof(s8);
+                       break;
+
+               case 'S':
+                       desc->arraytype = ARRAYTYPE_SHORT;
+                       desc->dataoffset = OFFSET(java_shortarray_t,data);
+                       desc->componentsize = sizeof(s2);
+                       break;
+
+               default:
+                       exceptions_throw_noclassdeffounderror(c->name);
+                       return NULL;
+               }
+               
+               desc->componentvftbl = NULL;
+               desc->elementvftbl = NULL;
+               desc->dimension = 1;
+               desc->elementtype = desc->arraytype;
+       }
+
+       return desc;
+}
+
+
+/* linker_compute_subclasses ***************************************************
+
+   XXX
+
+   ATTENTION: DO NOT REMOVE ANY OF THE LOCKING MECHANISMS BELOW:
+   This function needs to take the class renumber lock and stop the
+   world during class renumbering. The lock is used in C code which
+   is not that performance critical. Whereas JIT code uses critical
+   sections to atomically access the class values.
+
+*******************************************************************************/
+
+static void linker_compute_subclasses(classinfo *c)
+{
+
+       if (!(c->flags & ACC_INTERFACE)) {
+               c->nextsub = NULL;
+               c->sub     = NULL;
+               c->vftbl->baseval = 1; /* so it does not look like an interface */
+       }
+
+       if (!(c->flags & ACC_INTERFACE) && (c->super != NULL)) {
+               c->nextsub    = c->super->sub;
+               c->super->sub = c;
+       }
+
+       classvalue = 0;
+
+}
+
+
+/* linker_compute_class_values *************************************************
+
+   XXX
+
+*******************************************************************************/
+
+static void linker_compute_class_values(classinfo *c)
+{
+       classinfo *subs;
+
+       c->vftbl->baseval = ++classvalue;
+
+       subs = c->sub;
+
+       while (subs) {
+               linker_compute_class_values(subs);
+
+               subs = subs->nextsub;
+       }
+
+       c->vftbl->diffval = classvalue - c->vftbl->baseval;
+}
+
+
+/* linker_addinterface *********************************************************
+
+   Is needed by link_class for adding a VTBL to a class. All
+   interfaces implemented by ic are added as well.
+
+   RETURN VALUE:
+      true.........everything ok
+         false........an exception has been thrown
+
+*******************************************************************************/
+
+static bool linker_addinterface(classinfo *c, classinfo *ic)
+{
+       s4          j, k;
+       vftbl_t    *v;
+       s4          i;
+       classinfo  *sc;
+       methodinfo *m;
+
+       v = c->vftbl;
+       i = ic->index;
+
+       if (i >= v->interfacetablelength)
+               vm_abort("Internal error: interfacetable overflow");
+
+       /* if this interface has already been added, return immediately */
+
+       if (v->interfacetable[-i] != NULL)
+               return true;
+
+       if (ic->methodscount == 0) {  /* fake entry needed for subtype test */
+               v->interfacevftbllength[i] = 1;
+               v->interfacetable[-i]      = MNEW(methodptr, 1);
+               v->interfacetable[-i][0]   = NULL;
+       }
+       else {
+               v->interfacevftbllength[i] = ic->methodscount;
+               v->interfacetable[-i]      = MNEW(methodptr, ic->methodscount);
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       count_vftbl_len += sizeof(methodptr) *
+                               (ic->methodscount + (ic->methodscount == 0));
+#endif
+
+               for (j = 0; j < ic->methodscount; j++) {
+                       for (sc = c; sc != NULL; sc = sc->super) {
+                               for (k = 0; k < sc->methodscount; k++) {
+                                       m = &(sc->methods[k]);
+
+                                       if (method_canoverwrite(m, &(ic->methods[j]))) {
+                                               /* method m overwrites the (abstract) method */
+#if defined(ENABLE_VERIFIER)
+                                               /* Add loading constraints (for the more
+                                                  general types of the method
+                                                  ic->methods[j]).  */
+                                               if (!classcache_add_constraints_for_params(
+                                                                       c->classloader, ic->classloader,
+                                                                       &(ic->methods[j])))
+                                               {
+                                                       return false;
+                                               }
+#endif
+
+                                               /* XXX taken from gcj */
+                                               /* check for ACC_STATIC: IncompatibleClassChangeError */
+
+                                               /* check for !ACC_PUBLIC: IllegalAccessError */
+
+                                               /* check for ACC_ABSTRACT: AbstracMethodError,
+                                                  not sure about that one */
+
+                                               v->interfacetable[-i][j] = v->table[m->vftblindex];
+                                               goto foundmethod;
+                                       }
+                               }
+                       }
+
+                       /* If no method was found, insert the AbstractMethodError
+                          stub. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+                       if (opt_intrp)
+                               v->interfacetable[-i][j] =
+                                       (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+                       else
+# endif
+                               v->interfacetable[-i][j] =
+                                       (methodptr) (ptrint) &asm_abstractmethoderror;
+#else
+                       v->interfacetable[-i][j] =
+                               (methodptr) (ptrint) &intrp_asm_abstractmethoderror;
+#endif
+
+               foundmethod:
+                       ;
+               }
+       }
+
+       /* add superinterfaces of this interface */
+
+       for (j = 0; j < ic->interfacescount; j++)
+               if (!linker_addinterface(c, ic->interfaces[j]))
+                       return false;
+
+       /* everything ok */
+
+       return true;
+}
+
+
+/* class_highestinterface ******************************************************
+
+   Used by the function link_class to determine the amount of memory
+   needed for the interface table.
+
+*******************************************************************************/
+
+static s4 class_highestinterface(classinfo *c)
+{
+       s4 h;
+       s4 h2;
+       s4 i;
+       
+    /* check for ACC_INTERFACE bit already done in link_class_intern */
+
+    h = c->index;
+
+       for (i = 0; i < c->interfacescount; i++) {
+               h2 = class_highestinterface(c->interfaces[i]);
+
+               if (h2 > h)
+                       h = h2;
+       }
+
+       return h;
+}
+
+#if defined(__cplusplus)
+}
+#endif
+
+/*
+ * 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:
+ */
diff --git a/src/vm/linker.h b/src/vm/linker.h
deleted file mode 100644 (file)
index 7f4c632..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-/* src/vm/linker.h - class linker header
-
-   Copyright (C) 1996-2005, 2006, 2007, 2008
-   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
-
-   This file is part of CACAO.
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License as
-   published by the Free Software Foundation; either version 2, or (at
-   your option) any later version.
-
-   This program is distributed in the hope that it will be useful, but
-   WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   General Public License for more details.
-
-   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., 51 Franklin Street, Fifth Floor, Boston, MA
-   02110-1301, USA.
-
-*/
-
-
-#ifndef _LINKER_H
-#define _LINKER_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct arraydescriptor arraydescriptor;
-typedef struct primitivetypeinfo primitivetypeinfo;
-
-
-#include "config.h"
-#include "vm/types.h"
-
-#include "threads/mutex.hpp"
-
-#include "vm/class.hpp"
-#include "vm/references.h"
-#include "vm/vftbl.hpp"
-
-
-/* arraydescriptor *************************************************************
-
-   For every array class an arraydescriptor is allocated which
-   describes the array class. The arraydescriptor is referenced from
-   the vftbl of the array class.
-
-*******************************************************************************/
-
-struct arraydescriptor {
-       vftbl_t *componentvftbl; /* vftbl of the component type, NULL for primit. */
-       vftbl_t *elementvftbl;   /* vftbl of the element type, NULL for primitive */
-       s2       arraytype;      /* ARRAYTYPE_* constant                          */
-       s2       dimension;      /* dimension of the array (always >= 1)          */
-       s4       dataoffset;     /* offset of the array data from object pointer  */
-       s4       componentsize;  /* size of a component in bytes                  */
-       s2       elementtype;    /* ARRAYTYPE_* constant                          */
-};
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void       linker_preinit(void);
-void       linker_init(void);
-classinfo *link_class(classinfo *c);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LINKER_H */
-
-
-/*
- * 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:
- */
diff --git a/src/vm/linker.hpp b/src/vm/linker.hpp
new file mode 100644 (file)
index 0000000..7f4c632
--- /dev/null
@@ -0,0 +1,92 @@
+/* src/vm/linker.h - class linker header
+
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
+
+   This file is part of CACAO.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   This program is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   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., 51 Franklin Street, Fifth Floor, Boston, MA
+   02110-1301, USA.
+
+*/
+
+
+#ifndef _LINKER_H
+#define _LINKER_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct arraydescriptor arraydescriptor;
+typedef struct primitivetypeinfo primitivetypeinfo;
+
+
+#include "config.h"
+#include "vm/types.h"
+
+#include "threads/mutex.hpp"
+
+#include "vm/class.hpp"
+#include "vm/references.h"
+#include "vm/vftbl.hpp"
+
+
+/* arraydescriptor *************************************************************
+
+   For every array class an arraydescriptor is allocated which
+   describes the array class. The arraydescriptor is referenced from
+   the vftbl of the array class.
+
+*******************************************************************************/
+
+struct arraydescriptor {
+       vftbl_t *componentvftbl; /* vftbl of the component type, NULL for primit. */
+       vftbl_t *elementvftbl;   /* vftbl of the element type, NULL for primitive */
+       s2       arraytype;      /* ARRAYTYPE_* constant                          */
+       s2       dimension;      /* dimension of the array (always >= 1)          */
+       s4       dataoffset;     /* offset of the array data from object pointer  */
+       s4       componentsize;  /* size of a component in bytes                  */
+       s2       elementtype;    /* ARRAYTYPE_* constant                          */
+};
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void       linker_preinit(void);
+void       linker_init(void);
+classinfo *link_class(classinfo *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LINKER_H */
+
+
+/*
+ * 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:
+ */
index 32ac8e14c223f1da6a958169df43b29dbc52d42a..81ab0ad8594bd06ec0cd27cb3a0c5f6401db6209 100644 (file)
@@ -47,7 +47,7 @@
 #include "vm/field.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/method.hpp"
 #include "vm/options.h"
index 471842315974050813134d828068d835c360925a..59cafe93498863b05ff48ddca47e6add7ff9ecb0 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/method.hpp"
 #include "vm/options.h"
@@ -1217,7 +1217,7 @@ void method_methodref_println(constant_FMIref *mr)
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 754bacc17a34807bd0b560909544edbb78bd6fa7..b7e12c8d63039605bc138b25ba1daea765028fb2 100644 (file)
@@ -43,7 +43,7 @@ typedef struct codeinfo            codeinfo;
 #include "vm/jit/builtin.hpp"
 #include "vm/descriptor.h"
 #include "vm/global.h"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/references.h"
 
@@ -221,7 +221,7 @@ void method_methodref_println(constant_FMIref *mr);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 55f8cb67579372d9b332e3b27e639946ac52b4dc..314bb05d47b4d598f5c73834ba9a1981dbbad0b7 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "vm/class.hpp"
 #include "vm/global.h"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/utf8.h"
 
 
index 5443a3a3bb8c304fc5551dd2f929fa5ef52e31c0..d4b4e969939ae84fd73996b53607ae67cd64ecb0 100644 (file)
 
 #include "mm/memory.h"
 
-#include "vm/access.h"
+#include "vm/access.hpp"
 #include "vm/classcache.hpp"
 #include "vm/descriptor.h"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
-#include "vm/linker.h"
+#include "vm/linker.hpp"
 #include "vm/loader.hpp"
 #include "vm/options.h"
 #include "vm/primitive.hpp"
index 841109a0e7fff1c5f1e93a1ef62d216cff63f96b..b9c870c9ec1a8441efdaf09ddb734b8d319b0b4f 100644 (file)
@@ -457,7 +457,7 @@ classbuffer *zip_get(list_classpath_entry *lce, classinfo *c)
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4
index 660553594273fc3d6c83b1a4dfe12e8931126a53..d79f8efbbbc9ac63d60f8a5f0f9092700ec1b4d7 100644 (file)
@@ -110,7 +110,7 @@ classbuffer *zip_get(list_classpath_entry *lce, classinfo *c);
  * Emacs will automagically detect them.
  * ---------------------------------------------------------------------
  * Local variables:
- * mode: c
+ * mode: c++
  * indent-tabs-mode: t
  * c-basic-offset: 4
  * tab-width: 4