Merged branch subtype-trunk into default.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Sat, 20 Dec 2008 15:06:26 +0000 (16:06 +0100)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Sat, 20 Dec 2008 15:06:26 +0000 (16:06 +0100)
237 files changed:
src/mm/Makefile.am
src/mm/cacao-gc/compact.c
src/mm/cacao-gc/copy.c
src/mm/cacao-gc/final.c
src/mm/cacao-gc/gc.c
src/mm/cacao-gc/heap.c
src/mm/cacao-gc/mark.c
src/mm/cacao-gc/region.c
src/mm/cacao-gc/rootset.c
src/mm/codememory.c
src/mm/dumpmemory.cpp
src/mm/dumpmemory.hpp
src/mm/gc-boehm.cpp
src/mm/gc-none.cpp
src/mm/memory.c [deleted file]
src/mm/memory.cpp [new file with mode: 0644]
src/mm/memory.h [deleted file]
src/mm/memory.hpp [new file with mode: 0644]
src/mm/tlh.c
src/native/jni.cpp
src/native/jvmti/cacaodbg.c
src/native/jvmti/jvmti.c
src/native/localref.cpp
src/native/native.cpp
src/native/vm/cldc1.1/com_sun_cldc_io_ResourceInputStream.cpp
src/native/vm/cldc1.1/com_sun_cldc_io_j2me_socket_Protocol.cpp
src/native/vm/cldc1.1/java_lang_Float.cpp
src/native/vm/cldc1.1/java_lang_System.cpp
src/native/vm/cldc1.1/java_lang_Thread.cpp
src/native/vm/gnuclasspath/gnu_classpath_VMSystemProperties.cpp
src/native/vm/gnuclasspath/gnu_classpath_jdwp_VMFrame.c
src/native/vm/gnuclasspath/gnu_classpath_jdwp_VMVirtualMachine.c
src/native/vm/gnuclasspath/gnu_java_lang_management_VMClassLoadingMXBeanImpl.cpp
src/native/vm/gnuclasspath/gnu_java_lang_management_VMThreadMXBeanImpl.cpp
src/native/vm/gnuclasspath/java_lang_VMClass.cpp
src/native/vm/gnuclasspath/java_lang_VMClassLoader.cpp
src/native/vm/gnuclasspath/java_lang_VMRuntime.cpp
src/native/vm/gnuclasspath/java_lang_VMThread.cpp
src/native/vm/gnuclasspath/java_lang_VMThrowable.cpp
src/native/vm/gnuclasspath/java_lang_management_VMManagementFactory.cpp
src/native/vm/gnuclasspath/sun_reflect_ConstantPool.cpp
src/native/vm/nativevm.cpp
src/native/vm/openjdk/hpi.cpp
src/native/vm/openjdk/jvm.cpp
src/native/vm/openjdk/management.cpp
src/native/vm/sun_misc_Unsafe.cpp
src/threads/lock.cpp
src/threads/posix/thread-posix.cpp
src/threads/posix/thread-posix.hpp
src/threads/thread.cpp
src/threads/thread.hpp
src/threads/threadlist.cpp
src/threads/threadlist.hpp
src/toolbox/Makefile.am
src/toolbox/avl.c
src/toolbox/bitvector.c
src/toolbox/hashtable.c
src/toolbox/logging.c [deleted file]
src/toolbox/logging.cpp [new file with mode: 0644]
src/toolbox/logging.h [deleted file]
src/toolbox/logging.hpp [new file with mode: 0644]
src/toolbox/set.c
src/toolbox/util.c
src/toolbox/worklist.c
src/vm/Makefile.am
src/vm/access.cpp
src/vm/annotation.c [deleted file]
src/vm/annotation.cpp [new file with mode: 0644]
src/vm/annotation.h [deleted file]
src/vm/annotation.hpp [new file with mode: 0644]
src/vm/assertion.cpp
src/vm/class.cpp
src/vm/class.hpp
src/vm/classcache.cpp
src/vm/descriptor.c [deleted file]
src/vm/descriptor.cpp [new file with mode: 0644]
src/vm/descriptor.h [deleted file]
src/vm/descriptor.hpp [new file with mode: 0644]
src/vm/exceptions.cpp
src/vm/field.cpp
src/vm/field.hpp
src/vm/finalizer.c [deleted file]
src/vm/finalizer.cpp [new file with mode: 0644]
src/vm/finalizer.h [deleted file]
src/vm/finalizer.hpp [new file with mode: 0644]
src/vm/javaobjects.hpp
src/vm/jit/allocator/liveness.c
src/vm/jit/allocator/lsra.c
src/vm/jit/allocator/simplereg.c
src/vm/jit/alpha/codegen.c
src/vm/jit/alpha/emit.c
src/vm/jit/alpha/freebsd/md-os.c
src/vm/jit/alpha/linux/md-os.c
src/vm/jit/alpha/md-abi.c
src/vm/jit/alpha/patcher.c
src/vm/jit/argument.cpp
src/vm/jit/arm/codegen.c
src/vm/jit/arm/codegen.h
src/vm/jit/arm/emit.c
src/vm/jit/arm/linux/md-os.c
src/vm/jit/arm/md-abi.c
src/vm/jit/arm/md.c
src/vm/jit/arm/patcher.c
src/vm/jit/builtin.cpp
src/vm/jit/builtin.hpp
src/vm/jit/cfg.c
src/vm/jit/code.cpp
src/vm/jit/codegen-common.cpp
src/vm/jit/codegen-common.hpp
src/vm/jit/disass-common.c
src/vm/jit/dseg.c
src/vm/jit/exceptiontable.c
src/vm/jit/executionstate.c
src/vm/jit/i386/codegen.c
src/vm/jit/i386/cygwin/md-os.c
src/vm/jit/i386/darwin/md-os.c
src/vm/jit/i386/emit.c
src/vm/jit/i386/freebsd/md-os.c
src/vm/jit/i386/linux/md-os.c
src/vm/jit/i386/md-abi.c
src/vm/jit/i386/patcher.c
src/vm/jit/i386/solaris/md-os.c
src/vm/jit/inline/inline.cpp
src/vm/jit/intrp/codegen.c
src/vm/jit/intrp/dynamic-super.c
src/vm/jit/intrp/engine.c
src/vm/jit/intrp/patcher.c
src/vm/jit/ir/instruction.cpp
src/vm/jit/ir/instruction.hpp
src/vm/jit/jit.cpp
src/vm/jit/linenumbertable.cpp
src/vm/jit/loop/analyze.c
src/vm/jit/loop/graph.c
src/vm/jit/loop/loop.c
src/vm/jit/loop/tracing.c
src/vm/jit/m68k/codegen.c
src/vm/jit/m68k/emit.c
src/vm/jit/m68k/emit.h
src/vm/jit/m68k/linux/md-os.c
src/vm/jit/m68k/patcher.c
src/vm/jit/methodtree.c
src/vm/jit/mips/codegen.c
src/vm/jit/mips/emit.c
src/vm/jit/mips/irix/md-os.c
src/vm/jit/mips/linux/md-os.c
src/vm/jit/mips/md-abi.c
src/vm/jit/mips/patcher.c
src/vm/jit/oprofile-agent.cpp
src/vm/jit/optimizing/bytecode_escape.c
src/vm/jit/optimizing/dominators.cpp
src/vm/jit/optimizing/graph.c
src/vm/jit/optimizing/lifetimes.c
src/vm/jit/optimizing/lsra.c
src/vm/jit/optimizing/profile.c
src/vm/jit/optimizing/recompiler.cpp
src/vm/jit/optimizing/reorder.c
src/vm/jit/optimizing/ssa.c
src/vm/jit/optimizing/ssa2.c
src/vm/jit/optimizing/ssa3.c
src/vm/jit/optimizing/ssa_phi.c
src/vm/jit/optimizing/ssa_rename.c
src/vm/jit/parse.cpp
src/vm/jit/patcher-common.cpp
src/vm/jit/powerpc/codegen.c
src/vm/jit/powerpc/darwin/md-abi.c
src/vm/jit/powerpc/darwin/md-os.c
src/vm/jit/powerpc/emit.c
src/vm/jit/powerpc/linux/md-abi.c
src/vm/jit/powerpc/linux/md-os.c
src/vm/jit/powerpc/netbsd/md-abi.c
src/vm/jit/powerpc/netbsd/md-os.c
src/vm/jit/powerpc/patcher.c
src/vm/jit/powerpc64/codegen.c
src/vm/jit/powerpc64/emit.c
src/vm/jit/powerpc64/linux/md-abi.c
src/vm/jit/powerpc64/linux/md-os.c
src/vm/jit/powerpc64/patcher.c
src/vm/jit/reg.c
src/vm/jit/replace.cpp
src/vm/jit/s390/codegen.c
src/vm/jit/s390/emit.c
src/vm/jit/s390/md-abi.c
src/vm/jit/s390/md.c
src/vm/jit/s390/patcher.c
src/vm/jit/schedule/schedule.c
src/vm/jit/show.cpp
src/vm/jit/sparc64/codegen.c
src/vm/jit/sparc64/emit.c
src/vm/jit/sparc64/linux/md-os.c
src/vm/jit/sparc64/md-abi.c
src/vm/jit/sparc64/patcher.c
src/vm/jit/sparc64/solaris/md-os.c
src/vm/jit/stack.c
src/vm/jit/stacktrace.cpp
src/vm/jit/stacktrace.hpp
src/vm/jit/trace.cpp
src/vm/jit/trap.c
src/vm/jit/verify/typecheck-stackbased.cpp
src/vm/jit/verify/typecheck-typeinferer.cpp
src/vm/jit/verify/typecheck.cpp
src/vm/jit/verify/typeinfo.cpp
src/vm/jit/x86_64/codegen.c
src/vm/jit/x86_64/emit.c
src/vm/jit/x86_64/freebsd/md-os.c
src/vm/jit/x86_64/linux/md-os.c
src/vm/jit/x86_64/md-abi.c
src/vm/jit/x86_64/patcher.c
src/vm/jit/x86_64/solaris/md-os.c
src/vm/linker.cpp
src/vm/loader.cpp
src/vm/loader.hpp
src/vm/method.cpp
src/vm/method.hpp
src/vm/options.c
src/vm/os.hpp
src/vm/package.cpp
src/vm/properties.cpp
src/vm/references.h
src/vm/resolve.cpp
src/vm/rt-timing.c
src/vm/rt-timing.h
src/vm/signal.c [deleted file]
src/vm/signal.cpp [new file with mode: 0644]
src/vm/signallocal.h [deleted file]
src/vm/signallocal.hpp [new file with mode: 0644]
src/vm/stackmap.c
src/vm/statistics.c
src/vm/string.cpp
src/vm/suck.cpp
src/vm/utf8.c
src/vm/vm.cpp
src/vm/zip.cpp
tests/regression/bugzilla/All.java
tests/regression/bugzilla/PR112.java [new file with mode: 0644]
tests/regression/bugzilla/PR113.java [new file with mode: 0644]
tests/regression/bugzilla/PR114.java [new file with mode: 0644]
tests/regression/bugzilla/PR116.java [new file with mode: 0644]

index 78ba758a196f5adfac2e806460f21703cdb2482e..b486fcf3327a26ca3ae973fd931ae1caffcfa1cc 100644 (file)
@@ -63,8 +63,8 @@ libmm_la_SOURCES = \
        dumpmemory.hpp \
        $(GC_FILE) \
        gc.hpp \
-       memory.c \
-       memory.h
+       memory.cpp \
+       memory.hpp
 
 libmm_la_LIBADD = \
        $(GC_LIB)
index 5e384d3978a53a5ab79d9cdb588a6074eff1fbff..0cd0ad60d543b8f0604117bca7d628ccfb07b651 100644 (file)
@@ -31,8 +31,8 @@
 #include "gc.h"
 #include "heap.h"
 #include "mark.h"
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 
 
 /* Threading macros ***********************************************************/
index 425da5872b5a50a2c2eb464d16c9a5e773462ee6..94822d938b720202a4f773fca1910bc7fcb5800f 100644 (file)
@@ -33,8 +33,8 @@
 #include "mark.h"
 #include "region.h"
 #include "rootset.h"
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 #include "vm/global.h"
 
 
index b895797e4305c9ac5a9b6b854ae9b19b26c086eb..fadad86875ec0f5d9129784c1f42ca35c9f3f3ad 100644 (file)
@@ -29,8 +29,8 @@
 #include "gc.h"
 #include "final.h"
 #include "heap.h"
-#include "mm/memory.h"
-#include "vm/finalizer.h"
+#include "mm/memory.hpp"
+#include "vm/finalizer.hpp"
 
 
 /* Global Variables ***********************************************************/
index e9fd6d50f66e34a5f5232eff0da07d1cb7bcaf71..6853ebc95b910ccdfcdd641658e24bac156b177f 100644 (file)
 #include "mark.h"
 #include "region.h"
 #include "rootset.h"
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 
-#include "vm/finalizer.h"
+#include "vm/finalizer.hpp"
 #include "vm/rt-timing.h"
 #include "vm/vm.hpp"
 
index 22ce0691738fe9c8f42399c8e1be3bd1964972dc..66a9f8c5e5a269467987a9a10ec9ea0943fbf91c 100644 (file)
 #include "heap.h"
 #include "mark.h"
 #include "region.h"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "native/include/java_lang_String.h"
 #include "native/llni.h"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/global.h"
 #include "vm/options.h"
index fedfb9abb750990dd7b339b972510ad343280603..a18ceca7274dd004ce8e18568d6e04e0f8a08ea6 100644 (file)
@@ -30,8 +30,8 @@
 #include "heap.h"
 #include "mark.h"
 #include "rootset.h"
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 
 #include "vm/global.h"
 #include "vm/linker.hpp"
index 44a443d1ce7f3e0f61c4e62ea903cb9a72928c7d..f601e530a8783ea67a24619b89e058848fd455c6 100644 (file)
@@ -29,8 +29,8 @@
 #include "vm/types.h"
 
 #include "region.h"
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 
 
 /* region_init *****************************************************************
index 7761fa8089b0050309df666fa9c841c577b7058a..ce6a680712fd5d44da1f30042df4062bb2f00b68 100644 (file)
 #include "heap.h"
 #include "mark.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/threadlist.h"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/global.h"
 #include "vm/jit/replace.hpp"
index b56179221b9333c55b51f6423befe5654043ae84..c3e00384cabd03751410120125a8d08eeb40dd85 100644 (file)
@@ -33,7 +33,7 @@
 #include "threads/thread.hpp"
 
 #include "mm/codememory.h"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/global.h"
 #include "vm/options.h"
index 4650d52fbc2551fb78feab26853e401a6a379ec6..75de734a53a04a9e37fce82cb35b54a65201635c 100644 (file)
@@ -29,7 +29,7 @@
 #include <stdint.h>
 
 #include "mm/dumpmemory.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/thread.hpp"
 
index c871d3e04a7dd3bd342946bbab338682cd227145..79433a1864386310058d7d71810e1f1fb5893ce5 100644 (file)
@@ -209,7 +209,7 @@ public:
 
 
 // Includes.
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/thread.hpp"
 
index bfd612b010cf6be5879a74d721929707d003057f..ca8501e639d4ebc2fd8ad079e6424785591f1968 100644 (file)
 
 #include "boehm-gc/include/gc.h"
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
-#include "vm/finalizer.h"
+#include "vm/finalizer.hpp"
 #include "vm/global.h"
 #include "vm/loader.hpp"
 #include "vm/options.h"
index d0a488d2ae205a9b300eb038df3b07cdda3e9dc7..0ef0cf3f0909c0a95022080a7582c783770644c1 100644 (file)
@@ -36,9 +36,9 @@
 #include "boehm-gc/include/gc.h"
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/global.h"
diff --git a/src/mm/memory.c b/src/mm/memory.c
deleted file mode 100644 (file)
index 0774aee..0000000
+++ /dev/null
@@ -1,274 +0,0 @@
-/* src/mm/memory.c - memory management
-
-   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>
-
-#if defined(__DARWIN__)
-/* If we compile with -ansi on darwin, <sys/types.h> is not
-   included. So let's do it here. */
-# include <sys/types.h>
-#endif
-
-#include "vm/types.h"
-
-#include "arch.h"
-
-#include "mm/memory.h"
-
-#include "native/native.hpp"
-
-#include "threads/lock.hpp"
-#include "threads/thread.hpp"
-
-#include "toolbox/logging.h"
-
-#include "vm/global.h"
-#include "vm/string.hpp"
-#include "vm/vm.hpp"
-
-#include "vm/options.h"
-#include "vm/os.hpp"
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-
-/* memory_mprotect *************************************************************
-
-   Convenience function for mprotect.  This function also does error
-   checking.
-
-*******************************************************************************/
-
-void memory_mprotect(void *addr, size_t len, int prot)
-{
-       if (os_mprotect(addr, len, prot) != 0)
-               vm_abort_errno("memory_mprotect: os_mprotect failed");
-}
-
-
-/* memory_checked_alloc ********************************************************
-
-   Allocated zeroed-out memory and does an OOM check.
-
-   ERROR HANDLING:
-      XXX If no memory could be allocated, this function justs *exists*.
-
-*******************************************************************************/
-
-void *memory_checked_alloc(size_t size)
-{
-       /* always allocate memory zeroed out */
-
-       void *p = os_calloc(size, 1);
-
-       if (p == NULL)
-               vm_abort("memory_checked_alloc: calloc failed: out of memory");
-
-       return p;
-}
-
-
-void *mem_alloc(int32_t size)
-{
-       void *m;
-
-       if (size == 0)
-               return NULL;
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat) {
-               memoryusage += size;
-
-               if (memoryusage > maxmemusage)
-                       maxmemusage = memoryusage;
-       }
-#endif
-
-       m = memory_checked_alloc(size);
-
-#if defined(ENABLE_MEMCHECK)
-       /* XXX we would like to poison the memory, but callers rely on */
-       /* the zeroing. This should change sooner or later.            */
-       /* memset(m, MEMORY_CLEAR_BYTE, size); */
-#endif
-
-       return m;
-}
-
-
-void *mem_realloc(void *src, int32_t len1, int32_t len2)
-{
-       void *dst;
-
-       /* prevent compiler warnings */
-
-       dst = NULL;
-
-       if (src == NULL)
-               if (len1 != 0)
-                       vm_abort("mem_realloc: reallocating memoryblock with address NULL, length != 0");
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               memoryusage = (memoryusage - len1) + len2;
-#endif
-
-#if defined(ENABLE_MEMCHECK)
-       if (len2 < len1)
-               os_memset((u1*)dst + len2, MEMORY_CLEAR_BYTE, len1 - len2);
-#endif
-
-       dst = realloc(src, len2);
-
-       if (dst == NULL)
-               vm_abort("mem_realloc: realloc failed: out of memory");
-
-#if defined(ENABLE_MEMCHECK)
-       if (len2 > len1)
-               os_memset((u1*)dst + len1, MEMORY_CLEAR_BYTE, len2 - len1);
-#endif
-
-       return dst;
-}
-
-
-void mem_free(void *m, int32_t size)
-{
-       if (!m) {
-               if (size == 0)
-                       return;
-
-               log_text("returned memoryblock with address NULL, length != 0");
-               assert(0);
-       }
-
-#if defined(ENABLE_STATISTICS)
-       if (opt_stat)
-               memoryusage -= size;
-#endif
-
-#if defined(ENABLE_MEMCHECK)
-       /* destroy the contents */
-       os_memset(m, MEMORY_CLEAR_BYTE, size);
-#endif
-
-       os_free(m);
-}
-
-
-/* memory_thread ***************************************************************
-
-   Prints regularly memory statistics.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS) && !defined(NDEBUG)
-static void memory_thread(void)
-{
-       int32_t seconds;
-
-       /* Prevent compiler warning. */
-
-       seconds = 1;
-
-       /* If both arguments are specified, use the value of
-          ProfileMemoryUsage. */
-
-       if (opt_ProfileGCMemoryUsage)
-               seconds = opt_ProfileGCMemoryUsage;
-
-       if (opt_ProfileMemoryUsage)
-               seconds = opt_ProfileMemoryUsage;
-
-       while (true) {
-               /* sleep thread */
-
-               threads_sleep(seconds * 1000, 0);
-
-# if defined(ENABLE_STATISTICS)
-               /* Print current date and time (only when we print to the
-                  stdout). */
-
-               if (!opt_ProfileMemoryUsageGNUPlot)
-                       statistics_print_date();
-
-               /* print memory usage */
-
-               if (opt_ProfileMemoryUsage)
-                       statistics_print_memory_usage();
-
-               /* print GC memory usage */
-
-               if (opt_ProfileGCMemoryUsage)
-                       statistics_print_gc_memory_usage();
-# endif
-       }
-}
-#endif
-
-
-/* memory_start_thread *********************************************************
-
-   Starts the memory profiling thread.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS) && !defined(NDEBUG)
-bool memory_start_thread(void)
-{
-       utf *name;
-
-       name = utf_new_char("Memory Profiler");
-
-       /* start the memory profiling thread */
-
-       if (!threads_thread_start_internal(name, memory_thread))
-               return false;
-
-       /* everything's ok */
-
-       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/mm/memory.cpp b/src/mm/memory.cpp
new file mode 100644 (file)
index 0000000..f074e1d
--- /dev/null
@@ -0,0 +1,274 @@
+/* src/mm/memory.cpp - memory management
+
+   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>
+
+#if defined(__DARWIN__)
+/* If we compile with -ansi on darwin, <sys/types.h> is not
+   included. So let's do it here. */
+# include <sys/types.h>
+#endif
+
+#include "vm/types.h"
+
+#include "arch.h"
+
+#include "mm/memory.hpp"
+
+#include "native/native.hpp"
+
+#include "threads/lock.hpp"
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.hpp"
+
+#include "vm/global.h"
+#include "vm/string.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/options.h"
+#include "vm/os.hpp"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+
+/* memory_mprotect *************************************************************
+
+   Convenience function for mprotect.  This function also does error
+   checking.
+
+*******************************************************************************/
+
+void memory_mprotect(void *addr, size_t len, int prot)
+{
+       if (os::mprotect(addr, len, prot) != 0)
+               vm_abort_errno("memory_mprotect: os::mprotect failed");
+}
+
+
+/* memory_checked_alloc ********************************************************
+
+   Allocated zeroed-out memory and does an OOM check.
+
+   ERROR HANDLING:
+      XXX If no memory could be allocated, this function justs *exists*.
+
+*******************************************************************************/
+
+void *memory_checked_alloc(size_t size)
+{
+       /* always allocate memory zeroed out */
+
+       void *p = os::calloc(size, 1);
+
+       if (p == NULL)
+               vm_abort("memory_checked_alloc: calloc failed: out of memory");
+
+       return p;
+}
+
+
+void *mem_alloc(int32_t size)
+{
+       void *m;
+
+       if (size == 0)
+               return NULL;
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat) {
+               memoryusage += size;
+
+               if (memoryusage > maxmemusage)
+                       maxmemusage = memoryusage;
+       }
+#endif
+
+       m = memory_checked_alloc(size);
+
+#if defined(ENABLE_MEMCHECK)
+       /* XXX we would like to poison the memory, but callers rely on */
+       /* the zeroing. This should change sooner or later.            */
+       /* memset(m, MEMORY_CLEAR_BYTE, size); */
+#endif
+
+       return m;
+}
+
+
+void *mem_realloc(void *src, int32_t len1, int32_t len2)
+{
+       void *dst;
+
+       /* prevent compiler warnings */
+
+       dst = NULL;
+
+       if (src == NULL)
+               if (len1 != 0)
+                       vm_abort("mem_realloc: reallocating memoryblock with address NULL, length != 0");
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               memoryusage = (memoryusage - len1) + len2;
+#endif
+
+#if defined(ENABLE_MEMCHECK)
+       if (len2 < len1)
+               os::memset((u1*)dst + len2, MEMORY_CLEAR_BYTE, len1 - len2);
+#endif
+
+       dst = realloc(src, len2);
+
+       if (dst == NULL)
+               vm_abort("mem_realloc: realloc failed: out of memory");
+
+#if defined(ENABLE_MEMCHECK)
+       if (len2 > len1)
+               os::memset((u1*)dst + len1, MEMORY_CLEAR_BYTE, len2 - len1);
+#endif
+
+       return dst;
+}
+
+
+void mem_free(void *m, int32_t size)
+{
+       if (!m) {
+               if (size == 0)
+                       return;
+
+               log_text("returned memoryblock with address NULL, length != 0");
+               assert(0);
+       }
+
+#if defined(ENABLE_STATISTICS)
+       if (opt_stat)
+               memoryusage -= size;
+#endif
+
+#if defined(ENABLE_MEMCHECK)
+       /* destroy the contents */
+       os::memset(m, MEMORY_CLEAR_BYTE, size);
+#endif
+
+       os::free(m);
+}
+
+
+/* memory_thread ***************************************************************
+
+   Prints regularly memory statistics.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS) && !defined(NDEBUG)
+static void memory_thread(void)
+{
+       int32_t seconds;
+
+       /* Prevent compiler warning. */
+
+       seconds = 1;
+
+       /* If both arguments are specified, use the value of
+          ProfileMemoryUsage. */
+
+       if (opt_ProfileGCMemoryUsage)
+               seconds = opt_ProfileGCMemoryUsage;
+
+       if (opt_ProfileMemoryUsage)
+               seconds = opt_ProfileMemoryUsage;
+
+       while (true) {
+               /* sleep thread */
+
+               threads_sleep(seconds * 1000, 0);
+
+# if defined(ENABLE_STATISTICS)
+               /* Print current date and time (only when we print to the
+                  stdout). */
+
+               if (!opt_ProfileMemoryUsageGNUPlot)
+                       statistics_print_date();
+
+               /* print memory usage */
+
+               if (opt_ProfileMemoryUsage)
+                       statistics_print_memory_usage();
+
+               /* print GC memory usage */
+
+               if (opt_ProfileGCMemoryUsage)
+                       statistics_print_gc_memory_usage();
+# endif
+       }
+}
+#endif
+
+
+/* memory_start_thread *********************************************************
+
+   Starts the memory profiling thread.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS) && !defined(NDEBUG)
+bool memory_start_thread(void)
+{
+       utf *name;
+
+       name = utf_new_char("Memory Profiler");
+
+       /* start the memory profiling thread */
+
+       if (!threads_thread_start_internal(name, memory_thread))
+               return false;
+
+       /* everything's ok */
+
+       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/mm/memory.h b/src/mm/memory.h
deleted file mode 100644 (file)
index ec6393f..0000000
+++ /dev/null
@@ -1,169 +0,0 @@
-/* src/mm/memory.h - macros for memory management
-
-   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 _MEMORY_H
-#define _MEMORY_H
-
-#include "config.h"
-
-#include <stdint.h>
-
-
-// Align the size of memory allocations to this size.
-#define ALIGNSIZE 8
-#define MEMORY_ALIGN(pos,size) ((((pos) + (size) - 1) / (size)) * (size))
-
-
-// Constants for ENABLE_MEMCHECK.
-
-#if defined(ENABLE_MEMCHECK)
-#define MEMORY_CANARY_SIZE          16
-#define MEMORY_CANARY_FIRST_BYTE    0xca
-#define MEMORY_CLEAR_BYTE           0xa5
-#endif
-
-
-// Includes.
-#include "mm/codememory.h"
-#include "mm/dumpmemory.hpp"
-#include "mm/gc.hpp"
-
-
-/* 
----------------------------- Interface description -----------------------
-
-There are two possible choices for allocating memory:
-
-       1.   explicit allocating / deallocating
-
-                       mem_alloc ..... allocate a memory block 
-                       mem_free ...... free a memory block
-                       mem_realloc ... change size of a memory block (position may change)
-                       mem_usage ..... amount of allocated memory
-
-There are some useful macros:
-
-       NEW (type) ....... allocate memory for an element of type `type`
-       FREE (ptr,type) .. free memory
-       
-       MNEW (type,num) .. allocate memory for an array
-       MFREE (ptr,type,num) .. free memory
-       
-       MREALLOC (ptr,type,num1,num2) .. enlarge the array to size num2
-                                        
--------------------------------------------------------------------------------
-
-Some more macros:
-
-       MEMORY_ALIGN (pos, size) ... make pos divisible by size. always returns an
-                                 address >= pos.
-                             
-       
-       OFFSET (s,el) ....... returns the offset of 'el' in structure 's' in bytes.
-                             
-       MCOPY (dest,src,type,num) ... copy 'num' elements of type 'type'.
-       
-
-*/
-
-#define PADDING(pos,size)     (MEMORY_ALIGN((pos),(size)) - (pos))
-#define OFFSET(s,el)          ((int32_t) ((ptrint) &(((s*) 0)->el)))
-
-
-#define NEW(type)             ((type *) mem_alloc(sizeof(type)))
-#define FREE(ptr,type)        mem_free((ptr), sizeof(type))
-
-#define MNEW(type,num)        ((type *) mem_alloc(sizeof(type) * (num)))
-#define MFREE(ptr,type,num)   mem_free((ptr), sizeof(type) * (num))
-
-#define MREALLOC(ptr,type,num1,num2) mem_realloc((ptr), sizeof(type) * (num1), \
-                                                        sizeof(type) * (num2))
-
-
-#define MCOPY(dest,src,type,num) memcpy((dest), (src), sizeof(type) * (num))
-#define MSET(ptr,byte,type,num) memset((ptr), (byte), sizeof(type) * (num))
-#define MZERO(ptr,type,num)     MSET(ptr,0,type,num)
-#define MMOVE(dest,src,type,num) memmove((dest), (src), sizeof(type) * (num))
-
-
-/* GC macros (boehm only) *****************************************************/
-
-#if defined(ENABLE_GC_BOEHM)
-
-/* Uncollectable memory which can contain references */
-
-#define GCNEW_UNCOLLECTABLE(type,num) ((type *) heap_alloc_uncollectable(sizeof(type) * (num)))
-
-#define GCNEW(type)           heap_alloc(sizeof(type), true, NULL, true)
-#define GCMNEW(type,num)      heap_alloc(sizeof(type) * (num), true, NULL, true)
-
-#define GCFREE(ptr)           heap_free((ptr))
-
-#endif
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool  memory_init(void);
-
-void  memory_mprotect(void *addr, size_t len, int prot);
-
-void *memory_checked_alloc(size_t size);
-
-void *memory_cnew(int32_t size);
-void  memory_cfree(void *p, int32_t size);
-
-void *mem_alloc(int32_t size);
-void  mem_free(void *m, int32_t size);
-void *mem_realloc(void *src, int32_t len1, int32_t len2);
-
-#if defined(ENABLE_THREADS)
-bool  memory_start_thread(void);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _MEMORY_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/mm/memory.hpp b/src/mm/memory.hpp
new file mode 100644 (file)
index 0000000..9045b48
--- /dev/null
@@ -0,0 +1,169 @@
+/* src/mm/memory.hpp - macros for memory management
+
+   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 _MEMORY_H
+#define _MEMORY_H
+
+#include "config.h"
+
+#include <stdint.h>
+
+
+// Align the size of memory allocations to this size.
+#define ALIGNSIZE 8
+#define MEMORY_ALIGN(pos,size) ((((pos) + (size) - 1) / (size)) * (size))
+
+
+// Constants for ENABLE_MEMCHECK.
+
+#if defined(ENABLE_MEMCHECK)
+#define MEMORY_CANARY_SIZE          16
+#define MEMORY_CANARY_FIRST_BYTE    0xca
+#define MEMORY_CLEAR_BYTE           0xa5
+#endif
+
+
+// Includes.
+#include "mm/codememory.h"
+#include "mm/dumpmemory.hpp"
+#include "mm/gc.hpp"
+
+
+/* 
+---------------------------- Interface description -----------------------
+
+There are two possible choices for allocating memory:
+
+       1.   explicit allocating / deallocating
+
+                       mem_alloc ..... allocate a memory block 
+                       mem_free ...... free a memory block
+                       mem_realloc ... change size of a memory block (position may change)
+                       mem_usage ..... amount of allocated memory
+
+There are some useful macros:
+
+       NEW (type) ....... allocate memory for an element of type `type`
+       FREE (ptr,type) .. free memory
+       
+       MNEW (type,num) .. allocate memory for an array
+       MFREE (ptr,type,num) .. free memory
+       
+       MREALLOC (ptr,type,num1,num2) .. enlarge the array to size num2
+                                        
+-------------------------------------------------------------------------------
+
+Some more macros:
+
+       MEMORY_ALIGN (pos, size) ... make pos divisible by size. always returns an
+                                 address >= pos.
+                             
+       
+       OFFSET (s,el) ....... returns the offset of 'el' in structure 's' in bytes.
+                             
+       MCOPY (dest,src,type,num) ... copy 'num' elements of type 'type'.
+       
+
+*/
+
+#define PADDING(pos,size)     (MEMORY_ALIGN((pos),(size)) - (pos))
+#define OFFSET(s,el)          ((int32_t) ((ptrint) &(((s*) 0)->el)))
+
+
+#define NEW(type)             ((type *) mem_alloc(sizeof(type)))
+#define FREE(ptr,type)        mem_free((ptr), sizeof(type))
+
+#define MNEW(type,num)        ((type *) mem_alloc(sizeof(type) * (num)))
+#define MFREE(ptr,type,num)   mem_free((ptr), sizeof(type) * (num))
+
+#define MREALLOC(ptr,type,num1,num2) mem_realloc((ptr), sizeof(type) * (num1), \
+                                                        sizeof(type) * (num2))
+
+
+#define MCOPY(dest,src,type,num) memcpy((dest), (src), sizeof(type) * (num))
+#define MSET(ptr,byte,type,num) memset((ptr), (byte), sizeof(type) * (num))
+#define MZERO(ptr,type,num)     MSET(ptr,0,type,num)
+#define MMOVE(dest,src,type,num) memmove((dest), (src), sizeof(type) * (num))
+
+
+/* GC macros (boehm only) *****************************************************/
+
+#if defined(ENABLE_GC_BOEHM)
+
+/* Uncollectable memory which can contain references */
+
+#define GCNEW_UNCOLLECTABLE(type,num) ((type *) heap_alloc_uncollectable(sizeof(type) * (num)))
+
+#define GCNEW(type)           heap_alloc(sizeof(type), true, NULL, true)
+#define GCMNEW(type,num)      heap_alloc(sizeof(type) * (num), true, NULL, true)
+
+#define GCFREE(ptr)           heap_free((ptr))
+
+#endif
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool  memory_init(void);
+
+void  memory_mprotect(void *addr, size_t len, int prot);
+
+void *memory_checked_alloc(size_t size);
+
+void *memory_cnew(int32_t size);
+void  memory_cfree(void *p, int32_t size);
+
+void *mem_alloc(int32_t size);
+void  mem_free(void *m, int32_t size);
+void *mem_realloc(void *src, int32_t len1, int32_t len2);
+
+#if defined(ENABLE_THREADS)
+bool  memory_start_thread(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _MEMORY_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 e46cf87602be1397271c68a2f4751c08337d6bac..6fcaf5a7a42b0e5192f0252bb278437c3394b656 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "config.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "mm/tlh.h"
 
 #include "vm/global.h"
index 674f3b8b0d4e51084dbb7eb0b7570289fc029a55..1f3bb40d2a7fca51455b3bc97277aaeefa031740 100644 (file)
@@ -32,7 +32,7 @@
 #include "vm/types.h"
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
@@ -47,7 +47,7 @@
 #include "threads/mutex.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
index eb29c6f7b5313c27252ea99087e8647816281fd3..85c4f8774414b790f0a60d7002de46a87803de1d 100644 (file)
@@ -32,7 +32,7 @@
 #include "vm/jit/builtin.hpp"
 #include "vm/jit/asmpart.h"
 #include "vm/string.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "threads/mutex.h"
 #include "threads/thread.hpp"
 
index e152104dc03727f421198320dcd9683368b92726..461869ecc9cdb421a1532cbcb4bf29ae94865f6c 100644 (file)
 #include "vm/class.hpp"
 #include "vm/classcache.hpp"
 #include "mm/gc.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "vm/options.h"
 #include "vm/string.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "threads/mutex.h"
 #include "threads/thread.hpp"
 #include "threads/lock.hpp"
index d236afb5148224eadcb44773702bf07a12ce969f..bec9bfe0208f90a9b0079670ae254593d370397f 100644 (file)
 #include <assert.h>
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/options.h"
 #include "vm/vm.hpp"
index 7f0f078ba55f0bd3cfb029a05def1836b3408198..0c12b69d11b6eb2f803dd88e1d4d6b9980daf6cc 100644 (file)
 #include <functional>
 #include <map>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/native.hpp"
 
 #include "threads/mutex.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
index 2ece32fc4ba96ee68313b3df4e261b3dced6b02a..ba78eaaddf441a7309fec2eee7b96f5fa3495ed6 100644 (file)
@@ -31,7 +31,7 @@
 #include <errno.h>
 #include <zlib.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
index 9ad7f7c206d258eb6d074778a4b3ea8c0de0998a..16bebd345efc6aa23b3d1d82550b4c612853c676 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
index 9d521e2a18c5f23225074b5d29806e498bfe89a3..d4c200150097047afe2cc3974d753f1695bdeae9 100644 (file)
@@ -63,6 +63,18 @@ JNIEXPORT jint JNICALL Java_java_lang_Float_floatToIntBits(JNIEnv *env, jclass c
        return val.i;
 }
 
+/*
+ * Class:     java/lang/Float
+ * Method:    intBitsToFloat
+ * Signature: (I)F
+ */
+JNIEXPORT jfloat JNICALL Java_java_lang_Float_intBitsToFloat(JNIEnv *env, jclass clazz, jint value)
+{
+        imm_union val;
+        val.i = value;
+        return val.f;
+}
+
 } // extern "C"
 
 
@@ -70,6 +82,7 @@ JNIEXPORT jint JNICALL Java_java_lang_Float_floatToIntBits(JNIEnv *env, jclass c
  
 static JNINativeMethod methods[] = {
        { (char*) "floatToIntBits", (char*) "(F)I", (void*) (uintptr_t) &Java_java_lang_Float_floatToIntBits },
+       { (char*) "intBitsToFloat", (char*) "(I)F", (void*) (uintptr_t) &Java_java_lang_Float_intBitsToFloat }
 };
  
  
index ccc1c0eccc57c92e9d751b0db67fa881eff5e5a0..7403c9622f1402a4485646c24e2014ca42c0cbae 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdint.h>
 #include <stdlib.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/native.hpp"
@@ -38,6 +38,7 @@
 #endif
 
 #include "vm/jit/builtin.hpp"
+#include "vm/javaobjects.hpp"
 #include "vm/properties.hpp"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
@@ -93,6 +94,18 @@ JNIEXPORT jstring JNICALL Java_java_lang_System_getProperty0(JNIEnv *env, jclass
        return (jstring) result;
 }
 
+/*
+ * Class:     java/lang/System
+ * Method:    identityHashCode
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_java_lang_System_identityHashCode(JNIEnv *env, jclass clazz, jobject obj)
+{
+        java_lang_Object o(obj);
+
+        return o.get_hashcode();
+}
+
 } // extern "C"
 
 
@@ -101,6 +114,7 @@ JNIEXPORT jstring JNICALL Java_java_lang_System_getProperty0(JNIEnv *env, jclass
 static JNINativeMethod methods[] = {
        { (char*) "arraycopy",    (char*) "(Ljava/lang/Object;ILjava/lang/Object;II)V", (void*) (uintptr_t) &Java_java_lang_System_arraycopy    },
        { (char*) "getProperty0", (char*) "(Ljava/lang/String;)Ljava/lang/String;",     (void*) (uintptr_t) &Java_java_lang_System_getProperty0 },
+       { (char*) "identityHashCode", (char*) "(Ljava/lang/Object;)I",                  (void*) (uintptr_t) &Java_java_lang_System_identityHashCode }
 };
 
 
index 99a7393a06f78562a9a4d75d263a9600a63560f7..0f68bd5e01aa29b728649eed702c0153d7b691ef 100644 (file)
@@ -35,8 +35,9 @@
 #endif
 
 #include "threads/thread.hpp"
+#include "threads/threadlist.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/javaobjects.hpp"
@@ -128,7 +129,6 @@ JNIEXPORT jboolean JNICALL Java_java_lang_Thread_isAlive(JNIEnv *env, jobject _t
 }
 
 
-#if 0
 /*
  * Class:     java/lang/Thread
  * Method:    activeCount
@@ -136,6 +136,11 @@ JNIEXPORT jboolean JNICALL Java_java_lang_Thread_isAlive(JNIEnv *env, jobject _t
  */
 JNIEXPORT s4 JNICALL Java_java_lang_Thread_activeCount(JNIEnv *env, jclass clazz)
 {
+#if defined(ENABLE_THREADS)
+       return ThreadList::get_number_of_non_daemon_threads();
+#else
+       return 1;
+#endif
 }
 
 
@@ -146,9 +151,14 @@ JNIEXPORT s4 JNICALL Java_java_lang_Thread_activeCount(JNIEnv *env, jclass clazz
  */
 JNIEXPORT void JNICALL Java_java_lang_Thread_interrupt0(JNIEnv *env, jobject _this)
 {
+#if defined(ENABLE_THREADS)
+       java_lang_Thread jlt(_this);
+        threadobject* t = jlt.get_vm_thread();
+        threads_thread_interrupt(t);
+#endif
 }
 
-
+#if 0
 /*
  * Class:     java/lang/Thread
  * Method:    internalExit
@@ -183,10 +193,10 @@ static JNINativeMethod methods[] = {
        { (char*) "sleep",         (char*) "(J)V",                 (void*) (uintptr_t) &Java_java_lang_Thread_sleep         },
        { (char*) "start0",        (char*) "()V",                  (void*) (uintptr_t) &Java_java_lang_Thread_start0        },
        { (char*) "isAlive",       (char*) "()Z",                  (void*) (uintptr_t) &Java_java_lang_Thread_isAlive       },
-#if 0
        { (char*) "activeCount",   (char*) "()I",                  (void*) (uintptr_t) &Java_java_lang_Thread_activeCount   },
        { (char*) "setPriority0",  (char*) "(II)V",                (void*) (uintptr_t) &Java_java_lang_Thread_setPriority0  },
        { (char*) "interrupt0",    (char*) "()V",                  (void*) (uintptr_t) &Java_java_lang_Thread_interrupt0    },
+#if 0
        { (char*) "internalExit",  (char*) "()V",                  (void*) (uintptr_t) &Java_java_lang_Thread_internalExit  },
 #endif
        { (char*) "yield",         (char*) "()V",                  (void*) (uintptr_t) &Java_java_lang_Thread_yield         },
index 0789c0eda8d96a7a61fb1c31e31e32ab9a86c337..dc4e5ebb04726356aa8a571c0f3b228669a116b9 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/native.hpp"
index 9276ebb8feebcbf5fec468178da435e9fc36cf48..4897589cba18cafff294c07586fc88d03aafab10 100644 (file)
@@ -32,7 +32,7 @@
 #include "native/include/java_lang_Object.h"
 #include "native/include/gnu_classpath_jdwp_VMFrame.h"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 
 /*
index eaf47e6301c3cfea38b5233c8360fbd5f19c5cb4..63e253b7cfaf41545f6874aa484d6d839400b9e6 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdint.h>
 #include <string.h>
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "native/jni.hpp"
 #include "native/include/java_lang_Thread.h"
 #include "native/include/java_nio_ByteBuffer.h"
index c706681c933a4dbe55691df719b83d62a2fb10a0..c00c3e9a45402de02189d21b77698ece61da2cfd 100644 (file)
@@ -36,7 +36,7 @@
 # include "native/vm/include/gnu_java_lang_management_VMClassLoadingMXBeanImpl.h"
 #endif
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/classcache.hpp"
 #include "vm/utf8.h"
index f04140ff3851ccf8a8e11ba35278b614af15f778..359931c254fe82d3b79a60699afaa6a63c062460 100644 (file)
@@ -36,7 +36,7 @@
 # include "native/vm/include/gnu_java_lang_management_VMThreadMXBeanImpl.h"
 #endif
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/classcache.hpp"
 #include "vm/utf8.h"
index 5141c335de95f307c038aa24cccc389d037d59c4..d0d9e44dfddcfb38bfef0ad622730be1af456217 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/string.hpp"
 
 #if defined(ENABLE_ANNOTATIONS)
-#include "vm/annotation.h"
+#include "vm/annotation.hpp"
 #include "vm/vm.hpp"
 #endif
 
index 7e2c0b8359a2536f3a634e57d743ba1f983c16d0..ebeeb162885c7f07b55162ea875171cfeebc57a2 100644 (file)
@@ -29,7 +29,7 @@
 #include <stdint.h>
 #include <sys/stat.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
@@ -39,7 +39,7 @@
 # include "native/vm/include/java_lang_VMClassLoader.h"
 #endif
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/list.hpp"
 
 #if defined(ENABLE_ASSERTION)
index 93b8833f1335bd0aa0ec2609993f643b27353790..2a885667889121a6f8d78e290b960cbbd9ce1ee2 100644 (file)
@@ -39,7 +39,7 @@
 # include <mach/mach.h>
 #endif
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "mm/gc.hpp"
 
 #include "native/jni.hpp"
index da3eccb25488ba8f6f45dc8d81798a7ac3184940..da561ab5aae1e30e7adc637f185475a33539a3b0 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "config.h"
 
+#include <assert.h>
 #include <stdint.h>
 
 #include "native/jni.hpp"
@@ -56,7 +57,7 @@ JNIEXPORT jint JNICALL Java_java_lang_VMThread_countStackFrames(JNIEnv *env, job
 {
        log_println("Java_java_lang_VMThread_countStackFrames: Deprecated.  Not implemented.");
 
-    return 0;
+       return 0;
 }
 
 
@@ -88,6 +89,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_interrupt(JNIEnv *env, jobject _t
 
        h = (java_handle_t *) _this;
        t = thread_get_thread(h);
+       assert(t != NULL);
 
        threads_thread_interrupt(t);
 #endif
@@ -107,6 +109,7 @@ JNIEXPORT jboolean JNICALL Java_java_lang_VMThread_isInterrupted(JNIEnv *env, jo
 
        h = (java_handle_t *) _this;
        t = thread_get_thread(h);
+       assert(t != NULL);
 
        return thread_is_interrupted(t);
 #else
@@ -154,6 +157,7 @@ JNIEXPORT void JNICALL Java_java_lang_VMThread_nativeSetPriority(JNIEnv *env, jo
 
        h = (java_handle_t *) _this;
        t = thread_get_thread(h);
+       assert(t != NULL);
 
        threads_set_thread_priority(t->tid, priority);
 #endif
@@ -279,6 +283,7 @@ JNIEXPORT jstring JNICALL Java_java_lang_VMThread_getState(JNIEnv *env, jobject
 
        h = (java_handle_t *) _this;
        t = thread_get_thread(h);
+       assert(t != NULL);
 
        state = cacaothread_get_state(t);
        
@@ -298,6 +303,12 @@ JNIEXPORT jstring JNICALL Java_java_lang_VMThread_getState(JNIEnv *env, jobject
        case THREAD_STATE_TIMED_WAITING:
                u = utf_new_char("TIMED_WAITING");
                break;
+       case THREAD_STATE_PARKED:
+               u = utf_new_char("PARKED");
+               break;
+       case THREAD_STATE_TIMED_PARKED:
+               u = utf_new_char("TIMED_PARKED");
+               break;
        case THREAD_STATE_TERMINATED:
                u = utf_new_char("TERMINATED");
                break;
index d62fe2926d48200e96df73bfec11f287184ebfc6..fca7f8d1d783d0b9396f820adfe3ddeac5983569 100644 (file)
@@ -101,66 +101,7 @@ JNIEXPORT jobjectArray JNICALL Java_java_lang_VMThrowable_getStackTrace(JNIEnv *
 
        assert(st != NULL);
 
-       stacktrace_entry_t* ste = st->entries;
-
-       /* Create the stacktrace element array. */
-
-       java_handle_objectarray_t* oa = builtin_anewarray(st->length, class_java_lang_StackTraceElement);
-
-       if (oa == NULL)
-               return NULL;
-
-       for (int i = 0; i < st->length; i++, ste++) {
-               /* Get the codeinfo and methodinfo. */
-
-               codeinfo*   code = ste->code;
-               methodinfo* m    = code->m;
-
-               /* Get filename. */
-
-               java_handle_t* filename;
-
-               if (!(m->flags & ACC_NATIVE)) {
-                       if (m->clazz->sourcefile)
-                               filename = javastring_new(m->clazz->sourcefile);
-                       else
-                               filename = NULL;
-               }
-               else
-                       filename = NULL;
-
-               /* get line number */
-
-               int32_t linenumber;
-
-               if (m->flags & ACC_NATIVE) {
-                       linenumber = -1;
-               }
-               else {
-                       /* FIXME linenumbertable->find could change the methodinfo
-                          pointer when hitting an inlined method. */
-
-                       linenumber = code->linenumbertable->find(&m, ste->pc);
-                       linenumber = (linenumber == 0) ? -1 : linenumber;
-               }
-
-               /* get declaring class name */
-
-               java_handle_t* declaringclass = class_get_classname(m->clazz);
-
-               /* allocate a new stacktrace element */
-
-               java_handle_t* h = builtin_new(class_java_lang_StackTraceElement);
-
-               if (h == NULL)
-                       return NULL;
-
-               java_lang_StackTraceElement ste(h, filename, linenumber, declaringclass, javastring_new(m->name), ((m->flags & ACC_NATIVE) ? 1 : 0));
-
-               array_objectarray_element_set(oa, i, ste.get_handle());
-       }
-
-       return (jobjectArray) oa;
+       return stacktrace_get_StackTraceElements(st);
 }
 
 } // extern "C"
index 10f450dd13daffeca9c4bed8dab1571ebbb335e0..23400775965991fd8ab821e8198ef71ecb437a75 100644 (file)
@@ -36,7 +36,7 @@
 # include "native/vm/include/java_lang_management_VMManagementFactory.h"
 #endif
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/globals.hpp"
 #include "vm/vm.hpp"
index b56ca42c33cccf37f72773295d448dfaa4e5823f..b811d6068dca24d65060697de33a1f9a57f3d283 100644 (file)
@@ -40,7 +40,7 @@
 #include <assert.h>
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
@@ -51,7 +51,7 @@
 
 #include "native/vm/reflection.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/class.hpp"
 #include "vm/exceptions.hpp"
index a61f61920a7792201cf92bb3c1bcdad6c161d57b..675bacb8518215d0ff0fe8ca071ebe3efaa76817 100644 (file)
@@ -36,7 +36,7 @@
 #include "vm/os.hpp"
 
 #if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-# include "mm/memory.h"
+# include "mm/memory.hpp"
 
 # include "native/native.hpp"
 
index ad6eec544c960f81079d65585f4c44d0bd157fab..7c7527897a487dffbae493c7ffc441f5441f43d1 100644 (file)
@@ -28,7 +28,7 @@
 // Include this one early.
 #include "native/vm/openjdk/hpi.hpp"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index 7a63880bab9f37cf002a76c0fa07959a9a75e56f..cc431263185f5366f223875e3ac581068eef4c7a 100644 (file)
@@ -50,7 +50,9 @@
 #include INCLUDE_JVM_MD_H
 #include INCLUDE_JVM_H
 
-#include "mm/memory.h"
+#include "fdlibm/fdlibm.h"
+
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 #include "native/native.hpp"
@@ -62,8 +64,9 @@
 
 #include "threads/lock.hpp"
 #include "threads/thread.hpp"
+#include "threads/threadlist.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/list.hpp"
 
 #include "vm/array.hpp"
@@ -85,7 +88,7 @@
 #include "vm/primitive.hpp"
 #include "vm/properties.hpp"
 #include "vm/resolve.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
 
@@ -435,64 +438,11 @@ jobject JVM_GetStackTraceElement(JNIEnv *env, jobject throwable, jint index)
        java_lang_Throwable jlt(throwable);
        java_handle_bytearray_t* ba = jlt.get_backtrace();
 
-       // We need a critical section here as the stacktrace structure is
+       // XXX We need a critical section here as the stacktrace structure is
        // mapped onto a Java byte-array.
-       LLNI_CRITICAL_START;
-
        stacktrace_t* st = (stacktrace_t *) LLNI_array_data(ba);
 
-       if ((index < 0) || (index >= st->length)) {
-               /* XXX This should be an IndexOutOfBoundsException (check this
-                  again). */
-               exceptions_throw_arrayindexoutofboundsexception();
-               return NULL;
-       }
-
-       // Get the stacktrace entry.
-       stacktrace_entry_t* ste = &(st->entries[index]);
-
-       // Get the codeinfo, methodinfo and classinfo.
-       codeinfo*   code = ste->code;
-       methodinfo* m    = code->m;
-       classinfo*  c    = m->clazz;
-
-       // Get filename.
-       java_handle_t* filename;
-
-       if (!(m->flags & ACC_NATIVE)) {
-               if (c->sourcefile != NULL)
-                       filename = javastring_new(c->sourcefile);
-               else
-                       filename = NULL;
-       }
-       else
-               filename = NULL;
-
-       // Get line number.
-       int32_t linenumber;
-
-       if (m->flags & ACC_NATIVE) {
-               linenumber = -2;
-       }
-       else {
-               // FIXME linenumbertable->find could change the methodinfo
-               // pointer when hitting an inlined method.
-               linenumber = code->linenumbertable->find(&m, ste->pc);
-               linenumber = (linenumber == 0) ? -1 : linenumber;
-       }
-
-       LLNI_CRITICAL_END;
-
-       // Get declaring class name.
-       java_handle_t* declaringclass = class_get_classname(c);
-
-       // Allocate a new StackTraceElement object.
-       java_lang_StackTraceElement jlste(declaringclass, javastring_new(m->name), filename, linenumber);
-
-       if (jlste.is_null())
-               return NULL;
-
-       return (jobject) jlste.get_handle();
+       return stacktrace_get_StackTraceElement(st, index);
 }
 
 
@@ -2183,8 +2133,7 @@ jboolean JVM_IsThreadAlive(JNIEnv* env, jobject jthread)
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
-       /* The threadobject is null when a thread is created in Java. The
-          priority is set later during startup. */
+       /* The threadobject is null when a thread is created in Java. */
 
        if (t == NULL)
                return 0;
@@ -2289,6 +2238,8 @@ void JVM_Interrupt(JNIEnv* env, jobject jthread)
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
+       /* The threadobject is null when a thread is created in Java. */
+
        if (t == NULL)
                return;
 
@@ -2309,6 +2260,11 @@ jboolean JVM_IsInterrupted(JNIEnv* env, jobject jthread, jboolean clear_interrup
        h = (java_handle_t *) jthread;
        t = thread_get_thread(h);
 
+       /* The threadobject is null when a thread is created in Java. */
+
+       if (t == NULL)
+               return JNI_FALSE;
+
        interrupted = thread_is_interrupted(t);
 
        if (interrupted && clear_interrupted)
@@ -2648,14 +2604,26 @@ jobject JVM_NewMultiArray(JNIEnv *env, jclass eltClass, jintArray dim)
 
        /* Create an array-class if necessary. */
 
-       if (class_is_primitive(c))
+       if (class_is_primitive(c)) {
                ac = Primitive::get_arrayclass_by_name(c->name);
+
+               // Arrays of void are not allowed.
+               if (ac == NULL) {
+                       exceptions_throw_illegalargumentexception();
+                       return NULL;
+               }
+
+               if (length > 1)
+                       ac = class_multiarray_of((length - 1), ac, true);
+       }
        else
-               ac = class_array_of(c, true);
+               ac = class_multiarray_of(length, c, true);
 
        if (ac == NULL)
                return NULL;
 
+       /* Allocate a new array on the heap. */
+
        a = builtin_multianewarray(length, (java_handle_t *) ac, dims);
 
        return (jobject) a;
@@ -2717,9 +2685,13 @@ jint JVM_Recv(jint fd, char *buf, jint nBytes, jint flags)
 
 jint JVM_Send(jint fd, char *buf, jint nBytes, jint flags)
 {
-       log_println("JVM_Send: IMPLEMENT ME!");
+       TRACEJVMCALLSENTER(("JVM_Send(fd=%d, buf=%p, nBytes=%d, flags=%d", fd, buf, nBytes, flags));
 
-       return 0;
+       int result = os::send(fd, buf, nBytes, flags);
+
+       TRACEJVMCALLSEXIT(("->%d", result));
+
+       return result;
 }
 
 
@@ -2942,11 +2914,17 @@ void *JVM_FindLibraryEntry(void* handle, const char* name)
 
 /* JVM_IsNaN */
 
-jboolean JVM_IsNaN(jdouble a)
+jboolean JVM_IsNaN(jdouble d)
 {
-       log_println("JVM_IsNaN: IMPLEMENT ME!");
+       bool result;
 
-       return 0;
+       TRACEJVMCALLSENTER(("JVM_IsNaN(d=%f)", d));
+
+       result = isnan(d);
+
+       TRACEJVMCALLSEXIT(("->%d", result));
+
+       return result;
 }
 
 
@@ -3221,9 +3199,31 @@ jboolean JVM_CX8Field(JNIEnv *env, jobject obj, jfieldID fid, jlong oldVal, jlon
 
 jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 {
-       log_println("JVM_GetAllThreads: IMPLEMENT ME!");
+       // Get a list of all active threads.
+       list<threadobject*> active_threads;
+       ThreadList::get_active_threads(active_threads);
 
-       return NULL;
+       // Allocate array to hold the java.lang.Thread objects.
+       int32_t length = active_threads.size();
+       java_handle_objectarray_t* oa = builtin_anewarray(length, class_java_lang_Thread);
+
+       if (oa == NULL)
+               return NULL;
+
+       // Iterate over all threads (which were active just a second ago).
+       int32_t index = 0;
+       for (List<threadobject*>::iterator it = active_threads.begin(); it != active_threads.end(); it++) {
+               threadobject* t = *it;
+
+               java_handle_t* h = thread_get_object(t);
+               assert(h != NULL);
+
+               array_objectarray_element_set(oa, index, h);
+
+               index++;
+       }
+
+       return oa;
 }
 
 
@@ -3231,9 +3231,55 @@ jobjectArray JVM_GetAllThreads(JNIEnv *env, jclass dummy)
 
 jobjectArray JVM_DumpThreads(JNIEnv *env, jclass threadClass, jobjectArray threads)
 {
-       log_println("JVM_DumpThreads: IMPLEMENT ME!");
+       int32_t i;
 
-       return NULL;
+       TRACEJVMCALLS(("JVM_DumpThreads((env=%p, threadClass=%p, threads=%p)", env, threadClass, threads));
+
+       if (threads == NULL) {
+               exceptions_throw_nullpointerexception();
+               return NULL;
+       }
+
+       // Get length of the threads array.
+       int32_t length = array_length_get((java_handle_t*) threads);
+
+       if (length <= 0) {
+               exceptions_throw_illegalargumentexception();
+               return NULL;
+       }
+
+       // Allocate array to hold stacktraces.
+       classinfo* arrayclass = class_array_of(class_java_lang_StackTraceElement, true);
+       java_handle_objectarray_t* oas = builtin_anewarray(length, arrayclass);
+
+       if (oas == NULL) {
+               return NULL;
+       }
+
+       // Iterate over all passed thread objects.
+       for (i = 0; i < length; i++) {
+               java_handle_t* thread = array_objectarray_element_get(threads, i);
+
+               // Get thread for the given thread object.
+               threadobject* t = thread_get_thread(thread);
+
+               // The threadobject is null when a thread is created in Java.
+               if (t == NULL)
+                       continue;
+
+               // Get stacktrace for given thread.
+               stacktrace_t* st = stacktrace_get_of_thread(t);
+
+               // Convert stacktrace into array of StackTraceElements.
+               java_handle_objectarray_t* oa = stacktrace_get_StackTraceElements(st);
+
+               if (oa == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oas, i, (java_handle_t*) oa);
+       }
+
+       return oas;
 }
 
 
@@ -3341,12 +3387,11 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
                        return NULL;
 
                array_intarray_element_set(ia, 0, THREAD_STATE_WAITING);
-               /* XXX Implement parked stuff. */
-/*             array_intarray_element_set(ia, 1, PARKED); */
+               array_intarray_element_set(ia, 1, THREAD_STATE_PARKED);
                break; 
 
     case THREAD_STATE_TIMED_WAITING:
-               ia = builtin_newarray_int(3);
+               ia = builtin_newarray_int(2);
 
                if (ia == NULL)
                        return NULL;
@@ -3354,8 +3399,7 @@ jintArray JVM_GetThreadStateValues(JNIEnv* env, jint javaThreadState)
                /* XXX Not sure about that one. */
 /*             array_intarray_element_set(ia, 0, SLEEPING); */
                array_intarray_element_set(ia, 0, THREAD_STATE_TIMED_WAITING);
-               /* XXX Implement parked stuff. */
-/*             array_intarray_element_set(ia, 2, PARKED); */
+               array_intarray_element_set(ia, 1, THREAD_STATE_TIMED_PARKED);
                break; 
 
     case THREAD_STATE_TERMINATED:
@@ -3453,31 +3497,40 @@ jobjectArray JVM_GetThreadStateNames(JNIEnv* env, jint javaThreadState, jintArra
                        return NULL;
 
                s = javastring_new(utf_new_char("WAITING.OBJECT_WAIT"));
-/*             s = javastring_new(utf_new_char("WAITING.PARKED")); */
 
                if (s == NULL)
                        return NULL;
 
                array_objectarray_element_set(oa, 0, s);
-/*             array_objectarray_element_set(oa, 1, s); */
+
+               s = javastring_new(utf_new_char("WAITING.PARKED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 1, s);
                break; 
 
     case THREAD_STATE_TIMED_WAITING:
-               oa = builtin_anewarray(3, class_java_lang_String);
+               oa = builtin_anewarray(2, class_java_lang_String);
 
                if (oa == NULL)
                        return NULL;
 
 /*             s = javastring_new(utf_new_char("TIMED_WAITING.SLEEPING")); */
                s = javastring_new(utf_new_char("TIMED_WAITING.OBJECT_WAIT"));
-/*             s = javastring_new(utf_new_char("TIMED_WAITING.PARKED")); */
 
                if (s == NULL)
                        return NULL;
 
-/*             array_objectarray_element_set(oa, 0, s); */
                array_objectarray_element_set(oa, 0, s);
-/*             array_objectarray_element_set(oa, 2, s); */
+
+               s = javastring_new(utf_new_char("TIMED_WAITING.PARKED"));
+
+               if (s == NULL)
+                       return NULL;
+
+               array_objectarray_element_set(oa, 1, s);
                break; 
 
     case THREAD_STATE_TERMINATED:
index 3884893992643f7db617e5a40869d99a73964348..5bfb6c63b8eb90392fb66924bb50aa6f5be14697 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "native/vm/openjdk/management.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/os.hpp"
 #include "vm/vm.hpp"
index 950df13523d3fd106ff57418e2ce239cf1082fe6..a6c86a6daa8550c3e799ef774a7556a7123c4a73 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "threads/atomic.hpp"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
@@ -461,6 +461,39 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putFloat__JF(JNIEnv *env, jobject _t
 }
 
 
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getDouble
+ * Signature: (J)D
+ */
+JNIEXPORT jdouble JNICALL Java_sun_misc_Unsafe_getDouble__J(JNIEnv *env, jobject _this, jlong address)
+{
+       double *p;
+       double  value;
+
+       p = (double*) (intptr_t) address;
+
+       value = *p;
+
+       return value;
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    putDouble
+ * Signature: (JD)V
+ */
+JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putDouble__JD(JNIEnv *env, jobject _this, jlong address, jdouble value)
+{
+       double* p;
+
+       p = (double*) (intptr_t) address;
+
+       *p = value;
+}
+
+
 /*
  * Class:     sun/misc/Unsafe
  * Method:    objectFieldOffset
@@ -950,6 +983,17 @@ JNIEXPORT void JNICALL Java_sun_misc_Unsafe_putObjectVolatile(JNIEnv *env, jobje
 }
 
 
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getBooleanVolatile
+ * Signature: (Ljava/lang/Object;J)Z
+ */
+JNIEXPORT jboolean JNICALL Java_sun_misc_Unsafe_getBooleanVolatile(JNIEnv* env, jobject _this, jobject o, jlong offset)
+{
+       return FieldAccess::get_volatile<int32_t>(o, offset);
+}
+
+
 /*
  * Class:     sun/misc/Unsafe
  * Method:    getByteVolatile
@@ -961,6 +1005,28 @@ JNIEXPORT jbyte JNICALL Java_sun_misc_Unsafe_getByteVolatile(JNIEnv* env, jobjec
 }
 
 
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getShortVolatile
+ * Signature: (Ljava/lang/Object;J)S
+ */
+JNIEXPORT jshort JNICALL Java_sun_misc_Unsafe_getShortVolatile(JNIEnv* env, jobject _this, jobject o, jlong offset)
+{
+       return FieldAccess::get_volatile<int32_t>(o, offset);
+}
+
+
+/*
+ * Class:     sun/misc/Unsafe
+ * Method:    getCharVolatile
+ * Signature: (Ljava/lang/Object;J)C
+ */
+JNIEXPORT jchar JNICALL Java_sun_misc_Unsafe_getCharVolatile(JNIEnv* env, jobject _this, jobject o, jlong offset)
+{
+       return FieldAccess::get_volatile<int32_t>(o, offset);
+}
+
+
 /*
  * Class:     sun/misc/Unsafe
  * Method:    getIntVolatile
@@ -1126,6 +1192,8 @@ static JNINativeMethod methods[] = {
        { (char*) "putLong",                (char*) "(JJ)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_putLong__JJ                      },
        { (char*) "getFloat",               (char*) "(J)F",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_getFloat__J                      },
        { (char*) "putFloat",               (char*) "(JF)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_putFloat__JF                     },
+       { (char*) "getDouble",              (char*) "(J)D",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_getDouble__J                     },
+       { (char*) "putDouble",              (char*) "(JD)V",                                                      (void*) (uintptr_t) &Java_sun_misc_Unsafe_putDouble__JD                    },
        { (char*) "objectFieldOffset",      (char*) "(Ljava/lang/reflect/Field;)J",                               (void*) (uintptr_t) &Java_sun_misc_Unsafe_objectFieldOffset                },
        { (char*) "allocateMemory",         (char*) "(J)J",                                                       (void*) (uintptr_t) &Java_sun_misc_Unsafe_allocateMemory                   },
 #if 0
@@ -1152,7 +1220,10 @@ static JNINativeMethod methods[] = {
        { (char*) "compareAndSwapLong",     (char*) "(Ljava/lang/Object;JJJ)Z",                                   (void*) (uintptr_t) &Java_sun_misc_Unsafe_compareAndSwapLong               },
        { (char*) "getObjectVolatile",      (char*) "(Ljava/lang/Object;J)Ljava/lang/Object;",                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_getObjectVolatile                },
        { (char*) "putObjectVolatile",      (char*) "(Ljava/lang/Object;JLjava/lang/Object;)V",                   (void*) (uintptr_t) &Java_sun_misc_Unsafe_putObjectVolatile                },
+       { (char*) "getBooleanVolatile",     (char*) "(Ljava/lang/Object;J)Z",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getBooleanVolatile               },
        { (char*) "getByteVolatile",        (char*) "(Ljava/lang/Object;J)B",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getByteVolatile                  },
+       { (char*) "getShortVolatile",       (char*) "(Ljava/lang/Object;J)S",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getShortVolatile                 },
+       { (char*) "getCharVolatile",        (char*) "(Ljava/lang/Object;J)C",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getCharVolatile                  },
        { (char*) "getIntVolatile",         (char*) "(Ljava/lang/Object;J)I",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getIntVolatile                   },
        { (char*) "putIntVolatile",         (char*) "(Ljava/lang/Object;JI)V",                                    (void*) (uintptr_t) &Java_sun_misc_Unsafe_putIntVolatile                   },
        { (char*) "getLongVolatile",        (char*) "(Ljava/lang/Object;J)J",                                     (void*) (uintptr_t) &Java_sun_misc_Unsafe_getLongVolatile                  },
index 5bcee690db131362a170ab9dbd3d3132e8afce3b..df007f1e82e7f5d13ef2903a9f6c2c7e4b926726 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
@@ -46,7 +46,7 @@
 #include "toolbox/list.hpp"
 
 #include "vm/exceptions.hpp"
-#include "vm/finalizer.h"
+#include "vm/finalizer.hpp"
 #include "vm/global.h"
 #include "vm/options.h"
 #include "vm/string.hpp"
@@ -675,6 +675,22 @@ static void lock_inflate(java_handle_t *o, lock_record_t *lr)
 }
 
 
+/* sable_flc_waiting ***********************************************************
+
+   Enqueue the current thread on another thread's FLC list. The function
+   blocks until the lock has been inflated by the owning thread.
+
+   The algorithm used to be an almost literal copy from SableVM. The
+   superfluous list traversal in the waiting loop has been removed since,
+   though.
+
+   IN:
+         lockword.....the object's lockword as seen at the first locking attempt
+         t............the current thread
+         o............the object of which to enter the monitor
+
+*******************************************************************************/
+
 static void sable_flc_waiting(Lockword *lockword, threadobject *t, java_handle_t *o)
 {
        int32_t index;
@@ -714,30 +730,18 @@ static void sable_flc_waiting(Lockword *lockword, threadobject *t, java_handle_t
                        t_other->flc_tail = t;
                f = t_other->flc_tail;
 
-               for (;;)
+               // The other thread will clear flc_object.
+               while (t->flc_object)
                {
-                       threadobject *current;
+                       // We are not cleared yet -- the other thread cannot have seen
+                       // the FLC bit yet.
+                       assert(t_other->flc_bit);
 
                        // Wait until another thread sees the flc bit and notifies
                        // us of unlocking.
                        t->flc_cond->wait(t_other->flc_lock);
-
-                       if (t_other->flc_tail != f)
-                               break;
-                       /* Traverse FLC list looking if we're still there */
-                       current = t_other->flc_list;
-                       while (current && current != t)
-                               current = current->flc_next;
-                       if (!current)
-                               /* not in list anymore, can stop waiting */
-                               break;
-
-                       /* We are still in the list -- the other thread cannot have seen
-                          the FLC bit yet */
-                       assert(t_other->flc_bit);
                }
 
-               t->flc_object = NULL;   /* for garbage collector? */
                t->flc_next = NULL;
        }
        else
@@ -746,6 +750,17 @@ static void sable_flc_waiting(Lockword *lockword, threadobject *t, java_handle_t
        t_other->flc_lock->unlock();
 }
 
+/* notify_flc_waiters **********************************************************
+
+   Traverse the thread's FLC list and inflate all corresponding locks. Notify
+   the associated threads as well.
+
+   IN:
+         t............the current thread
+         o............the object currently being unlocked
+
+*******************************************************************************/
+
 static void notify_flc_waiters(threadobject *t, java_handle_t *o)
 {
        threadobject *current;
@@ -775,6 +790,7 @@ static void notify_flc_waiters(threadobject *t, java_handle_t *o)
 
                // Wake the waiting threads.
                current->flc_cond->broadcast();
+               current->flc_object = NULL;
 
                current = current->flc_next;
        }
index 949c1b59918df83aea78ccdf8531e0da4cc20eaa..40c59aa68c3b96e6f7263631bec314aaae2e9712 100644 (file)
@@ -43,7 +43,7 @@
 #include "arch.h"
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #if defined(ENABLE_GC_CACAO)
 # include "mm/cacao-gc/gc.h"
@@ -58,7 +58,7 @@
 #include "threads/threadlist.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
@@ -66,7 +66,7 @@
 #include "vm/globals.hpp"
 #include "vm/javaobjects.hpp"
 #include "vm/options.h"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/string.hpp"
 #include "vm/vm.hpp"
 
@@ -1381,7 +1381,10 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi
                while (!t->interrupted && !(parking ? t->park_permit : t->signaled)
                           && threads_current_time_is_earlier_than(wakeupTime))
                {
-                       thread_set_state_timed_waiting(t);
+                       if (parking)
+                               thread_set_state_timed_parked(t);
+                       else
+                               thread_set_state_timed_waiting(t);
 
                        t->waitcond->timedwait(t->waitmutex, wakeupTime);
 
@@ -1391,7 +1394,10 @@ static void threads_wait_with_timeout(threadobject *t, struct timespec *wakeupTi
        else {
                /* no timeout */
                while (!t->interrupted && !(parking ? t->park_permit : t->signaled)) {
-                       thread_set_state_waiting(t);
+                       if (parking)
+                               thread_set_state_parked(t);
+                       else
+                               thread_set_state_waiting(t);
 
                        t->waitcond->wait(t->waitmutex);
 
index 76892b7c3a6539fcceba3af97f98fa1d9f30d36a..8f0e55c71ad5fac2115d5143259408dfe0a8b1e1 100644 (file)
@@ -193,7 +193,7 @@ inline static threadobject* thread_get_current(void);
 
 
 // Includes.
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 
index 8804f6eb55f06e37d07a6925c0c23545b1beb187..1579fd4e1ed42269625109f877913ef3f1a9e67e 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #if defined(ENABLE_GC_BOEHM)
 /* We need to include Boehm's gc.h here for GC_register_my_thread and
@@ -948,6 +948,12 @@ void thread_print_info(threadobject *t)
        case THREAD_STATE_TIMED_WAITING:
                printf(" waiting on condition");
                break;
+       case THREAD_STATE_PARKED:
+               printf(" parked");
+               break;
+       case THREAD_STATE_TIMED_PARKED:
+               printf(" timed parked");
+               break;
        case THREAD_STATE_TERMINATED:
                printf(" terminated");
                break;
@@ -981,6 +987,26 @@ intptr_t threads_get_current_tid(void)
 }
 
 
+/**
+ * Set the current state of the given thread. This method should only
+ * be called while holding the threadlist-lock and after checking that
+ * the new state is valid. It is best to not call this method directly
+ * but call the specific setter methods below.
+ */
+static inline void thread_set_state(threadobject *t, int state)
+{
+       // Set the state of our internal threadobject.
+       t->state = state;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       // Set the state of the java.lang.Thread object.
+       java_lang_Thread thread(thread_get_object(t));
+       assert(thread.is_non_null());
+       thread.set_threadStatus(state);
+#endif
+}
+
+
 /* thread_set_state_runnable ***************************************************
 
    Set the current state of the given thread to THREAD_STATE_RUNNABLE.
@@ -997,7 +1023,7 @@ void thread_set_state_runnable(threadobject *t)
        ThreadList::lock();
 
        if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_RUNNABLE;
+               thread_set_state(t, THREAD_STATE_RUNNABLE);
 
                DEBUGTHREADS("is RUNNABLE", t);
        }
@@ -1022,7 +1048,7 @@ void thread_set_state_waiting(threadobject *t)
        ThreadList::lock();
 
        if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_WAITING;
+               thread_set_state(t, THREAD_STATE_WAITING);
 
                DEBUGTHREADS("is WAITING", t);
        }
@@ -1048,7 +1074,7 @@ void thread_set_state_timed_waiting(threadobject *t)
        ThreadList::lock();
 
        if (t->state != THREAD_STATE_TERMINATED) {
-               t->state = THREAD_STATE_TIMED_WAITING;
+               thread_set_state(t, THREAD_STATE_TIMED_WAITING);
 
                DEBUGTHREADS("is TIMED_WAITING", t);
        }
@@ -1057,6 +1083,56 @@ void thread_set_state_timed_waiting(threadobject *t)
 }
 
 
+/* thread_set_state_parked *****************************************************
+
+   Set the current state of the given thread to THREAD_STATE_PARKED.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_parked(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       ThreadList::lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               thread_set_state(t, THREAD_STATE_PARKED);
+
+               DEBUGTHREADS("is PARKED", t);
+       }
+
+       ThreadList::unlock();
+}
+
+
+/* thread_set_state_timed_parked ***********************************************
+
+   Set the current state of the given thread to THREAD_STATE_TIMED_PARKED.
+
+   NOTE: If the thread has already terminated, don't set the state.
+         This is important for threads_detach_thread.
+
+*******************************************************************************/
+
+void thread_set_state_timed_parked(threadobject *t)
+{
+       /* Set the state inside a lock. */
+
+       ThreadList::lock();
+
+       if (t->state != THREAD_STATE_TERMINATED) {
+               thread_set_state(t, THREAD_STATE_TIMED_PARKED);
+
+               DEBUGTHREADS("is TIMED_PARKED", t);
+       }
+
+       ThreadList::unlock();
+}
+
+
 /* thread_set_state_terminated *************************************************
 
    Set the current state of the given thread to
@@ -1070,7 +1146,7 @@ void thread_set_state_terminated(threadobject *t)
 
        ThreadList::lock();
 
-       t->state = THREAD_STATE_TERMINATED;
+       thread_set_state(t, THREAD_STATE_TERMINATED);
 
        DEBUGTHREADS("is TERMINATED", t);
 
@@ -1136,6 +1212,8 @@ bool threads_thread_is_alive(threadobject *t)
        case THREAD_STATE_BLOCKED:
        case THREAD_STATE_WAITING:
        case THREAD_STATE_TIMED_WAITING:
+       case THREAD_STATE_PARKED:
+       case THREAD_STATE_TIMED_PARKED:
                return true;
 
        default:
index b50db4370728cc6ae88aae68d9d921a6781c9d97..c3563cf33ddb73d2f58624ba866071d149753f7c 100644 (file)
@@ -59,6 +59,8 @@
 #define THREAD_STATE_WAITING          3
 #define THREAD_STATE_TIMED_WAITING    4
 #define THREAD_STATE_TERMINATED       5
+#define THREAD_STATE_PARKED           6
+#define THREAD_STATE_TIMED_PARKED     7
 
 
 /* thread priorities **********************************************************/
@@ -326,6 +328,8 @@ intptr_t      threads_get_current_tid(void);
 void          thread_set_state_runnable(threadobject *t);
 void          thread_set_state_waiting(threadobject *t);
 void          thread_set_state_timed_waiting(threadobject *t);
+void          thread_set_state_parked(threadobject *t);
+void          thread_set_state_timed_parked(threadobject *t);
 void          thread_set_state_terminated(threadobject *t);
 
 threadobject *thread_get_thread(java_handle_t *h);
index bcf7f0e18e80cf06709307d497fade4484eb7a8a..9284bdb8412cc58226563cbba8279a9e76b17ac1 100644 (file)
@@ -34,7 +34,7 @@
 #include "threads/thread.hpp"
 
 #include "toolbox/list.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/stacktrace.hpp"
 
@@ -101,6 +101,26 @@ void ThreadList::dump_threads()
 }
 
 
+/**
+ * Fills the passed list with all currently active threads. Creating a copy
+ * of the thread list here, is the only way to ensure we do not end up in a
+ * dead-lock when iterating over the list.
+ *
+ * @param list list class to be filled
+ */
+void ThreadList::get_active_threads(list<threadobject*> &list)
+{
+       // Lock the thread lists.
+       lock();
+
+       // Use the assignment operator to create a copy of the thread list.
+       list = _active_thread_list;
+
+       // Unlock the thread lists.
+       unlock();
+}
+
+
 /**
  * Return a free thread object.
  *
index 2a9f2059c296ce538ca1e60be51fe0d01424ff15..4df7b93456df1d87f928b570658c0e350edafe25 100644 (file)
@@ -73,6 +73,7 @@ public:
        static inline void          add_to_active_thread_list(threadobject* t);
 
        static void                 dump_threads();
+       static void                 get_active_threads(list<threadobject*> &list);
        static inline threadobject* get_main_thread();
        static threadobject*        get_free_thread();
        static int32_t              get_free_thread_index();
index c5c2cae128d049c22d2c0a37dde36f5f7a120854..32048a75bf17805cf61706ae06da40afcdad8991 100644 (file)
@@ -36,8 +36,8 @@ libtoolbox_la_SOURCES = \
        hashtable.c \
        hashtable.h \
        list.hpp \
-       logging.c \
-       logging.h \
+       logging.cpp \
+       logging.hpp \
        set.h \
        set.c \
        util.c \
index 404328c05dba516049198abc7f42db81b3fa7332..d9d31210b3a863ecf9015efd341b2dc86c33c197 100644 (file)
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/mutex.hpp"
 
 #include "toolbox/avl.h"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/global.h"
 #include "vm/vm.hpp"
index 66b9df11561033c0222f2486dd8a1f527b5551a0..9d82d46b910886acfed7a977417887b7f9f70261 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "config.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "toolbox/bitvector.h"
 
 
index dd49f3de543a65e191c909da805d04ab9c5764df..9fa938f416abf01cee84220c1a529ef6ccc77810 100644 (file)
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/mutex.hpp"
 
diff --git a/src/toolbox/logging.c b/src/toolbox/logging.c
deleted file mode 100644 (file)
index 7ff7f1b..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/* src/toolbox/logging.c - contains logging 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 <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "threads/thread.hpp"
-
-#include "toolbox/logging.h"
-#include "toolbox/util.h"
-
-#include "vm/global.h"
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-
-/***************************************************************************
-                        LOG FILE HANDLING 
-***************************************************************************/
-
-FILE *logfile = NULL;
-
-
-void log_init(const char *fname)
-{
-       if (fname) {
-               if (fname[0]) {
-                       logfile = fopen(fname, "w");
-               }
-       }
-}
-
-
-/* log_start *******************************************************************
-
-   Writes the preleading LOG: text to the protocol file (if opened) or
-   to stdout.
-
-*******************************************************************************/
-
-void log_start(void)
-{
-#if defined(ENABLE_THREADS)
-       ptrint tid;
-
-       tid = threads_get_current_tid();
-#endif
-
-       if (logfile) {
-#if defined(ENABLE_THREADS)
-# if SIZEOF_VOID_P == 8
-               fprintf(logfile, "[0x%016lx] ", tid );
-# else
-               fprintf(logfile, "[0x%08x] ", tid);
-# endif
-#endif
-       }
-       else {
-#if defined(ENABLE_THREADS)
-# if SIZEOF_VOID_P == 8
-               fprintf(stdout, "LOG: [0x%016lx] ", tid);
-# else
-               fprintf(stdout, "LOG: [0x%08x] ", tid);
-# endif
-#else
-               fputs("LOG: ", stdout);
-#endif
-       }
-}
-
-
-/* log_vprint ******************************************************************
-
-   Writes logtext to the protocol file (if opened) or to stdout.
-
-*******************************************************************************/
-
-void log_vprint(const char *text, va_list ap)
-{
-       if (logfile)
-               vfprintf(logfile, text, ap);
-       else
-               vfprintf(stdout, text, ap);
-}
-
-
-/* log_print *******************************************************************
-
-   Writes logtext to the protocol file (if opened) or to stdout.
-
-*******************************************************************************/
-
-void log_print(const char *text, ...)
-{
-       va_list ap;
-
-       va_start(ap, text);
-       log_vprint(text, ap);
-       va_end(ap);
-}
-
-
-/* log_println *****************************************************************
-
-   Writes logtext to the protocol file (if opened) or to stdout with a
-   trailing newline.
-
-*******************************************************************************/
-
-void log_println(const char *text, ...)
-{
-       va_list ap;
-
-       log_start();
-
-       va_start(ap, text);
-       log_vprint(text, ap);
-       va_end(ap);
-
-       log_finish();
-}
-
-
-/* log_finish ******************************************************************
-
-   Finishes a logtext line with trailing newline and a fflush.
-
-*******************************************************************************/
-
-void log_finish(void)
-{
-       if (logfile) {
-               fputs("\n", logfile);
-               fflush(logfile);
-       }
-       else {
-               fputs("\n", stdout);
-               fflush(stdout);
-       }
-}
-
-
-/* log_message_utf *************************************************************
-
-   Outputs log text like this:
-
-   LOG: Creating class: java/lang/Object
-
-*******************************************************************************/
-
-void log_message_utf(const char *msg, utf *u)
-{
-       char *buf;
-       s4    len;
-
-       len = strlen(msg) + utf_bytes(u) + strlen("0");
-
-       buf = MNEW(char, len);
-
-       strcpy(buf, msg);
-       utf_cat(buf, u);
-
-       log_text(buf);
-
-       MFREE(buf, char, len);
-}
-
-
-/* log_message_class ***********************************************************
-
-   Outputs log text like this:
-
-   LOG: Loading class: java/lang/Object
-
-*******************************************************************************/
-
-void log_message_class(const char *msg, classinfo *c)
-{
-       log_message_utf(msg, c->name);
-}
-
-
-/* log_message_class_message_class *********************************************
-
-   Outputs log text like this:
-
-   LOG: Initialize super class java/lang/Object from java/lang/VMThread
-
-*******************************************************************************/
-
-void log_message_class_message_class(const char *msg1, classinfo *c1,
-                                                                        const char *msg2, classinfo *c2)
-{
-       char *buf;
-       s4    len;
-
-       len =
-               strlen(msg1) + utf_bytes(c1->name) +
-               strlen(msg2) + utf_bytes(c2->name) + strlen("0");
-
-       buf = MNEW(char, len);
-
-       strcpy(buf, msg1);
-       utf_cat_classname(buf, c1->name);
-       strcat(buf, msg2);
-       utf_cat_classname(buf, c2->name);
-
-       log_text(buf);
-
-       MFREE(buf, char, len);
-}
-
-
-/* log_message_method **********************************************************
-
-   Outputs log text like this:
-
-   LOG: Compiling: java.lang.Object.clone()Ljava/lang/Object;
-
-*******************************************************************************/
-
-void log_message_method(const char *msg, methodinfo *m)
-{
-       char *buf;
-       s4    len;
-
-       len = strlen(msg) + utf_bytes(m->clazz->name) + strlen(".") +
-               utf_bytes(m->name) + utf_bytes(m->descriptor) + strlen("0");
-
-       buf = MNEW(char, len);
-
-       strcpy(buf, msg);
-       utf_cat_classname(buf, m->clazz->name);
-       strcat(buf, ".");
-       utf_cat(buf, m->name);
-       utf_cat(buf, m->descriptor);
-
-       log_text(buf);
-
-       MFREE(buf, char, len);
-}
-
-
-/*
- * 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/toolbox/logging.cpp b/src/toolbox/logging.cpp
new file mode 100644 (file)
index 0000000..c38b32b
--- /dev/null
@@ -0,0 +1,287 @@
+/* src/toolbox/logging.c - contains logging 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.hpp"
+
+#include "threads/thread.hpp"
+
+#include "toolbox/logging.hpp"
+#include "toolbox/util.h"
+
+#include "vm/global.h"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+
+/***************************************************************************
+                        LOG FILE HANDLING 
+***************************************************************************/
+
+FILE *logfile = NULL;
+
+
+void log_init(const char *fname)
+{
+       if (fname) {
+               if (fname[0]) {
+                       logfile = fopen(fname, "w");
+               }
+       }
+}
+
+
+/* log_start *******************************************************************
+
+   Writes the preleading LOG: text to the protocol file (if opened) or
+   to stdout.
+
+*******************************************************************************/
+
+void log_start(void)
+{
+#if defined(ENABLE_THREADS)
+       ptrint tid;
+
+       tid = threads_get_current_tid();
+#endif
+
+       if (logfile) {
+#if defined(ENABLE_THREADS)
+# if SIZEOF_VOID_P == 8
+               fprintf(logfile, "[0x%016lx] ", tid );
+# else
+               fprintf(logfile, "[0x%08x] ", tid);
+# endif
+#endif
+       }
+       else {
+#if defined(ENABLE_THREADS)
+# if SIZEOF_VOID_P == 8
+               fprintf(stdout, "LOG: [0x%016lx] ", tid);
+# else
+               fprintf(stdout, "LOG: [0x%08x] ", tid);
+# endif
+#else
+               fputs("LOG: ", stdout);
+#endif
+       }
+}
+
+
+/* log_vprint ******************************************************************
+
+   Writes logtext to the protocol file (if opened) or to stdout.
+
+*******************************************************************************/
+
+void log_vprint(const char *text, va_list ap)
+{
+       if (logfile)
+               vfprintf(logfile, text, ap);
+       else
+               vfprintf(stdout, text, ap);
+}
+
+
+/* log_print *******************************************************************
+
+   Writes logtext to the protocol file (if opened) or to stdout.
+
+*******************************************************************************/
+
+void log_print(const char *text, ...)
+{
+       va_list ap;
+
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+}
+
+
+/* log_println *****************************************************************
+
+   Writes logtext to the protocol file (if opened) or to stdout with a
+   trailing newline.
+
+*******************************************************************************/
+
+void log_println(const char *text, ...)
+{
+       va_list ap;
+
+       log_start();
+
+       va_start(ap, text);
+       log_vprint(text, ap);
+       va_end(ap);
+
+       log_finish();
+}
+
+
+/* log_finish ******************************************************************
+
+   Finishes a logtext line with trailing newline and a fflush.
+
+*******************************************************************************/
+
+void log_finish(void)
+{
+       if (logfile) {
+               fputs("\n", logfile);
+               fflush(logfile);
+       }
+       else {
+               fputs("\n", stdout);
+               fflush(stdout);
+       }
+}
+
+
+/* log_message_utf *************************************************************
+
+   Outputs log text like this:
+
+   LOG: Creating class: java/lang/Object
+
+*******************************************************************************/
+
+void log_message_utf(const char *msg, utf *u)
+{
+       char *buf;
+       s4    len;
+
+       len = strlen(msg) + utf_bytes(u) + strlen("0");
+
+       buf = MNEW(char, len);
+
+       strcpy(buf, msg);
+       utf_cat(buf, u);
+
+       log_text(buf);
+
+       MFREE(buf, char, len);
+}
+
+
+/* log_message_class ***********************************************************
+
+   Outputs log text like this:
+
+   LOG: Loading class: java/lang/Object
+
+*******************************************************************************/
+
+void log_message_class(const char *msg, classinfo *c)
+{
+       log_message_utf(msg, c->name);
+}
+
+
+/* log_message_class_message_class *********************************************
+
+   Outputs log text like this:
+
+   LOG: Initialize super class java/lang/Object from java/lang/VMThread
+
+*******************************************************************************/
+
+void log_message_class_message_class(const char *msg1, classinfo *c1,
+                                                                        const char *msg2, classinfo *c2)
+{
+       char *buf;
+       s4    len;
+
+       len =
+               strlen(msg1) + utf_bytes(c1->name) +
+               strlen(msg2) + utf_bytes(c2->name) + strlen("0");
+
+       buf = MNEW(char, len);
+
+       strcpy(buf, msg1);
+       utf_cat_classname(buf, c1->name);
+       strcat(buf, msg2);
+       utf_cat_classname(buf, c2->name);
+
+       log_text(buf);
+
+       MFREE(buf, char, len);
+}
+
+
+/* log_message_method **********************************************************
+
+   Outputs log text like this:
+
+   LOG: Compiling: java.lang.Object.clone()Ljava/lang/Object;
+
+*******************************************************************************/
+
+void log_message_method(const char *msg, methodinfo *m)
+{
+       char *buf;
+       s4    len;
+
+       len = strlen(msg) + utf_bytes(m->clazz->name) + strlen(".") +
+               utf_bytes(m->name) + utf_bytes(m->descriptor) + strlen("0");
+
+       buf = MNEW(char, len);
+
+       strcpy(buf, msg);
+       utf_cat_classname(buf, m->clazz->name);
+       strcat(buf, ".");
+       utf_cat(buf, m->name);
+       utf_cat(buf, m->descriptor);
+
+       log_text(buf);
+
+       MFREE(buf, char, len);
+}
+
+
+/*
+ * 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/toolbox/logging.h b/src/toolbox/logging.h
deleted file mode 100644 (file)
index eed61bd..0000000
+++ /dev/null
@@ -1,84 +0,0 @@
-/* src/toolbox/logging.h - contains logging 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.
-
-*/
-
-
-#ifndef _LOGGING_H
-#define _LOGGING_H
-
-#include "config.h"
-
-#include <stdio.h>
-#include <stdarg.h>
-
-#include "vm/class.hpp"
-#include "vm/method.hpp"
-#include "vm/utf8.h"
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void log_init(const char *fname);
-
-void log_start(void);
-
-void log_vprint(const char *text, va_list ap);
-void log_print(const char *text, ...);
-void log_println(const char *text, ...);
-
-void log_finish(void);
-
-
-/* log message functions */
-void log_message_utf(const char *msg, utf *u);
-void log_message_class(const char *msg, classinfo *c);
-void log_message_class_message_class(const char *msg1, classinfo *c1,
-                                                                        const char *msg2, classinfo *c2);
-void log_message_method(const char *msg, methodinfo *m);
-
-#define log_text(s) log_println("%s", (s))
-#define dolog log_println
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _LOGGING_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/toolbox/logging.hpp b/src/toolbox/logging.hpp
new file mode 100644 (file)
index 0000000..3b70b6b
--- /dev/null
@@ -0,0 +1,84 @@
+/* src/toolbox/logging.h - contains logging 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.
+
+*/
+
+
+#ifndef _LOGGING_H
+#define _LOGGING_H
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "vm/class.hpp"
+#include "vm/method.hpp"
+#include "vm/utf8.h"
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void log_init(const char *fname);
+
+void log_start(void);
+
+void log_vprint(const char *text, va_list ap);
+void log_print(const char *text, ...);
+void log_println(const char *text, ...);
+
+void log_finish(void);
+
+
+/* log message functions */
+void log_message_utf(const char *msg, utf *u);
+void log_message_class(const char *msg, classinfo *c);
+void log_message_class_message_class(const char *msg1, classinfo *c1,
+                                                                        const char *msg2, classinfo *c2);
+void log_message_method(const char *msg, methodinfo *m);
+
+#define log_text(s) log_println("%s", (s))
+#define dolog log_println
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LOGGING_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 c63ddf8827f91b68d35225c7f09820a02111219d..d30fafaae532a7f702615f34d11f03672b724623 100644 (file)
@@ -36,7 +36,7 @@
 
 #include "toolbox/set.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/global.h"
 
index 2e26c259b6c1be35205db5583e73d469480cd6f7..4adb970f5f00d0c0ffa97d1a37f8d8a6a13eedb0 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "vm/vm.hpp"
 
 
index 6cb9fb37a90daf9838c3f9c6963fc15f65ee5e36..5489f1709d9cb61aeea1188b5e6de61d90f988ca 100644 (file)
@@ -29,7 +29,7 @@
 
 */
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "toolbox/worklist.h"
 
 
index 4dd35b7777dffcaf8468de71eaf49b9965f24311..7830a5a19c566886a09d5b37f318c04a3d420c58 100644 (file)
@@ -42,8 +42,8 @@ endif
 if ENABLE_JAVASE
 if ENABLE_ANNOTATIONS
 ANNOTATION_SOURCES = \
-       annotation.c \
-       annotation.h
+       annotation.cpp \
+       annotation.hpp
 endif
 
 STACKMAP_SOURCES = \
@@ -88,14 +88,14 @@ libvm_la_SOURCES = \
        classcache.cpp \
        classcache.hpp \
        $(CYCLES_STATS_SOURCES) \
-       descriptor.c \
-       descriptor.h \
+       descriptor.cpp \
+       descriptor.hpp \
        exceptions.cpp \
        exceptions.hpp \
        field.cpp \
        field.hpp \
-       finalizer.c \
-       finalizer.h \
+       finalizer.cpp \
+       finalizer.hpp \
        globals.cpp \
        globals.hpp \
        initialize.cpp \
@@ -122,8 +122,8 @@ libvm_la_SOURCES = \
        resolve.cpp \
        resolve.hpp \
        $(RT_TIMING_SOURCES) \
-       signal.c \
-       signallocal.h \
+       signal.cpp \
+       signallocal.hpp \
        $(STACKMAP_SOURCES) \
        $(STATISTICS_SOURCES) \
        string.cpp \
index a0abbc1569e81429bedaa00f7ec48dc1baacfbc4..73899e0e3a53b56dc810a50dd821b92b11e69493 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
@@ -341,10 +341,10 @@ bool access_check_method(methodinfo *m, int callerdepth)
        return true;
 }
 
-#if defined(__cplusplus)
-}
 #endif
 
+#if defined(__cplusplus)
+}
 #endif
 
 
diff --git a/src/vm/annotation.c b/src/vm/annotation.c
deleted file mode 100644 (file)
index bbca2af..0000000
+++ /dev/null
@@ -1,614 +0,0 @@
-/* src/vm/annotation.c - class annotations
-
-   Copyright (C) 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 "native/llni.h"
-
-#include "mm/memory.h"
-
-#include "toolbox/logging.h"
-
-#include "vm/annotation.h"
-#include "vm/array.hpp"
-#include "vm/jit/builtin.hpp"
-#include "vm/class.hpp"
-#include "vm/loader.hpp"
-#include "vm/primitive.hpp"
-#include "vm/suck.hpp"
-#include "vm/types.h"
-
-#if !defined(ENABLE_ANNOTATIONS)
-# error annotation support has to be enabled when compling this file!
-#endif
-
-
-/* annotation_bytearrays_resize ***********************************************
-
-   Resize an array of bytearrays.
-
-   IN:
-       bytearrays.....array of bytearrays
-       size...........new size of the refered array
-   
-   RETURN VALUE:
-       The new array if a resize was neccessarry, the old if the given size
-       equals the current size or NULL if an error occured.
-
-*******************************************************************************/
-
-static java_handle_objectarray_t *annotation_bytearrays_resize(
-       java_handle_objectarray_t *bytearrays, uint32_t size)
-{
-       java_handle_objectarray_t *newbas = NULL; /* new array     */
-       uint32_t minsize = 0;      /* count of object refs to copy */
-       uint32_t oldsize = 0;      /* size of old array            */
-
-       if (bytearrays != NULL) {
-               oldsize = array_length_get((java_handle_t*)bytearrays);
-               
-               /* if the size already fits do nothing */
-               if (size == oldsize) {
-                       return bytearrays;
-               }
-       }
-       
-       newbas = builtin_anewarray(size,
-               Primitive_get_arrayclass_by_type(PRIMITIVETYPE_BYTE));
-       
-       /* is there a old byte array array? */
-       if (newbas != NULL && bytearrays != NULL) {
-               minsize = size < oldsize ? size : oldsize;
-
-               LLNI_CRITICAL_START;
-               MCOPY(
-                       LLNI_array_data(newbas), LLNI_array_data(bytearrays),
-                       java_object_t*, minsize);
-               LLNI_CRITICAL_END;
-       }
-
-       return newbas;
-}
-
-
-/* annotation_bytearrays_insert ***********************************************
-
-   Insert a bytearray into an array of bytearrays.
-
-   IN:
-       bytearrays........array of bytearrays where 'bytearray' has to be
-                         inserted at position 'index'.
-       index.............position where 'ba' has to be inserted into
-                         'bytearrays'.
-       bytearray.........byte array which has to be inserted into
-                         'bytearrays'.
-
-   RETURN VALUE:
-       The new array if a resize was neccessarry, the old if the given size
-       equals the current size or NULL if an error occured.
-
-*******************************************************************************/
-
-static java_handle_t *annotation_bytearrays_insert(
-       java_handle_t *bytearrays, uint32_t index,
-       java_handle_bytearray_t *bytearray)
-{
-       java_handle_objectarray_t *bas; /* bytearrays                */
-       uint32_t size = 0;              /* current size of the array */
-
-       /* do nothing if NULL is inserted but no array exists */
-       if (bytearray == NULL && bytearrays == NULL) {
-               return NULL;
-       }
-
-       /* get lengths if array exists */
-       if (bytearrays != NULL) {
-               size = array_length_get(bytearrays);
-       }
-
-       bas = (java_handle_objectarray_t*)bytearrays;
-
-       if (bytearray == NULL) {
-               /* insert NULL only if array is big enough */
-               if (size > index) {
-                       array_objectarray_element_set(bas, index, NULL);
-               }
-       }
-       else {
-               /* resize array if it's not enough for inserted value */
-               if (size <= index) {
-                       bas = annotation_bytearrays_resize(bas, index + 1);
-
-                       if (bas == NULL) {
-                               /* out of memory */
-                               return NULL;
-                       }
-               }
-
-               array_objectarray_element_set(bas, index, (java_handle_t*)bytearray);
-       }
-       
-       return (java_handle_t*)bas;
-}
-
-
-/* annotation_load_attribute_body *********************************************
-
-   This function loads the body of a generic attribute.
-
-   XXX: Maybe this function should be called loader_load_attribute_body and
-        located in vm/loader.c?
-
-   attribute_info {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u1 info[attribute_length];
-   }
-
-   IN:
-       cb.................classbuffer from which to read the data.
-       errormsg_prefix....prefix for error messages (if any).
-
-   OUT:
-       attribute..........bytearray-pointer which will be set to the read data.
-   
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-static bool annotation_load_attribute_body(classbuffer *cb,
-       java_handle_bytearray_t **attribute, const char *errormsg_prefix)
-{
-       uint32_t                 size = 0;    /* size of the attribute     */
-       java_handle_bytearray_t *ba   = NULL; /* the raw attributes' bytes */
-
-       assert(cb != NULL);
-       assert(attribute != NULL);
-
-       if (!suck_check_classbuffer_size(cb, 4)) {
-               log_println("%s: size missing", errormsg_prefix);
-               return false;
-       }
-
-       /* load attribute_length */
-       size = suck_u4(cb);
-       
-       if (!suck_check_classbuffer_size(cb, size)) {
-               log_println("%s: invalid size", errormsg_prefix);
-               return false;
-       }
-       
-       /* if attribute_length == 0 then NULL is
-        * the right value for this attribute */
-       if (size > 0) {
-               ba = builtin_newarray_byte(size);
-
-               if (ba == NULL) {
-                       /* out of memory */
-                       return false;
-               }
-
-               /* load data */
-               LLNI_CRITICAL_START;
-
-               suck_nbytes((uint8_t*)LLNI_array_data(ba), cb, size);
-
-               LLNI_CRITICAL_END;
-
-               /* return data */
-               *attribute = ba;
-       }
-       
-       return true;
-}
-
-
-/* annotation_load_method_attribute_annotationdefault *************************
-
-   Load annotation default value.
-
-   AnnotationDefault_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       element_value default_value;
-   }
-
-   IN:
-       cb.................classbuffer from which to read the data.
-       m..................methodinfo for the method of which the annotation
-                          default value is read and into which the value is
-                          stored into.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_method_attribute_annotationdefault(
-               classbuffer *cb, methodinfo *m)
-{
-       int                      slot               = 0;
-                                /* the slot of the method                        */
-       java_handle_bytearray_t *annotationdefault  = NULL;
-                                /* unparsed annotation defalut value             */
-       java_handle_t           *annotationdefaults = NULL;
-                                /* array of unparsed annotation default values   */
-
-       assert(cb != NULL);
-       assert(m != NULL);
-
-       LLNI_classinfo_field_get(
-               m->clazz, method_annotationdefaults, annotationdefaults);
-
-       if (!annotation_load_attribute_body(
-                       cb, &annotationdefault,
-                       "invalid annotation default method attribute")) {
-               return false;
-       }
-
-       if (annotationdefault != NULL) {
-               slot = m - m->clazz->methods;
-               annotationdefaults = annotation_bytearrays_insert(
-                               annotationdefaults, slot, annotationdefault);
-
-               if (annotationdefaults == NULL) {
-                       return false;
-               }
-
-               LLNI_classinfo_field_set(
-                       m->clazz, method_annotationdefaults, annotationdefaults);
-       }
-
-       return true;
-}
-
-
-/* annotation_load_method_attribute_runtimevisibleparameterannotations ********
-
-   Load runtime visible parameter annotations.
-
-   RuntimeVisibleParameterAnnotations_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u1 num_parameters;
-       {
-           u2 num_annotations;
-           annotation annotations[num_annotations];
-       } parameter_annotations[num_parameters];
-   }
-
-   IN:
-       cb.................classbuffer from which to read the data.
-       m..................methodinfo for the method of which the parameter
-                          annotations are read and into which the parameter
-                          annotations are stored into.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_method_attribute_runtimevisibleparameterannotations(
-               classbuffer *cb, methodinfo *m)
-{
-       int                      slot                 = 0;
-                                /* the slot of the method                  */
-       java_handle_bytearray_t *annotations          = NULL;
-                                /* unparsed parameter annotations          */
-       java_handle_t           *parameterannotations = NULL;
-                                /* array of unparsed parameter annotations */
-
-       assert(cb != NULL);
-       assert(m != NULL);
-
-       LLNI_classinfo_field_get(
-               m->clazz, method_parameterannotations, parameterannotations);
-
-       if (!annotation_load_attribute_body(
-                       cb, &annotations,
-                       "invalid runtime visible parameter annotations method attribute")) {
-               return false;
-       }
-
-       if (annotations != NULL) {
-               slot = m - m->clazz->methods;
-               parameterannotations = annotation_bytearrays_insert(
-                               parameterannotations, slot, annotations);
-
-               if (parameterannotations == NULL) {
-                       return false;
-               }
-
-               LLNI_classinfo_field_set(
-                       m->clazz, method_parameterannotations, parameterannotations);
-       }
-
-       return true;
-}
-
-
-/* annotation_load_method_attribute_runtimeinvisibleparameterannotations ******
-   Load runtime invisible parameter annotations.
-
-   <quote cite="http://jcp.org/en/jsr/detail?id=202">
-   The RuntimeInvisibleParameterAnnotations attribute is similar to the
-   RuntimeVisibleParameterAnnotations attribute, except that the annotations
-   represented by a RuntimeInvisibleParameterAnnotations attribute must not be
-   made available for return by reflective APIs, unless the the JVM has
-   specifically been instructed to retain these annotations via some
-   implementation-specific mechanism such as a command line flag. In the
-   absence of such instructions, the JVM ignores this attribute.
-   </quote>
-
-   Hotspot loads them into the same bytearray as the runtime visible parameter
-   annotations (after the runtime visible parameter annotations). But in J2SE
-   the bytearray will only be parsed as if there is only one annotation
-   structure in it, so the runtime invisible parameter annotatios will be
-   ignored.
-
-   Therefore I do not even bother to read them.
-
-   RuntimeInvisibleParameterAnnotations_attribute {
-       u2 attribute_name_index;
-       u4 attribute_length;
-       u1 num_parameters;
-       {
-           u2 num_annotations;
-           annotation annotations[num_annotations];
-       } parameter_annotations[num_parameters];
-   }
-
-   IN:
-       cb.................classbuffer from which to read the data.
-       m..................methodinfo for the method of which the parameter
-                          annotations are read and into which the parameter
-                          annotations are stored into.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
-               classbuffer *cb, methodinfo *m)
-{
-       return loader_skip_attribute_body(cb);
-}
-
-
-/* annotation_load_class_attribute_runtimevisibleannotations ******************
-   
-   Load runtime visible annotations of a class.
-   
-   IN:
-       cb........the classbuffer from which the attribute has to be loaded.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_class_attribute_runtimevisibleannotations(
-       classbuffer *cb)
-{
-       java_handle_bytearray_t *annotations = NULL; /* unparsed annotations */
-       
-       if (!annotation_load_attribute_body(
-                       cb, &annotations,
-                       "invalid runtime visible annotations class attribute")) {
-               return false;
-       }
-
-       LLNI_classinfo_field_set(cb->clazz, annotations, (java_handle_t*)annotations);
-
-       return true;
-}
-
-
-/* annotation_load_class_attribute_runtimeinvisibleannotations ****************
-   
-   Load runtime invisible annotations of a class (just skip them).
-   
-   IN:
-       cb........the classbuffer from which the attribute has to be loaded.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_class_attribute_runtimeinvisibleannotations(
-       classbuffer *cb)
-{
-       return loader_skip_attribute_body(cb);
-}
-
-
-/* annotation_load_method_attribute_runtimevisibleannotations *****************
-   
-   Load runtime visible annotations of a method.
-  
-   IN:
-       cb........the classbuffer from which the attribute has to be loaded.
-       m.........the method of which the runtime visible annotations have
-                 to be loaded.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_method_attribute_runtimevisibleannotations(
-       classbuffer *cb, methodinfo *m)
-{
-       int                      slot               = 0;
-                                /* slot of the method */
-       java_handle_bytearray_t *annotations        = NULL;
-                                /* unparsed annotations */
-       java_handle_t           *method_annotations = NULL;
-                                /* array of unparsed method annotations */
-
-       assert(cb != NULL);
-       assert(m != NULL);
-
-       LLNI_classinfo_field_get(
-               m->clazz, method_annotations, method_annotations);
-
-       if (!annotation_load_attribute_body(
-                       cb, &annotations,
-                       "invalid runtime visible annotations method attribute")) {
-               return false;
-       }
-
-       if (annotations != NULL) {
-               slot = m - m->clazz->methods;
-               method_annotations = annotation_bytearrays_insert(
-                               method_annotations, slot, annotations);
-
-               if (method_annotations == NULL) {
-                       return false;
-               }
-               
-               LLNI_classinfo_field_set(
-                       m->clazz, method_annotations, method_annotations);
-       }
-
-       return true;
-}
-
-
-/* annotation_load_method_attribute_runtimeinvisibleannotations ****************
-   
-   Load runtime invisible annotations of a method (just skip them).
-   
-   IN:
-       cb........the classbuffer from which the attribute has to be loaded.
-       m.........the method of which the runtime invisible annotations have
-                 to be loaded.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_method_attribute_runtimeinvisibleannotations(
-       classbuffer *cb, methodinfo *m)
-{
-       return loader_skip_attribute_body(cb);
-}
-
-
-/* annotation_load_field_attribute_runtimevisibleannotations ******************
-   
-   Load runtime visible annotations of a field.
-   
-   IN:
-       cb........the classbuffer from which the attribute has to be loaded.
-       f.........the field of which the runtime visible annotations have
-                 to be loaded.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_field_attribute_runtimevisibleannotations(
-       classbuffer *cb, fieldinfo *f)
-{
-       int                      slot              = 0;
-                                /* slot of the field                   */
-       java_handle_bytearray_t *annotations       = NULL;
-                                /* unparsed annotations                */
-       java_handle_t           *field_annotations = NULL;
-                                /* array of unparsed field annotations */
-
-       assert(cb != NULL);
-       assert(f != NULL);
-
-       LLNI_classinfo_field_get(
-               f->clazz, field_annotations, field_annotations);
-
-       if (!annotation_load_attribute_body(
-                       cb, &annotations,
-                       "invalid runtime visible annotations field attribute")) {
-               return false;
-       }
-
-       if (annotations != NULL) {
-               slot = f - f->clazz->fields;
-               field_annotations = annotation_bytearrays_insert(
-                               field_annotations, slot, annotations);
-
-               if (field_annotations == NULL) {
-                       return false;
-               }
-
-               LLNI_classinfo_field_set(
-                       f->clazz, field_annotations, field_annotations);
-       }
-
-       return true;
-}
-
-
-/* annotation_load_field_attribute_runtimeinvisibleannotations ****************
-   
-   Load runtime invisible annotations of a field (just skip them).
-   
-   IN:
-       cb........the classbuffer from which the attribute has to be loaded.
-       f.........the field of which the runtime invisible annotations have
-                 to be loaded.
-
-   RETURN VALUE:
-       true if all went good. false otherwhise.
-
-*******************************************************************************/
-
-bool annotation_load_field_attribute_runtimeinvisibleannotations(
-       classbuffer *cb, fieldinfo *f)
-{
-       return loader_skip_attribute_body(cb);
-}
-
-
-/*
- * 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/annotation.cpp b/src/vm/annotation.cpp
new file mode 100644 (file)
index 0000000..2a5fafd
--- /dev/null
@@ -0,0 +1,614 @@
+/* src/vm/annotation.cpp - class annotations
+
+   Copyright (C) 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 "native/llni.h"
+
+#include "mm/memory.hpp"
+
+#include "toolbox/logging.hpp"
+
+#include "vm/annotation.hpp"
+#include "vm/array.hpp"
+#include "vm/jit/builtin.hpp"
+#include "vm/class.hpp"
+#include "vm/loader.hpp"
+#include "vm/primitive.hpp"
+#include "vm/suck.hpp"
+#include "vm/types.h"
+
+#if !defined(ENABLE_ANNOTATIONS)
+# error annotation support has to be enabled when compling this file!
+#endif
+
+
+/* annotation_bytearrays_resize ***********************************************
+
+   Resize an array of bytearrays.
+
+   IN:
+       bytearrays.....array of bytearrays
+       size...........new size of the refered array
+   
+   RETURN VALUE:
+       The new array if a resize was neccessarry, the old if the given size
+       equals the current size or NULL if an error occured.
+
+*******************************************************************************/
+
+static java_handle_objectarray_t *annotation_bytearrays_resize(
+       java_handle_objectarray_t *bytearrays, uint32_t size)
+{
+       java_handle_objectarray_t *newbas = NULL; /* new array     */
+       uint32_t minsize = 0;      /* count of object refs to copy */
+       uint32_t oldsize = 0;      /* size of old array            */
+
+       if (bytearrays != NULL) {
+               oldsize = array_length_get((java_handle_t*)bytearrays);
+               
+               /* if the size already fits do nothing */
+               if (size == oldsize) {
+                       return bytearrays;
+               }
+       }
+       
+       newbas = builtin_anewarray(size,
+               Primitive::get_arrayclass_by_type(PRIMITIVETYPE_BYTE));
+       
+       /* is there a old byte array array? */
+       if (newbas != NULL && bytearrays != NULL) {
+               minsize = size < oldsize ? size : oldsize;
+
+               LLNI_CRITICAL_START;
+               MCOPY(
+                       LLNI_array_data(newbas), LLNI_array_data(bytearrays),
+                       java_object_t*, minsize);
+               LLNI_CRITICAL_END;
+       }
+
+       return newbas;
+}
+
+
+/* annotation_bytearrays_insert ***********************************************
+
+   Insert a bytearray into an array of bytearrays.
+
+   IN:
+       bytearrays........array of bytearrays where 'bytearray' has to be
+                         inserted at position 'index'.
+       index.............position where 'ba' has to be inserted into
+                         'bytearrays'.
+       bytearray.........byte array which has to be inserted into
+                         'bytearrays'.
+
+   RETURN VALUE:
+       The new array if a resize was neccessarry, the old if the given size
+       equals the current size or NULL if an error occured.
+
+*******************************************************************************/
+
+static java_handle_t *annotation_bytearrays_insert(
+       java_handle_t *bytearrays, uint32_t index,
+       java_handle_bytearray_t *bytearray)
+{
+       java_handle_objectarray_t *bas; /* bytearrays                */
+       uint32_t size = 0;              /* current size of the array */
+
+       /* do nothing if NULL is inserted but no array exists */
+       if (bytearray == NULL && bytearrays == NULL) {
+               return NULL;
+       }
+
+       /* get lengths if array exists */
+       if (bytearrays != NULL) {
+               size = array_length_get(bytearrays);
+       }
+
+       bas = (java_handle_objectarray_t*)bytearrays;
+
+       if (bytearray == NULL) {
+               /* insert NULL only if array is big enough */
+               if (size > index) {
+                       array_objectarray_element_set(bas, index, NULL);
+               }
+       }
+       else {
+               /* resize array if it's not enough for inserted value */
+               if (size <= index) {
+                       bas = annotation_bytearrays_resize(bas, index + 1);
+
+                       if (bas == NULL) {
+                               /* out of memory */
+                               return NULL;
+                       }
+               }
+
+               array_objectarray_element_set(bas, index, (java_handle_t*)bytearray);
+       }
+       
+       return (java_handle_t*)bas;
+}
+
+
+/* annotation_load_attribute_body *********************************************
+
+   This function loads the body of a generic attribute.
+
+   XXX: Maybe this function should be called loader_load_attribute_body and
+        located in vm/loader.c?
+
+   attribute_info {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 info[attribute_length];
+   }
+
+   IN:
+       cb.................classbuffer from which to read the data.
+       errormsg_prefix....prefix for error messages (if any).
+
+   OUT:
+       attribute..........bytearray-pointer which will be set to the read data.
+   
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+static bool annotation_load_attribute_body(classbuffer *cb,
+       java_handle_bytearray_t **attribute, const char *errormsg_prefix)
+{
+       uint32_t                 size = 0;    /* size of the attribute     */
+       java_handle_bytearray_t *ba   = NULL; /* the raw attributes' bytes */
+
+       assert(cb != NULL);
+       assert(attribute != NULL);
+
+       if (!suck_check_classbuffer_size(cb, 4)) {
+               log_println("%s: size missing", errormsg_prefix);
+               return false;
+       }
+
+       /* load attribute_length */
+       size = suck_u4(cb);
+       
+       if (!suck_check_classbuffer_size(cb, size)) {
+               log_println("%s: invalid size", errormsg_prefix);
+               return false;
+       }
+       
+       /* if attribute_length == 0 then NULL is
+        * the right value for this attribute */
+       if (size > 0) {
+               ba = builtin_newarray_byte(size);
+
+               if (ba == NULL) {
+                       /* out of memory */
+                       return false;
+               }
+
+               /* load data */
+               LLNI_CRITICAL_START;
+
+               suck_nbytes((uint8_t*)LLNI_array_data(ba), cb, size);
+
+               LLNI_CRITICAL_END;
+
+               /* return data */
+               *attribute = ba;
+       }
+       
+       return true;
+}
+
+
+/* annotation_load_method_attribute_annotationdefault *************************
+
+   Load annotation default value.
+
+   AnnotationDefault_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       element_value default_value;
+   }
+
+   IN:
+       cb.................classbuffer from which to read the data.
+       m..................methodinfo for the method of which the annotation
+                          default value is read and into which the value is
+                          stored into.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_method_attribute_annotationdefault(
+               classbuffer *cb, methodinfo *m)
+{
+       int                      slot               = 0;
+                                /* the slot of the method                        */
+       java_handle_bytearray_t *annotationdefault  = NULL;
+                                /* unparsed annotation defalut value             */
+       java_handle_t           *annotationdefaults = NULL;
+                                /* array of unparsed annotation default values   */
+
+       assert(cb != NULL);
+       assert(m != NULL);
+
+       LLNI_classinfo_field_get(
+               m->clazz, method_annotationdefaults, annotationdefaults);
+
+       if (!annotation_load_attribute_body(
+                       cb, &annotationdefault,
+                       "invalid annotation default method attribute")) {
+               return false;
+       }
+
+       if (annotationdefault != NULL) {
+               slot = m - m->clazz->methods;
+               annotationdefaults = annotation_bytearrays_insert(
+                               annotationdefaults, slot, annotationdefault);
+
+               if (annotationdefaults == NULL) {
+                       return false;
+               }
+
+               LLNI_classinfo_field_set(
+                       m->clazz, method_annotationdefaults, annotationdefaults);
+       }
+
+       return true;
+}
+
+
+/* annotation_load_method_attribute_runtimevisibleparameterannotations ********
+
+   Load runtime visible parameter annotations.
+
+   RuntimeVisibleParameterAnnotations_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 num_parameters;
+       {
+           u2 num_annotations;
+           annotation annotations[num_annotations];
+       } parameter_annotations[num_parameters];
+   }
+
+   IN:
+       cb.................classbuffer from which to read the data.
+       m..................methodinfo for the method of which the parameter
+                          annotations are read and into which the parameter
+                          annotations are stored into.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_method_attribute_runtimevisibleparameterannotations(
+               classbuffer *cb, methodinfo *m)
+{
+       int                      slot                 = 0;
+                                /* the slot of the method                  */
+       java_handle_bytearray_t *annotations          = NULL;
+                                /* unparsed parameter annotations          */
+       java_handle_t           *parameterannotations = NULL;
+                                /* array of unparsed parameter annotations */
+
+       assert(cb != NULL);
+       assert(m != NULL);
+
+       LLNI_classinfo_field_get(
+               m->clazz, method_parameterannotations, parameterannotations);
+
+       if (!annotation_load_attribute_body(
+                       cb, &annotations,
+                       "invalid runtime visible parameter annotations method attribute")) {
+               return false;
+       }
+
+       if (annotations != NULL) {
+               slot = m - m->clazz->methods;
+               parameterannotations = annotation_bytearrays_insert(
+                               parameterannotations, slot, annotations);
+
+               if (parameterannotations == NULL) {
+                       return false;
+               }
+
+               LLNI_classinfo_field_set(
+                       m->clazz, method_parameterannotations, parameterannotations);
+       }
+
+       return true;
+}
+
+
+/* annotation_load_method_attribute_runtimeinvisibleparameterannotations ******
+   Load runtime invisible parameter annotations.
+
+   <quote cite="http://jcp.org/en/jsr/detail?id=202">
+   The RuntimeInvisibleParameterAnnotations attribute is similar to the
+   RuntimeVisibleParameterAnnotations attribute, except that the annotations
+   represented by a RuntimeInvisibleParameterAnnotations attribute must not be
+   made available for return by reflective APIs, unless the the JVM has
+   specifically been instructed to retain these annotations via some
+   implementation-specific mechanism such as a command line flag. In the
+   absence of such instructions, the JVM ignores this attribute.
+   </quote>
+
+   Hotspot loads them into the same bytearray as the runtime visible parameter
+   annotations (after the runtime visible parameter annotations). But in J2SE
+   the bytearray will only be parsed as if there is only one annotation
+   structure in it, so the runtime invisible parameter annotatios will be
+   ignored.
+
+   Therefore I do not even bother to read them.
+
+   RuntimeInvisibleParameterAnnotations_attribute {
+       u2 attribute_name_index;
+       u4 attribute_length;
+       u1 num_parameters;
+       {
+           u2 num_annotations;
+           annotation annotations[num_annotations];
+       } parameter_annotations[num_parameters];
+   }
+
+   IN:
+       cb.................classbuffer from which to read the data.
+       m..................methodinfo for the method of which the parameter
+                          annotations are read and into which the parameter
+                          annotations are stored into.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
+               classbuffer *cb, methodinfo *m)
+{
+       return loader_skip_attribute_body(cb);
+}
+
+
+/* annotation_load_class_attribute_runtimevisibleannotations ******************
+   
+   Load runtime visible annotations of a class.
+   
+   IN:
+       cb........the classbuffer from which the attribute has to be loaded.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_class_attribute_runtimevisibleannotations(
+       classbuffer *cb)
+{
+       java_handle_bytearray_t *annotations = NULL; /* unparsed annotations */
+       
+       if (!annotation_load_attribute_body(
+                       cb, &annotations,
+                       "invalid runtime visible annotations class attribute")) {
+               return false;
+       }
+
+       LLNI_classinfo_field_set(cb->clazz, annotations, (java_handle_t*)annotations);
+
+       return true;
+}
+
+
+/* annotation_load_class_attribute_runtimeinvisibleannotations ****************
+   
+   Load runtime invisible annotations of a class (just skip them).
+   
+   IN:
+       cb........the classbuffer from which the attribute has to be loaded.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_class_attribute_runtimeinvisibleannotations(
+       classbuffer *cb)
+{
+       return loader_skip_attribute_body(cb);
+}
+
+
+/* annotation_load_method_attribute_runtimevisibleannotations *****************
+   
+   Load runtime visible annotations of a method.
+  
+   IN:
+       cb........the classbuffer from which the attribute has to be loaded.
+       m.........the method of which the runtime visible annotations have
+                 to be loaded.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_method_attribute_runtimevisibleannotations(
+       classbuffer *cb, methodinfo *m)
+{
+       int                      slot               = 0;
+                                /* slot of the method */
+       java_handle_bytearray_t *annotations        = NULL;
+                                /* unparsed annotations */
+       java_handle_t           *method_annotations = NULL;
+                                /* array of unparsed method annotations */
+
+       assert(cb != NULL);
+       assert(m != NULL);
+
+       LLNI_classinfo_field_get(
+               m->clazz, method_annotations, method_annotations);
+
+       if (!annotation_load_attribute_body(
+                       cb, &annotations,
+                       "invalid runtime visible annotations method attribute")) {
+               return false;
+       }
+
+       if (annotations != NULL) {
+               slot = m - m->clazz->methods;
+               method_annotations = annotation_bytearrays_insert(
+                               method_annotations, slot, annotations);
+
+               if (method_annotations == NULL) {
+                       return false;
+               }
+               
+               LLNI_classinfo_field_set(
+                       m->clazz, method_annotations, method_annotations);
+       }
+
+       return true;
+}
+
+
+/* annotation_load_method_attribute_runtimeinvisibleannotations ****************
+   
+   Load runtime invisible annotations of a method (just skip them).
+   
+   IN:
+       cb........the classbuffer from which the attribute has to be loaded.
+       m.........the method of which the runtime invisible annotations have
+                 to be loaded.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_method_attribute_runtimeinvisibleannotations(
+       classbuffer *cb, methodinfo *m)
+{
+       return loader_skip_attribute_body(cb);
+}
+
+
+/* annotation_load_field_attribute_runtimevisibleannotations ******************
+   
+   Load runtime visible annotations of a field.
+   
+   IN:
+       cb........the classbuffer from which the attribute has to be loaded.
+       f.........the field of which the runtime visible annotations have
+                 to be loaded.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_field_attribute_runtimevisibleannotations(
+       classbuffer *cb, fieldinfo *f)
+{
+       int                      slot              = 0;
+                                /* slot of the field                   */
+       java_handle_bytearray_t *annotations       = NULL;
+                                /* unparsed annotations                */
+       java_handle_t           *field_annotations = NULL;
+                                /* array of unparsed field annotations */
+
+       assert(cb != NULL);
+       assert(f != NULL);
+
+       LLNI_classinfo_field_get(
+               f->clazz, field_annotations, field_annotations);
+
+       if (!annotation_load_attribute_body(
+                       cb, &annotations,
+                       "invalid runtime visible annotations field attribute")) {
+               return false;
+       }
+
+       if (annotations != NULL) {
+               slot = f - f->clazz->fields;
+               field_annotations = annotation_bytearrays_insert(
+                               field_annotations, slot, annotations);
+
+               if (field_annotations == NULL) {
+                       return false;
+               }
+
+               LLNI_classinfo_field_set(
+                       f->clazz, field_annotations, field_annotations);
+       }
+
+       return true;
+}
+
+
+/* annotation_load_field_attribute_runtimeinvisibleannotations ****************
+   
+   Load runtime invisible annotations of a field (just skip them).
+   
+   IN:
+       cb........the classbuffer from which the attribute has to be loaded.
+       f.........the field of which the runtime invisible annotations have
+                 to be loaded.
+
+   RETURN VALUE:
+       true if all went good. false otherwhise.
+
+*******************************************************************************/
+
+bool annotation_load_field_attribute_runtimeinvisibleannotations(
+       classbuffer *cb, fieldinfo *f)
+{
+       return loader_skip_attribute_body(cb);
+}
+
+
+/*
+ * 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/annotation.h b/src/vm/annotation.h
deleted file mode 100644 (file)
index 2a8b116..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-/* src/vm/annotation.h - class annotations
-
-   Copyright (C) 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 _ANNOTATION_H
-#define _ANNOTATION_H
-
-
-#include "config.h"
-
-#include "vm/types.h"
-
-#include "vm/class.hpp"
-#include "vm/field.hpp"
-#include "vm/global.h"
-#include "vm/loader.hpp"
-#include "vm/method.hpp"
-
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-bool annotation_load_class_attribute_runtimevisibleannotations(
-       classbuffer *cb);
-
-bool annotation_load_class_attribute_runtimeinvisibleannotations(
-       classbuffer *cb);
-
-bool annotation_load_method_attribute_runtimevisibleannotations(
-       classbuffer *cb, methodinfo *m);
-
-bool annotation_load_method_attribute_runtimeinvisibleannotations(
-       classbuffer *cb, methodinfo *m);
-
-bool annotation_load_field_attribute_runtimevisibleannotations(
-       classbuffer *cb, fieldinfo *f);
-
-bool annotation_load_field_attribute_runtimeinvisibleannotations(
-       classbuffer *cb, fieldinfo *f);
-
-bool annotation_load_method_attribute_annotationdefault(
-       classbuffer *cb, methodinfo *m);
-
-bool annotation_load_method_attribute_runtimevisibleparameterannotations(
-       classbuffer *cb, methodinfo *m);
-
-bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
-       classbuffer *cb, methodinfo *m);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _ANNOTATION_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/annotation.hpp b/src/vm/annotation.hpp
new file mode 100644 (file)
index 0000000..3ee896c
--- /dev/null
@@ -0,0 +1,93 @@
+/* src/vm/annotation.hpp - class annotations
+
+   Copyright (C) 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 _ANNOTATION_HPP
+#define _ANNOTATION_HPP
+
+
+#include "config.h"
+
+#include "vm/types.h"
+
+#include "vm/class.hpp"
+#include "vm/field.hpp"
+#include "vm/global.h"
+#include "vm/loader.hpp"
+#include "vm/method.hpp"
+
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool annotation_load_class_attribute_runtimevisibleannotations(
+       classbuffer *cb);
+
+bool annotation_load_class_attribute_runtimeinvisibleannotations(
+       classbuffer *cb);
+
+bool annotation_load_method_attribute_runtimevisibleannotations(
+       classbuffer *cb, methodinfo *m);
+
+bool annotation_load_method_attribute_runtimeinvisibleannotations(
+       classbuffer *cb, methodinfo *m);
+
+bool annotation_load_field_attribute_runtimevisibleannotations(
+       classbuffer *cb, fieldinfo *f);
+
+bool annotation_load_field_attribute_runtimeinvisibleannotations(
+       classbuffer *cb, fieldinfo *f);
+
+bool annotation_load_method_attribute_annotationdefault(
+       classbuffer *cb, methodinfo *m);
+
+bool annotation_load_method_attribute_runtimevisibleparameterannotations(
+       classbuffer *cb, methodinfo *m);
+
+bool annotation_load_method_attribute_runtimeinvisibleparameterannotations(
+       classbuffer *cb, methodinfo *m);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _ANNOTATION_HPP */
+
+
+/*
+ * 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 7252aa320ac0bfd6cb788ed6ff155e6e9bec0ce5..ada17e4d0f096538605257c1ae8eb49d218c2b04 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <cstddef>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/list.hpp"
 
index 0aa5f21233972cf757f8f2f0f4b8c7285d38a7a7..698356d11566973010920c69af5720f75694445d 100644 (file)
 
 #include "arch.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
 #include "threads/lock.hpp"
 #include "threads/mutex.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
@@ -2117,6 +2117,13 @@ int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
        classref_or_classinfo  outer;
        utf                   *innername;
        int                    i;
+       int32_t                flags;
+
+       /* default to flags of passed class */
+
+       flags = c->flags;
+
+       /* if requested we check if passed class is inner class */
 
        if (!ignoreInnerClassesAttrib && (c->innerclasscount != 0)) {
                /* search for passed class as inner class */
@@ -2137,16 +2144,16 @@ int32_t class_get_modifiers(classinfo *c, bool ignoreInnerClassesAttrib)
 
                                if (outer.any)
                                        /* return flags got from the outer class file */
-                                       return c->innerclass[i].flags & ACC_CLASS_REFLECT_MASK;
-                               else
-                                       return c->flags & ACC_CLASS_REFLECT_MASK;
+                                       flags = c->innerclass[i].flags;
+
+                               break;
                        }
                }
        }
 
-       /* passed class is no inner class or it was not requested */
+       /* remove ACC_SUPER bit from flags */
 
-       return c->flags & ACC_CLASS_REFLECT_MASK;
+       return flags & ~ACC_SUPER & ACC_CLASS_REFLECT_MASK;
 }
 
 
index d1584b1c4228073671997988bbf27eb9038c663c..b09bcca47a72faddf93afb91035681c292848bf0 100644 (file)
@@ -40,7 +40,7 @@ typedef struct extra_classref extra_classref;
 #include "vm/types.h"
 
 #if defined(ENABLE_JAVASE)
-# include "vm/annotation.h"
+# include "vm/annotation.hpp"
 #endif
 
 #include "vm/field.hpp"
index 93db61a9b4eeaafbbf5bc37a6ad168a4d1473cc8..f0900e2289860f5c4af9d62a47b072610289abad 100644 (file)
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 #include "threads/mutex.hpp"
 
 #include "toolbox/hashtable.h"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/classcache.hpp"
 #include "vm/exceptions.hpp"
 
 /* #define CLASSCACHE_VERBOSE */
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
-
 /*============================================================================*/
 /* STATISTICS                                                                 */
 /*============================================================================*/
@@ -1574,10 +1570,6 @@ dump_it:
        CLASSCACHE_UNLOCK();
 }
 
-#if defined(__cplusplus)
-}
-#endif
-
 #endif /* NDEBUG */
 
 /*
diff --git a/src/vm/descriptor.c b/src/vm/descriptor.c
deleted file mode 100644 (file)
index 235154e..0000000
+++ /dev/null
@@ -1,1398 +0,0 @@
-/* src/vm/descriptor.c - checking and parsing of field / method descriptors
-
-   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 "vm/types.h"
-
-#include "md-abi.h"
-
-#include "mm/memory.h"
-
-#include "vm/descriptor.h"
-#include "vm/exceptions.hpp"
-#include "vm/options.h"
-#include "vm/primitive.hpp"
-#include "vm/vm.hpp"
-
-#include "vm/jit/abi.h"
-
-
-/* constants (private to descriptor.c) ****************************************/
-
-/* initial number of entries for the classrefhash of a descriptor_pool */
-/* (currently the hash is never grown!) */
-#define CLASSREFHASH_INIT_SIZE  64
-
-/* initial number of entries for the descriptorhash of a descriptor_pool */
-/* (currently the hash is never grown!) */
-#define DESCRIPTORHASH_INIT_SIZE  128
-
-/* data structures (private to descriptor.c) **********************************/
-
-typedef struct classref_hash_entry classref_hash_entry;
-typedef struct descriptor_hash_entry descriptor_hash_entry;
-
-/* entry struct for the classrefhash of descriptor_pool */
-struct classref_hash_entry {
-       classref_hash_entry *hashlink;  /* for hash chaining            */
-       utf                 *name;      /* name of the class refered to */
-       u2                   index;     /* index into classref table    */
-};
-
-/* entry struct for the descriptorhash of descriptor_pool */
-struct descriptor_hash_entry {
-       descriptor_hash_entry *hashlink;
-       utf                   *desc;
-       parseddesc_t           parseddesc;
-       s2                     paramslots; /* number of params, LONG/DOUBLE counted as 2 */
-};
-
-
-/****************************************************************************/
-/* MACROS FOR DESCRIPTOR PARSING (private to descriptor.c)                  */
-/****************************************************************************/
-
-/* SKIP_FIELDDESCRIPTOR:
- * utf_ptr must point to the first character of a field descriptor.
- * After the macro call utf_ptr points to the first character after
- * the field descriptor.
- *
- * CAUTION: This macro does not check for an unexpected end of the
- * descriptor. Better use SKIP_FIELDDESCRIPTOR_SAFE.
- */
-#define SKIP_FIELDDESCRIPTOR(utf_ptr)                                                  \
-       do { while (*(utf_ptr)=='[') (utf_ptr)++;                                       \
-               if (*(utf_ptr)++=='L')                                                                  \
-                       while(*(utf_ptr)++ != ';') /* skip */; } while(0)
-
-/* SKIP_FIELDDESCRIPTOR_SAFE:
- * utf_ptr must point to the first character of a field descriptor.
- * After the macro call utf_ptr points to the first character after
- * the field descriptor.
- *
- * Input:
- *     utf_ptr....points to first char of descriptor
- *     end_ptr....points to first char after the end of the string
- *     errorflag..must be initialized (to false) by the caller!
- * Output:
- *     utf_ptr....points to first char after the descriptor
- *     errorflag..set to true if the string ended unexpectedly
- */
-#define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag)                   \
-       do { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++;     \
-               if ((utf_ptr) == (end_ptr))                                                                             \
-                       (errorflag) = true;                                                                                     \
-               else                                                                                                                    \
-                       if (*(utf_ptr)++=='L') {                                                                        \
-                               while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';')    \
-                                       /* skip */;                                                                                     \
-                               if ((utf_ptr)[-1] != ';')                                                               \
-                                       (errorflag) = true; }} while(0)
-
-
-/****************************************************************************/
-/* DEBUG HELPERS                                                            */
-/****************************************************************************/
-
-/*#define DESCRIPTOR_VERBOSE*/
-
-/****************************************************************************/
-/* FUNCTIONS                                                                */
-/****************************************************************************/
-
-/* descriptor_to_basic_type ****************************************************
-
-   Return the basic type to use for a value with this descriptor.
-
-   IN:
-       utf..............descriptor utf string
-
-   OUT:
-       A TYPE_* constant.
-
-   PRECONDITIONS:
-       This function assumes that the descriptor has passed 
-          descriptor_pool_add checks and that it does not start with '('.
-
-*******************************************************************************/
-
-int descriptor_to_basic_type(utf *descriptor)
-{
-       assert(descriptor->blength >= 1);
-       
-       switch (descriptor->text[0]) {
-       case 'Z':
-       case 'B':
-       case 'C':
-       case 'S':
-       case 'I':
-               return TYPE_INT;
-
-       case 'J':
-               return TYPE_LNG;
-
-       case 'F':
-               return TYPE_FLT;
-
-       case 'D':
-               return TYPE_DBL;
-
-       case 'L':
-       case '[':
-               return TYPE_ADR;
-
-       default:
-               vm_abort("descriptor_to_basic_type: invalid type %c",
-                                descriptor->text[0]);
-       }
-
-       /* keep the compiler happy */
-
-       return 0;
-}
-
-
-/* descriptor_typesize *********************************************************
-
-   Return the size in bytes needed for the given type.
-
-   IN:
-       td..............typedesc describing the type
-
-   OUT:
-       The number of bytes
-
-*******************************************************************************/
-
-int descriptor_typesize(typedesc *td)
-{
-       assert(td);
-
-       switch (td->type) {
-       case TYPE_INT:
-       case TYPE_FLT:
-               return 4;
-
-       case TYPE_LNG:
-       case TYPE_DBL:
-               return 8;
-
-       case TYPE_ADR:
-               return SIZEOF_VOID_P;
-
-       default:
-               vm_abort("descriptor_typesize: invalid type %d", td->type);
-       }
-
-       /* keep the compiler happy */
-
-       return 0;
-}
-
-
-/* name_from_descriptor ********************************************************
-
-   Return the class name indicated by the given descriptor
-   (Internally used helper function)
-
-   IN:
-       c................class containing the descriptor
-       utf_ptr..........first character of descriptor
-       end_ptr..........first character after the end of the string
-       mode.............a combination (binary or) of the following flags:
-
-               (Flags marked with * are the default settings.)
-
-               How to handle "V" descriptors:
-
-                            * DESCRIPTOR_VOID.....handle it like other primitive types
-                   DESCRIPTOR_NOVOID...treat it as an error
-
-               How to deal with extra characters after the end of the
-               descriptor:
-
-                            * DESCRIPTOR_NOCHECKEND...ignore (useful for parameter lists)
-                   DESCRIPTOR_CHECKEND.....treat them as an error
-
-   OUT:
-       *next............if non-NULL, *next is set to the first character after
-                        the descriptor. (Undefined if an error occurs.)
-       *name............set to the utf name of the class
-
-   RETURN VALUE:
-       true.............descriptor parsed successfully
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-#define DESCRIPTOR_VOID          0      /* default */
-#define DESCRIPTOR_NOVOID        0x0040
-#define DESCRIPTOR_NOCHECKEND    0      /* default */
-#define DESCRIPTOR_CHECKEND      0x1000
-
-static bool 
-name_from_descriptor(classinfo *c,
-                                        char *utf_ptr, char *end_ptr,
-                                        char **next, int mode, utf **name)
-{
-       char *start = utf_ptr;
-       bool error = false;
-
-       assert(c);
-       assert(utf_ptr);
-       assert(end_ptr);
-       assert(name);
-       
-       *name = NULL;           
-       SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
-
-       if (mode & DESCRIPTOR_CHECKEND)
-               error |= (utf_ptr != end_ptr);
-       
-       if (!error) {
-               if (next) *next = utf_ptr;
-               
-               switch (*start) {
-                 case 'V':
-                         if (mode & DESCRIPTOR_NOVOID)
-                                 break;
-                         /* FALLTHROUGH! */
-                 case 'I':
-                 case 'J':
-                 case 'F':
-                 case 'D':
-                 case 'B':
-                 case 'C':
-                 case 'S':
-                 case 'Z':
-                         return true;
-                         
-                 case 'L':
-                         start++;
-                         utf_ptr--;
-                         /* FALLTHROUGH! */
-                 case '[':
-                         *name = utf_new(start, utf_ptr - start);
-                         return true;
-               }
-       }
-
-       exceptions_throw_classformaterror(c, "Invalid descriptor");
-       return false;
-}
-
-
-/* descriptor_to_typedesc ******************************************************
-   Parse the given type descriptor and fill a typedesc struct
-   (Internally used helper function)
-
-   IN:
-       pool.............the descriptor pool
-          utf_ptr..........points to first character of type descriptor
-          end_pos..........points after last character of the whole descriptor
-
-   OUT:
-       *next............set to next character after type descriptor
-          *d...............filled with parsed information
-
-   RETURN VALUE:
-       true.............parsing succeeded  
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-static bool
-descriptor_to_typedesc(descriptor_pool *pool, char *utf_ptr, char *end_pos,
-                                          char **next, typedesc *td)
-{
-       utf *name;
-       
-       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, next, 0, &name))
-               return false;
-
-       if (name) {
-               /* a reference type */
-               td->type = TYPE_ADR;
-               td->primitivetype = TYPE_ADR;
-               td->arraydim = 0;
-               for (utf_ptr = name->text; *utf_ptr == '['; ++utf_ptr)
-                       td->arraydim++;
-               td->classref = descriptor_pool_lookup_classref(pool, name);
-
-       } else {
-               /* a primitive type */
-               switch (*utf_ptr) {
-               case 'B': 
-                       td->primitivetype = PRIMITIVETYPE_BYTE;
-                       td->type = TYPE_INT;
-                       break;
-               case 'C':
-                       td->primitivetype = PRIMITIVETYPE_CHAR;
-                       td->type = TYPE_INT;
-                       break;
-               case 'S':  
-                       td->primitivetype = PRIMITIVETYPE_SHORT;
-                       td->type = TYPE_INT;
-                       break;
-               case 'Z':
-                       td->primitivetype = PRIMITIVETYPE_BOOLEAN;
-                       td->type = TYPE_INT;
-                       break;
-               case 'I':
-                       td->primitivetype = PRIMITIVETYPE_INT;
-                       td->type = TYPE_INT;
-                       break;
-               case 'D':
-                       td->primitivetype = PRIMITIVETYPE_DOUBLE;
-                       td->type = TYPE_DBL;
-                       break;
-               case 'F':
-                       td->primitivetype = PRIMITIVETYPE_FLOAT;
-                       td->type = TYPE_FLT;
-                       break;
-               case 'J':
-                       td->primitivetype = PRIMITIVETYPE_LONG;
-                       td->type = TYPE_LNG;
-                       break;
-               case 'V':
-                       td->primitivetype = PRIMITIVETYPE_VOID;
-                       td->type = TYPE_VOID;
-                       break;
-               default:
-                       assert(false);
-               }
-
-               td->arraydim = 0;
-               td->classref = NULL;
-       }
-
-       return true;
-}
-
-
-/* descriptor_pool_new *********************************************************
-   Allocate a new descriptor_pool
-
-   IN:
-       referer..........class for which to create the pool
-
-   RETURN VALUE:
-       a pointer to the new descriptor_pool
-
-*******************************************************************************/
-
-descriptor_pool * 
-descriptor_pool_new(classinfo *referer)
-{
-       descriptor_pool *pool;
-       u4 hashsize;
-       u4 slot;
-
-       pool = DNEW(descriptor_pool);
-       assert(pool);
-
-       pool->referer = referer;
-       pool->fieldcount = 0;
-       pool->methodcount = 0;
-       pool->paramcount = 0;
-       pool->descriptorsize = 0;
-       pool->descriptors = NULL;
-       pool->descriptors_next = NULL;
-       pool->classrefs = NULL;
-       pool->descriptor_kind = NULL;
-       pool->descriptor_kind_next = NULL;
-
-       hashsize = CLASSREFHASH_INIT_SIZE;
-       pool->classrefhash.size = hashsize;
-       pool->classrefhash.entries = 0;
-       pool->classrefhash.ptr = DMNEW(void*, hashsize);
-       for (slot=0; slot<hashsize; ++slot)
-               pool->classrefhash.ptr[slot] = NULL;
-
-       hashsize = DESCRIPTORHASH_INIT_SIZE;
-       pool->descriptorhash.size = hashsize;
-       pool->descriptorhash.entries = 0;
-       pool->descriptorhash.ptr = DMNEW(void*, hashsize);
-       for (slot=0; slot<hashsize; ++slot)
-               pool->descriptorhash.ptr[slot] = NULL;
-
-       return pool;
-}
-
-
-/* descriptor_pool_add_class ***************************************************
-   Add the given class reference to the pool
-
-   IN:
-       pool.............the descriptor_pool
-          name.............the class reference to add
-
-   RETURN VALUE:
-       true.............reference has been added
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-bool 
-descriptor_pool_add_class(descriptor_pool *pool, utf *name)
-{
-       u4 key,slot;
-       classref_hash_entry *c;
-       
-       assert(pool);
-       assert(name);
-
-#ifdef DESCRIPTOR_VERBOSE
-       fprintf(stderr,"descriptor_pool_add_class(%p,",(void*)pool);
-       utf_fprint_printable_ascii(stderr,name);fprintf(stderr,")\n");
-#endif
-
-       /* find a place in the hashtable */
-
-       key = utf_hashkey(name->text, name->blength);
-       slot = key & (pool->classrefhash.size - 1);
-       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-
-       while (c) {
-               if (c->name == name)
-                       return true; /* already stored */
-               c = c->hashlink;
-       }
-
-       /* check if the name is a valid classname */
-
-       if (!is_valid_name(name->text,UTF_END(name))) {
-               exceptions_throw_classformaterror(pool->referer, "Invalid class name");
-               return false; /* exception */
-       }
-
-       /* XXX check maximum array dimension */
-       
-       c = DNEW(classref_hash_entry);
-       c->name = name;
-       c->index = pool->classrefhash.entries++;
-       c->hashlink = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-       pool->classrefhash.ptr[slot] = c;
-
-       return true;
-}
-
-
-/* descriptor_pool_add *********************************************************
-   Check the given descriptor and add it to the pool
-
-   IN:
-       pool.............the descriptor_pool
-          desc.............the descriptor to add. Maybe a field or method desc.
-
-   OUT:
-       *paramslots......if non-NULL, set to the number of parameters.
-                           LONG and DOUBLE are counted twice
-
-   RETURN VALUE:
-       true.............descriptor has been added
-          false............an exception has been thrown
-
-*******************************************************************************/
-
-bool 
-descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
-{
-       u4 key,slot;
-       descriptor_hash_entry *d;
-       char *utf_ptr;
-       char *end_pos;
-       utf *name;
-       s4 argcount = 0;
-       
-#ifdef DESCRIPTOR_VERBOSE
-       fprintf(stderr,"descriptor_pool_add(%p,",(void*)pool);
-       utf_fprint_printable_ascii(stderr,desc);fprintf(stderr,")\n");
-#endif
-
-       assert(pool);
-       assert(desc);
-
-       /* find a place in the hashtable */
-
-       key = utf_hashkey(desc->text, desc->blength);
-       slot = key & (pool->descriptorhash.size - 1);
-       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-
-       /* Save all method descriptors in the hashtable, since the parsed         */
-       /* descriptor may vary between differenf methods (static vs. non-static). */
-
-       utf_ptr = desc->text;
-
-       if (*utf_ptr != '(') {
-               while (d) {
-                       if (d->desc == desc) {
-                               if (paramslots)
-                                       *paramslots = d->paramslots;
-                               return true; /* already stored */
-                       }
-                       d = d->hashlink;
-               }
-       }
-
-       /* add the descriptor to the pool */
-
-       d = DNEW(descriptor_hash_entry);
-       d->desc = desc;
-       d->parseddesc.any = NULL;
-       d->hashlink = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-       pool->descriptorhash.ptr[slot] = d;
-
-       /* now check the descriptor */
-
-       end_pos = UTF_END(desc);
-       
-       if (*utf_ptr == '(') {
-               /* a method descriptor */
-
-               pool->methodcount++;
-               utf_ptr++;
-
-               /* check arguments */
-
-               while ((utf_ptr != end_pos) && (*utf_ptr != ')')) {
-                       pool->paramcount++;
-
-                       /* We cannot count the `this' argument here because
-                        * we don't know if the method is static. */
-
-                       if (*utf_ptr == 'J' || *utf_ptr == 'D')
-                               argcount += 2;
-                       else
-                               argcount++;
-
-                       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, &utf_ptr,
-                                                                     DESCRIPTOR_NOVOID, &name))
-                               return false;
-
-                       if (name)
-                               if (!descriptor_pool_add_class(pool, name))
-                                       return false;
-               }
-
-               if (utf_ptr == end_pos) {
-                       exceptions_throw_classformaterror(pool->referer,
-                                                                                         "Missing ')' in method descriptor");
-                       return false;
-               }
-
-               utf_ptr++; /* skip ')' */
-
-               if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
-                                                                 DESCRIPTOR_CHECKEND, &name))
-                       return false;
-
-               if (name)
-                       if (!descriptor_pool_add_class(pool,name))
-                               return false;
-
-               if (argcount > 255) {
-                       exceptions_throw_classformaterror(pool->referer,
-                                                                                         "Too many arguments in signature");
-                       return false;
-               }
-
-       } else {
-               /* a field descriptor */
-
-               pool->fieldcount++;
-               
-           if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
-                                                         DESCRIPTOR_NOVOID | DESCRIPTOR_CHECKEND,
-                                                                 &name))
-                       return false;
-
-               if (name)
-                       if (!descriptor_pool_add_class(pool,name))
-                               return false;
-       }
-
-       d->paramslots = argcount;
-
-       if (paramslots)
-               *paramslots = argcount;
-
-       return true;
-}
-
-
-/* descriptor_pool_create_classrefs ********************************************
-   Create a table containing all the classrefs which were added to the pool
-
-   IN:
-       pool.............the descriptor_pool
-
-   OUT:
-       *count...........if count is non-NULL, this is set to the number
-                           of classrefs in the table
-
-   RETURN VALUE:
-       a pointer to the constant_classref table
-
-*******************************************************************************/
-
-constant_classref * 
-descriptor_pool_create_classrefs(descriptor_pool *pool, s4 *count)
-{
-       u4 nclasses;
-       u4 slot;
-       classref_hash_entry *c;
-       constant_classref *ref;
-       
-       assert(pool);
-
-       nclasses = pool->classrefhash.entries;
-       pool->classrefs = MNEW(constant_classref,nclasses);
-
-       /* fill the constant_classref structs */
-
-       for (slot = 0; slot < pool->classrefhash.size; ++slot) {
-               c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-               while (c) {
-                       ref = pool->classrefs + c->index;
-                       CLASSREF_INIT(*ref, pool->referer, c->name);
-                       c = c->hashlink;
-               }
-       }
-
-       if (count)
-               *count = nclasses;
-
-       return pool->classrefs;
-}
-
-
-/* descriptor_pool_lookup_classref *********************************************
-   Return the constant_classref for the given class name
-
-   IN:
-       pool.............the descriptor_pool
-          classname........name of the class to look up
-
-   RETURN VALUE:
-       a pointer to the constant_classref, or
-          NULL if an exception has been thrown
-
-*******************************************************************************/
-
-constant_classref * 
-descriptor_pool_lookup_classref(descriptor_pool *pool, utf *classname)
-{
-       u4 key,slot;
-       classref_hash_entry *c;
-
-       assert(pool);
-       assert(pool->classrefs);
-       assert(classname);
-
-       key = utf_hashkey(classname->text, classname->blength);
-       slot = key & (pool->classrefhash.size - 1);
-       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-
-       while (c) {
-               if (c->name == classname)
-                       return pool->classrefs + c->index;
-               c = c->hashlink;
-       }
-
-       exceptions_throw_internalerror("Class reference not found in descriptor pool");
-       return NULL;
-}
-
-
-/* descriptor_pool_alloc_parsed_descriptors ************************************
-   Allocate space for the parsed descriptors
-
-   IN:
-       pool.............the descriptor_pool
-
-   NOTE:
-       This function must be called after all descriptors have been added
-          with descriptor_pool_add.
-
-*******************************************************************************/
-
-void 
-descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool)
-{
-       u4 size;
-       
-       assert(pool);
-
-       /* TWISTI: paramcount + 1: we don't know if the method is static or   */
-       /* not, i have no better solution yet.                                */
-
-       size =
-               pool->fieldcount * sizeof(typedesc) +
-               pool->methodcount * (sizeof(methoddesc) - sizeof(typedesc)) +
-               pool->paramcount * sizeof(typedesc) +
-               pool->methodcount * sizeof(typedesc);      /* possible `this' pointer */
-
-       pool->descriptorsize = size;
-       if (size) {
-               pool->descriptors = MNEW(u1, size);
-               pool->descriptors_next = pool->descriptors;
-       }
-
-       size = pool->fieldcount + pool->methodcount;
-       if (size) {
-               pool->descriptor_kind = DMNEW(u1, size);
-               pool->descriptor_kind_next = pool->descriptor_kind;
-       }
-}
-
-
-/* descriptor_pool_parse_field_descriptor **************************************
-   Parse the given field descriptor
-
-   IN:
-       pool.............the descriptor_pool
-          desc.............the field descriptor
-
-   RETURN VALUE:
-       a pointer to the parsed field descriptor, or
-          NULL if an exception has been thrown
-
-   NOTE:
-       descriptor_pool_alloc_parsed_descriptors must be called (once)
-       before this function is used.
-
-*******************************************************************************/
-
-typedesc * 
-descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc)
-{
-       u4 key,slot;
-       descriptor_hash_entry *d;
-       typedesc *td;
-
-       assert(pool);
-       assert(pool->descriptors);
-       assert(pool->descriptors_next);
-
-       /* lookup the descriptor in the hashtable */
-
-       key = utf_hashkey(desc->text, desc->blength);
-       slot = key & (pool->descriptorhash.size - 1);
-       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-
-       while (d) {
-               if (d->desc == desc) {
-                       /* found */
-                       if (d->parseddesc.fd)
-                               return d->parseddesc.fd;
-                       break;
-               }
-               d = d->hashlink;
-       }
-
-       assert(d);
-       
-       if (desc->text[0] == '(') {
-               exceptions_throw_classformaterror(pool->referer,
-                                                                                 "Method descriptor used in field reference");
-               return NULL;
-       }
-
-       td = (typedesc *) pool->descriptors_next;
-       pool->descriptors_next += sizeof(typedesc);
-       
-       if (!descriptor_to_typedesc(pool, desc->text, UTF_END(desc), NULL, td))
-               return NULL;
-
-       *(pool->descriptor_kind_next++) = 'f';
-
-       d->parseddesc.fd = td;
-
-       return td;
-}
-
-
-/* descriptor_pool_parse_method_descriptor *************************************
-   Parse the given method descriptor
-
-   IN:
-       pool.............the descriptor_pool
-       desc.............the method descriptor
-       mflags...........the method flags
-          thisclass........classref to the class containing the method.
-                                               This is ignored if mflags contains ACC_STATIC.
-                                               The classref is stored for inserting the 'this' argument.
-
-   RETURN VALUE:
-       a pointer to the parsed method descriptor, or
-          NULL if an exception has been thrown
-
-   NOTE: 
-       descriptor_pool_alloc_parsed_descriptors must be called
-       (once) before this function is used.
-
-*******************************************************************************/
-
-methoddesc * 
-descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
-                                                                               s4 mflags,constant_classref *thisclass)
-{
-       u4 key, slot;
-       descriptor_hash_entry *d;
-       methoddesc            *md;
-       typedesc              *td;
-       char *utf_ptr;
-       char *end_pos;
-       s2 paramcount = 0;
-       s2 paramslots = 0;
-
-#ifdef DESCRIPTOR_VERBOSE
-       fprintf(stderr,"descriptor_pool_parse_method_descriptor(%p,%d,%p,",
-                       (void*)pool,(int)mflags,(void*)thisclass);
-       utf_fprint_printable_ascii(stderr,desc); fprintf(stderr,")\n");
-#endif
-
-       assert(pool);
-       assert(pool->descriptors);
-       assert(pool->descriptors_next);
-
-       /* check that it is a method descriptor */
-       
-       if (desc->text[0] != '(') {
-               exceptions_throw_classformaterror(pool->referer,
-                                                                                 "Field descriptor used in method reference");
-               return NULL;
-       }
-
-       /* lookup the descriptor in the hashtable */
-
-       key = utf_hashkey(desc->text, desc->blength);
-       slot = key & (pool->descriptorhash.size - 1);
-       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-
-       /* find an un-parsed descriptor */
-
-       while (d) {
-               if (d->desc == desc)
-                       if (!d->parseddesc.md)
-                               break;
-               d = d->hashlink;
-       }
-
-       assert(d);
-
-       md = (methoddesc *) pool->descriptors_next;
-       pool->descriptors_next += sizeof(methoddesc) - sizeof(typedesc);
-
-       utf_ptr = desc->text + 1; /* skip '(' */
-       end_pos = UTF_END(desc);
-
-       td = md->paramtypes;
-
-       /* count the `this' pointer */
-
-       if ((mflags != ACC_UNDEF) && !(mflags & ACC_STATIC)) {
-               td->type = TYPE_ADR;
-               td->primitivetype = TYPE_ADR;
-               td->arraydim = 0;
-               td->classref = thisclass;
-
-               td++;
-               pool->descriptors_next += sizeof(typedesc);
-               paramcount++;
-               paramslots++;
-       }
-
-       while (*utf_ptr != ')') {
-               /* parse a parameter type */
-
-               if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, &utf_ptr, td))
-                       return NULL;
-
-               if (IS_2_WORD_TYPE(td->type))
-                       paramslots++;
-               
-               td++;
-               pool->descriptors_next += sizeof(typedesc);
-               paramcount++;
-               paramslots++;
-       }
-       utf_ptr++; /* skip ')' */
-
-       /* Skip possible `this' pointer in paramtypes array to allow a possible   */
-       /* memory move later in parse.                                            */
-       /* We store the thisclass reference, so we can later correctly fill in    */
-       /* the parameter slot of the 'this' argument.                             */
-
-       if (mflags == ACC_UNDEF) {
-               td->classref = thisclass;
-               td++;
-               pool->descriptors_next += sizeof(typedesc);
-       }
-
-       /* parse return type */
-
-       if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, NULL,
-                                                               &(md->returntype)))
-               return NULL;
-
-       md->paramcount = paramcount;
-       md->paramslots = paramslots;
-
-       /* If mflags != ACC_UNDEF we parse a real loaded method, so do
-          param prealloc.  Otherwise we do this in stack analysis. */
-
-       if (mflags != ACC_UNDEF) {
-               if (md->paramcount > 0) {
-                       /* allocate memory for params */
-
-                       md->params = MNEW(paramdesc, md->paramcount);
-               }
-               else {
-                       md->params = METHODDESC_NOPARAMS;
-               }
-
-               /* fill the paramdesc */
-               /* md_param_alloc has to be called if md->paramcount == 0,
-                  too, so it can make the reservation for the Linkage Area,
-                  Return Register... */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-               if (!opt_intrp)
-# endif
-                       {
-                               /* As builtin-functions are native functions, we have
-                                  to pre-allocate for the native ABI. */
-
-                               if (mflags & ACC_METHOD_BUILTIN)
-                                       md_param_alloc_native(md);
-                               else
-                                       md_param_alloc(md);
-                       }
-#endif
-       }
-       else {
-               /* params will be allocated later by
-                  descriptor_params_from_paramtypes if necessary */
-
-               md->params = NULL;
-       }
-
-       *(pool->descriptor_kind_next++) = 'm';
-
-       d->parseddesc.md = md;
-
-       return md;
-}
-
-/* descriptor_params_from_paramtypes *******************************************
-   Create the paramdescs for a method descriptor. This function is called
-   when we know whether the method is static or not. This function may only
-   be called once for each methoddesc, and only if md->params == NULL.
-
-   IN:
-       md...............the parsed method descriptor
-                           md->params MUST be NULL.
-          mflags...........the ACC_* access flags of the method. Only the
-                           ACC_STATIC bit is checked.
-                                               The value ACC_UNDEF is NOT allowed.
-
-   RETURN VALUE:
-       true.............the paramdescs were created successfully
-          false............an exception has been thrown
-
-   POSTCONDITION:
-       md->parms != NULL
-
-*******************************************************************************/
-
-bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
-{
-       typedesc *td;
-
-       assert(md);
-       assert(md->params == NULL);
-       assert(mflags != ACC_UNDEF);
-
-       td = md->paramtypes;
-
-       /* check for `this' pointer */
-
-       if (!(mflags & ACC_STATIC)) {
-               constant_classref *thisclass;
-
-               /* fetch class reference from reserved param slot */
-               thisclass = td[md->paramcount].classref;
-               assert(thisclass);
-
-               if (md->paramcount > 0) {
-                       /* shift param types by 1 argument */
-                       MMOVE(td + 1, td, typedesc, md->paramcount);
-               }
-
-               /* fill in first argument `this' */
-
-               td->type = TYPE_ADR;
-               td->primitivetype = TYPE_ADR;
-               td->arraydim = 0;
-               td->classref = thisclass;
-
-               md->paramcount++;
-               md->paramslots++;
-       }
-
-       /* if the method has params, process them */
-
-       if (md->paramcount > 0) {
-               /* allocate memory for params */
-
-               md->params = MNEW(paramdesc, md->paramcount);
-
-       } else {
-               md->params = METHODDESC_NOPARAMS;
-       }
-
-       /* fill the paramdesc */
-       /* md_param_alloc has to be called if md->paramcount == 0, too, so
-          it can make the reservation for the Linkage Area, Return
-          Register.. */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-       if (!opt_intrp)
-# endif
-               {
-                       /* As builtin-functions are native functions, we have to
-                          pre-allocate for the native ABI. */
-
-                       if (mflags & ACC_METHOD_BUILTIN)
-                               md_param_alloc_native(md);
-                       else
-                               md_param_alloc(md);
-               }
-#endif
-
-       return true;
-}
-
-
-/* descriptor_pool_get_parsed_descriptors **************************************
-   Return a pointer to the block of parsed descriptors
-
-   IN:
-       pool.............the descriptor_pool
-
-   OUT:
-          *size............if size is non-NULL, this is set to the size of the
-                           parsed descriptor block (in u1)
-
-   RETURN VALUE:
-       a pointer to the block of parsed descriptors
-
-   NOTE:
-       descriptor_pool_alloc_parsed_descriptors must be called (once)
-       before this function is used.
-
-*******************************************************************************/
-
-void * 
-descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size)
-{
-       assert(pool);
-       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
-       
-       if (size)
-               *size = pool->descriptorsize;
-
-       return pool->descriptors;
-}
-
-
-/* descriptor_pool_get_sizes ***************************************************
-   Get the sizes of the class reference table and the parsed descriptors
-
-   IN:
-       pool.............the descriptor_pool
-
-   OUT:
-       *classrefsize....set to size of the class reference table
-          *descsize........set to size of the parsed descriptors
-
-   NOTE:
-       This function may only be called after both
-              descriptor_pool_create_classrefs, and
-                  descriptor_pool_alloc_parsed_descriptors
-          have been called.
-
-*******************************************************************************/
-
-void 
-descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize, u4 *descsize)
-{
-       assert(pool);
-       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
-       assert(pool->classrefs);
-       assert(classrefsize);
-       assert(descsize);
-
-       *classrefsize = pool->classrefhash.entries * sizeof(constant_classref);
-       *descsize = pool->descriptorsize;
-}
-
-
-/****************************************************************************/
-/* DEBUG HELPERS                                                            */
-/****************************************************************************/
-
-#ifndef NDEBUG
-/* descriptor_debug_print_typedesc *********************************************
-   Print the given typedesc to the given stream
-
-   IN:
-          file.............stream to print to
-          d................the parsed descriptor
-
-*******************************************************************************/
-
-void 
-descriptor_debug_print_typedesc(FILE *file,typedesc *d)
-{
-       int ch;
-
-       if (!d) {
-               fprintf(file,"(typedesc *)NULL");
-               return;
-       }
-       
-       if (d->type == TYPE_ADR) {
-               if (d->classref)
-                       utf_fprint_printable_ascii(file,d->classref->name);
-               else
-                       fprintf(file,"<class=NULL>");
-       }
-       else {
-               switch (d->primitivetype) {
-                       case PRIMITIVETYPE_INT    : ch='I'; break;
-                       case PRIMITIVETYPE_CHAR   : ch='C'; break;
-                       case PRIMITIVETYPE_BYTE   : ch='B'; break;
-                       case PRIMITIVETYPE_SHORT  : ch='S'; break;
-                       case PRIMITIVETYPE_BOOLEAN: ch='Z'; break;
-                       case PRIMITIVETYPE_LONG   : ch='J'; break;
-                       case PRIMITIVETYPE_FLOAT  : ch='F'; break;
-                       case PRIMITIVETYPE_DOUBLE : ch='D'; break;
-                       case PRIMITIVETYPE_VOID   : ch='V'; break;
-                       default                   : ch='!';
-               }
-               fputc(ch,file);
-       }
-       if (d->arraydim)
-               fprintf(file,"[%d]",d->arraydim);
-}
-
-/* descriptor_debug_print_paramdesc ********************************************
-   Print the given paramdesc to the given stream
-
-   IN:
-          file.............stream to print to
-          d................the parameter descriptor
-
-*******************************************************************************/
-
-void
-descriptor_debug_print_paramdesc(FILE *file,paramdesc *d)
-{
-       if (!d) {
-               fprintf(file,"(paramdesc *)NULL");
-               return;
-       }
-       
-       if (d->inmemory) {
-               fprintf(file,"<m%d>",d->regoff);
-       }
-       else {
-               fprintf(file,"<r%d>",d->regoff);
-       }
-}
-
-/* descriptor_debug_print_methoddesc *******************************************
-   Print the given methoddesc to the given stream
-
-   IN:
-          file.............stream to print to
-          d................the parsed descriptor
-
-*******************************************************************************/
-
-void 
-descriptor_debug_print_methoddesc(FILE *file,methoddesc *d)
-{
-       int i;
-       
-       if (!d) {
-               fprintf(file,"(methoddesc *)NULL");
-               return;
-       }
-       
-       fputc('(',file);
-       for (i=0; i<d->paramcount; ++i) {
-               if (i)
-                       fputc(',',file);
-               descriptor_debug_print_typedesc(file,d->paramtypes + i);
-               if (d->params) {
-                       descriptor_debug_print_paramdesc(file,d->params + i);
-               }
-       }
-       if (d->params == METHODDESC_NOPARAMS)
-               fputs("<NOPARAMS>",file);
-       fputc(')',file);
-       descriptor_debug_print_typedesc(file,&(d->returntype));
-}
-
-/* descriptor_pool_debug_dump **************************************************
-   Print the state of the descriptor_pool to the given stream
-
-   IN:
-       pool.............the descriptor_pool
-          file.............stream to print to
-
-*******************************************************************************/
-
-void 
-descriptor_pool_debug_dump(descriptor_pool *pool,FILE *file)
-{
-       u4 slot;
-       u1 *pos;
-       u1 *kind;
-       u4 size;
-       
-       fprintf(file,"======[descriptor_pool for ");
-       utf_fprint_printable_ascii(file,pool->referer->name);
-       fprintf(file,"]======\n");
-
-       fprintf(file,"fieldcount:     %d\n",pool->fieldcount);
-       fprintf(file,"methodcount:    %d\n",pool->methodcount);
-       fprintf(file,"paramcount:     %d\n",pool->paramcount);
-       fprintf(file,"classrefcount:  %d\n",pool->classrefhash.entries);
-       fprintf(file,"descriptorsize: %d bytes\n",pool->descriptorsize);
-       fprintf(file,"classrefsize:   %d bytes\n",
-                       (int)(pool->classrefhash.entries * sizeof(constant_classref)));
-
-       fprintf(file,"class references:\n");
-       for (slot=0; slot<pool->classrefhash.size; ++slot) {
-               classref_hash_entry *c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
-               while (c) {
-                       fprintf(file,"    %4d: ",c->index);
-                       utf_fprint_printable_ascii(file,c->name);
-                       fprintf(file,"\n");
-                       c = c->hashlink;
-               }
-       }
-
-       fprintf(file,"hashed descriptors:\n");
-       for (slot=0; slot<pool->descriptorhash.size; ++slot) {
-               descriptor_hash_entry *c = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
-               while (c) {
-                       fprintf(file,"    %p: ",c->parseddesc.any);
-                       utf_fprint_printable_ascii(file,c->desc);
-                       fprintf(file,"\n");
-                       c = c->hashlink;
-               }
-       }
-
-       fprintf(file,"descriptors:\n");
-       if (pool->descriptors) {
-               pos = pool->descriptors;
-               size = pool->descriptors_next - pool->descriptors;
-               fprintf(file,"    size: %d bytes\n",size);
-               
-               if (pool->descriptor_kind) {
-                       kind = pool->descriptor_kind;
-
-                       while (pos < (pool->descriptors + size)) {
-                               fprintf(file,"    %p: ",pos);
-                               switch (*kind++) {
-                                       case 'f':
-                                               descriptor_debug_print_typedesc(file,(typedesc*)pos);
-                                               pos += sizeof(typedesc);
-                                               break;
-                                       case 'm':
-                                               descriptor_debug_print_methoddesc(file,(methoddesc*)pos);
-                                               pos += ((methoddesc*)pos)->paramcount * sizeof(typedesc);
-                                               pos += sizeof(methoddesc) - sizeof(typedesc);
-                                               break;
-                                       default:
-                                               fprintf(file,"INVALID KIND");
-                               }
-                               fputc('\n',file);
-                       }
-               }
-               else {
-                       while (size >= sizeof(void*)) {
-                               fprintf(file,"    %p\n",*((void**)pos));
-                               pos += sizeof(void*);
-                               size -= sizeof(void*);
-                       }
-               }
-       }
-
-       fprintf(file,"==========================================================\n");
-}
-#endif /* !defined(NDEBUG) */
-
-/*
- * 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/descriptor.cpp b/src/vm/descriptor.cpp
new file mode 100644 (file)
index 0000000..d8e0e34
--- /dev/null
@@ -0,0 +1,1406 @@
+/* src/vm/descriptor.c - checking and parsing of field / method descriptors
+
+   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 "vm/types.h"
+
+#include "md-abi.h"
+
+#include "mm/memory.hpp"
+
+#include "vm/descriptor.hpp"
+#include "vm/exceptions.hpp"
+#include "vm/options.h"
+#include "vm/primitive.hpp"
+#include "vm/vm.hpp"
+
+#include "vm/jit/abi.h"
+
+
+/* constants (private to descriptor.c) ****************************************/
+
+/* initial number of entries for the classrefhash of a descriptor_pool */
+/* (currently the hash is never grown!) */
+#define CLASSREFHASH_INIT_SIZE  64
+
+/* initial number of entries for the descriptorhash of a descriptor_pool */
+/* (currently the hash is never grown!) */
+#define DESCRIPTORHASH_INIT_SIZE  128
+
+/* data structures (private to descriptor.c) **********************************/
+
+typedef struct classref_hash_entry classref_hash_entry;
+typedef struct descriptor_hash_entry descriptor_hash_entry;
+
+/* entry struct for the classrefhash of descriptor_pool */
+struct classref_hash_entry {
+       classref_hash_entry *hashlink;  /* for hash chaining            */
+       utf                 *name;      /* name of the class refered to */
+       u2                   index;     /* index into classref table    */
+};
+
+/* entry struct for the descriptorhash of descriptor_pool */
+struct descriptor_hash_entry {
+       descriptor_hash_entry *hashlink;
+       utf                   *desc;
+       parseddesc_t           parseddesc;
+       s2                     paramslots; /* number of params, LONG/DOUBLE counted as 2 */
+};
+
+
+/****************************************************************************/
+/* MACROS FOR DESCRIPTOR PARSING (private to descriptor.c)                  */
+/****************************************************************************/
+
+/* SKIP_FIELDDESCRIPTOR:
+ * utf_ptr must point to the first character of a field descriptor.
+ * After the macro call utf_ptr points to the first character after
+ * the field descriptor.
+ *
+ * CAUTION: This macro does not check for an unexpected end of the
+ * descriptor. Better use SKIP_FIELDDESCRIPTOR_SAFE.
+ */
+#define SKIP_FIELDDESCRIPTOR(utf_ptr)                                                  \
+       do { while (*(utf_ptr)=='[') (utf_ptr)++;                                       \
+               if (*(utf_ptr)++=='L')                                                                  \
+                       while(*(utf_ptr)++ != ';') /* skip */; } while(0)
+
+/* SKIP_FIELDDESCRIPTOR_SAFE:
+ * utf_ptr must point to the first character of a field descriptor.
+ * After the macro call utf_ptr points to the first character after
+ * the field descriptor.
+ *
+ * Input:
+ *     utf_ptr....points to first char of descriptor
+ *     end_ptr....points to first char after the end of the string
+ *     errorflag..must be initialized (to false) by the caller!
+ * Output:
+ *     utf_ptr....points to first char after the descriptor
+ *     errorflag..set to true if the string ended unexpectedly
+ */
+#define SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr,end_ptr,errorflag)                   \
+       do { while ((utf_ptr) != (end_ptr) && *(utf_ptr)=='[') (utf_ptr)++;     \
+               if ((utf_ptr) == (end_ptr))                                                                             \
+                       (errorflag) = true;                                                                                     \
+               else                                                                                                                    \
+                       if (*(utf_ptr)++=='L') {                                                                        \
+                               while((utf_ptr) != (end_ptr) && *(utf_ptr)++ != ';')    \
+                                       /* skip */;                                                                                     \
+                               if ((utf_ptr)[-1] != ';')                                                               \
+                                       (errorflag) = true; }} while(0)
+
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/****************************************************************************/
+/* DEBUG HELPERS                                                            */
+/****************************************************************************/
+
+/*#define DESCRIPTOR_VERBOSE*/
+
+/****************************************************************************/
+/* FUNCTIONS                                                                */
+/****************************************************************************/
+
+/* descriptor_to_basic_type ****************************************************
+
+   Return the basic type to use for a value with this descriptor.
+
+   IN:
+       utf..............descriptor utf string
+
+   OUT:
+       A TYPE_* constant.
+
+   PRECONDITIONS:
+       This function assumes that the descriptor has passed 
+          descriptor_pool_add checks and that it does not start with '('.
+
+*******************************************************************************/
+
+int descriptor_to_basic_type(utf *descriptor)
+{
+       assert(descriptor->blength >= 1);
+       
+       switch (descriptor->text[0]) {
+       case 'Z':
+       case 'B':
+       case 'C':
+       case 'S':
+       case 'I':
+               return TYPE_INT;
+
+       case 'J':
+               return TYPE_LNG;
+
+       case 'F':
+               return TYPE_FLT;
+
+       case 'D':
+               return TYPE_DBL;
+
+       case 'L':
+       case '[':
+               return TYPE_ADR;
+
+       default:
+               vm_abort("descriptor_to_basic_type: invalid type %c",
+                                descriptor->text[0]);
+       }
+
+       /* keep the compiler happy */
+
+       return 0;
+}
+
+
+/* descriptor_typesize *********************************************************
+
+   Return the size in bytes needed for the given type.
+
+   IN:
+       td..............typedesc describing the type
+
+   OUT:
+       The number of bytes
+
+*******************************************************************************/
+
+int descriptor_typesize(typedesc *td)
+{
+       assert(td);
+
+       switch (td->type) {
+       case TYPE_INT:
+       case TYPE_FLT:
+               return 4;
+
+       case TYPE_LNG:
+       case TYPE_DBL:
+               return 8;
+
+       case TYPE_ADR:
+               return SIZEOF_VOID_P;
+
+       default:
+               vm_abort("descriptor_typesize: invalid type %d", td->type);
+       }
+
+       /* keep the compiler happy */
+
+       return 0;
+}
+
+
+/* name_from_descriptor ********************************************************
+
+   Return the class name indicated by the given descriptor
+   (Internally used helper function)
+
+   IN:
+       c................class containing the descriptor
+       utf_ptr..........first character of descriptor
+       end_ptr..........first character after the end of the string
+       mode.............a combination (binary or) of the following flags:
+
+               (Flags marked with * are the default settings.)
+
+               How to handle "V" descriptors:
+
+                            * DESCRIPTOR_VOID.....handle it like other primitive types
+                   DESCRIPTOR_NOVOID...treat it as an error
+
+               How to deal with extra characters after the end of the
+               descriptor:
+
+                            * DESCRIPTOR_NOCHECKEND...ignore (useful for parameter lists)
+                   DESCRIPTOR_CHECKEND.....treat them as an error
+
+   OUT:
+       *next............if non-NULL, *next is set to the first character after
+                        the descriptor. (Undefined if an error occurs.)
+       *name............set to the utf name of the class
+
+   RETURN VALUE:
+       true.............descriptor parsed successfully
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+#define DESCRIPTOR_VOID          0      /* default */
+#define DESCRIPTOR_NOVOID        0x0040
+#define DESCRIPTOR_NOCHECKEND    0      /* default */
+#define DESCRIPTOR_CHECKEND      0x1000
+
+static bool 
+name_from_descriptor(classinfo *c,
+                                        char *utf_ptr, char *end_ptr,
+                                        char **next, int mode, utf **name)
+{
+       char *start = utf_ptr;
+       bool error = false;
+
+       assert(c);
+       assert(utf_ptr);
+       assert(end_ptr);
+       assert(name);
+       
+       *name = NULL;           
+       SKIP_FIELDDESCRIPTOR_SAFE(utf_ptr, end_ptr, error);
+
+       if (mode & DESCRIPTOR_CHECKEND)
+               error |= (utf_ptr != end_ptr);
+       
+       if (!error) {
+               if (next) *next = utf_ptr;
+               
+               switch (*start) {
+                 case 'V':
+                         if (mode & DESCRIPTOR_NOVOID)
+                                 break;
+                         /* FALLTHROUGH! */
+                 case 'I':
+                 case 'J':
+                 case 'F':
+                 case 'D':
+                 case 'B':
+                 case 'C':
+                 case 'S':
+                 case 'Z':
+                         return true;
+                         
+                 case 'L':
+                         start++;
+                         utf_ptr--;
+                         /* FALLTHROUGH! */
+                 case '[':
+                         *name = utf_new(start, utf_ptr - start);
+                         return true;
+               }
+       }
+
+       exceptions_throw_classformaterror(c, "Invalid descriptor");
+       return false;
+}
+
+
+/* descriptor_to_typedesc ******************************************************
+   Parse the given type descriptor and fill a typedesc struct
+   (Internally used helper function)
+
+   IN:
+       pool.............the descriptor pool
+          utf_ptr..........points to first character of type descriptor
+          end_pos..........points after last character of the whole descriptor
+
+   OUT:
+       *next............set to next character after type descriptor
+          *d...............filled with parsed information
+
+   RETURN VALUE:
+       true.............parsing succeeded  
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+static bool
+descriptor_to_typedesc(descriptor_pool *pool, char *utf_ptr, char *end_pos,
+                                          char **next, typedesc *td)
+{
+       utf *name;
+       
+       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, next, 0, &name))
+               return false;
+
+       if (name) {
+               /* a reference type */
+               td->type = TYPE_ADR;
+               td->primitivetype = TYPE_ADR;
+               td->arraydim = 0;
+               for (utf_ptr = name->text; *utf_ptr == '['; ++utf_ptr)
+                       td->arraydim++;
+               td->classref = descriptor_pool_lookup_classref(pool, name);
+
+       } else {
+               /* a primitive type */
+               switch (*utf_ptr) {
+               case 'B': 
+                       td->primitivetype = PRIMITIVETYPE_BYTE;
+                       td->type = TYPE_INT;
+                       break;
+               case 'C':
+                       td->primitivetype = PRIMITIVETYPE_CHAR;
+                       td->type = TYPE_INT;
+                       break;
+               case 'S':  
+                       td->primitivetype = PRIMITIVETYPE_SHORT;
+                       td->type = TYPE_INT;
+                       break;
+               case 'Z':
+                       td->primitivetype = PRIMITIVETYPE_BOOLEAN;
+                       td->type = TYPE_INT;
+                       break;
+               case 'I':
+                       td->primitivetype = PRIMITIVETYPE_INT;
+                       td->type = TYPE_INT;
+                       break;
+               case 'D':
+                       td->primitivetype = PRIMITIVETYPE_DOUBLE;
+                       td->type = TYPE_DBL;
+                       break;
+               case 'F':
+                       td->primitivetype = PRIMITIVETYPE_FLOAT;
+                       td->type = TYPE_FLT;
+                       break;
+               case 'J':
+                       td->primitivetype = PRIMITIVETYPE_LONG;
+                       td->type = TYPE_LNG;
+                       break;
+               case 'V':
+                       td->primitivetype = PRIMITIVETYPE_VOID;
+                       td->type = TYPE_VOID;
+                       break;
+               default:
+                       assert(false);
+               }
+
+               td->arraydim = 0;
+               td->classref = NULL;
+       }
+
+       return true;
+}
+
+
+/* descriptor_pool_new *********************************************************
+   Allocate a new descriptor_pool
+
+   IN:
+       referer..........class for which to create the pool
+
+   RETURN VALUE:
+       a pointer to the new descriptor_pool
+
+*******************************************************************************/
+
+descriptor_pool * 
+descriptor_pool_new(classinfo *referer)
+{
+       descriptor_pool *pool;
+       u4 hashsize;
+       u4 slot;
+
+       pool = (descriptor_pool*) DumpMemory::allocate(sizeof(descriptor_pool));
+       assert(pool);
+
+       pool->referer = referer;
+       pool->fieldcount = 0;
+       pool->methodcount = 0;
+       pool->paramcount = 0;
+       pool->descriptorsize = 0;
+       pool->descriptors = NULL;
+       pool->descriptors_next = NULL;
+       pool->classrefs = NULL;
+       pool->descriptor_kind = NULL;
+       pool->descriptor_kind_next = NULL;
+
+       hashsize = CLASSREFHASH_INIT_SIZE;
+       pool->classrefhash.size = hashsize;
+       pool->classrefhash.entries = 0;
+       pool->classrefhash.ptr = (void **) DumpMemory::allocate(sizeof(void*) * hashsize);
+       for (slot=0; slot<hashsize; ++slot)
+               pool->classrefhash.ptr[slot] = NULL;
+
+       hashsize = DESCRIPTORHASH_INIT_SIZE;
+       pool->descriptorhash.size = hashsize;
+       pool->descriptorhash.entries = 0;
+       pool->descriptorhash.ptr = (void**) DumpMemory::allocate(sizeof(void*) * hashsize);
+       for (slot=0; slot<hashsize; ++slot)
+               pool->descriptorhash.ptr[slot] = NULL;
+
+       return pool;
+}
+
+
+/* descriptor_pool_add_class ***************************************************
+   Add the given class reference to the pool
+
+   IN:
+       pool.............the descriptor_pool
+          name.............the class reference to add
+
+   RETURN VALUE:
+       true.............reference has been added
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+bool 
+descriptor_pool_add_class(descriptor_pool *pool, utf *name)
+{
+       u4 key,slot;
+       classref_hash_entry *c;
+       
+       assert(pool);
+       assert(name);
+
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_add_class(%p,",(void*)pool);
+       utf_fprint_printable_ascii(stderr,name);fprintf(stderr,")\n");
+#endif
+
+       /* find a place in the hashtable */
+
+       key = utf_hashkey(name->text, name->blength);
+       slot = key & (pool->classrefhash.size - 1);
+       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+
+       while (c) {
+               if (c->name == name)
+                       return true; /* already stored */
+               c = c->hashlink;
+       }
+
+       /* check if the name is a valid classname */
+
+       if (!is_valid_name(name->text,UTF_END(name))) {
+               exceptions_throw_classformaterror(pool->referer, "Invalid class name");
+               return false; /* exception */
+       }
+
+       /* XXX check maximum array dimension */
+       
+       c = (classref_hash_entry*) DumpMemory::allocate(sizeof(classref_hash_entry));
+       c->name = name;
+       c->index = pool->classrefhash.entries++;
+       c->hashlink = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+       pool->classrefhash.ptr[slot] = c;
+
+       return true;
+}
+
+
+/* descriptor_pool_add *********************************************************
+   Check the given descriptor and add it to the pool
+
+   IN:
+       pool.............the descriptor_pool
+          desc.............the descriptor to add. Maybe a field or method desc.
+
+   OUT:
+       *paramslots......if non-NULL, set to the number of parameters.
+                           LONG and DOUBLE are counted twice
+
+   RETURN VALUE:
+       true.............descriptor has been added
+          false............an exception has been thrown
+
+*******************************************************************************/
+
+bool 
+descriptor_pool_add(descriptor_pool *pool, utf *desc, int *paramslots)
+{
+       u4 key,slot;
+       descriptor_hash_entry *d;
+       char *utf_ptr;
+       char *end_pos;
+       utf *name;
+       s4 argcount = 0;
+       
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_add(%p,",(void*)pool);
+       utf_fprint_printable_ascii(stderr,desc);fprintf(stderr,")\n");
+#endif
+
+       assert(pool);
+       assert(desc);
+
+       /* find a place in the hashtable */
+
+       key = utf_hashkey(desc->text, desc->blength);
+       slot = key & (pool->descriptorhash.size - 1);
+       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+
+       /* Save all method descriptors in the hashtable, since the parsed         */
+       /* descriptor may vary between differenf methods (static vs. non-static). */
+
+       utf_ptr = desc->text;
+
+       if (*utf_ptr != '(') {
+               while (d) {
+                       if (d->desc == desc) {
+                               if (paramslots)
+                                       *paramslots = d->paramslots;
+                               return true; /* already stored */
+                       }
+                       d = d->hashlink;
+               }
+       }
+
+       /* add the descriptor to the pool */
+
+       d = (descriptor_hash_entry*) DumpMemory::allocate(sizeof(descriptor_hash_entry));
+       d->desc = desc;
+       d->parseddesc.any = NULL;
+       d->hashlink = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+       pool->descriptorhash.ptr[slot] = d;
+
+       /* now check the descriptor */
+
+       end_pos = UTF_END(desc);
+       
+       if (*utf_ptr == '(') {
+               /* a method descriptor */
+
+               pool->methodcount++;
+               utf_ptr++;
+
+               /* check arguments */
+
+               while ((utf_ptr != end_pos) && (*utf_ptr != ')')) {
+                       pool->paramcount++;
+
+                       /* We cannot count the `this' argument here because
+                        * we don't know if the method is static. */
+
+                       if (*utf_ptr == 'J' || *utf_ptr == 'D')
+                               argcount += 2;
+                       else
+                               argcount++;
+
+                       if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, &utf_ptr,
+                                                                     DESCRIPTOR_NOVOID, &name))
+                               return false;
+
+                       if (name)
+                               if (!descriptor_pool_add_class(pool, name))
+                                       return false;
+               }
+
+               if (utf_ptr == end_pos) {
+                       exceptions_throw_classformaterror(pool->referer,
+                                                                                         "Missing ')' in method descriptor");
+                       return false;
+               }
+
+               utf_ptr++; /* skip ')' */
+
+               if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
+                                                                 DESCRIPTOR_CHECKEND, &name))
+                       return false;
+
+               if (name)
+                       if (!descriptor_pool_add_class(pool,name))
+                               return false;
+
+               if (argcount > 255) {
+                       exceptions_throw_classformaterror(pool->referer,
+                                                                                         "Too many arguments in signature");
+                       return false;
+               }
+
+       } else {
+               /* a field descriptor */
+
+               pool->fieldcount++;
+               
+           if (!name_from_descriptor(pool->referer, utf_ptr, end_pos, NULL,
+                                                         DESCRIPTOR_NOVOID | DESCRIPTOR_CHECKEND,
+                                                                 &name))
+                       return false;
+
+               if (name)
+                       if (!descriptor_pool_add_class(pool,name))
+                               return false;
+       }
+
+       d->paramslots = argcount;
+
+       if (paramslots)
+               *paramslots = argcount;
+
+       return true;
+}
+
+
+/* descriptor_pool_create_classrefs ********************************************
+   Create a table containing all the classrefs which were added to the pool
+
+   IN:
+       pool.............the descriptor_pool
+
+   OUT:
+       *count...........if count is non-NULL, this is set to the number
+                           of classrefs in the table
+
+   RETURN VALUE:
+       a pointer to the constant_classref table
+
+*******************************************************************************/
+
+constant_classref * 
+descriptor_pool_create_classrefs(descriptor_pool *pool, s4 *count)
+{
+       u4 nclasses;
+       u4 slot;
+       classref_hash_entry *c;
+       constant_classref *ref;
+       
+       assert(pool);
+
+       nclasses = pool->classrefhash.entries;
+       pool->classrefs = MNEW(constant_classref,nclasses);
+
+       /* fill the constant_classref structs */
+
+       for (slot = 0; slot < pool->classrefhash.size; ++slot) {
+               c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+               while (c) {
+                       ref = pool->classrefs + c->index;
+                       CLASSREF_INIT(*ref, pool->referer, c->name);
+                       c = c->hashlink;
+               }
+       }
+
+       if (count)
+               *count = nclasses;
+
+       return pool->classrefs;
+}
+
+
+/* descriptor_pool_lookup_classref *********************************************
+   Return the constant_classref for the given class name
+
+   IN:
+       pool.............the descriptor_pool
+          classname........name of the class to look up
+
+   RETURN VALUE:
+       a pointer to the constant_classref, or
+          NULL if an exception has been thrown
+
+*******************************************************************************/
+
+constant_classref * 
+descriptor_pool_lookup_classref(descriptor_pool *pool, utf *classname)
+{
+       u4 key,slot;
+       classref_hash_entry *c;
+
+       assert(pool);
+       assert(pool->classrefs);
+       assert(classname);
+
+       key = utf_hashkey(classname->text, classname->blength);
+       slot = key & (pool->classrefhash.size - 1);
+       c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+
+       while (c) {
+               if (c->name == classname)
+                       return pool->classrefs + c->index;
+               c = c->hashlink;
+       }
+
+       exceptions_throw_internalerror("Class reference not found in descriptor pool");
+       return NULL;
+}
+
+
+/* descriptor_pool_alloc_parsed_descriptors ************************************
+   Allocate space for the parsed descriptors
+
+   IN:
+       pool.............the descriptor_pool
+
+   NOTE:
+       This function must be called after all descriptors have been added
+          with descriptor_pool_add.
+
+*******************************************************************************/
+
+void 
+descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool)
+{
+       u4 size;
+       
+       assert(pool);
+
+       /* TWISTI: paramcount + 1: we don't know if the method is static or   */
+       /* not, i have no better solution yet.                                */
+
+       size =
+               pool->fieldcount * sizeof(typedesc) +
+               pool->methodcount * (sizeof(methoddesc) - sizeof(typedesc)) +
+               pool->paramcount * sizeof(typedesc) +
+               pool->methodcount * sizeof(typedesc);      /* possible `this' pointer */
+
+       pool->descriptorsize = size;
+       if (size) {
+               pool->descriptors = MNEW(u1, size);
+               pool->descriptors_next = pool->descriptors;
+       }
+
+       size = pool->fieldcount + pool->methodcount;
+       if (size) {
+               pool->descriptor_kind = (u1*) DumpMemory::allocate(sizeof(u1) * size);
+               pool->descriptor_kind_next = pool->descriptor_kind;
+       }
+}
+
+
+/* descriptor_pool_parse_field_descriptor **************************************
+   Parse the given field descriptor
+
+   IN:
+       pool.............the descriptor_pool
+          desc.............the field descriptor
+
+   RETURN VALUE:
+       a pointer to the parsed field descriptor, or
+          NULL if an exception has been thrown
+
+   NOTE:
+       descriptor_pool_alloc_parsed_descriptors must be called (once)
+       before this function is used.
+
+*******************************************************************************/
+
+typedesc * 
+descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc)
+{
+       u4 key,slot;
+       descriptor_hash_entry *d;
+       typedesc *td;
+
+       assert(pool);
+       assert(pool->descriptors);
+       assert(pool->descriptors_next);
+
+       /* lookup the descriptor in the hashtable */
+
+       key = utf_hashkey(desc->text, desc->blength);
+       slot = key & (pool->descriptorhash.size - 1);
+       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+
+       while (d) {
+               if (d->desc == desc) {
+                       /* found */
+                       if (d->parseddesc.fd)
+                               return d->parseddesc.fd;
+                       break;
+               }
+               d = d->hashlink;
+       }
+
+       assert(d);
+       
+       if (desc->text[0] == '(') {
+               exceptions_throw_classformaterror(pool->referer,
+                                                                                 "Method descriptor used in field reference");
+               return NULL;
+       }
+
+       td = (typedesc *) pool->descriptors_next;
+       pool->descriptors_next += sizeof(typedesc);
+       
+       if (!descriptor_to_typedesc(pool, desc->text, UTF_END(desc), NULL, td))
+               return NULL;
+
+       *(pool->descriptor_kind_next++) = 'f';
+
+       d->parseddesc.fd = td;
+
+       return td;
+}
+
+
+/* descriptor_pool_parse_method_descriptor *************************************
+   Parse the given method descriptor
+
+   IN:
+       pool.............the descriptor_pool
+       desc.............the method descriptor
+       mflags...........the method flags
+          thisclass........classref to the class containing the method.
+                                               This is ignored if mflags contains ACC_STATIC.
+                                               The classref is stored for inserting the 'this' argument.
+
+   RETURN VALUE:
+       a pointer to the parsed method descriptor, or
+          NULL if an exception has been thrown
+
+   NOTE: 
+       descriptor_pool_alloc_parsed_descriptors must be called
+       (once) before this function is used.
+
+*******************************************************************************/
+
+methoddesc * 
+descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc,
+                                                                               s4 mflags,constant_classref *thisclass)
+{
+       u4 key, slot;
+       descriptor_hash_entry *d;
+       methoddesc            *md;
+       typedesc              *td;
+       char *utf_ptr;
+       char *end_pos;
+       s2 paramcount = 0;
+       s2 paramslots = 0;
+
+#ifdef DESCRIPTOR_VERBOSE
+       fprintf(stderr,"descriptor_pool_parse_method_descriptor(%p,%d,%p,",
+                       (void*)pool,(int)mflags,(void*)thisclass);
+       utf_fprint_printable_ascii(stderr,desc); fprintf(stderr,")\n");
+#endif
+
+       assert(pool);
+       assert(pool->descriptors);
+       assert(pool->descriptors_next);
+
+       /* check that it is a method descriptor */
+       
+       if (desc->text[0] != '(') {
+               exceptions_throw_classformaterror(pool->referer,
+                                                                                 "Field descriptor used in method reference");
+               return NULL;
+       }
+
+       /* lookup the descriptor in the hashtable */
+
+       key = utf_hashkey(desc->text, desc->blength);
+       slot = key & (pool->descriptorhash.size - 1);
+       d = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+
+       /* find an un-parsed descriptor */
+
+       while (d) {
+               if (d->desc == desc)
+                       if (!d->parseddesc.md)
+                               break;
+               d = d->hashlink;
+       }
+
+       assert(d);
+
+       md = (methoddesc *) pool->descriptors_next;
+       pool->descriptors_next += sizeof(methoddesc) - sizeof(typedesc);
+
+       utf_ptr = desc->text + 1; /* skip '(' */
+       end_pos = UTF_END(desc);
+
+       td = md->paramtypes;
+
+       /* count the `this' pointer */
+
+       if ((mflags != ACC_UNDEF) && !(mflags & ACC_STATIC)) {
+               td->type = TYPE_ADR;
+               td->primitivetype = TYPE_ADR;
+               td->arraydim = 0;
+               td->classref = thisclass;
+
+               td++;
+               pool->descriptors_next += sizeof(typedesc);
+               paramcount++;
+               paramslots++;
+       }
+
+       while (*utf_ptr != ')') {
+               /* parse a parameter type */
+
+               if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, &utf_ptr, td))
+                       return NULL;
+
+               if (IS_2_WORD_TYPE(td->type))
+                       paramslots++;
+               
+               td++;
+               pool->descriptors_next += sizeof(typedesc);
+               paramcount++;
+               paramslots++;
+       }
+       utf_ptr++; /* skip ')' */
+
+       /* Skip possible `this' pointer in paramtypes array to allow a possible   */
+       /* memory move later in parse.                                            */
+       /* We store the thisclass reference, so we can later correctly fill in    */
+       /* the parameter slot of the 'this' argument.                             */
+
+       if (mflags == ACC_UNDEF) {
+               td->classref = thisclass;
+               td++;
+               pool->descriptors_next += sizeof(typedesc);
+       }
+
+       /* parse return type */
+
+       if (!descriptor_to_typedesc(pool, utf_ptr, end_pos, NULL,
+                                                               &(md->returntype)))
+               return NULL;
+
+       md->paramcount = paramcount;
+       md->paramslots = paramslots;
+
+       /* If mflags != ACC_UNDEF we parse a real loaded method, so do
+          param prealloc.  Otherwise we do this in stack analysis. */
+
+       if (mflags != ACC_UNDEF) {
+               if (md->paramcount > 0) {
+                       /* allocate memory for params */
+
+                       md->params = MNEW(paramdesc, md->paramcount);
+               }
+               else {
+                       md->params = METHODDESC_NOPARAMS;
+               }
+
+               /* fill the paramdesc */
+               /* md_param_alloc has to be called if md->paramcount == 0,
+                  too, so it can make the reservation for the Linkage Area,
+                  Return Register... */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+               if (!opt_intrp)
+# endif
+                       {
+                               /* As builtin-functions are native functions, we have
+                                  to pre-allocate for the native ABI. */
+
+                               if (mflags & ACC_METHOD_BUILTIN)
+                                       md_param_alloc_native(md);
+                               else
+                                       md_param_alloc(md);
+                       }
+#endif
+       }
+       else {
+               /* params will be allocated later by
+                  descriptor_params_from_paramtypes if necessary */
+
+               md->params = NULL;
+       }
+
+       *(pool->descriptor_kind_next++) = 'm';
+
+       d->parseddesc.md = md;
+
+       return md;
+}
+
+/* descriptor_params_from_paramtypes *******************************************
+   Create the paramdescs for a method descriptor. This function is called
+   when we know whether the method is static or not. This function may only
+   be called once for each methoddesc, and only if md->params == NULL.
+
+   IN:
+       md...............the parsed method descriptor
+                           md->params MUST be NULL.
+          mflags...........the ACC_* access flags of the method. Only the
+                           ACC_STATIC bit is checked.
+                                               The value ACC_UNDEF is NOT allowed.
+
+   RETURN VALUE:
+       true.............the paramdescs were created successfully
+          false............an exception has been thrown
+
+   POSTCONDITION:
+       md->parms != NULL
+
+*******************************************************************************/
+
+bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags)
+{
+       typedesc *td;
+
+       assert(md);
+       assert(md->params == NULL);
+       assert(mflags != ACC_UNDEF);
+
+       td = md->paramtypes;
+
+       /* check for `this' pointer */
+
+       if (!(mflags & ACC_STATIC)) {
+               constant_classref *thisclass;
+
+               /* fetch class reference from reserved param slot */
+               thisclass = td[md->paramcount].classref;
+               assert(thisclass);
+
+               if (md->paramcount > 0) {
+                       /* shift param types by 1 argument */
+                       MMOVE(td + 1, td, typedesc, md->paramcount);
+               }
+
+               /* fill in first argument `this' */
+
+               td->type = TYPE_ADR;
+               td->primitivetype = TYPE_ADR;
+               td->arraydim = 0;
+               td->classref = thisclass;
+
+               md->paramcount++;
+               md->paramslots++;
+       }
+
+       /* if the method has params, process them */
+
+       if (md->paramcount > 0) {
+               /* allocate memory for params */
+
+               md->params = MNEW(paramdesc, md->paramcount);
+
+       } else {
+               md->params = METHODDESC_NOPARAMS;
+       }
+
+       /* fill the paramdesc */
+       /* md_param_alloc has to be called if md->paramcount == 0, too, so
+          it can make the reservation for the Linkage Area, Return
+          Register.. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (!opt_intrp)
+# endif
+               {
+                       /* As builtin-functions are native functions, we have to
+                          pre-allocate for the native ABI. */
+
+                       if (mflags & ACC_METHOD_BUILTIN)
+                               md_param_alloc_native(md);
+                       else
+                               md_param_alloc(md);
+               }
+#endif
+
+       return true;
+}
+
+
+/* descriptor_pool_get_parsed_descriptors **************************************
+   Return a pointer to the block of parsed descriptors
+
+   IN:
+       pool.............the descriptor_pool
+
+   OUT:
+          *size............if size is non-NULL, this is set to the size of the
+                           parsed descriptor block (in u1)
+
+   RETURN VALUE:
+       a pointer to the block of parsed descriptors
+
+   NOTE:
+       descriptor_pool_alloc_parsed_descriptors must be called (once)
+       before this function is used.
+
+*******************************************************************************/
+
+void * 
+descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size)
+{
+       assert(pool);
+       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
+       
+       if (size)
+               *size = pool->descriptorsize;
+
+       return pool->descriptors;
+}
+
+
+/* descriptor_pool_get_sizes ***************************************************
+   Get the sizes of the class reference table and the parsed descriptors
+
+   IN:
+       pool.............the descriptor_pool
+
+   OUT:
+       *classrefsize....set to size of the class reference table
+          *descsize........set to size of the parsed descriptors
+
+   NOTE:
+       This function may only be called after both
+              descriptor_pool_create_classrefs, and
+                  descriptor_pool_alloc_parsed_descriptors
+          have been called.
+
+*******************************************************************************/
+
+void 
+descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize, u4 *descsize)
+{
+       assert(pool);
+       assert((!pool->fieldcount && !pool->methodcount) || pool->descriptors);
+       assert(pool->classrefs);
+       assert(classrefsize);
+       assert(descsize);
+
+       *classrefsize = pool->classrefhash.entries * sizeof(constant_classref);
+       *descsize = pool->descriptorsize;
+}
+
+
+/****************************************************************************/
+/* DEBUG HELPERS                                                            */
+/****************************************************************************/
+
+#ifndef NDEBUG
+/* descriptor_debug_print_typedesc *********************************************
+   Print the given typedesc to the given stream
+
+   IN:
+          file.............stream to print to
+          d................the parsed descriptor
+
+*******************************************************************************/
+
+void 
+descriptor_debug_print_typedesc(FILE *file,typedesc *d)
+{
+       int ch;
+
+       if (!d) {
+               fprintf(file,"(typedesc *)NULL");
+               return;
+       }
+       
+       if (d->type == TYPE_ADR) {
+               if (d->classref)
+                       utf_fprint_printable_ascii(file,d->classref->name);
+               else
+                       fprintf(file,"<class=NULL>");
+       }
+       else {
+               switch (d->primitivetype) {
+                       case PRIMITIVETYPE_INT    : ch='I'; break;
+                       case PRIMITIVETYPE_CHAR   : ch='C'; break;
+                       case PRIMITIVETYPE_BYTE   : ch='B'; break;
+                       case PRIMITIVETYPE_SHORT  : ch='S'; break;
+                       case PRIMITIVETYPE_BOOLEAN: ch='Z'; break;
+                       case PRIMITIVETYPE_LONG   : ch='J'; break;
+                       case PRIMITIVETYPE_FLOAT  : ch='F'; break;
+                       case PRIMITIVETYPE_DOUBLE : ch='D'; break;
+                       case PRIMITIVETYPE_VOID   : ch='V'; break;
+                       default                   : ch='!';
+               }
+               fputc(ch,file);
+       }
+       if (d->arraydim)
+               fprintf(file,"[%d]",d->arraydim);
+}
+
+/* descriptor_debug_print_paramdesc ********************************************
+   Print the given paramdesc to the given stream
+
+   IN:
+          file.............stream to print to
+          d................the parameter descriptor
+
+*******************************************************************************/
+
+void
+descriptor_debug_print_paramdesc(FILE *file,paramdesc *d)
+{
+       if (!d) {
+               fprintf(file,"(paramdesc *)NULL");
+               return;
+       }
+       
+       if (d->inmemory) {
+               fprintf(file,"<m%d>",d->regoff);
+       }
+       else {
+               fprintf(file,"<r%d>",d->regoff);
+       }
+}
+
+/* descriptor_debug_print_methoddesc *******************************************
+   Print the given methoddesc to the given stream
+
+   IN:
+          file.............stream to print to
+          d................the parsed descriptor
+
+*******************************************************************************/
+
+void 
+descriptor_debug_print_methoddesc(FILE *file,methoddesc *d)
+{
+       int i;
+       
+       if (!d) {
+               fprintf(file,"(methoddesc *)NULL");
+               return;
+       }
+       
+       fputc('(',file);
+       for (i=0; i<d->paramcount; ++i) {
+               if (i)
+                       fputc(',',file);
+               descriptor_debug_print_typedesc(file,d->paramtypes + i);
+               if (d->params) {
+                       descriptor_debug_print_paramdesc(file,d->params + i);
+               }
+       }
+       if (d->params == METHODDESC_NOPARAMS)
+               fputs("<NOPARAMS>",file);
+       fputc(')',file);
+       descriptor_debug_print_typedesc(file,&(d->returntype));
+}
+
+/* descriptor_pool_debug_dump **************************************************
+   Print the state of the descriptor_pool to the given stream
+
+   IN:
+       pool.............the descriptor_pool
+          file.............stream to print to
+
+*******************************************************************************/
+
+void 
+descriptor_pool_debug_dump(descriptor_pool *pool,FILE *file)
+{
+       u4 slot;
+       u1 *pos;
+       u1 *kind;
+       u4 size;
+       
+       fprintf(file,"======[descriptor_pool for ");
+       utf_fprint_printable_ascii(file,pool->referer->name);
+       fprintf(file,"]======\n");
+
+       fprintf(file,"fieldcount:     %d\n",pool->fieldcount);
+       fprintf(file,"methodcount:    %d\n",pool->methodcount);
+       fprintf(file,"paramcount:     %d\n",pool->paramcount);
+       fprintf(file,"classrefcount:  %d\n",pool->classrefhash.entries);
+       fprintf(file,"descriptorsize: %d bytes\n",pool->descriptorsize);
+       fprintf(file,"classrefsize:   %d bytes\n",
+                       (int)(pool->classrefhash.entries * sizeof(constant_classref)));
+
+       fprintf(file,"class references:\n");
+       for (slot=0; slot<pool->classrefhash.size; ++slot) {
+               classref_hash_entry *c = (classref_hash_entry *) pool->classrefhash.ptr[slot];
+               while (c) {
+                       fprintf(file,"    %4d: ",c->index);
+                       utf_fprint_printable_ascii(file,c->name);
+                       fprintf(file,"\n");
+                       c = c->hashlink;
+               }
+       }
+
+       fprintf(file,"hashed descriptors:\n");
+       for (slot=0; slot<pool->descriptorhash.size; ++slot) {
+               descriptor_hash_entry *c = (descriptor_hash_entry *) pool->descriptorhash.ptr[slot];
+               while (c) {
+                       fprintf(file,"    %p: ",c->parseddesc.any);
+                       utf_fprint_printable_ascii(file,c->desc);
+                       fprintf(file,"\n");
+                       c = c->hashlink;
+               }
+       }
+
+       fprintf(file,"descriptors:\n");
+       if (pool->descriptors) {
+               pos = pool->descriptors;
+               size = pool->descriptors_next - pool->descriptors;
+               fprintf(file,"    size: %d bytes\n",size);
+               
+               if (pool->descriptor_kind) {
+                       kind = pool->descriptor_kind;
+
+                       while (pos < (pool->descriptors + size)) {
+                               fprintf(file,"    %p: ",pos);
+                               switch (*kind++) {
+                                       case 'f':
+                                               descriptor_debug_print_typedesc(file,(typedesc*)pos);
+                                               pos += sizeof(typedesc);
+                                               break;
+                                       case 'm':
+                                               descriptor_debug_print_methoddesc(file,(methoddesc*)pos);
+                                               pos += ((methoddesc*)pos)->paramcount * sizeof(typedesc);
+                                               pos += sizeof(methoddesc) - sizeof(typedesc);
+                                               break;
+                                       default:
+                                               fprintf(file,"INVALID KIND");
+                               }
+                               fputc('\n',file);
+                       }
+               }
+               else {
+                       while (size >= sizeof(void*)) {
+                               fprintf(file,"    %p\n",*((void**)pos));
+                               pos += sizeof(void*);
+                               size -= sizeof(void*);
+                       }
+               }
+       }
+
+       fprintf(file,"==========================================================\n");
+}
+#endif /* !defined(NDEBUG) */
+
+#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/descriptor.h b/src/vm/descriptor.h
deleted file mode 100644 (file)
index bf6c69e..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-/* src/vm/descriptor.h - checking and parsing of field / method descriptors
-
-   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 _DESCRIPTOR_H
-#define _DESCRIPTOR_H
-
-/* forward typedefs ***********************************************************/
-
-typedef struct descriptor_pool descriptor_pool;
-typedef struct typedesc        typedesc;
-typedef struct paramdesc       paramdesc;
-typedef struct methoddesc      methoddesc;
-
-
-#include "config.h"
-
-#include <stdint.h>
-
-#include "vm/types.h"
-
-#include "toolbox/hashtable.h"
-
-#include "vm/class.hpp"
-#include "vm/global.h"
-#include "vm/method.hpp"
-#include "vm/references.h"
-#include "vm/utf8.h"
-
-#include "arch.h"              /* needed for HAS_ADDRESS_REGISTER_FILE */
-
-
-/* data structures ************************************************************/
-
-/*----------------------------------------------------------------------------*/
-/* Descriptor Pools                                                           */
-/*                                                                            */
-/* A descriptor_pool is a temporary data structure used during loading of     */
-/* a class. The descriptor_pool is used to allocate the table of              */
-/* constant_classrefs the class uses, and for parsing the field and method    */
-/* descriptors which occurr within the class. The inner workings of           */
-/* descriptor_pool are not important for outside code.                        */
-/*                                                                            */
-/* You use a descriptor_pool as follows:                                      */
-/*                                                                            */
-/* 1. create one with descriptor_pool_new                                     */
-/* 2. add all explicit class references with descriptor_pool_add_class        */
-/* 3. add all field/method descriptors with descriptor_pool_add               */
-/* 4. call descriptor_pool_create_classrefs                                   */
-/*    You can now lookup classrefs with descriptor_pool_lookup_classref       */
-/* 5. call descriptor_pool_alloc_parsed_descriptors                           */
-/* 6. for each field descriptor call descriptor_pool_parse_field_descriptor   */
-/*    for each method descriptor call descriptor_pool_parse_method_descriptor */
-/* 7. call descriptor_pool_get_parsed_descriptors                             */
-/*                                                                            */
-/* IMPORTANT: The descriptor_pool functions use DNEW and DMNEW for allocating */
-/*            memory which can be thrown away when the steps above have been  */
-/*            done.                                                           */
-/*----------------------------------------------------------------------------*/
-
-struct descriptor_pool {
-       classinfo         *referer;
-       u4                 fieldcount;
-       u4                 methodcount;
-       u4                 paramcount;
-       u4                 descriptorsize;
-       u1                *descriptors;
-       u1                *descriptors_next;
-       hashtable          descriptorhash;
-       constant_classref *classrefs;
-       hashtable          classrefhash;
-       u1                *descriptor_kind;       /* useful for debugging */
-       u1                *descriptor_kind_next;  /* useful for debugging */
-};
-
-
-/* data structures for parsed field/method descriptors ************************/
-
-struct typedesc {
-       constant_classref *classref;      /* class reference for TYPE_ADR types   */
-       u1                 type;          /* TYPE_??? constant [1]                */
-       u1                 primitivetype; /* (PRIMITIVE)TYPE_??? constant [2]     */
-       u1                 arraydim;      /* array dimension (0 if no array)      */
-};
-
-/* [1]...the type field contains the basic type used within the VM. So ints,  */
-/*       shorts, chars, bytes, booleans all have TYPE_INT.                    */
-/* [2]...the primitivetype field contains the declared type.                  */
-/*       So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR.         */
-/*       For non-primitive types primitivetype is TYPE_ADR.                   */
-
-struct paramdesc {
-#if defined(__MIPS__)
-       u1   type;                  /* TYPE_??? of the register allocated         */
-#endif
-       bool     inmemory;          /* argument in register or on stack           */
-       uint32_t index;             /* index into argument register array         */
-       uint32_t regoff;            /* register index or stack offset             */
-};
-
-struct methoddesc {
-       s2         paramcount;      /* number of parameters                       */
-       s2         paramslots;      /* like above but LONG,DOUBLE count twice     */
-       s4         argintreguse;    /* number of used integer argument registers  */
-       s4         argfltreguse;    /* number of used float argument registers    */
-#if defined(HAS_ADDRESS_REGISTER_FILE)
-       s4         argadrreguse;    /* number of used address registers */
-#endif
-       s4         memuse;          /* number of stack slots used                 */
-       paramdesc *params;          /* allocated parameter descriptions [3]       */
-       typedesc   returntype;      /* parsed descriptor of the return type       */
-       typedesc   paramtypes[1];   /* parameter types, variable length!          */
-};
-
-/* [3]...If params is NULL, the parameter descriptions have not yet been      */
-/*       allocated. In this case ___the possible 'this' pointer of the method */
-/*       is NOT counted in paramcount/paramslots and it is NOT included in    */
-/*       the paramtypes array___.                                             */
-/*       If params != NULL, the parameter descriptions have been              */
-/*       allocated, and the 'this' pointer of the method, if any, IS included.*/
-/*       In case the method has no parameters at all, the special value       */
-/*       METHODDESC_NO_PARAMS is used (see below).                            */
-
-/* METHODDESC_NO_PARAMS is a special value for the methoddesc.params field    */
-/* indicating that the method is a static method without any parameters.      */
-/* This special value must be != NULL and it may only be set if               */
-/* md->paramcount == 0.                                                       */
-
-#define METHODDESC_NOPARAMS  ((paramdesc*)1)
-
-/* function prototypes ********************************************************/
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-descriptor_pool * descriptor_pool_new(classinfo *referer);
-
-bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
-bool descriptor_pool_add(descriptor_pool *pool,utf *desc,int *paramslots);
-
-int  descriptor_to_basic_type(utf *desc);
-int  descriptor_typesize(typedesc *td);
-
-constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
-                                                                                                        s4 *count);
-constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
-
-void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
-
-typedesc *descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc);
-methoddesc *descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc, s4 mflags,
-                                                                                                       constant_classref *thisclass);
-
-bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags);
-
-void *descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size);
-void descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize,
-                                                          u4 *descsize);
-
-#ifndef NDEBUG
-void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
-void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
-void descriptor_debug_print_paramdesc(FILE *file,paramdesc *d);
-void descriptor_pool_debug_dump(descriptor_pool *pool, FILE *file);
-#endif /* !defined(NDEBUG) */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _DESCRIPTOR_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/descriptor.hpp b/src/vm/descriptor.hpp
new file mode 100644 (file)
index 0000000..bf6c69e
--- /dev/null
@@ -0,0 +1,208 @@
+/* src/vm/descriptor.h - checking and parsing of field / method descriptors
+
+   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 _DESCRIPTOR_H
+#define _DESCRIPTOR_H
+
+/* forward typedefs ***********************************************************/
+
+typedef struct descriptor_pool descriptor_pool;
+typedef struct typedesc        typedesc;
+typedef struct paramdesc       paramdesc;
+typedef struct methoddesc      methoddesc;
+
+
+#include "config.h"
+
+#include <stdint.h>
+
+#include "vm/types.h"
+
+#include "toolbox/hashtable.h"
+
+#include "vm/class.hpp"
+#include "vm/global.h"
+#include "vm/method.hpp"
+#include "vm/references.h"
+#include "vm/utf8.h"
+
+#include "arch.h"              /* needed for HAS_ADDRESS_REGISTER_FILE */
+
+
+/* data structures ************************************************************/
+
+/*----------------------------------------------------------------------------*/
+/* Descriptor Pools                                                           */
+/*                                                                            */
+/* A descriptor_pool is a temporary data structure used during loading of     */
+/* a class. The descriptor_pool is used to allocate the table of              */
+/* constant_classrefs the class uses, and for parsing the field and method    */
+/* descriptors which occurr within the class. The inner workings of           */
+/* descriptor_pool are not important for outside code.                        */
+/*                                                                            */
+/* You use a descriptor_pool as follows:                                      */
+/*                                                                            */
+/* 1. create one with descriptor_pool_new                                     */
+/* 2. add all explicit class references with descriptor_pool_add_class        */
+/* 3. add all field/method descriptors with descriptor_pool_add               */
+/* 4. call descriptor_pool_create_classrefs                                   */
+/*    You can now lookup classrefs with descriptor_pool_lookup_classref       */
+/* 5. call descriptor_pool_alloc_parsed_descriptors                           */
+/* 6. for each field descriptor call descriptor_pool_parse_field_descriptor   */
+/*    for each method descriptor call descriptor_pool_parse_method_descriptor */
+/* 7. call descriptor_pool_get_parsed_descriptors                             */
+/*                                                                            */
+/* IMPORTANT: The descriptor_pool functions use DNEW and DMNEW for allocating */
+/*            memory which can be thrown away when the steps above have been  */
+/*            done.                                                           */
+/*----------------------------------------------------------------------------*/
+
+struct descriptor_pool {
+       classinfo         *referer;
+       u4                 fieldcount;
+       u4                 methodcount;
+       u4                 paramcount;
+       u4                 descriptorsize;
+       u1                *descriptors;
+       u1                *descriptors_next;
+       hashtable          descriptorhash;
+       constant_classref *classrefs;
+       hashtable          classrefhash;
+       u1                *descriptor_kind;       /* useful for debugging */
+       u1                *descriptor_kind_next;  /* useful for debugging */
+};
+
+
+/* data structures for parsed field/method descriptors ************************/
+
+struct typedesc {
+       constant_classref *classref;      /* class reference for TYPE_ADR types   */
+       u1                 type;          /* TYPE_??? constant [1]                */
+       u1                 primitivetype; /* (PRIMITIVE)TYPE_??? constant [2]     */
+       u1                 arraydim;      /* array dimension (0 if no array)      */
+};
+
+/* [1]...the type field contains the basic type used within the VM. So ints,  */
+/*       shorts, chars, bytes, booleans all have TYPE_INT.                    */
+/* [2]...the primitivetype field contains the declared type.                  */
+/*       So short is PRIMITIVETYPE_SHORT, char is PRIMITIVETYPE_CHAR.         */
+/*       For non-primitive types primitivetype is TYPE_ADR.                   */
+
+struct paramdesc {
+#if defined(__MIPS__)
+       u1   type;                  /* TYPE_??? of the register allocated         */
+#endif
+       bool     inmemory;          /* argument in register or on stack           */
+       uint32_t index;             /* index into argument register array         */
+       uint32_t regoff;            /* register index or stack offset             */
+};
+
+struct methoddesc {
+       s2         paramcount;      /* number of parameters                       */
+       s2         paramslots;      /* like above but LONG,DOUBLE count twice     */
+       s4         argintreguse;    /* number of used integer argument registers  */
+       s4         argfltreguse;    /* number of used float argument registers    */
+#if defined(HAS_ADDRESS_REGISTER_FILE)
+       s4         argadrreguse;    /* number of used address registers */
+#endif
+       s4         memuse;          /* number of stack slots used                 */
+       paramdesc *params;          /* allocated parameter descriptions [3]       */
+       typedesc   returntype;      /* parsed descriptor of the return type       */
+       typedesc   paramtypes[1];   /* parameter types, variable length!          */
+};
+
+/* [3]...If params is NULL, the parameter descriptions have not yet been      */
+/*       allocated. In this case ___the possible 'this' pointer of the method */
+/*       is NOT counted in paramcount/paramslots and it is NOT included in    */
+/*       the paramtypes array___.                                             */
+/*       If params != NULL, the parameter descriptions have been              */
+/*       allocated, and the 'this' pointer of the method, if any, IS included.*/
+/*       In case the method has no parameters at all, the special value       */
+/*       METHODDESC_NO_PARAMS is used (see below).                            */
+
+/* METHODDESC_NO_PARAMS is a special value for the methoddesc.params field    */
+/* indicating that the method is a static method without any parameters.      */
+/* This special value must be != NULL and it may only be set if               */
+/* md->paramcount == 0.                                                       */
+
+#define METHODDESC_NOPARAMS  ((paramdesc*)1)
+
+/* function prototypes ********************************************************/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+descriptor_pool * descriptor_pool_new(classinfo *referer);
+
+bool descriptor_pool_add_class(descriptor_pool *pool,utf *name);
+bool descriptor_pool_add(descriptor_pool *pool,utf *desc,int *paramslots);
+
+int  descriptor_to_basic_type(utf *desc);
+int  descriptor_typesize(typedesc *td);
+
+constant_classref * descriptor_pool_create_classrefs(descriptor_pool *pool,
+                                                                                                        s4 *count);
+constant_classref * descriptor_pool_lookup_classref(descriptor_pool *pool,utf *classname);
+
+void descriptor_pool_alloc_parsed_descriptors(descriptor_pool *pool);
+
+typedesc *descriptor_pool_parse_field_descriptor(descriptor_pool *pool, utf *desc);
+methoddesc *descriptor_pool_parse_method_descriptor(descriptor_pool *pool, utf *desc, s4 mflags,
+                                                                                                       constant_classref *thisclass);
+
+bool descriptor_params_from_paramtypes(methoddesc *md, s4 mflags);
+
+void *descriptor_pool_get_parsed_descriptors(descriptor_pool *pool, s4 *size);
+void descriptor_pool_get_sizes(descriptor_pool *pool, u4 *classrefsize,
+                                                          u4 *descsize);
+
+#ifndef NDEBUG
+void descriptor_debug_print_typedesc(FILE *file,typedesc *d);
+void descriptor_debug_print_methoddesc(FILE *file,methoddesc *d);
+void descriptor_debug_print_paramdesc(FILE *file,paramdesc *d);
+void descriptor_pool_debug_dump(descriptor_pool *pool, FILE *file);
+#endif /* !defined(NDEBUG) */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _DESCRIPTOR_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 5f01f221ec791b015e8ce58e33dd7847429057a4..332fca04b15e1c1304b1921a9b7c292fc84a96d3 100644 (file)
@@ -35,7 +35,7 @@
 
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 #include "native/native.hpp"
index 987217cffd4aeea8a3cecba34a73b97f76a19cc5..6b6b4ed43be2776661cef9998341f69008b6bea4 100644 (file)
 #include <stdint.h>
 #include <stdio.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
 #include "vm/types.h"
 
-#include "vm/annotation.h"
+#include "vm/annotation.hpp"
 #include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/class.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/field.hpp"
 #include "vm/global.h"
index a25d09e3b8b54b91c3513696a437468ea17d53d5..2bb538290cebab76d0b88c88f1dea68778c6affb 100644 (file)
@@ -34,7 +34,7 @@ typedef struct fieldinfo fieldinfo;
 #include "config.h"
 #include "vm/types.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/class.hpp"
 #include "vm/global.h"
 #include "vm/loader.hpp"
diff --git a/src/vm/finalizer.c b/src/vm/finalizer.c
deleted file mode 100644 (file)
index ea331ec..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-/* src/vm/finalizer.c - finalizer linked list and thread
-
-   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 <stdlib.h>
-
-#include "vm/types.h"
-
-#include "mm/memory.h"
-
-#include "threads/condition.hpp"
-#include "threads/mutex.hpp"
-#include "threads/thread.hpp"
-
-#include "vm/jit/builtin.hpp"
-#include "vm/exceptions.hpp"
-#include "vm/global.h"
-#include "vm/options.h"
-#include "vm/vm.hpp"
-
-#include "vm/jit/asmpart.h"
-
-
-/* global variables ***********************************************************/
-
-#if defined(ENABLE_THREADS)
-static Mutex     *finalizer_thread_mutex;
-static Condition *finalizer_thread_cond;
-#endif
-
-
-/* finalizer_init **************************************************************
-
-   Initializes the finalizer global lock and the linked list.
-
-*******************************************************************************/
-
-bool finalizer_init(void)
-{
-       TRACESUBSYSTEMINITIALIZATION("finalizer_init");
-
-#if defined(ENABLE_THREADS)
-       finalizer_thread_mutex = Mutex_new();
-       finalizer_thread_cond  = Condition_new();
-#endif
-
-       /* everything's ok */
-
-       return true;
-}
-
-
-/* finalizer_thread ************************************************************
-
-   This thread waits on an object for a notification and the runs the
-   finalizers (finalizer thread).  This is necessary because of a
-   possible deadlock in the GC.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-static void finalizer_thread(void)
-{
-       while (true) {
-               /* get the lock on the finalizer mutex, so we can call wait */
-
-               Mutex_lock(finalizer_thread_mutex);
-
-               /* wait forever on that condition till we are signaled */
-       
-               Condition_wait(finalizer_thread_cond, finalizer_thread_mutex);
-
-               /* leave the lock */
-
-               Mutex_unlock(finalizer_thread_mutex);
-
-#if !defined(NDEBUG)
-               if (opt_DebugFinalizer)
-                       log_println("[finalizer thread    : status=awake]");
-#endif
-
-               /* and call the finalizers */
-
-               gc_invoke_finalizers();
-
-#if !defined(NDEBUG)
-               if (opt_DebugFinalizer)
-                       log_println("[finalizer thread    : status=sleeping]");
-#endif
-       }
-}
-#endif
-
-
-/* finalizer_start_thread ******************************************************
-
-   Starts the finalizer thread.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-bool finalizer_start_thread(void)
-{
-       utf *name;
-
-       name = utf_new_char("Finalizer");
-
-       if (!threads_thread_start_internal(name, finalizer_thread))
-               return false;
-
-       /* everything's ok */
-
-       return true;
-}
-#endif
-
-
-/* finalizer_notify ************************************************************
-
-   Notifies the finalizer thread that it should run the
-   gc_invoke_finalizers from the GC.
-
-*******************************************************************************/
-
-void finalizer_notify(void)
-{
-#if !defined(NDEBUG)
-       if (opt_DebugFinalizer)
-               log_println("[finalizer notified]");
-#endif
-
-#if defined(ENABLE_THREADS)
-       /* get the lock on the finalizer lock object, so we can call wait */
-
-       Mutex_lock(finalizer_thread_mutex);
-
-       /* signal the finalizer thread */
-
-       Condition_signal(finalizer_thread_cond);
-
-       /* leave the lock */
-
-       Mutex_unlock(finalizer_thread_mutex);
-#else
-       /* if we don't have threads, just run the finalizers */
-
-       gc_invoke_finalizers();
-#endif
-}
-
-
-/* finalizer_run ***************************************************************
-
-   Actually run the finalizer functions.
-
-*******************************************************************************/
-
-void finalizer_run(void *o, void *p)
-{
-       java_handle_t *h;
-       classinfo     *c;
-
-       h = (java_handle_t *) o;
-
-#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
-       /* XXX this is only a dirty hack to make Boehm work with handles */
-
-       h = LLNI_WRAP((java_object_t *) h);
-#endif
-
-       LLNI_class_get(h, c);
-
-#if !defined(NDEBUG)
-       if (opt_DebugFinalizer) {
-               log_start();
-               log_print("[finalizer running   : o=%p p=%p class=", o, p);
-               class_print(c);
-               log_print("]");
-               log_finish();
-       }
-#endif
-
-       /* call the finalizer function */
-
-       (void) vm_call_method(c->finalizer, h);
-
-#if !defined(NDEBUG)
-       if (opt_DebugFinalizer && (exceptions_get_exception() != NULL)) {
-               log_println("[finalizer exception]");
-               exceptions_print_stacktrace();
-       }
-#endif
-
-       /* if we had an exception in the finalizer, ignore it */
-
-       exceptions_clear_exception();
-}
-
-
-/*
- * 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/finalizer.cpp b/src/vm/finalizer.cpp
new file mode 100644 (file)
index 0000000..cd14c48
--- /dev/null
@@ -0,0 +1,240 @@
+/* src/vm/finalizer.c - finalizer linked list and thread
+
+   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 <stdlib.h>
+
+#include "vm/types.h"
+
+#include "mm/memory.hpp"
+
+#include "threads/condition.hpp"
+#include "threads/mutex.hpp"
+#include "threads/thread.hpp"
+
+#include "vm/jit/builtin.hpp"
+#include "vm/exceptions.hpp"
+#include "vm/global.h"
+#include "vm/options.h"
+#include "vm/vm.hpp"
+
+#include "vm/jit/asmpart.h"
+
+
+/* global variables ***********************************************************/
+
+#if defined(ENABLE_THREADS)
+static Mutex     *finalizer_thread_mutex;
+static Condition *finalizer_thread_cond;
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/* finalizer_init **************************************************************
+
+   Initializes the finalizer global lock and the linked list.
+
+*******************************************************************************/
+
+bool finalizer_init(void)
+{
+       TRACESUBSYSTEMINITIALIZATION("finalizer_init");
+
+#if defined(ENABLE_THREADS)
+       finalizer_thread_mutex = new Mutex();
+       finalizer_thread_cond  = new Condition();
+#endif
+
+       /* everything's ok */
+
+       return true;
+}
+
+
+/* finalizer_thread ************************************************************
+
+   This thread waits on an object for a notification and the runs the
+   finalizers (finalizer thread).  This is necessary because of a
+   possible deadlock in the GC.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+static void finalizer_thread(void)
+{
+       while (true) {
+               /* get the lock on the finalizer mutex, so we can call wait */
+
+               finalizer_thread_mutex->lock();
+
+               /* wait forever on that condition till we are signaled */
+       
+               finalizer_thread_cond->wait(finalizer_thread_mutex);
+
+               /* leave the lock */
+
+               finalizer_thread_mutex->unlock();
+
+#if !defined(NDEBUG)
+               if (opt_DebugFinalizer)
+                       log_println("[finalizer thread    : status=awake]");
+#endif
+
+               /* and call the finalizers */
+
+               gc_invoke_finalizers();
+
+#if !defined(NDEBUG)
+               if (opt_DebugFinalizer)
+                       log_println("[finalizer thread    : status=sleeping]");
+#endif
+       }
+}
+#endif
+
+
+/* finalizer_start_thread ******************************************************
+
+   Starts the finalizer thread.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+bool finalizer_start_thread(void)
+{
+       utf *name;
+
+       name = utf_new_char("Finalizer");
+
+       if (!threads_thread_start_internal(name, finalizer_thread))
+               return false;
+
+       /* everything's ok */
+
+       return true;
+}
+#endif
+
+
+/* finalizer_notify ************************************************************
+
+   Notifies the finalizer thread that it should run the
+   gc_invoke_finalizers from the GC.
+
+*******************************************************************************/
+
+void finalizer_notify(void)
+{
+#if !defined(NDEBUG)
+       if (opt_DebugFinalizer)
+               log_println("[finalizer notified]");
+#endif
+
+#if defined(ENABLE_THREADS)
+       /* get the lock on the finalizer lock object, so we can call wait */
+
+       finalizer_thread_mutex->lock();
+
+       /* signal the finalizer thread */
+
+       finalizer_thread_cond->signal();
+
+       /* leave the lock */
+
+       finalizer_thread_mutex->unlock();
+#else
+       /* if we don't have threads, just run the finalizers */
+
+       gc_invoke_finalizers();
+#endif
+}
+
+
+/* finalizer_run ***************************************************************
+
+   Actually run the finalizer functions.
+
+*******************************************************************************/
+
+void finalizer_run(void *o, void *p)
+{
+       java_handle_t *h;
+       classinfo     *c;
+
+       h = (java_handle_t *) o;
+
+#if !defined(ENABLE_GC_CACAO) && defined(ENABLE_HANDLES)
+       /* XXX this is only a dirty hack to make Boehm work with handles */
+
+       h = LLNI_WRAP((java_object_t *) h);
+#endif
+
+       LLNI_class_get(h, c);
+
+#if !defined(NDEBUG)
+       if (opt_DebugFinalizer) {
+               log_start();
+               log_print("[finalizer running   : o=%p p=%p class=", o, p);
+               class_print(c);
+               log_print("]");
+               log_finish();
+       }
+#endif
+
+       /* call the finalizer function */
+
+       (void) vm_call_method(c->finalizer, h);
+
+#if !defined(NDEBUG)
+       if (opt_DebugFinalizer && (exceptions_get_exception() != NULL)) {
+               log_println("[finalizer exception]");
+               exceptions_print_stacktrace();
+       }
+#endif
+
+       /* if we had an exception in the finalizer, ignore it */
+
+       exceptions_clear_exception();
+}
+
+#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:
+ */
diff --git a/src/vm/finalizer.h b/src/vm/finalizer.h
deleted file mode 100644 (file)
index 04abf9e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-/* src/vm/finalizer.h - finalizer linked list and thread header
-
-   Copyright (C) 1996-2005, 2006, 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 _FINALIZER_H
-#define _FINALIZER_H
-
-#include "config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "vm/types.h"
-
-#include "vm/global.h"
-
-
-/* function prototypes ********************************************************/
-
-bool finalizer_init(void);
-bool finalizer_start_thread(void);
-void finalizer_notify(void);
-void finalizer_run(void *o, void *p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _FINALIZER_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/finalizer.hpp b/src/vm/finalizer.hpp
new file mode 100644 (file)
index 0000000..04abf9e
--- /dev/null
@@ -0,0 +1,65 @@
+/* src/vm/finalizer.h - finalizer linked list and thread header
+
+   Copyright (C) 1996-2005, 2006, 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 _FINALIZER_H
+#define _FINALIZER_H
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "vm/types.h"
+
+#include "vm/global.h"
+
+
+/* function prototypes ********************************************************/
+
+bool finalizer_init(void);
+bool finalizer_start_thread(void);
+void finalizer_notify(void);
+void finalizer_run(void *o, void *p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _FINALIZER_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 f53021823dc92506107df2aba9a4c5834c4520e8..285e23572ab532443ef3e31e76a86b7c8480fe08 100644 (file)
@@ -29,7 +29,7 @@
 
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
@@ -1969,8 +1969,9 @@ public:
        inline java_handle_t* get_uncaughtExceptionHandler() const;
 
        // Setters.
-       inline void set_priority(int32_t value);
-       inline void set_group   (java_handle_t* value);
+       inline void set_priority    (int32_t value);
+       inline void set_group       (java_handle_t* value);
+       inline void set_threadStatus(int32_t value);
 };
 
 
@@ -2005,6 +2006,11 @@ inline void java_lang_Thread::set_group(java_handle_t* value)
        set(_handle, offset_group, value);
 }
 
+inline void java_lang_Thread::set_threadStatus(int32_t value)
+{
+       set(_handle, offset_threadStatus, value);
+}
+
 
 
 /**
index de94a0f44dec49e543d95311902a3a1898488ea5..8e748688741ac3ee07735494245892cd961d84ba 100644 (file)
@@ -30,9 +30,9 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/worklist.h"
 
 #include "vm/jit/builtin.hpp"
index bfe0e16662bf4ef9b86bf1cfe99063b58e75e062..c5e1ad29997dfec1bce10a2388cf75e037d11484 100644 (file)
@@ -35,9 +35,9 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
index f852229bf0b426b63f880ffa5ba7d9ab80314d06..f3390ba045c9e96125824b126f2ad9b2ab5b3900 100644 (file)
@@ -33,7 +33,7 @@
 #include "arch.h"
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
index b136fd4dcaaefac36a11c63d4a751ac2f4c60b23..a49b1a0af59426899539c7e7a9ec37272353f68e 100644 (file)
@@ -36,7 +36,7 @@
 #include "vm/jit/alpha/arch.h"
 #include "vm/jit/alpha/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index 8bf59e90e858c4fce000427a83bc9bb62b1c70b9..96fb6f0be0a72427f95e41a37e9ca06be35828b6 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "vm/jit/alpha/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index e60626f3fabaff75554193c6a5b7560da4c5a62b..3d9169da8dc975b4664d48ec63bbb2f5205dd00b 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/alpha/md-abi.h"
 
 #include "vm/global.h"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/jit/asmpart.h"
 
 
index 8e127a9fab4e3bae10487216f640ecdda617c28a..1fe5e80861fb0c0e766639bc63a2ff5282229c28 100644 (file)
@@ -39,7 +39,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
index 496834761c646923fdd60750d8c98553d8ae80fd..c968be9862d9c4615c40fa7a83ec2682e56f0970 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "vm/jit/alpha/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index 6d3c5fdf4d6697f33a7aa17da8a192359732f0d0..2e0aeaa95c7131d43563e28f650e53ab92a12534 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "vm/jit/alpha/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index a670883d6c6fce869f976adb1afdc5e344abae3e..5ee7ca6d5b22e5b8d62acb6a222f05f38402a7bf 100644 (file)
 
 #include "arch.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
 #include "vm/array.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 #include "vm/method.hpp"
 #include "vm/primitive.hpp"
index 4b86e510f050e22bf584c9850842b51fb17c4a26..a0085a806efce8d275e22c62404722e04352c67c 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/arm/arch.h"
 #include "vm/jit/arm/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
@@ -2296,21 +2296,33 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEVIRTUAL:
                                if (lm == NULL) {
-                                       patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, 0);
+                                       int32_t disp = dseg_add_unique_s4(cd, 0);
+                                       patcher_add_patch_ref(jd, PATCHER_invokevirtual, um, disp);
 
-                                       s1 = 0;
-                               }
-                               else
-                                       s1 = OFFSET(vftbl_t, table[0]) +
-                                               sizeof(methodptr) * lm->vftblindex;
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
 
-                               /* implicit null-pointer check */
-                               M_LDR_INTERN(REG_METHODPTR, REG_A0,
-                                                        OFFSET(java_object_t, vftbl));
-                               M_LDR_INTERN(REG_PV, REG_METHODPTR, s1);
+                                       // Sanity check.
+                                       assert(REG_ITMP1 != REG_METHODPTR);
+                                       assert(REG_ITMP2 == REG_METHODPTR);
 
-                               /* generate the actual call */
+                                       M_DSEG_LOAD(REG_ITMP1, disp);
+                                       M_ADD(REG_METHODPTR, REG_METHODPTR, REG_ITMP1);
 
+                                       // This must be a load with displacement,
+                                       // otherwise the JIT method address patching does
+                                       // not work anymore (see md_jit_method_patch_address).
+                                       M_LDR_INTERN(REG_PV, REG_METHODPTR, 0);
+                               }
+                               else {
+                                       s1 = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * lm->vftblindex;
+
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
+                                       M_LDR(REG_PV, REG_METHODPTR, s1);
+                               }
+
+                               // Generate the actual call.
                                M_MOV(REG_LR, REG_PC);
                                M_MOV(REG_PC, REG_PV);
                                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
@@ -2319,25 +2331,43 @@ bool codegen_emit(jitdata *jd)
 
                        case ICMD_INVOKEINTERFACE:
                                if (lm == NULL) {
-                                       patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, 0);
+                                       int32_t disp  = dseg_add_unique_s4(cd, 0);
+                                       int32_t disp2 = dseg_add_unique_s4(cd, 0);
 
-                                       s1 = 0;
-                                       s2 = 0;
+                                       // XXX We need two displacements.
+                                       assert(disp2 == disp - 4);
+                                       patcher_add_patch_ref(jd, PATCHER_invokeinterface, um, disp);
+
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
+
+                                       // Sanity check.
+                                       assert(REG_ITMP1 != REG_METHODPTR);
+                                       assert(REG_ITMP2 == REG_METHODPTR);
+                                       assert(REG_ITMP3 != REG_METHODPTR);
+
+                                       M_DSEG_LOAD(REG_ITMP1, disp);
+                                       M_LDR_REG(REG_METHODPTR, REG_METHODPTR, REG_ITMP1);
+
+                                       M_DSEG_LOAD(REG_ITMP3, disp2);
+                                       M_ADD(REG_METHODPTR, REG_METHODPTR, REG_ITMP3);
+
+                                       // This must be a load with displacement,
+                                       // otherwise the JIT method address patching does
+                                       // not work anymore (see md_jit_method_patch_address).
+                                       M_LDR_INTERN(REG_PV, REG_METHODPTR, 0);
                                }
                                else {
-                                       s1 = OFFSET(vftbl_t, interfacetable[0]) -
-                                               sizeof(methodptr*) * lm->clazz->index;
+                                       s1 = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * lm->clazz->index;
                                        s2 = sizeof(methodptr) * (lm - lm->clazz->methods);
-                               }
-
-                               /* implicit null-pointer check */
-                               M_LDR_INTERN(REG_METHODPTR, REG_A0,
-                                                        OFFSET(java_object_t, vftbl));
-                               M_LDR_INTERN(REG_METHODPTR, REG_METHODPTR, s1);
-                               M_LDR_INTERN(REG_PV, REG_METHODPTR, s2);
 
-                               /* generate the actual call */
+                                       // The following instruction MUST NOT change a0 because of the implicit NPE check.
+                                       M_LDR_INTERN(REG_METHODPTR, REG_A0, OFFSET(java_object_t, vftbl));
+                                       M_LDR(REG_METHODPTR, REG_METHODPTR, s1);
+                                       M_LDR(REG_PV, REG_METHODPTR, s2);
+                               }
 
+                               // Generate the actual call.
                                M_MOV(REG_LR, REG_PC);
                                M_MOV(REG_PC, REG_PV);
                                s1 = (s4) (cd->mcodeptr - cd->mcodebase);
index b57d26cb229286f0579dfb68d3ef4954699715c5..1a45898e86cec5442e37000df0f533bf6e920113 100644 (file)
@@ -186,6 +186,9 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
         cd->mcodeptr += 4; \
     } while (0)
 
+#define M_MEM_GET_Rd(mcode)    (((mcode) >> 12) & 0x0f)
+#define M_MEM_GET_Rbase(mcode) (((mcode) >> 16) & 0x0f)
+
 
 /* load and store instruction: M_MEM2
    cond ... conditional execution
@@ -487,6 +490,9 @@ void asm_debug_intern(int a1, int a2, int a3, int a4);
 #define M_LDMFD(regs,base) M_MEM_MULTI(UNCOND,1,0,regs,base,0,1,1)
 #define M_STMFD(regs,base) M_MEM_MULTI(UNCOND,0,0,regs,base,1,0,1)
 
+#define M_LDR_REG(d,base,offreg) M_MEM(UNCOND,1,0,d,base,offreg,1,1,1,0)
+#define M_STR_REG(d,base,offreg) M_MEM(UNCOND,0,0,d,base,offreg,1,1,1,0)
+
 #define M_LDR_INTERN(d,base,off) \
     do { \
         CHECK_OFFSET(off, 0x0fff); \
index a30de77364a166ce0da50c490da268a9341e4e6c..c6c922c2131a23f032395369989bd6a03925ca12 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "vm/jit/arm/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
@@ -49,7 +49,7 @@
 #include "vm/jit/trace.hpp"
 #include "vm/jit/trap.h"
 
-#include "toolbox/logging.h" /* XXX for debugging only */
+#include "toolbox/logging.hpp" /* XXX for debugging only */
 
 
 /* emit_load *******************************************************************
index 1b1142e5a39b7f94a3f30881bfc6f5b182c8d5d8..10e7c13a2a80ce5239e60c7ff7cad6060d1ef0cc 100644 (file)
@@ -52,7 +52,7 @@ typedef struct ucontext {
 #include "threads/thread.hpp"
 
 #include "vm/os.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
index bdf6a14f918d2debb0234f7a15315cfef23a0531..c0f00f81a395d33a453e14195e0c2eb20ab3b053 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "vm/jit/arm/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index b150f1a14831499f59267ff14222b67708e1627d..30df98d484ba893b04a6925ec15d4c3b7ff2de6b 100644 (file)
@@ -28,6 +28,7 @@
 #include <assert.h>
 #include <stdint.h>
 
+#include "vm/jit/arm/codegen.h"
 #include "vm/jit/arm/md.h"
 #include "vm/jit/arm/md-abi.h"
 
@@ -59,10 +60,18 @@ void md_init(void)
    or
 
    e590b000    ldr   fp, [r0]
-   e59bc000    ldr   ip, [fp]
+   e59bc004    ldr   ip, [fp, #4]
    e1a0e00f    mov   lr, pc
    e1a0f00c    mov   pc, ip
 
+   or
+
+   e590b000    ldr     fp, [r0]
+   e28bca01    add     ip, fp, #4096   ; 0x1000
+   e59cc004    ldr     ip, [ip, #4]
+   e1a0e00f    mov     lr, pc
+   e1a0f00c    mov     pc, ip
+
    How we find out the patching address to store new method pointer:
     - loaded IP with LDR IP,[METHODPTR]?
         yes=INVOKEVIRTUAL or INVOKEINTERFACE (things are easy!)
@@ -76,7 +85,7 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
 {
        uint32_t *pc;
        uint32_t  mcode;
-       int32_t   offset;
+       int32_t   disp;
        void     *pa;                       /* patch address                      */
 
        /* Go back to the actual load instruction. */
@@ -87,22 +96,39 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
 
        mcode = pc[0];
 
-       /* sanity check: are we inside jit code? */
+       /* Sanity check: Are we inside jit code? */
 
        assert(pc[1] == 0xe1a0e00f /*MOV LR,PC*/);
        assert(pc[2] == 0xe1a0f00c /*MOV PC,IP*/);
 
-       /* get the load instruction and offset */
-
-       offset = (int32_t) (mcode & 0x0fff);
+       /* Sanity check: We unconditionally loaded a word into REG_PV? */
 
        assert ((mcode & 0xff70f000) == 0xe510c000);
 
-       if ((mcode & 0x000f0000) == 0x000b0000) {
-               /* sanity check: offset was positive */
+       /* Get load displacement. */
+
+       disp = (int32_t) (mcode & 0x0fff);
+
+       /* Case: We loaded from base REG_PV with negative displacement. */
+
+       if (M_MEM_GET_Rbase(mcode) == REG_PV && (mcode & 0x00800000) == 0) {
+               /* We loaded from data segment, displacement can be larger. */
+
+               mcode = pc[-1];
+
+               /* check for "SUB IP, IP, #??, ROTL 12" */
+
+               if ((mcode & 0xffffff00) == 0xe24cca00)
+                       disp += (int32_t) ((mcode & 0x00ff) << 12);
+
+               /* and get the final data segment address */
+
+               pa = ((uint8_t *) pv) - disp;
+       }
 
-               assert((mcode & 0x00800000) == 0x00800000);
+       /* Case: We loaded from base REG_METHODPTR with positive displacement. */
 
+       else if (M_MEM_GET_Rbase(mcode) == REG_METHODPTR && (mcode & 0x00800000) == 0x00800000) {
                /* return NULL if no mptr was specified (used for replacement) */
 
                if (mptr == NULL)
@@ -110,26 +136,36 @@ void *md_jit_method_patch_address(void *pv, void *ra, void *mptr)
 
                /* we loaded from REG_METHODPTR */
 
-               pa = ((uint8_t *) mptr) + offset;
+               pa = ((uint8_t *) mptr) + disp;
        }
-       else {
-               /* sanity check: we loaded from REG_IP; offset was negative or zero */
 
-               assert((mcode & 0x008f0000) == 0x000c0000 ||
-                      (mcode & 0x008f0fff) == 0x008c0000);
+       /* Case: We loaded from base REG_PV with positive offset. */
 
-               /* we loaded from data segment; offset can be larger */
+       else if (M_MEM_GET_Rbase(mcode) == REG_PV && (mcode & 0x00800000) == 0x00800000) {
+               /* We loaded from REG_METHODPTR with a larger displacement */
 
                mcode = pc[-1];
 
-               /* check for "SUB IP, IP, #??, ROTL 12" */
+               /* check for "ADD IP, FP, #??, ROTL 12" */
 
-               if ((mcode & 0xffffff00) == 0xe24cca00)
-                       offset += (int32_t) ((mcode & 0x00ff) << 12);
+               if ((mcode & 0xffffff00) == 0xe28bca00)
+                       disp += (int32_t) ((mcode & 0x00ff) << 12);
+               else
+                       vm_abort_disassemble(pc - 1, 4, "md_jit_method_patch_address: unknown instruction %x", mcode);
 
-               /* and get the final data segment address */
+               /* we loaded from REG_METHODPTR */
+
+               pa = ((uint8_t *) mptr) + disp;
+       }
+
+       /* Case is not covered, something is severely wrong. */
+
+       else {
+               vm_abort_disassemble(pc, 3, "md_jit_method_patch_address: unknown instruction %x", mcode);
+
+               /* Keep compiler happy. */
 
-               pa = ((uint8_t *) pv) - offset;        
+               pa = NULL;
        }
 
        return pa;
index 36f0adfc328d561a9f6fbfa6b313d002f982011b..c2fbbe3402b24789d2c8fef285f0af513191ebc5 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "vm/jit/arm/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
 #include "vm/jit/patcher-common.hpp"
 
 
-#define gen_resolveload(inst,offset) \
-       assert((offset) >= -0x0fff && (offset) <= 0x0fff); \
-       assert(!((inst) & 0x0fff)); \
-       if ((offset) <  0) { \
-               (inst) = ((inst) & 0xff7ff000) | ((-(offset)) & 0x0fff); \
-               /*(inst) &= ~(1 << 23);*/ \
-       } else { \
-               (inst) = ((inst) & 0xfffff000) | ((offset) & 0x0fff); \
-               /*(inst) |= (1 << 23);*/ \
-       }
-
-
 /* patcher_patch_code **********************************************************
 
    Just patches back the original machine code.
@@ -282,8 +270,8 @@ bool patcher_invokestatic_special(patchref_t *pr)
 
 bool patcher_invokevirtual(patchref_t *pr)
 {
-       uint32_t*          pc = (uint32_t*)           pr->mpc;
-       unresolved_method* um = (unresolved_method *) pr->ref;
+       unresolved_method* um    = (unresolved_method*) pr->ref;
+       int32_t*           datap = (int32_t*)           pr->datap;
 
        // Resolve the method.
        methodinfo* m = resolve_method_eager(um);
@@ -292,10 +280,8 @@ bool patcher_invokevirtual(patchref_t *pr)
                return false;
 
        // Patch vftbl index.
-       gen_resolveload(pc[1], (int32_t) (OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex));
-
-       // Synchronize instruction cache.
-       md_icacheflush(pc + 1, 1 * 4);
+       int32_t disp = OFFSET(vftbl_t, table[0]) + sizeof(methodptr) * m->vftblindex;
+       *datap = disp;
 
        // Patch back the original code.
        patcher_patch_code(pr);
@@ -315,13 +301,12 @@ bool patcher_invokevirtual(patchref_t *pr)
    e1a0e00f    mov   lr, pc
    e1a0f00c    mov   pc, ip
 
-
 *******************************************************************************/
 
 bool patcher_invokeinterface(patchref_t *pr)
 {
-       uint32_t*          pc = (uint32_t*)           pr->mpc;
-       unresolved_method* um = (unresolved_method *) pr->ref;
+       unresolved_method* um    = (unresolved_method*) pr->ref;
+       int32_t*           datap = (int32_t*)           pr->datap;
 
        // Resolve the method.
        methodinfo* m = resolve_method_eager(um);
@@ -330,13 +315,15 @@ bool patcher_invokeinterface(patchref_t *pr)
                return false;
 
        // Patch interfacetable index.
-       gen_resolveload(pc[1], (int32_t) (OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * m->clazz->index));
+       int32_t disp = OFFSET(vftbl_t, interfacetable[0]) - sizeof(methodptr*) * m->clazz->index;
+       *datap = disp;
 
-       // Patch method offset.
-       gen_resolveload(pc[2], (int32_t) (sizeof(methodptr) * (m - m->clazz->methods)));
+       // HACK The next data segment entry is one below.
+       datap--;
 
-       // Synchronize instruction cache.
-       md_icacheflush(pc + 1, 2 * 4);
+       // Patch method offset.
+       disp = sizeof(methodptr) * (m - m->clazz->methods);
+       *datap = disp;
 
        // Patch back the original code.
        patcher_patch_code(pr);
index f2c1a5f6b4d7523b023732cfbb94d96cd5069f44..491d48ce6c056cac6b6c212424807374485f3d46 100644 (file)
@@ -48,7 +48,7 @@
 #endif
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
@@ -56,7 +56,7 @@
 #include "threads/mutex.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/util.h"
 
 #include "vm/array.hpp"
index eb2d80e1c79138804eb221c8b89451024646a638..60b58e25c672497252ad3d94c99c1377b1a950c6 100644 (file)
@@ -36,9 +36,9 @@ typedef struct builtintable_entry builtintable_entry;
 #include "arch.h"
 #include "md-abi.h"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/utf8.h"
 
 
index 4772b95f2f71d984b7cb776122ff305233e7527e..63e3821c4b07f2cfd01c600f38b79f2564ce3f60 100644 (file)
@@ -30,7 +30,7 @@
 #include <assert.h>
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/global.h"
 
index b39852d2ed7a8f20024421d435153fc70bb2bb25..53dec1fd2485d6a1b2cedbbaf02b19869321a5a8 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "arch.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/options.h"
 #include "vm/vm.hpp"
index dd1768e588f642b96a4e26bfeaf306bb0f45de03..218c2537f9b85a4c2cd314b8f1c09f0468ba06ad 100644 (file)
 #include "md.h"
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/avl.h"
 #include "toolbox/list.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "native/llni.h"
 #include "native/localref.hpp"
index 98a7142369cf3284f97950090543d139d9398cae..b988853b39629bf11a957320305f2b67b14ffc86 100644 (file)
@@ -41,7 +41,7 @@ typedef struct dataref                dataref;
 #include "toolbox/list.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 #include "vm/method.hpp"
 #include "vm/references.h"
index f3636f88d1118d9635bb60741de06f9ffb065593..75ebe3b3dd1a76844589cd136f4b28af8d496ca8 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/disass.h"
 
index b66da4bd4c3ed83bfe60b8ffedcbe78056ab76cc..92129f4112ca012c6d99a53b7ac62461dda04642 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/options.h"
 
index 9130543d24762d806416a9e9774bd7369b3ddd33..7745c7ff358f64dfec685b8f54bee1f2c8eee07c 100644 (file)
@@ -28,7 +28,7 @@
 #include <assert.h>
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/code.hpp"
 #include "vm/jit/exceptiontable.h"
index cfcac31c3dc4e1a5b114b35a39427448dd0e9948..2a7958deac3b2af7435d49cc681d3e32e694d865 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/os.hpp"
 
 #include "vm/jit/abi.h"
index a367f37aa4a05b5cd11801c2ca5a16bacd01d923..8eab0fbf0511a4cce0d56cac92d930db7c06b8ed 100644 (file)
@@ -36,7 +36,7 @@
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index e35e6f6a18ca1dca37200e53b182f85c3234923a..add516af78ad62c8f60bb7983561c66b394488db 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "vm/types.h"
 
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/jit/asmpart.h"
 
 
index 87157e5009984fac885e9903971efb261fd67628..b9f3afd9de575a9b1697f2dc96553ee273ff33eb 100644 (file)
@@ -39,7 +39,7 @@
 
 #include "vm/jit/builtin.hpp"
 #include "vm/global.h"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
index d7140291a69a36eb02f0ad3c28563c7d14053561..3a264f162542561af62ca4197e098192313699a4 100644 (file)
@@ -33,7 +33,7 @@
 #include "vm/jit/i386/emit.h"
 #include "vm/jit/i386/md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index 9a1dc9d5eaedd2ac8ec652d873bfcc4e297b54d1..9a18831478fc3f327233a3c0c7725ad10d788f24 100644 (file)
@@ -36,7 +36,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
index f046f37d6cfbddacd0746d1706ec511cf416d36c..19be0e4b7fed8ee85218560bfc617fd88233d9f6 100644 (file)
@@ -38,7 +38,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
index dbaf089b81d80c4ba3f5b02f8ae5e0f0bcda1b70..f304686bc70606edb2980a96ee3be4440365bfe5 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "vm/jit/i386/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index 3eecac97ed221fe0b0a2956aef2876cd1ab686b1..fb04b86c4e1e2ac8a88bad0f5f35d963862e2383 100644 (file)
@@ -32,7 +32,7 @@
 #include "vm/jit/i386/codegen.h"
 #include "vm/jit/i386/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index 67363ec8d5c45948e7232997ca1f78a6d6a7a16e..16e649d6d41d92936af8dfbcec3339cf3d941040 100644 (file)
@@ -36,7 +36,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
index 73c8667d2ee95dca23bd2a420fbfb9ef18c4da3b..721e143d4654fcf7b36f31983b7dc5dd9d5f32b3 100644 (file)
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 #include "threads/mutex.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/class.hpp"
index 4fbca4a70d15856dfe575b7af0675374fcef8cea..0e477cc37a270dd6302ef42cd2f3ab5a4a66d481 100644 (file)
@@ -43,7 +43,7 @@
 #include "vm/jit/intrp/codegen.h"
 #include "vm/jit/intrp/intrp.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index 78f75df0204b50835800cfbf1058069c7e1998d5..db0baf5ba6563a131ab7ca6242cca322d8cf2d52 100644 (file)
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
 #include "toolbox/hashtable.h"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/options.h"
 
index a09239243c2e1b46069a6a370a0cfcefe7d92e5e..118883f720c09c21215ae8d55979395389073968 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "md-abi.h"                           /* required for TRACE_ARGS_NUM */
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/thread.hpp"
 
index 518c757b167aa39bdd85e7b37ad561993d5679f5..530e38e961df18815c5fbcac4e63ad08a27a6d0d 100644 (file)
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index 9be1a6fdf57352a18aebed489cafab28132f1169..027ff15021a2870310213db23eb57242bb380992 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <stdint.h>
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 
 #include "vm/jit/ir/instruction.hpp"
 
index c9f3e30753d9d6c2478a30467e95ca3f7fe30608..cfbaead66282590a3cfca3300b19b61f70231cae 100644 (file)
@@ -35,7 +35,7 @@ typedef struct insinfo_inline insinfo_inline;
 
 #include <stdint.h>
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 
 #include "vm/jit/jit.hpp"
 #include "vm/jit/replace.hpp"
index baaf5900f62eeedcb16ce7aee9dbaa6e9ce91ac1..2da94922a2cccd49e8a876dcb7ae6a67ecb8ba07 100644 (file)
 
 #include "md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "threads/mutex.hpp"
 
index 379f6de8ad79f3c424704e1a135d1a5db12ea57c..7a19b1dfb91701f4497471c999d677859039eee2 100644 (file)
@@ -30,7 +30,7 @@
 
 #include <algorithm>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/list.hpp"
 
index 211e492bde7e519dbeb908ffbeac72f5714d2c5a..4bf02301d492c826fb1f37e98998a742d1c0d525 100644 (file)
@@ -32,8 +32,8 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/jit.hpp"
 #include "vm/jit/stack.h"
index 91f580d4bdcf3a21cfdbad0d4ac9a610df44bc66..9c420e5b842c978b9d98c0d694892c67deea9a82 100644 (file)
@@ -36,8 +36,8 @@
 
 #include <assert.h>
 
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 #include "vm/jit/jit.hpp"
 #include "vm/jit/loop/graph.h"
 #include "vm/jit/loop/loop.h"
index 56d4ee09ffd0cf9f9b3ac7d722471b09209b49c3..2a50956f0be31f4bb6316b80767adb6881ae8fc2 100644 (file)
@@ -40,8 +40,8 @@
 /*  #include <stdio.h> */
 #include <stdlib.h>
 
-#include "mm/memory.h"
-#include "toolbox/logging.h"
+#include "mm/memory.hpp"
+#include "toolbox/logging.hpp"
 #include "vm/global.h" 
 #include "vm/jit/jit.hpp"      
 #include "vm/jit/loop/loop.h"
index b2e295e6bae6245347f063701aec4752b2108eb9..78c4fab34a38b4f931dffd416023e444e5f826c3 100644 (file)
@@ -34,7 +34,7 @@
 */
 
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "vm/jit/builtin.hpp"
 #include "vm/resolve.hpp"
 #include "vm/jit/loop/loop.h"
index a6ad45abeef0244cfe0ed521ba3f4dd8acdce5fb..5c46894032a1423a32348317ed8de6b93f14b8be 100644 (file)
@@ -34,7 +34,7 @@
 #include "vm/jit/m68k/codegen.h"
 #include "vm/jit/m68k/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index 81fc1288f2d5ac61e799535cf29cbfecaccc7ccd..63d74a8e6f5fed954cc43ca0bbcbdddbddd6102d 100644 (file)
@@ -30,7 +30,7 @@
 #include "vm/jit/m68k/codegen.h"
 #include "vm/jit/m68k/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/builtin.hpp"
 
index c0358ea8d3a661d3e33a6d65c9abd9b4acacb8ae..6980ad21fd1d2d689733e8f4c1a5397270a09838 100644 (file)
@@ -1,9 +1,7 @@
 /* src/vm/jit/m68k/emit.h
  
-   Copyright (C) 1996-2005, 2006, 2007 R. Grafl, A. Krall, C. Kruegel,
-   C. Oates, R. Obermaisser, M. Platter, M. Probst, S. Ring,
-   E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich,
-   J. Wenninger, Institut f. Computersprachen - TU Wien
+   Copyright (C) 1996-2005, 2006, 2007, 2008
+   CACAOVM - Verein zur Foerderung der freien virtuellen Maschine CACAO
 
    This file is part of CACAO.
 
@@ -24,8 +22,9 @@
 
 */
 
-#ifndef _EMIT_H_
-#define _EMIT_H_
+
+#ifndef _EMIT_H
+#define _EMIT_H
 
 #include "config.h"
 
 
 void emit_mov_imm_reg (codegendata *cd, s4 imm, s4 dreg);
 void emit_mov_imm_areg(codegendata *cd, s4 imm, s4 dreg);
-void emit_verbosecall_enter(jitdata* jd);
-void emit_verbosecall_exit(jitdata* jd);
 
-#endif
+#endif /* _EMIT_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 21c54f56df80fc82f908b20d5cde9446d842ff3f..36e85035df313b7dc366bfcab3037a91f2029308 100644 (file)
@@ -28,7 +28,7 @@
 #include "vm/jit/m68k/md.h"
 #include "vm/jit/m68k/linux/md-abi.h"
 
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/vm.hpp"
 
 #include "vm/jit/asmpart.h"
index 186e7dcdf20bc490cf5d3d9bafa21a99d2d74e05..1bea411e74fadbe3f0a40f77ed81a2bb9ce33807 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "vm/jit/m68k/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "native/native.hpp"
 
 #include "vm/jit/builtin.hpp"
index 0cb513794b8f5998e0979b414544f812b6356bea..2d125364af7662db83fec266a87d513d0e53463c 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/avl.h"
 
index e81137a706df83df1b9f9581ae93a76d7d8efd1a..7fac7239123a0ac7950dab501895bae3951acce0 100644 (file)
@@ -35,7 +35,7 @@
 #include "vm/jit/mips/arch.h"
 #include "vm/jit/mips/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index fb41435ebd8bf88e3c02f9827346a2d2d3765c7f..98e9b451fe4c21059433141c593cf52245bc19ae 100644 (file)
@@ -32,7 +32,7 @@
 #include "vm/jit/mips/codegen.h"
 #include "vm/jit/mips/md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index 39117af25e977df19bae4686bfbf16433def1c09..9f6a87cbf46531220e2d7e07803f983cef8ed8d2 100644 (file)
@@ -38,7 +38,7 @@
 #include "mm/gc.hpp"
 
 #include "vm/global.h"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/codegen-common.hpp"
index f7b6601de5b8556c29b47905d88115ebc1df5156..e707d6ee2ec446aa96a1b707175c5c27c8c30cac 100644 (file)
@@ -38,9 +38,9 @@
 #include "vm/jit/mips/md-abi.h"
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
index 3b4be869c9e99f15e01b652a88f55dc2246e4276..da2af84aaae52957cb26bee8dd77ec23638f0339 100644 (file)
@@ -32,9 +32,9 @@
 
 #include "vm/jit/mips/md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 #include "vm/method.hpp"
 
index a5a5785b11810fa80ac1a1a8d2e5090f669822bb..d36ea67f3bc55ebb65f9e5963bdf3ea02056e1d1 100644 (file)
@@ -31,7 +31,7 @@
 #include "vm/jit/mips/codegen.h"
 #include "vm/jit/mips/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index 36e97a77f99a7bcfd8723c4b88a97690fe8309d7..9c6f44ee4c3b264e94da04b39ef6c4be4c4040d2 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "config.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/code.hpp"
 #include "vm/jit/oprofile-agent.hpp"
index 2d7044bc65b3ef3acfb74f60638e876275658180..722e2f04132fb5aac88bed890cf1d3ae92ca4791 100644 (file)
 #include <stdint.h>
 
 #include "mm/dumpmemory.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 
 #include "vm/class.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 #include "vm/references.h"
 #include "vm/resolve.hpp"
index 9fe830b3f8ed74d3c2dc2740634d4c6f6ebbb4ee..f2cb5c9c4462e70097d4d6e0e2d241586e7be204 100644 (file)
@@ -27,7 +27,7 @@
 
 #include "config.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 
index fdde38c0c9fa9ff75a0b245758ccaf3f9e69cce7..12a8ecfbdc2ed73f377a09f66f5500c932c35a86 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "config.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 
index 8abc257417b2040f789d205e178d9a2db701f732..317ae077f42a4157e973777df6ffe3e3c92eb452 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 #include "toolbox/worklist.h"
index 5ea6e55d1b46cf7a14cd8f3237cec715788c69b2..0c43e2c45dac783f4f6d77b957f9afe5ff5d9c6d 100644 (file)
@@ -31,7 +31,7 @@
 #include "arch.h"
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 
@@ -49,7 +49,7 @@
 
 #include "vm/jit/optimizing/lsra.h"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 extern const char *string_java_lang_InternalError;
 /* function prototypes */
index e397be6021bf31dc2313016d4226fadc7191a265..ea81010678fd9687b4a2c9eedd0dd736e67fdef3 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/threadlist.hpp"
 #include "threads/thread.hpp"
index 4f3d5242620b67f44ffe68e4489763e611596a73..29fdc80d9f72c25977930d110be5bf428b5da9ec 100644 (file)
@@ -28,7 +28,7 @@
 #include <assert.h>
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/condition.hpp"
 #include "threads/mutex.hpp"
index 2b135943f62a20f0473c95bf7340dfa646c8a183..3dd1819332d444339086b803614b9b6f178868af 100644 (file)
@@ -37,7 +37,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "vm/jit/jit.hpp"
 
 
index 357f323f6a9d3a8e1d2d2cd2fce0d6024b3a4d73..dd70dac52f9b42b881ae08d7760cfb97363b8443 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 #include "toolbox/worklist.h"
index ad1038a853d2902b2a48a6aa5f18f49585d3250d..07c89e32440f6071b9318d9f48befed406403f9e 100644 (file)
@@ -26,7 +26,7 @@
 
 #include "config.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 #include "toolbox/set.h"
index 3391d41dd4d2223fb82a4487d2f64b32b9da9861..88d9f95f503323f2cdc92e572adb1758f47e88e1 100644 (file)
@@ -43,7 +43,7 @@
 
 #include "vm/jit/jit.hpp"
 #include "vm/global.h"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "mm/dumpmemory.hpp"
 #include "toolbox/list.hpp"
 
index e79b1654d7be1452270a65c824c339a069977198..c21c06a962166b8dd5abde85ac250cc082b4f3c5 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 #include "toolbox/worklist.h"
index 87fdd130f76934a7e717f966a38113915dfb6158..98ae0d4c09c943b263db58f3d750449414a65dce 100644 (file)
@@ -28,7 +28,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "toolbox/bitvector.h"
 #include "toolbox/worklist.h"
index 63a15bb8960880051544123019bd3abda7a0e836..49fa5c2bcd570c4c86b609b12327a378b35c6059 100644 (file)
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
 #include "threads/lock.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
index b4799b3138184ab603afefb94ae348f42dab2a79..146e52834fd672135a7f368b5f892f7c155368f9 100644 (file)
 #include "codegen.h"                   /* for PATCHER_NOPS */
 #include "md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
 #include "toolbox/list.hpp"
-#include "toolbox/logging.h"           /* XXX remove me! */
+#include "toolbox/logging.hpp"           /* XXX remove me! */
 
 #include "vm/exceptions.hpp"
 #include "vm/initialize.hpp"
@@ -247,7 +247,13 @@ bool patcher_is_patched(patchref_t* pr)
        // instruction as the patcher structure contains.
        uint32_t mcode = *((uint32_t*) pr->mpc);
 
+#if PATCHER_CALL_SIZE == 4
        if (mcode != pr->mcode) {
+#elif PATCHER_CALL_SIZE == 2
+       if ((uint16_t) mcode != (uint16_t) pr->mcode) {
+#else
+#error Unknown PATCHER_CALL_SIZE
+#endif
                // The code differs.
                return false;
        }
@@ -301,7 +307,6 @@ java_handle_t *patcher_handler(u1 *pc)
        codeinfo      *code;
        patchref_t    *pr;
        bool           result;
-       java_handle_t *e;
 #if !defined(NDEBUG)
        patcher_function_list_t *l;
        int                      i;
@@ -387,10 +392,13 @@ java_handle_t *patcher_handler(u1 *pc)
        }
 #endif
 
-       /* check for return value and exit accordingly */
-
+       // Check for return value and exit accordingly.
        if (result == false) {
-               e = exceptions_get_and_clear_exception();
+               // Mangle the pending exception.
+               resolve_handle_pending_exception(true);
+
+               // Get the exception and return it.
+               java_handle_t* e = exceptions_get_and_clear_exception();
 
                code->patchers->unlock();
 
index dcfc0482e276bfe38417c7cbebd7ecc8ca58ab41..555f0cf8350dcdb650de97d349e35ab4fa183d28 100644 (file)
@@ -36,7 +36,7 @@
 #include "vm/jit/powerpc/arch.h"
 #include "vm/jit/powerpc/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index 68899b4eed91f0bd048674cd78691b49a7cbb961..35b7c48226739bd39e5160182c64d0b7c21880af 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "vm/jit/powerpc/darwin/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index d2e6bf2313e963153948df503ede60f17255d6aa..a809cfef206df309c76d2d0040331b143638ec6e 100644 (file)
@@ -39,7 +39,7 @@
 
 #include "vm/jit/builtin.hpp"
 #include "vm/global.h"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 
index 66221d67d115adbbdcd0aeec1ce1697bb31027db..9569377aad1d700a664beea758decf578d318057 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "vm/jit/powerpc/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index df5af31dbfbdf1d354915418c61458a22a099666..1282c5ee5c6fde83a034834780843aeb6c21507d 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "vm/jit/powerpc/linux/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index e59a84cbb1813b29b7e3f0194d8b4877e7041f74..5d2bf98e4a62ba77153fdddf5cdad099418258b9 100644 (file)
@@ -39,7 +39,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
index aa9caeb424cc5dba210566c91949ef7d161a8b6b..36dd169c3798aa17a0164944a2f75d2b26f50927 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "vm/jit/powerpc/netbsd/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index a18683ef72475c94e1b79cf88d0e784706acd892..0fde3887cb54b9ab2179631830e309a9a8db3c0d 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "vm/jit/powerpc/netbsd/md-abi.h"
 
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.hpp"
index a4fc722b1de7077f4e5689b3c2918b3580021e45..b62294b5d948cf29ef1b1518351e43acec976137 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "vm/jit/powerpc/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index 6de89aaf0b6c5c16d65127a5f882d02e4e68a968..7c609638f81d49574abc9c015c5ecee2967a24bf 100644 (file)
@@ -37,7 +37,7 @@
 #include "vm/jit/powerpc64/arch.h"
 #include "vm/jit/powerpc64/codegen.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index 4e7a37f718c21b0200688098c29e828f78dc7257..0888baefe8a7696ca8e8db354b53a15ae67eec4d 100644 (file)
@@ -29,7 +29,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "md-abi.h"
 #include "vm/jit/powerpc64/codegen.h"
index 68f1ae5e768a8f47acb1eed3089f9ed0d2909d39..e77ff4806166704c44b50e9798bbd3ae402f3407 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "vm/jit/powerpc64/linux/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index ebb284b4410cf7cba3fbd8fedef59dcdf2363d7a..203cb007c24e4e673ae2037242b3dbfa7ac3d79d 100644 (file)
@@ -39,7 +39,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/os.hpp"
 
 #include "vm/jit/asmpart.h"
index 9e1799c2296270d680a9243dd4d27786a04991a6..c923f84484df325666cd3cf0e4b6e3ea77fe15b8 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "vm/jit/powerpc64/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
index 3829d98651bcb3169a3434c88c365f9a35ed9cf6..8dff2425134056e04f727d2b2641da7edee7dede 100644 (file)
@@ -34,7 +34,7 @@
 #include "arch.h"
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "vm/jit/abi.h"
 #include "vm/jit/reg.h"
 
index 427f0746a9228bf04242c82e96af16aaaa0098fc..94b0b1edb06932ddf640baee19d618a033c03082 100644 (file)
 #endif
 
 #include "mm/dumpmemory.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/classcache.hpp"
 #include "vm/globals.hpp"
index f69e661fb8f8a64fc5a4d8cccc5442923820b369..b2780c05b58b1f3705da23e56a1a428e916b49ca 100644 (file)
@@ -37,7 +37,7 @@
 #include "native/localref.hpp"
 #include "native/native.hpp"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index ef5c2289c0135f08b54fb810b268fa5aa0ee566a..f4ed94218354bd2aee426b0a7943eb657343e3ac 100644 (file)
@@ -31,7 +31,7 @@
 #include "vm/jit/s390/emit.h"
 #include "vm/jit/s390/md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index 95ad22ac5d0e1e6be847fa5f99c2d56d075a872f..474b7ff2ac0f0f07f0e5cbe0940483f16cdaf6ae 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "config.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 #include "vm/types.h"
 
index 5e11280ac1dc33ceeb731e5cd3ec03929b100126..0788e45a16cd0ff09be8918b80c1ae3d80960963 100644 (file)
@@ -37,7 +37,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/exceptions.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/abi.h"
index 1add8371907da523544b80c3f0dbe8479616def7..21054fd8aae3102c027ca278973e71d5a2810de4 100644 (file)
@@ -28,7 +28,7 @@
 #include <assert.h>
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "native/native.hpp"
 
 #include "vm/jit/builtin.hpp"
index 894821011cf8f1a252cdc7d3172dbcd8cd881df6..294e4d802a5e99cb1c629f59dd8a28e494a15dd4 100644 (file)
@@ -40,7 +40,7 @@
 
 #include "disass.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include "vm/options.h"
 #include "vm/statistics.h"
 #include "vm/jit/schedule/schedule.h"
index e0ba2a3cfaa9de1257e145af3606709e6216a40f..2019644e43fd30c238b8e11f06b90d5b787e8658 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index b048fbe3272e933413752b0fe8aa8da7966f299d..1de656e749b74e8aefc6ce82f545b00b1dfbc682 100644 (file)
@@ -37,7 +37,7 @@
 #include "vm/jit/sparc64/codegen.h"
 #include "vm/jit/sparc64/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index e7f8f379e6b21bfebf2ecf4a2e1fb8b8d7bcd2dd..0c71d11a786dad601fb80cc9fea719a3fc1f54f4 100644 (file)
@@ -33,7 +33,7 @@
 #include "vm/jit/sparc64/md-abi.h"
 #include "vm/jit/sparc64/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/options.h"
index e1cdfdb9f08de767d5931942ad77fa128b0711a5..97c10e3f6d42808c6329fcf7ff7063ff89a8c606 100644 (file)
@@ -34,7 +34,7 @@
 #include "vm/jit/sparc64/codegen.h"
 #include "vm/jit/sparc64/md-abi.h"
 
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.hpp"
index cc12be598716a5abb965949cc178b629d7e566ff..3218d422894bf39f9fb9d195a57845d2a48255e7 100644 (file)
 
 #include "vm/jit/sparc64/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
 #include "vm/jit/stack.h"
 
 /* temp */
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 #include <assert.h>
 
 
index c36a5abc7bcdcfe40e5d19a978642b0d8a3fe49f..61043c3c2811ecdf43a96533739e244042cd482d 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/sparc64/codegen.h"
 #include "vm/jit/sparc64/md.h"
index 7c4c802a84d1c7bc3a27784cdc854854300ba231..8b13aa3f80d2fa1bbd5847e402ee68cf4c06db9b 100644 (file)
@@ -37,7 +37,7 @@
 #include "vm/jit/sparc64/codegen.h"
 #include "vm/jit/sparc64/md-abi.h"
 
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.hpp"
index 8c7ad97c3c9bab8c95dca5327998f05532f08eeb..06ff37115626da6f2912bdc61d1b873756025f46 100644 (file)
 #include "arch.h"
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/exceptions.hpp"
index 9b63c7e176ea5e99c2af50f6fa33346d91ca674f..8efa4b25bcfe75e72a730f6f78fbaae542274ab6 100644 (file)
@@ -35,7 +35,7 @@
 #include "md.h"
 
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/jit/stacktrace.hpp"
 
@@ -43,7 +43,7 @@
 
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/array.hpp"
 #include "vm/jit/builtin.hpp"
@@ -674,6 +674,129 @@ java_handle_bytearray_t *stacktrace_get_current(void)
 }
 
 
+/**
+ * Creates a java.lang.StackTraceElement for one element of the given
+ * stacktrace.
+ *
+ * @param st Given stacktrace.
+ * @param index Index of element inside stacktrace.
+ * @return The filled StackTraceElement object.
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_t* stacktrace_get_StackTraceElement(stacktrace_t* st, int32_t index)
+{
+       assert(st != NULL);
+
+       if ((index < 0) || (index >= st->length)) {
+               /* XXX This should be an IndexOutOfBoundsException (check this
+                  again). */
+               exceptions_throw_arrayindexoutofboundsexception();
+               return NULL;
+       }
+
+       // Get the stacktrace entry.
+       stacktrace_entry_t* ste = &(st->entries[index]);
+
+       // Get the codeinfo, methodinfo and classinfo.
+       codeinfo*   code = ste->code;
+       methodinfo* m    = code->m;
+       classinfo*  c    = m->clazz;
+
+       // Get filename.
+       java_handle_t* filename;
+
+       if (!(m->flags & ACC_NATIVE)) {
+               if (c->sourcefile != NULL)
+                       filename = javastring_new(c->sourcefile);
+               else
+                       filename = NULL;
+       }
+       else
+               filename = NULL;
+
+       // Get line number.
+       int32_t linenumber;
+
+       if (m->flags & ACC_NATIVE) {
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+               linenumber = -1;
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+               linenumber = -2;
+#else
+# error unknown classpath configuration
+#endif
+       }
+       else {
+               // FIXME linenumbertable->find could change the methodinfo
+               // pointer when hitting an inlined method.
+               linenumber = code->linenumbertable->find(&m, ste->pc);
+               linenumber = (linenumber == 0) ? -1 : linenumber;
+       }
+
+       // Get declaring class name.
+       java_handle_t* declaringclass = class_get_classname(c);
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_GNU_CLASSPATH)
+       // Allocate a new StackTraceElement object.
+       java_handle_t* h = builtin_new(class_java_lang_StackTraceElement);
+
+       if (h == NULL)
+                       return NULL;
+
+       java_lang_StackTraceElement jlste(h, filename, linenumber, declaringclass, javastring_new(m->name), ((m->flags & ACC_NATIVE) ? 1 : 0));
+#elif defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       // Allocate a new StackTraceElement object.
+       java_lang_StackTraceElement jlste(declaringclass, javastring_new(m->name), filename, linenumber);
+
+       if (jlste.is_null())
+               return NULL;
+#else
+# error unknown classpath configuration
+#endif
+
+       return jlste.get_handle();
+}
+#endif
+
+
+/**
+ * Creates a complete array of java.lang.StackTraceElement objects
+ * for the given stacktrace.
+ *
+ * @param st Given stacktrace.
+ * @return Array of filled StackTraceElement objects.
+ */
+#if defined(ENABLE_JAVASE)
+java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t* st)
+{
+       // Get length of stacktrace. If stacktrace is not available
+       // an empty array should be returned.
+       int32_t length = (st != NULL) ? st->length : 0;
+
+       // Create the stacktrace element array.
+       java_handle_objectarray_t* oa = builtin_anewarray(length, class_java_lang_StackTraceElement);
+
+       if (oa == NULL)
+               return NULL;
+
+       // Iterate over all stacktrace elements.
+       for (int i = 0; i < length; i++) {
+
+               // Get stacktrace element at current index.
+               java_handle_t* h = stacktrace_get_StackTraceElement(st, i);
+
+               if (h == NULL)
+                       return NULL;
+
+               // Store stacktrace element in array.
+               array_objectarray_element_set(oa, i, h);
+       }
+
+       return oa;
+}
+#endif
+
+
 /* stacktrace_get_caller_class *************************************************
 
    Get the class on the stack at the given depth.  This function skips
@@ -1187,6 +1310,36 @@ void stacktrace_print_current(void)
 }
 
 
+/**
+ * Creates a stacktrace for the given thread.
+ *
+ * @param t Given thread.
+ * @return Current stacktrace of the given thread.
+ *
+ * XXX: Creation of the stacktrace starts at the most recent
+ * stackframeinfo block. If the thread is not inside the native
+ * world, the created stacktrace is not complete!
+ */
+#if defined(ENABLE_THREADS)
+stacktrace_t* stacktrace_get_of_thread(threadobject* t)
+{
+       stackframeinfo_t*        sfi;
+       java_handle_bytearray_t* ba;
+       stacktrace_t*            st;
+
+       sfi = t->_stackframeinfo;
+       ba  = stacktrace_get(sfi);
+
+       if (ba == NULL)
+               return NULL;
+
+       st  = (stacktrace_t*) LLNI_array_data(ba);
+
+       return st;
+}
+#endif
+
+
 /* stacktrace_print_of_thread **************************************************
 
    Print the current stacktrace of the given thread.
index 6aa0ecf5baf2553dda180c58ee84c3e8a796495d..2c2920c826b55de4d14e1b517dd824f176b06fce 100644 (file)
@@ -106,6 +106,8 @@ java_handle_bytearray_t   *stacktrace_get(stackframeinfo_t *sfi);
 java_handle_bytearray_t   *stacktrace_get_current(void);
 
 #if defined(ENABLE_JAVASE)
+java_handle_t*             stacktrace_get_StackTraceElement(stacktrace_t *st, int32_t index);
+java_handle_objectarray_t* stacktrace_get_StackTraceElements(stacktrace_t *st);
 classinfo                 *stacktrace_get_caller_class(int depth);
 classloader_t             *stacktrace_first_nonnull_classloader(void);
 java_handle_objectarray_t *stacktrace_getClassContext(void);
@@ -117,6 +119,7 @@ void                       stacktrace_print(stacktrace_t *st);
 void                       stacktrace_print_current(void);
 
 #if defined(ENABLE_THREADS)
+stacktrace_t*              stacktrace_get_of_thread(threadobject *t);
 void                       stacktrace_print_of_thread(threadobject *t);
 #endif
 
index 91a36557323fa150643bce6d55e14576d0fed7b9..98667f76cc0692b9ef3a08a1fd9e5dcbbe01f98a 100644 (file)
 #include "arch.h"
 #include "md-abi.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/global.h"
 #include "vm/globals.hpp"
index 1ac7ffe7e71e6d016b8d3a8594b75da78803f214..a5ab45182a04089a685ee0ce89b04447b757ab09 100644 (file)
 #include "md.h"
 #include "md-trap.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/exceptions.hpp"
 #include "vm/options.h"
index 8ac6267b802f65a9dbff59bddd52761a238fc15d..6d0566268cc0e3fa32c3a98cb8e791fcfc9387e9 100644 (file)
@@ -30,7 +30,7 @@
 #include "vm/types.h"
 
 #include "vm/jit/builtin.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/array.hpp"
 #include "vm/exceptions.hpp"
index 7626890762e3150811d039daf9e155ccc5bb11c3..4f69f8e3e2000b3e6d1b92e4dc288990f9f7914b 100644 (file)
 #include <assert.h>
 #include <string.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/access.hpp"
 #include "vm/array.hpp"
index d63c422007abe0180f8f967c261d7f63df2d2489..d4687166af45f9eb6814a8d46582a857b04d1c86 100644 (file)
@@ -141,11 +141,11 @@ error reporting.
 
 #ifdef ENABLE_VERIFIER
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/access.hpp"
 #include "vm/array.hpp"
index 4df771a9da68dccb5f8fadefd9aa365a749ab21c..0e6f46dc831b0a608f1797f0437d732864247a2a 100644 (file)
 #include <assert.h>
 #include <string.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/array.hpp"
 #include "vm/class.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/globals.hpp"
 #include "vm/loader.hpp"
@@ -44,9 +44,6 @@
 #include "vm/jit/jit.hpp"
 #include "vm/jit/verify/typeinfo.hpp"
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
 
 /* check if a linked class is an array class. Only use for linked classes! */
 #define CLASSINFO_IS_ARRAY(clsinfo)  ((clsinfo)->vftbl->arraydesc != NULL)
@@ -2550,10 +2547,6 @@ typevector_print(FILE *file,varinfo *vec,int size)
     }
 }
 
-#if defined(__cplusplus)
-}
-#endif
-
 #endif /* TYPEINFO_DEBUG */
 
 
index 96f4967bc9f052f7a74ea741adf8dee33a2389bd..80c81af88b5c59ba9345d556d9b92f0adf58839d 100644 (file)
@@ -37,7 +37,7 @@
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/localref.hpp"
 #include "native/native.hpp"
index 9c777fb54a558b0545c5177ea11a2fdea6107ae3..5f6f0d87a76fcfa7323255f0f2b4ba83246806a5 100644 (file)
@@ -33,7 +33,7 @@
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/emit.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/lock.hpp"
 
index 4b683342a409e8298af3c8e412e57cb0b6db21e5..fd9244d33d4553012885a1821d94213db37cf46d 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "threads/thread.hpp"
 
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/stacktrace.hpp"
index 5036ff2ef64da28a635ca2bb0d7f61670ae04b61..1c30b8bbf94fac72d746b7f3256e047461f258f6 100644 (file)
@@ -40,7 +40,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
@@ -260,6 +260,22 @@ void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p)
        xpc = (u1 *) _mc->gregs[REG_RIP];
        ra  = xpc;                          /* return address is equal to xpc     */
 
+       // Check if the trap instruction is valid.
+       // TODO Move this into patcher_handler.
+       if (patcher_is_valid_trap_instruction_at(xpc) == false) {
+               // Check if the PC has been patched during our way to this
+               // signal handler (see PR85).
+               if (patcher_is_patched_at(xpc) == true)
+                       return;
+
+               // We have a problem...
+               log_println("md_signal_handler_sigill: Unknown illegal instruction at 0x%lx", xpc);
+#if defined(ENABLE_DISASSEMBLER)
+               (void) disassinstr(xpc);
+#endif
+               vm_abort("Aborting...");
+       }
+
        /* This is a patcher. */
 
        type = TRAP_PATCHER;
index fd248a596b4743b2fee491ed2acc697a56b58653..10dd05b45d7455b3178fa02b916ecad2da4e6d6f 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "vm/jit/x86_64/md-abi.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 
 #include "vm/jit/abi.h"
index 32008300ec1111a032adfaa2beb18ff5375101e1..ae4b7aa2131eb14c9949dca08ab808ba38f185ab 100644 (file)
@@ -32,7 +32,7 @@
 #include "vm/jit/x86_64/codegen.h"
 #include "vm/jit/x86_64/md.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
@@ -59,6 +59,21 @@ void patcher_patch_code(patchref_t *pr)
        md_icacheflush((void*) pr->mpc, PATCHER_CALL_SIZE);
 }
 
+/**
+ * Check if the trap instruction at the given PC is valid.
+ *
+ * @param pc Program counter.
+ *
+ * @return true if valid, false otherwise.
+ */
+bool patcher_is_valid_trap_instruction_at(void* pc)
+{
+       uint16_t mcode = *((uint16_t*) pc);
+
+       // Check for the undefined instruction we use.
+       return (mcode == 0x0b0f);
+}
+
 
 /* patcher_resolve_classref_to_classinfo ***************************************
 
index 14824a49e62a305f34c122b52b9873e24abb0b4e..cce569be9344dbbb9bc937103d9c7d1e99efb58e 100644 (file)
@@ -38,7 +38,7 @@
 #include "threads/thread.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 
 #include "vm/jit/asmpart.h"
 #include "vm/jit/executionstate.h"
index 50639b736310468fe801800ded6d5af43b443748..b1bd60a427ca66815990cf6269939f03395e75be 100644 (file)
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/native.hpp"
 
 #include "threads/lock.hpp"
 #include "threads/mutex.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/access.hpp"
 #include "vm/array.hpp"
@@ -1108,8 +1108,8 @@ static arraydescriptor *link_array(classinfo *c)
                        desc->elementvftbl = compvftbl->arraydesc->elementvftbl;
 
                        if (compvftbl->arraydesc->dimension >= 255) {
-                               log_text("Creating array of dimension >255");
-                               assert(0);
+                               exceptions_throw_illegalargumentexception();
+                               return NULL;
                        }
 
                        desc->dimension = compvftbl->arraydesc->dimension + 1;
index 81ab0ad8594bd06ec0cd27cb3a0c5f6401db6209..7bc8ff4a177568738f2648857c824ef74c470099 100644 (file)
 #include "vm/types.h"
 
 #include "mm/dumpmemory.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
 #include "threads/mutex.hpp"
 
 #include "toolbox/hashtable.h"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/jit/builtin.hpp"
 #include "vm/classcache.hpp"
@@ -61,7 +61,7 @@
 
 
 #if defined(ENABLE_JAVASE)
-# include "vm/annotation.h"
+# include "vm/annotation.hpp"
 # include "vm/stackmap.h"
 #endif
 
index 3e30e4a278335bbac03f62261085155852ae7131..b452176cb3b299760fb02518099a5b0da4159e7d 100644 (file)
@@ -37,7 +37,7 @@ typedef struct classbuffer classbuffer;
 
 #include "vm/types.h"
 
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/class.hpp"
 #include "vm/global.h"
 #include "vm/method.hpp"
index 59cafe93498863b05ff48ddca47e6add7ff9ecb0..21f542400075da4e55c13da38236e24826c61996 100644 (file)
@@ -31,7 +31,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
index b7e12c8d63039605bc138b25ba1daea765028fb2..6fbc0c153d9a71e6d6020230a41eae21fcee2965 100644 (file)
@@ -41,7 +41,7 @@ typedef struct codeinfo            codeinfo;
 #include "threads/mutex.hpp"
 
 #include "vm/jit/builtin.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/global.h"
 #include "vm/linker.hpp"
 #include "vm/loader.hpp"
index 3c3bace7016621d07fa95fe0ddd201a9e4549b13..b5b88a710336ff78ef428488af5da03a10489230 100644 (file)
@@ -30,7 +30,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/options.h"
 #include "vm/os.hpp"
index 66de93d5155630e879a91ecd66cb3e81a2b945bb..052c0a370da758378dfb04365d88079499e86bb3 100644 (file)
@@ -145,6 +145,7 @@ public:
        static inline int     mprotect(void* addr, size_t len, int prot);
        static inline ssize_t readlink(const char* path, char* buf, size_t bufsiz);
        static inline int     scandir(const char* dir, struct dirent*** namelist, int(*filter)(const struct dirent*), int(*compar)(const void*, const void*));
+       static inline ssize_t send(int s, const void* buf, size_t len, int flags);
        static inline int     setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen);
        static inline int     shutdown(int s, int how);
        static inline int     socket(int domain, int type, int protocol);
@@ -527,6 +528,16 @@ inline int os::scandir(const char *dir, struct dirent ***namelist, int(*filter)(
 #endif
 }
 
+inline ssize_t os::send(int s, const void* buf, size_t len, int flags)
+{
+       // TODO Should be restartable on Linux and interruptible on Solaris.
+#if defined(HAVE_SEND)
+       return ::send(s, buf, len, flags);
+#else
+# error send not available
+#endif
+}
+
 inline int os::setsockopt(int s, int level, int optname, const void* optval, socklen_t optlen)
 {
 #if defined(HAVE_SETSOCKOPT)
index a112aca2f7d95045bea1a33d1acd41fabc8d4a81..f5287bf15b0841dd06696348086e1ca4fb0df4f5 100644 (file)
@@ -27,7 +27,7 @@
 
 #include <stdint.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/options.h"
 #include "vm/package.hpp"
index f5b66db4d3b487236a19f6461e24ebd148877eba..e2f3858388d5e1cb33a64280c60d52102efe0ce4 100644 (file)
@@ -34,7 +34,7 @@
 #include <unistd.h>
 #include <sys/utsname.h>
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
index be2455b0047c1d4b35c274df36c8d7661ec5641d..f880b7913d42bc5855043dae63819d0d3b1ae47c 100644 (file)
@@ -62,7 +62,7 @@ typedef union parseddesc {
 #include "vm/types.h"
 
 #include "vm/class.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/field.hpp"
 #include "vm/global.h"
 #include "vm/method.hpp"
index d4b4e969939ae84fd73996b53607ae67cd64ecb0..80d8a4a11561bb371c8d4cf016a8f91d3a2224ab 100644 (file)
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/access.hpp"
 #include "vm/classcache.hpp"
-#include "vm/descriptor.h"
+#include "vm/descriptor.hpp"
 #include "vm/exceptions.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
index 2064de2d02d0a2c5732b146baba78bf1c5a38f44..04384f85307f1486adc1fc85a4cd97935ef9bde1 100644 (file)
@@ -32,7 +32,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/global.h"
 #include "vm/rt-timing.h"
index 26d31a41b267a337c5e97e14996d0db860d4e082..0c18ac0a5f0d6098aea182cb6c58c7a8518de562 100644 (file)
@@ -34,7 +34,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/global.h"
 
diff --git a/src/vm/signal.c b/src/vm/signal.c
deleted file mode 100644 (file)
index ed7d495..0000000
+++ /dev/null
@@ -1,401 +0,0 @@
-/* src/vm/signal.c - machine independent signal 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 <signal.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#if defined(__DARWIN__)
-/* If we compile with -ansi on darwin, <sys/types.h> is not
- included. So let's do it here. */
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-
-#include "arch.h"
-
-#if defined(ENABLE_GC_BOEHM)
-# include "mm/memory.h"
-#endif
-
-#include "threads/thread.hpp"
-#include "threads/threadlist.hpp"
-
-#include "vm/exceptions.hpp"
-#include "vm/globals.hpp"
-#include "vm/method.hpp"
-#include "vm/options.h"
-#include "vm/signallocal.h"
-#include "vm/vm.hpp"
-
-#if defined(ENABLE_STATISTICS)
-# include "vm/statistics.h"
-#endif
-
-
-/* function prototypes ********************************************************/
-
-void signal_handler_sighup(int sig, siginfo_t *siginfo, void *_p);
-
-
-/* signal_init *****************************************************************
-
-   Initializes the signal subsystem and installs the signal handler.
-
-*******************************************************************************/
-
-bool signal_init(void)
-{
-#if !defined(__CYGWIN__)
-       sigset_t mask;
-
-       TRACESUBSYSTEMINITIALIZATION("signal_init");
-
-#if defined(__LINUX__) && defined(ENABLE_THREADS)
-       /* XXX Remove for exact-GC. */
-       if (threads_pthreads_implementation_nptl) {
-#endif
-
-       /* Block the following signals (SIGINT for <ctrl>-c, SIGQUIT for
-          <ctrl>-\).  We enable them later in signal_thread, but only for
-          this thread. */
-
-       if (sigemptyset(&mask) != 0)
-               vm_abort_errno("signal_init: sigemptyset failed");
-
-#if !defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       /* Let OpenJDK handle SIGINT itself. */
-
-       if (sigaddset(&mask, SIGINT) != 0)
-               vm_abort_errno("signal_init: sigaddset failed");
-#endif
-
-#if !defined(__FREEBSD__)
-       if (sigaddset(&mask, SIGQUIT) != 0)
-               vm_abort_errno("signal_init: sigaddset failed");
-#endif
-
-       if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
-               vm_abort_errno("signal_init: sigprocmask failed");
-
-#if defined(__LINUX__) && defined(ENABLE_THREADS)
-       /* XXX Remove for exact-GC. */
-       }
-#endif
-
-#if defined(ENABLE_GC_BOEHM)
-       /* Allocate something so the garbage collector's signal handlers
-          are installed. */
-
-       (void) GCNEW(int);
-#endif
-
-       /* Install signal handlers for signals we want to catch in all
-          threads. */
-
-#if defined(ENABLE_JIT)
-# if defined(ENABLE_INTRP)
-       if (!opt_intrp) {
-# endif
-               /* SIGSEGV handler */
-
-               signal_register_signal(SIGSEGV, (functionptr) md_signal_handler_sigsegv,
-                                                          SA_NODEFER | SA_SIGINFO);
-
-#  if defined(SIGBUS)
-               signal_register_signal(SIGBUS, (functionptr) md_signal_handler_sigsegv,
-                                                          SA_NODEFER | SA_SIGINFO);
-#  endif
-
-#  if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
-               /* SIGFPE handler */
-
-               signal_register_signal(SIGFPE, (functionptr) md_signal_handler_sigfpe,
-                                                          SA_NODEFER | SA_SIGINFO);
-#  endif
-
-#  if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__)
-               /* XXX use better defines for that (in arch.h) */
-               /* SIGILL handler */
-
-               signal_register_signal(SIGILL, (functionptr) md_signal_handler_sigill,
-                                                          SA_NODEFER | SA_SIGINFO);
-#  endif
-
-#  if defined(__POWERPC__)
-               /* XXX use better defines for that (in arch.h) */
-               /* SIGTRAP handler */
-
-               signal_register_signal(SIGTRAP, (functionptr) md_signal_handler_sigtrap,
-                                                          SA_NODEFER | SA_SIGINFO);
-#  endif
-# if defined(ENABLE_INTRP)
-       }
-# endif
-
-#if defined(__DARWIN__)
-       do {
-               struct utsname name;
-               kern_return_t kr;
-
-               /* Check if we're on 10.4 (Tiger/8.x) or earlier */
-               if (uname(&name) != 0) 
-                       break;
-
-               /* Make sure the string is large enough */
-               /* Check the major number (ascii comparison) */
-               /* Verify that we're not looking at '10.' by checking for a trailing period. */
-               if (name.release[0] == '\0' || name.release[0] > '8' || name.release[1] != '.')
-                       break;
-
-               /* Reset CrashReporter's task signal handler */
-               kr = task_set_exception_ports(mach_task_self(),
-                                                                         EXC_MASK_BAD_ACCESS
-#  if defined(__I386__)
-                                                                         | EXC_MASK_BAD_INSTRUCTION
-#endif
-                                                                         , MACH_PORT_NULL,
-                                                                         EXCEPTION_STATE_IDENTITY,
-                                                                         MACHINE_THREAD_STATE);
-
-               assert(kr == KERN_SUCCESS);
-       } while (false);
-#endif
-#endif /* !defined(ENABLE_JIT) */
-
-#if defined(ENABLE_THREADS)
-       /* SIGHUP handler for threads_thread_interrupt */
-
-       signal_register_signal(Signal_INTERRUPT_SYSTEM_CALL, (functionptr) signal_handler_sighup, 0);
-#endif
-
-#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
-       /* SIGUSR1 handler for the exact GC to suspend threads */
-
-       signal_register_signal(SIGUSR1, (functionptr) md_signal_handler_sigusr1,
-                                                  SA_SIGINFO);
-#endif
-
-#if defined(ENABLE_THREADS) && defined(ENABLE_PROFILING)
-       /* SIGUSR2 handler for profiling sampling */
-
-       signal_register_signal(SIGUSR2, (functionptr) md_signal_handler_sigusr2,
-                                                  SA_SIGINFO);
-#endif
-
-#endif /* !defined(__CYGWIN__) */
-
-       return true;
-}
-
-
-/* signal_register_signal ******************************************************
-
-   Register the specified handler with the specified signal.
-
-*******************************************************************************/
-
-void signal_register_signal(int signum, functionptr handler, int flags)
-{
-       struct sigaction act;
-
-       void (*function)(int, siginfo_t *, void *);
-
-       function = (void (*)(int, siginfo_t *, void *)) handler;
-
-       if (sigemptyset(&act.sa_mask) != 0)
-               vm_abort_errno("signal_register_signal: sigemptyset failed");
-
-       act.sa_sigaction = function;
-       act.sa_flags     = flags;
-
-       if (sigaction(signum, &act, NULL) != 0)
-               vm_abort_errno("signal_register_signal: sigaction failed");
-}
-
-
-/* signal_thread ************************************************************
-
-   This thread sets the signal mask to catch the user input signals
-   (SIGINT, SIGQUIT).  We use such a thread, so we don't get the
-   signals on every single thread running.
-
-*******************************************************************************/
-
-static void signal_thread(void)
-{
-       threadobject *t;
-       sigset_t      mask;
-       int           sig;
-       int result;
-
-       t = THREADOBJECT;
-
-       if (sigemptyset(&mask) != 0)
-               vm_abort_errno("signal_thread: sigemptyset failed");
-
-#if !defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       /* Let OpenJDK handle SIGINT itself. */
-
-       if (sigaddset(&mask, SIGINT) != 0)
-               vm_abort_errno("signal_thread: sigaddset failed");
-#endif
-
-#if !defined(__FREEBSD__)
-       if (sigaddset(&mask, SIGQUIT) != 0)
-               vm_abort_errno("signal_thread: sigaddset failed");
-#endif
-
-       for (;;) {
-               /* just wait for a signal */
-
-#if defined(ENABLE_THREADS)
-               thread_set_state_waiting(t);
-#endif
-
-               // sigwait can return EINTR (unlike what the Linux man-page
-               // says).
-               do {
-                       result = sigwait(&mask, &sig);
-               } while (result == EINTR);
-
-               if (result != 0)
-                       vm_abort_errnum(result, "signal_thread: sigwait failed");
-
-#if defined(ENABLE_THREADS)
-               thread_set_state_runnable(t);
-#endif
-
-               /* Handle the signal. */
-
-               signal_thread_handler(sig);
-       }
-}
-
-
-/* signal_thread_handler *******************************************************
-
-   Handles the signals caught in the signal handler thread.  Also used
-   from sun.misc.Signal with OpenJDK.
-
-*******************************************************************************/
-
-void signal_thread_handler(int sig)
-{
-       switch (sig) {
-       case SIGINT:
-               /* exit the vm properly */
-
-               vm_exit(1);
-               break;
-
-       case SIGQUIT:
-               /* print a thread dump */
-#if defined(ENABLE_THREADS)
-               ThreadList_dump_threads();
-#endif
-
-#if defined(ENABLE_STATISTICS)
-               if (opt_stat)
-                       statistics_print_memory_usage();
-#endif
-               break;
-
-#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
-       default: {
-               // For OpenJDK we dispatch all unknown signals to Java.
-               methodinfo* m = class_resolvemethod(class_sun_misc_Signal, utf_dispatch, utf_int__void);
-               (void) vm_call_method(m, NULL, sig);
-
-               if (exceptions_get_exception()) {
-                       log_println("signal_thread_handler: Java signal handler throw an exception while dispatching signal %d:", sig);
-                       exceptions_print_stacktrace();
-                       vm_abort("signal_thread_handler: Aborting...");
-               }
-               break;
-       }
-#else
-       default:
-               vm_abort("signal_thread_handler: Unknown signal %d", sig);
-#endif
-       }
-}
-
-
-/* signal_start_thread *********************************************************
-
-   Starts the signal handler thread.
-
-*******************************************************************************/
-
-bool signal_start_thread(void)
-{
-#if defined(ENABLE_THREADS)
-       utf *name;
-
-       name = utf_new_char("Signal Handler");
-
-       if (!threads_thread_start_internal(name, signal_thread))
-               return false;
-
-       /* everything's ok */
-
-       return true;
-#else
-#warning FIX ME!
-#endif
-}
-
-
-/* signal_handler_sighup *******************************************************
-
-   This handler is required by threads_thread_interrupt and does
-   nothing.
-
-*******************************************************************************/
-
-#if defined(ENABLE_THREADS)
-void signal_handler_sighup(int sig, siginfo_t *siginfo, void *_p)
-{
-       /* do nothing */
-}
-#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:
- */
diff --git a/src/vm/signal.cpp b/src/vm/signal.cpp
new file mode 100644 (file)
index 0000000..15d6263
--- /dev/null
@@ -0,0 +1,401 @@
+/* src/vm/signal.c - machine independent signal 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 <signal.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#if defined(__DARWIN__)
+/* If we compile with -ansi on darwin, <sys/types.h> is not
+ included. So let's do it here. */
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
+
+#include "arch.h"
+
+#if defined(ENABLE_GC_BOEHM)
+# include "mm/memory.hpp"
+#endif
+
+#include "threads/thread.hpp"
+#include "threads/threadlist.hpp"
+
+#include "vm/exceptions.hpp"
+#include "vm/globals.hpp"
+#include "vm/method.hpp"
+#include "vm/options.h"
+#include "vm/signallocal.hpp"
+#include "vm/vm.hpp"
+
+#if defined(ENABLE_STATISTICS)
+# include "vm/statistics.h"
+#endif
+
+
+/* function prototypes ********************************************************/
+
+void signal_handler_sighup(int sig, siginfo_t *siginfo, void *_p);
+
+
+/* signal_init *****************************************************************
+
+   Initializes the signal subsystem and installs the signal handler.
+
+*******************************************************************************/
+
+bool signal_init(void)
+{
+#if !defined(__CYGWIN__)
+       sigset_t mask;
+
+       TRACESUBSYSTEMINITIALIZATION("signal_init");
+
+#if defined(__LINUX__) && defined(ENABLE_THREADS)
+       /* XXX Remove for exact-GC. */
+       if (threads_pthreads_implementation_nptl) {
+#endif
+
+       /* Block the following signals (SIGINT for <ctrl>-c, SIGQUIT for
+          <ctrl>-\).  We enable them later in signal_thread, but only for
+          this thread. */
+
+       if (sigemptyset(&mask) != 0)
+               vm_abort_errno("signal_init: sigemptyset failed");
+
+#if !defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       /* Let OpenJDK handle SIGINT itself. */
+
+       if (sigaddset(&mask, SIGINT) != 0)
+               vm_abort_errno("signal_init: sigaddset failed");
+#endif
+
+#if !defined(__FREEBSD__)
+       if (sigaddset(&mask, SIGQUIT) != 0)
+               vm_abort_errno("signal_init: sigaddset failed");
+#endif
+
+       if (sigprocmask(SIG_BLOCK, &mask, NULL) != 0)
+               vm_abort_errno("signal_init: sigprocmask failed");
+
+#if defined(__LINUX__) && defined(ENABLE_THREADS)
+       /* XXX Remove for exact-GC. */
+       }
+#endif
+
+#if defined(ENABLE_GC_BOEHM)
+       /* Allocate something so the garbage collector's signal handlers
+          are installed. */
+
+       (void) GCNEW(int);
+#endif
+
+       /* Install signal handlers for signals we want to catch in all
+          threads. */
+
+#if defined(ENABLE_JIT)
+# if defined(ENABLE_INTRP)
+       if (!opt_intrp) {
+# endif
+               /* SIGSEGV handler */
+
+               signal_register_signal(SIGSEGV, (functionptr) md_signal_handler_sigsegv,
+                                                          SA_NODEFER | SA_SIGINFO);
+
+#  if defined(SIGBUS)
+               signal_register_signal(SIGBUS, (functionptr) md_signal_handler_sigsegv,
+                                                          SA_NODEFER | SA_SIGINFO);
+#  endif
+
+#  if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
+               /* SIGFPE handler */
+
+               signal_register_signal(SIGFPE, (functionptr) md_signal_handler_sigfpe,
+                                                          SA_NODEFER | SA_SIGINFO);
+#  endif
+
+#  if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__)
+               /* XXX use better defines for that (in arch.h) */
+               /* SIGILL handler */
+
+               signal_register_signal(SIGILL, (functionptr) md_signal_handler_sigill,
+                                                          SA_NODEFER | SA_SIGINFO);
+#  endif
+
+#  if defined(__POWERPC__)
+               /* XXX use better defines for that (in arch.h) */
+               /* SIGTRAP handler */
+
+               signal_register_signal(SIGTRAP, (functionptr) md_signal_handler_sigtrap,
+                                                          SA_NODEFER | SA_SIGINFO);
+#  endif
+# if defined(ENABLE_INTRP)
+       }
+# endif
+
+#if defined(__DARWIN__)
+       do {
+               struct utsname name;
+               kern_return_t kr;
+
+               /* Check if we're on 10.4 (Tiger/8.x) or earlier */
+               if (uname(&name) != 0) 
+                       break;
+
+               /* Make sure the string is large enough */
+               /* Check the major number (ascii comparison) */
+               /* Verify that we're not looking at '10.' by checking for a trailing period. */
+               if (name.release[0] == '\0' || name.release[0] > '8' || name.release[1] != '.')
+                       break;
+
+               /* Reset CrashReporter's task signal handler */
+               kr = task_set_exception_ports(mach_task_self(),
+                                                                         EXC_MASK_BAD_ACCESS
+#  if defined(__I386__)
+                                                                         | EXC_MASK_BAD_INSTRUCTION
+#endif
+                                                                         , MACH_PORT_NULL,
+                                                                         EXCEPTION_STATE_IDENTITY,
+                                                                         MACHINE_THREAD_STATE);
+
+               assert(kr == KERN_SUCCESS);
+       } while (false);
+#endif
+#endif /* !defined(ENABLE_JIT) */
+
+#if defined(ENABLE_THREADS)
+       /* SIGHUP handler for threads_thread_interrupt */
+
+       signal_register_signal(Signal_INTERRUPT_SYSTEM_CALL, (functionptr) signal_handler_sighup, 0);
+#endif
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_GC_CACAO)
+       /* SIGUSR1 handler for the exact GC to suspend threads */
+
+       signal_register_signal(SIGUSR1, (functionptr) md_signal_handler_sigusr1,
+                                                  SA_SIGINFO);
+#endif
+
+#if defined(ENABLE_THREADS) && defined(ENABLE_PROFILING)
+       /* SIGUSR2 handler for profiling sampling */
+
+       signal_register_signal(SIGUSR2, (functionptr) md_signal_handler_sigusr2,
+                                                  SA_SIGINFO);
+#endif
+
+#endif /* !defined(__CYGWIN__) */
+
+       return true;
+}
+
+
+/* signal_register_signal ******************************************************
+
+   Register the specified handler with the specified signal.
+
+*******************************************************************************/
+
+void signal_register_signal(int signum, functionptr handler, int flags)
+{
+       struct sigaction act;
+
+       void (*function)(int, siginfo_t *, void *);
+
+       function = (void (*)(int, siginfo_t *, void *)) handler;
+
+       if (sigemptyset(&act.sa_mask) != 0)
+               vm_abort_errno("signal_register_signal: sigemptyset failed");
+
+       act.sa_sigaction = function;
+       act.sa_flags     = flags;
+
+       if (sigaction(signum, &act, NULL) != 0)
+               vm_abort_errno("signal_register_signal: sigaction failed");
+}
+
+
+/* signal_thread ************************************************************
+
+   This thread sets the signal mask to catch the user input signals
+   (SIGINT, SIGQUIT).  We use such a thread, so we don't get the
+   signals on every single thread running.
+
+*******************************************************************************/
+
+static void signal_thread(void)
+{
+       threadobject *t;
+       sigset_t      mask;
+       int           sig;
+       int result;
+
+       t = THREADOBJECT;
+
+       if (sigemptyset(&mask) != 0)
+               vm_abort_errno("signal_thread: sigemptyset failed");
+
+#if !defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       /* Let OpenJDK handle SIGINT itself. */
+
+       if (sigaddset(&mask, SIGINT) != 0)
+               vm_abort_errno("signal_thread: sigaddset failed");
+#endif
+
+#if !defined(__FREEBSD__)
+       if (sigaddset(&mask, SIGQUIT) != 0)
+               vm_abort_errno("signal_thread: sigaddset failed");
+#endif
+
+       for (;;) {
+               /* just wait for a signal */
+
+#if defined(ENABLE_THREADS)
+               thread_set_state_waiting(t);
+#endif
+
+               // sigwait can return EINTR (unlike what the Linux man-page
+               // says).
+               do {
+                       result = sigwait(&mask, &sig);
+               } while (result == EINTR);
+
+               if (result != 0)
+                       vm_abort_errnum(result, "signal_thread: sigwait failed");
+
+#if defined(ENABLE_THREADS)
+               thread_set_state_runnable(t);
+#endif
+
+               /* Handle the signal. */
+
+               signal_thread_handler(sig);
+       }
+}
+
+
+/* signal_thread_handler *******************************************************
+
+   Handles the signals caught in the signal handler thread.  Also used
+   from sun.misc.Signal with OpenJDK.
+
+*******************************************************************************/
+
+void signal_thread_handler(int sig)
+{
+       switch (sig) {
+       case SIGINT:
+               /* exit the vm properly */
+
+               vm_exit(1);
+               break;
+
+       case SIGQUIT:
+               /* print a thread dump */
+#if defined(ENABLE_THREADS)
+               ThreadList::dump_threads();
+#endif
+
+#if defined(ENABLE_STATISTICS)
+               if (opt_stat)
+                       statistics_print_memory_usage();
+#endif
+               break;
+
+#if defined(WITH_JAVA_RUNTIME_LIBRARY_OPENJDK)
+       default: {
+               // For OpenJDK we dispatch all unknown signals to Java.
+               methodinfo* m = class_resolvemethod(class_sun_misc_Signal, utf_dispatch, utf_int__void);
+               (void) vm_call_method(m, NULL, sig);
+
+               if (exceptions_get_exception()) {
+                       log_println("signal_thread_handler: Java signal handler throw an exception while dispatching signal %d:", sig);
+                       exceptions_print_stacktrace();
+                       vm_abort("signal_thread_handler: Aborting...");
+               }
+               break;
+       }
+#else
+       default:
+               vm_abort("signal_thread_handler: Unknown signal %d", sig);
+#endif
+       }
+}
+
+
+/* signal_start_thread *********************************************************
+
+   Starts the signal handler thread.
+
+*******************************************************************************/
+
+bool signal_start_thread(void)
+{
+#if defined(ENABLE_THREADS)
+       utf *name;
+
+       name = utf_new_char("Signal Handler");
+
+       if (!threads_thread_start_internal(name, signal_thread))
+               return false;
+
+       /* everything's ok */
+
+       return true;
+#else
+#warning FIX ME!
+#endif
+}
+
+
+/* signal_handler_sighup *******************************************************
+
+   This handler is required by threads_thread_interrupt and does
+   nothing.
+
+*******************************************************************************/
+
+#if defined(ENABLE_THREADS)
+void signal_handler_sighup(int sig, siginfo_t *siginfo, void *_p)
+{
+       /* do nothing */
+}
+#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:
+ */
diff --git a/src/vm/signallocal.h b/src/vm/signallocal.h
deleted file mode 100644 (file)
index 469d949..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-/* src/vm/signallocal.h - machine independent signal 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.
-
-*/
-
-
-#ifndef _CACAO_SIGNAL_H
-#define _CACAO_SIGNAL_H
-
-#include "config.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <signal.h>
-
-#include "vm/global.h"
-
-
-// Signal defines.
-
-#if defined(__LINUX__)
-// See openjdk/jdk/src/solaris/native/java/net/linux_close.c (sigWakeup)
-// See openjdk/jdk/src/solaris/native/sun/nio/ch/NativeThread.c (INTERRUPT_SIGNAL)
-# define Signal_INTERRUPT_SYSTEM_CALL    (__SIGRTMAX - 2)
-#else
-# define Signal_INTERRUPT_SYSTEM_CALL    SIGHUP
-#endif
-
-
-/* function prototypes ********************************************************/
-
-bool  signal_init(void);
-void  signal_register_signal(int signum, functionptr handler, int flags);
-
-void  signal_thread_handler(int sig);
-bool  signal_start_thread(void);
-
-/* machine dependent signal handler */
-
-void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p);
-
-#if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
-void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p);
-#endif
-
-#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__)
-/* XXX use better defines for that (in arch.h) */
-void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p);
-#endif
-
-#if defined(__POWERPC__)
-/* XXX use better defines for that (in arch.h) */
-void md_signal_handler_sigtrap(int sig, siginfo_t *siginfo, void *_p);
-#endif
-
-void md_signal_handler_sigusr1(int sig, siginfo_t *siginfo, void *_p);
-
-void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _CACAO_SIGNAL_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/signallocal.hpp b/src/vm/signallocal.hpp
new file mode 100644 (file)
index 0000000..94d1727
--- /dev/null
@@ -0,0 +1,99 @@
+/* src/vm/signallocal.h - machine independent signal 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.
+
+*/
+
+
+#ifndef _CACAO_SIGNAL_H
+#define _CACAO_SIGNAL_H
+
+#include "config.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <signal.h>
+
+#include "vm/global.h"
+
+
+// Signal defines.
+
+#if defined(__LINUX__)
+// See openjdk/jdk/src/solaris/native/java/net/linux_close.c (sigWakeup)
+// See openjdk/jdk/src/solaris/native/sun/nio/ch/NativeThread.c (INTERRUPT_SIGNAL)
+# define Signal_INTERRUPT_SYSTEM_CALL    (__SIGRTMAX - 2)
+#else
+# define Signal_INTERRUPT_SYSTEM_CALL    SIGHUP
+#endif
+
+
+/* function prototypes ********************************************************/
+
+bool  signal_init(void);
+void  signal_register_signal(int signum, functionptr handler, int flags);
+
+void  signal_thread_handler(int sig);
+bool  signal_start_thread(void);
+
+/* machine dependent signal handler */
+
+void md_signal_handler_sigsegv(int sig, siginfo_t *siginfo, void *_p);
+
+#if SUPPORT_HARDWARE_DIVIDE_BY_ZERO
+void md_signal_handler_sigfpe(int sig, siginfo_t *siginfo, void *_p);
+#endif
+
+#if defined(__ALPHA__) || defined(__ARM__) || defined(__I386__) || defined(__MIPS__) || defined(__POWERPC__) || defined(__POWERPC64__) || defined(__S390__) || defined(__X86_64__) || defined(__M68K__)
+/* XXX use better defines for that (in arch.h) */
+void md_signal_handler_sigill(int sig, siginfo_t *siginfo, void *_p);
+#endif
+
+#if defined(__POWERPC__)
+/* XXX use better defines for that (in arch.h) */
+void md_signal_handler_sigtrap(int sig, siginfo_t *siginfo, void *_p);
+#endif
+
+void md_signal_handler_sigusr1(int sig, siginfo_t *siginfo, void *_p);
+
+void md_signal_handler_sigusr2(int sig, siginfo_t *siginfo, void *_p);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _CACAO_SIGNAL_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 87117d05e8f6dc3a6590b4da9be4c53286bb178a..d4886be3460dcf0feb0ab4602b9be08f01becd52 100644 (file)
@@ -26,7 +26,7 @@
 #include "config.h"
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/class.hpp"
 #include "vm/exceptions.hpp"
index 27926b52e5fb1f2e5f08bc42de808c80f50eceb3..9c07ef78b47af9ea09433e58e58bb31a1d9a0b6e 100644 (file)
@@ -44,7 +44,7 @@
 
 #include "mm/gc.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/class.hpp"
 #include "vm/field.hpp"
index 184f8f66cf742b936a148e9e9b386598f2a4259a..632f69e040da2314fe6adae59b1bbb039173f403 100644 (file)
@@ -33,7 +33,7 @@
 
 #include "vm/global.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/llni.h"
 
index 1c1664a7ed4dfb94c2a78762701ddf57ff6668fc..1c801c5636fb2756ec89acb067fdc5ed7e0d8247 100644 (file)
 
 #include "arch.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/mutex.hpp"
 
 #include "toolbox/list.hpp"
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 #include "toolbox/util.h"
 
 #include "vm/exceptions.hpp"
index 1d7d7605fae6a4565acb47c69aabb3e3eb8c4479..ccc5e0f745e407d7aa730363b51527ce12adbd2a 100644 (file)
@@ -30,7 +30,7 @@
 
 #include "vm/types.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "threads/mutex.hpp"
 
index 3cd7343b50966ba29fee481e715198c99d70141b..448e4a7e99992f0a3f506316c970979bf3ffd391 100644 (file)
@@ -43,7 +43,7 @@
 #include "mm/codememory.h"
 #include "mm/dumpmemory.hpp"
 #include "mm/gc.hpp"
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "native/jni.hpp"
 #include "native/llni.h"
@@ -55,7 +55,7 @@
 #include "threads/lock.hpp"
 #include "threads/thread.hpp"
 
-#include "toolbox/logging.h"
+#include "toolbox/logging.hpp"
 
 #include "vm/array.hpp"
 
@@ -66,7 +66,7 @@
 #include "vm/jit/builtin.hpp"
 #include "vm/classcache.hpp"
 #include "vm/exceptions.hpp"
-#include "vm/finalizer.h"
+#include "vm/finalizer.hpp"
 #include "vm/global.h"
 #include "vm/globals.hpp"
 #include "vm/initialize.hpp"
@@ -74,7 +74,7 @@
 #include "vm/os.hpp"
 #include "vm/primitive.hpp"
 #include "vm/properties.hpp"
-#include "vm/signallocal.h"
+#include "vm/signallocal.hpp"
 #include "vm/statistics.h"
 #include "vm/string.hpp"
 #include "vm/suck.hpp"
@@ -189,6 +189,8 @@ enum {
        OPT_MS,
        OPT_MX,
 
+       OPT_XCHECK_JNI,
+
        /* CACAO options */
 
        OPT_VERBOSE1,
@@ -212,6 +214,8 @@ enum {
 
 #if defined(ENABLE_VERIFIER)
        OPT_NOVERIFY,
+       OPT_XVERIFY_ALL,
+       OPT_XVERIFY_NONE,
 #if defined(TYPECHECK_VERBOSE)
        OPT_VERBOSETC,
 #endif
@@ -304,7 +308,8 @@ opt_struct opts[] = {
        { "noasyncgc",         false, OPT_IGNORE },
 #if defined(ENABLE_VERIFIER)
        { "noverify",          false, OPT_NOVERIFY },
-       { "Xverify:none",      false, OPT_NOVERIFY },
+       { "Xverify:all",       false, OPT_XVERIFY_ALL },
+       { "Xverify:none",      false, OPT_XVERIFY_NONE },
 #endif
        { "v",                 false, OPT_VERBOSE1 },
        { "verbose:",          true,  OPT_VERBOSE },
@@ -376,6 +381,8 @@ opt_struct opts[] = {
        { "Xss",               true,  OPT_SS },
        { "ss",                true,  OPT_SS },
 
+       { "Xcheck:jni",        false, OPT_XCHECK_JNI },
+
 #if defined(ENABLE_PROFILING)
        { "Xprof:",            true,  OPT_PROF_OPTION },
        { "Xprof",             false, OPT_PROF },
@@ -976,6 +983,10 @@ VM::VM(JavaVMInitArgs* vm_args)
                        }
                        break;
 
+               case OPT_XCHECK_JNI:
+                       // HotSpot compatibility option.
+                       break;
+
                case OPT_VERBOSE1:
                        opt_verbose = true;
                        break;
@@ -1028,7 +1039,12 @@ VM::VM(JavaVMInitArgs* vm_args)
                        break;
 
 #if defined(ENABLE_VERIFIER)
+               case OPT_XVERIFY_ALL:
+                       opt_verify = true;
+                       break;
+
                case OPT_NOVERIFY:
+               case OPT_XVERIFY_NONE:
                        opt_verify = false;
                        break;
 #endif
index b9c870c9ec1a8441efdaf09ddb734b8d319b0b4f..601e31d08c7564996f3d67cdc1510b6e571c8cd6 100644 (file)
 
 #include "vm/types.h"
 
-#include "vm/descriptor.h" /* needed to prevent circular dependency */
+#include "vm/descriptor.hpp" /* needed to prevent circular dependency */
 #include "toolbox/hashtable.h"
 
-#include "mm/memory.h"
+#include "mm/memory.hpp"
 
 #include "vm/global.h"
 #include "vm/suck.hpp"
index 94e7d3d33c0fecd07b11cc7ec6d6b87605235627..cdc16f1d5057a15977f449a94d146bb65f77c1ff 100644 (file)
@@ -34,7 +34,11 @@ PR57.class,
 PR58.class,
 PR65.class,
 PR80.class,
-PR89.class
+PR89.class,
+PR112.class,
+PR113.class,
+PR114.class,
+PR116.class
 })
 
 public class All {
diff --git a/tests/regression/bugzilla/PR112.java b/tests/regression/bugzilla/PR112.java
new file mode 100644 (file)
index 0000000..7611ddd
--- /dev/null
@@ -0,0 +1,44 @@
+/* tests/regression/bugzilla/PR112.java
+
+   Copyright (C) 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.
+
+*/
+
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.*;
+
+public class PR112 {
+    @Test ( expected = IllegalArgumentException.class )
+    public void test() throws IllegalArgumentException {
+        // Derived from OpenJDK's jdk jtreg test
+        // java/lang/reflect/Array/ExceedMaxDim.java
+        Object o = Array.newInstance(Integer.TYPE, 0);
+
+        for (int i = 1; i <= 254; i++) {
+            o = Array.newInstance(o.getClass(), 1);
+        }
+
+        o = Array.newInstance(o.getClass(), 1);
+    }
+}
diff --git a/tests/regression/bugzilla/PR113.java b/tests/regression/bugzilla/PR113.java
new file mode 100644 (file)
index 0000000..68662ab
--- /dev/null
@@ -0,0 +1,37 @@
+/* tests/regression/bugzilla/PR112.java
+
+   Copyright (C) 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.
+
+*/
+
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class PR113 {
+    @Test
+    public void test() {
+        // Derived from OpenJDK's jdk jtreg test
+        // java/lang/Class/getModifiers/StripACC_SUPER.java
+       int modifiers = PR113.class.getModifiers();
+       assertFalse(java.lang.reflect.Modifier.isSynchronized(modifiers));
+    }
+}
diff --git a/tests/regression/bugzilla/PR114.java b/tests/regression/bugzilla/PR114.java
new file mode 100644 (file)
index 0000000..84d6fa7
--- /dev/null
@@ -0,0 +1,43 @@
+/* tests/regression/bugzilla/PR114.java
+
+   Copyright (C) 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.
+
+*/
+
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import java.io.File;
+
+public class PR114 {
+    @Test ( expected = NoClassDefFoundError.class )
+    public void test() throws NoClassDefFoundError {
+        // Delete the class file which is extended.
+        new File("PR114$A.class").delete();
+
+        new A().sub();
+    }
+
+    class A {
+        public void sub() {}
+    }
+}
diff --git a/tests/regression/bugzilla/PR116.java b/tests/regression/bugzilla/PR116.java
new file mode 100644 (file)
index 0000000..61cdbc2
--- /dev/null
@@ -0,0 +1,49 @@
+/* tests/regression/bugzilla/PR116.java
+
+   Copyright (C) 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.
+
+*/
+
+
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+import java.lang.reflect.Array;
+
+public class PR116 {
+    private static final int N = 5;
+    private static class Foo {}
+
+    @Test
+    public void test() {
+        for (int i = 1; i <= N; i++) {
+            int[] dim = new int[i];
+            for (int j = 0; j < i; j++)
+                dim[j] = 23;
+
+            Object o = Array.newInstance(Foo.class, dim);
+            //System.out.println("PR116: dim=" + i + ", class='" + o.getClass() + "'");
+
+           assertNotNull(o);
+           assertTrue(o.getClass().isArray());
+        }
+    }
+}